summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java18
-rw-r--r--apex/Android.bp1
-rw-r--r--flags/Android.bp15
-rw-r--r--flags/wifi_flags.aconfig75
-rw-r--r--framework/Android.bp8
-rw-r--r--framework/aidl-export/android/net/wifi/MscsParams.aidl19
-rw-r--r--framework/aidl-export/android/net/wifi/OuiKeyedData.aidl19
-rw-r--r--framework/aidl-export/android/net/wifi/p2p/WifiP2pGroupList.aidl19
-rw-r--r--framework/aidl-export/android/net/wifi/twt/TwtRequest.aidl19
-rw-r--r--framework/api/current.txt105
-rw-r--r--framework/api/lint-baseline.txt2
-rw-r--r--framework/api/module-lib-lint-baseline.txt2
-rw-r--r--framework/api/system-current.txt305
-rw-r--r--framework/api/system-lint-baseline.txt6
-rw-r--r--framework/jarjar-rules.txt2
-rw-r--r--framework/java/android/net/wifi/BaseWifiService.java105
-rw-r--r--framework/java/android/net/wifi/IBooleanListener.aidl2
-rw-r--r--framework/java/android/net/wifi/IByteArrayListener.aidl27
-rw-r--r--framework/java/android/net/wifi/IMapListener.aidl27
-rw-r--r--framework/java/android/net/wifi/IScanDataListener.aidl26
-rw-r--r--framework/java/android/net/wifi/ISoftApCallback.aidl11
-rw-r--r--framework/java/android/net/wifi/ITwtCallback.aidl53
-rw-r--r--framework/java/android/net/wifi/ITwtCapabilitiesListener.aidl29
-rw-r--r--framework/java/android/net/wifi/ITwtStatsListener.aidl29
-rw-r--r--framework/java/android/net/wifi/IWifiManager.aidl45
-rw-r--r--framework/java/android/net/wifi/IWifiScanner.aidl3
-rw-r--r--framework/java/android/net/wifi/MscsParams.java312
-rw-r--r--framework/java/android/net/wifi/OuiKeyedData.java26
-rw-r--r--framework/java/android/net/wifi/ParcelUtil.java17
-rw-r--r--framework/java/android/net/wifi/QosCharacteristics.java726
-rw-r--r--framework/java/android/net/wifi/QosPolicyParams.java73
-rw-r--r--framework/java/android/net/wifi/ScanResult.java407
-rw-r--r--framework/java/android/net/wifi/SoftApConfiguration.java5
-rw-r--r--framework/java/android/net/wifi/SoftApInfo.java59
-rw-r--r--framework/java/android/net/wifi/SoftApState.aidl21
-rw-r--r--framework/java/android/net/wifi/SoftApState.java46
-rw-r--r--framework/java/android/net/wifi/UriParserResults.java212
-rw-r--r--framework/java/android/net/wifi/WifiAnnotations.java10
-rw-r--r--framework/java/android/net/wifi/WifiConfiguration.java383
-rw-r--r--framework/java/android/net/wifi/WifiInfo.java65
-rw-r--r--framework/java/android/net/wifi/WifiManager.java766
-rw-r--r--framework/java/android/net/wifi/WifiNetworkSuggestion.java29
-rw-r--r--framework/java/android/net/wifi/WifiScanner.java45
-rw-r--r--framework/java/android/net/wifi/WifiTwtSession.java107
-rw-r--r--framework/java/android/net/wifi/WifiUriParser.java280
-rw-r--r--framework/java/android/net/wifi/WifiUsabilityStatsEntry.java6
-rw-r--r--framework/java/android/net/wifi/aware/ConfigRequest.java122
-rw-r--r--framework/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl5
-rw-r--r--framework/java/android/net/wifi/aware/PublishConfig.java67
-rw-r--r--framework/java/android/net/wifi/aware/ServiceDiscoveryInfo.java31
-rw-r--r--framework/java/android/net/wifi/aware/SubscribeConfig.java67
-rw-r--r--framework/java/android/net/wifi/aware/WifiAwareManager.java47
-rw-r--r--framework/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java2
-rw-r--r--framework/java/android/net/wifi/p2p/IWifiP2pListener.aidl45
-rw-r--r--framework/java/android/net/wifi/p2p/IWifiP2pManager.aidl4
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pConfig.java53
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pDevice.java133
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pDiscoveryConfig.java226
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pExtListenParams.java149
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pGroup.java93
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pInfo.java5
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pManager.java480
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java48
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pWfdInfo.java2
-rw-r--r--framework/java/android/net/wifi/rtt/RangingRequest.java178
-rw-r--r--framework/java/android/net/wifi/rtt/RangingResult.java784
-rw-r--r--framework/java/android/net/wifi/rtt/ResponderConfig.java337
-rw-r--r--framework/java/android/net/wifi/rtt/WifiRttManager.java9
-rw-r--r--framework/java/android/net/wifi/twt/TwtRequest.java213
-rw-r--r--framework/java/android/net/wifi/twt/TwtSession.java126
-rw-r--r--framework/java/android/net/wifi/twt/TwtSessionCallback.java137
-rw-r--r--framework/tests/src/android/net/wifi/MscsParamsTest.java138
-rw-r--r--framework/tests/src/android/net/wifi/OuiKeyedDataUtil.java52
-rw-r--r--framework/tests/src/android/net/wifi/QosCharacteristicsTest.java282
-rw-r--r--framework/tests/src/android/net/wifi/QosPolicyParamsTest.java47
-rw-r--r--framework/tests/src/android/net/wifi/ScanResultTest.java6
-rw-r--r--framework/tests/src/android/net/wifi/SoftApInfoTest.java21
-rw-r--r--framework/tests/src/android/net/wifi/UriParserResultsTest.java105
-rw-r--r--framework/tests/src/android/net/wifi/WifiConfigurationTest.java28
-rw-r--r--framework/tests/src/android/net/wifi/WifiInfoTest.java18
-rw-r--r--framework/tests/src/android/net/wifi/WifiManagerTest.java253
-rw-r--r--framework/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java18
-rw-r--r--framework/tests/src/android/net/wifi/WifiUriParserTest.java185
-rw-r--r--framework/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java145
-rw-r--r--framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java7
-rw-r--r--framework/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java69
-rw-r--r--framework/tests/src/android/net/wifi/p2p/WifiP2pDiscoveryConfigTest.java84
-rw-r--r--framework/tests/src/android/net/wifi/p2p/WifiP2pExtListenParamsTest.java62
-rw-r--r--framework/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java50
-rw-r--r--framework/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java14
-rw-r--r--framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java125
-rw-r--r--framework/tests/src/android/net/wifi/twt/TwtRequestTest.java57
-rw-r--r--framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java222
-rw-r--r--service/Android.bp2
-rw-r--r--service/ServiceWifiResources/res/values-af/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-am/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ar/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-as/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-az/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-be/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-bg/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-bn/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-bs/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ca/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-cs/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-da/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-de/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-el/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-en-rAU/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-en-rCA/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-en-rGB/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-en-rIN/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-en-rXC/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-es-rUS/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-es/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-et/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-eu/strings.xml8
-rw-r--r--service/ServiceWifiResources/res/values-fa/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-fi/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-fr-feminine/strings.xml22
-rw-r--r--service/ServiceWifiResources/res/values-fr-masculine/strings.xml22
-rw-r--r--service/ServiceWifiResources/res/values-fr-neuter/strings.xml22
-rw-r--r--service/ServiceWifiResources/res/values-fr-rCA/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-fr/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-gl/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-gu/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-hi/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-hr/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-hu/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-hy/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-in/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-is/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-it/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-iw/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ja/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ka/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-kk/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-km/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-kn/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ko/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ky/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-lo/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-lt/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-lv/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-mk/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ml/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-mn/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-mr/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ms/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-my/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-nb/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ne/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-nl/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-or/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-pa/strings.xml8
-rw-r--r--service/ServiceWifiResources/res/values-pl/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-pt-rBR/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-pt-rPT/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-pt/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ro/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ru/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-si/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-sk/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-sl/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-sq/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-sr/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-sv/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-sw/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ta/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-te/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-th/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-tl/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-tr/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-uk/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-ur/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-uz/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-vi/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-zh-rCN/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-zh-rHK/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-zh-rTW/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values-zu/strings.xml4
-rw-r--r--service/ServiceWifiResources/res/values/config.xml59
-rw-r--r--service/ServiceWifiResources/res/values/overlayable.xml8
-rw-r--r--service/ServiceWifiResources/res/values/strings.xml4
-rw-r--r--service/java/com/android/server/wifi/ActiveModeWarden.java40
-rw-r--r--service/java/com/android/server/wifi/ApplicationQosPolicyRequestHandler.java32
-rw-r--r--service/java/com/android/server/wifi/ApplicationQosPolicyTrackingTable.java14
-rw-r--r--service/java/com/android/server/wifi/AvailableNetworkNotifier.java2
-rw-r--r--service/java/com/android/server/wifi/BackupRestoreController.java196
-rw-r--r--service/java/com/android/server/wifi/ClientMode.java2
-rw-r--r--service/java/com/android/server/wifi/ClientModeDefaults.java3
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java325
-rw-r--r--service/java/com/android/server/wifi/ConcreteClientModeManager.java16
-rw-r--r--service/java/com/android/server/wifi/ConnectHelper.java12
-rw-r--r--service/java/com/android/server/wifi/DppManager.java2
-rw-r--r--service/java/com/android/server/wifi/ExternalScoreUpdateObserverProxy.java2
-rw-r--r--service/java/com/android/server/wifi/HalDeviceManager.java7
-rw-r--r--service/java/com/android/server/wifi/HostapdHalAidlImp.java6
-rw-r--r--service/java/com/android/server/wifi/HostapdHalHidlImp.java3
-rw-r--r--service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java67
-rw-r--r--service/java/com/android/server/wifi/InsecureEapNetworkHandler.java14
-rw-r--r--service/java/com/android/server/wifi/InterfaceConflictManager.java2
-rw-r--r--service/java/com/android/server/wifi/LogcatLog.java18
-rw-r--r--service/java/com/android/server/wifi/NetworkSuggestionNominator.java4
-rw-r--r--service/java/com/android/server/wifi/PmkCacheManager.java227
-rw-r--r--service/java/com/android/server/wifi/RestrictedWifiNetworkFactory.java18
-rw-r--r--service/java/com/android/server/wifi/RunnerHandler.java10
-rw-r--r--service/java/com/android/server/wifi/RunnerState.java12
-rw-r--r--service/java/com/android/server/wifi/ScanDetail.java21
-rw-r--r--service/java/com/android/server/wifi/ScanRequestProxy.java3
-rw-r--r--service/java/com/android/server/wifi/SelfRecovery.java22
-rw-r--r--service/java/com/android/server/wifi/SoftApManager.java115
-rw-r--r--service/java/com/android/server/wifi/SoftApModeConfiguration.java14
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java72
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java71
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHal.java51
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java236
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java95
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaNetworkCallbackAidlImpl.java2
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java107
-rw-r--r--service/java/com/android/server/wifi/TwtManager.java651
-rw-r--r--service/java/com/android/server/wifi/UntrustedWifiNetworkFactory.java19
-rw-r--r--service/java/com/android/server/wifi/WifiApConfigStore.java29
-rw-r--r--service/java/com/android/server/wifi/WifiBackupDataV1Parser.java46
-rw-r--r--service/java/com/android/server/wifi/WifiBlocklistMonitor.java11
-rw-r--r--service/java/com/android/server/wifi/WifiCarrierInfoManager.java53
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java48
-rw-r--r--service/java/com/android/server/wifi/WifiConfigurationUtil.java21
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java83
-rw-r--r--service/java/com/android/server/wifi/WifiCountryCode.java28
-rw-r--r--service/java/com/android/server/wifi/WifiDataStall.java2
-rw-r--r--service/java/com/android/server/wifi/WifiDialogManager.java43
-rw-r--r--service/java/com/android/server/wifi/WifiGlobals.java86
-rw-r--r--service/java/com/android/server/wifi/WifiHealthMonitor.java4
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java38
-rw-r--r--service/java/com/android/server/wifi/WifiLastResortWatchdog.java4
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java85
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java450
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java34
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSelector.java159
-rw-r--r--service/java/com/android/server/wifi/WifiPseudonymManager.java2
-rw-r--r--service/java/com/android/server/wifi/WifiRoamingConfigStore.java235
-rw-r--r--service/java/com/android/server/wifi/WifiScoreCard.java6
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java784
-rw-r--r--service/java/com/android/server/wifi/WifiSettingsBackupRestore.java135
-rw-r--r--service/java/com/android/server/wifi/WifiSettingsConfigStore.java77
-rw-r--r--service/java/com/android/server/wifi/WifiShellCommand.java42
-rw-r--r--service/java/com/android/server/wifi/WifiSignalPollResults.java10
-rw-r--r--service/java/com/android/server/wifi/WifiThreadRunner.java17
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java158
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java21
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java21
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java7
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java29
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareStateManager.java246
-rw-r--r--service/java/com/android/server/wifi/b2b/WifiRoamingModeManager.java147
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiNanIface.java15
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiStaIface.java63
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIface.java17
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java42
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java34
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackHidlImpl.java4
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceHidlImpl.java4
-rw-r--r--service/java/com/android/server/wifi/hal/WifiRttController.java12
-rw-r--r--service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java171
-rw-r--r--service/java/com/android/server/wifi/hal/WifiRttControllerHidlImpl.java69
-rw-r--r--service/java/com/android/server/wifi/hal/WifiStaIface.java99
-rw-r--r--service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java353
-rw-r--r--service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java17
-rw-r--r--service/java/com/android/server/wifi/hotspot2/NetworkDetail.java60
-rw-r--r--service/java/com/android/server/wifi/mockwifi/MockWifiServiceUtil.java3
-rw-r--r--service/java/com/android/server/wifi/p2p/ExternalApproverManager.java2
-rw-r--r--service/java/com/android/server/wifi/p2p/ISupplicantP2pIfaceHal.java48
-rw-r--r--service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java185
-rw-r--r--service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImpl.java2
-rw-r--r--service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlV1_4Impl.java2
-rw-r--r--service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java80
-rw-r--r--service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImpl.java231
-rw-r--r--service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImpl.java22
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pMetrics.java158
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pNative.java221
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java1062
-rw-r--r--service/java/com/android/server/wifi/rtt/RttServiceImpl.java143
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java53
-rw-r--r--service/java/com/android/server/wifi/util/ApConfigUtil.java44
-rw-r--r--service/java/com/android/server/wifi/util/HalAidlUtil.java47
-rw-r--r--service/java/com/android/server/wifi/util/InformationElementUtil.java201
-rw-r--r--service/java/com/android/server/wifi/util/IpConfigStore.java4
-rw-r--r--service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java37
-rw-r--r--service/java/com/android/server/wifi/util/WifiPermissionsUtil.java17
-rw-r--r--service/java/com/android/server/wifi/util/XmlUtil.java172
-rw-r--r--service/proto/src/metrics.proto7
-rw-r--r--service/tests/wifitests/Android.bp53
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java181
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyRequestHandlerTest.java62
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyTrackingTableTest.java58
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/AvailableNetworkNotifierTest.java14
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/BackupRestoreControllerTest.java68
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java383
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java30
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ConnectHelperTest.java29
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java18
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/HostapdHalAidlImpTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/HostapdHalHidlImpTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java64
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/MultiInternetWifiNetworkFactoryTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java9
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java48
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/OemWifiNetworkFactoryTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java6
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/OuiKeyedDataUtil.java56
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/RestrictedWifiNetworkFactoryTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java8
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java17
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java436
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java269
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java91
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java39
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/TwtManagerTest.java361
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java60
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java85
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java45
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java35
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java93
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java6
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java163
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java38
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java34
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java30
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java171
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java316
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java159
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java68
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java230
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiPseudonymManagerTest.java12
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiRoamingConfigStoreTest.java162
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java1096
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiSettingsBackupRestoreTest.java132
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java9
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java18
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java10
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java98
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java132
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/b2b/WifiRoamingModeManagerTest.java110
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/entitlement/PseudonymInfoTest.java12
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/HalTestUtils.java75
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceAidlImplTest.java86
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerAidlImplTest.java61
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerHidlImplTest.java21
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceAidlImplTest.java57
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImplTest.java311
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImplTest.java179
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImplTest.java16
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java44
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java116
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java224
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java578
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/rtt/RttMetricsTest.java24
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/rtt/RttServiceImplTest.java42
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/rtt/RttTestUtils.java109
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/HalAidlUtilTest.java43
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java173
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java75
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java95
-rwxr-xr-xwifi_upload_hook.py115
374 files changed, 24053 insertions, 3840 deletions
diff --git a/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java b/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java
index 7bbfed3b8a..4dab628bbc 100644
--- a/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java
+++ b/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java
@@ -246,19 +246,17 @@ public class WifiDialogActivity extends Activity {
@Override
protected void onStop() {
super.onStop();
- if (!isChangingConfigurations()) {
- if (!BuildCompat.isAtLeastU()) {
- // Before U, we don't have INTERNAL_SYSTEM_WINDOW permission to always show at the
- // top, so close all dialogs when we're not visible anymore.
- for (int i = 0; i < mActiveDialogsPerId.size(); i++) {
- mActiveDialogsPerId.valueAt(i).cancel();
- }
+ if (!isChangingConfigurations() && !BuildCompat.isAtLeastU()) {
+ // Before U, we don't have INTERNAL_SYSTEM_WINDOW permission to always show at the
+ // top, so close all dialogs when we're not visible anymore (i.e. another app launches
+ // on top of us).
+ for (int i = 0; i < mActiveDialogsPerId.size(); i++) {
+ mActiveDialogsPerId.valueAt(i).cancel();
}
return;
}
- // If we're stopping due to a configuration change, dismiss all the dialogs without
- // removing it from mLaunchIntentsPerId to prevent window leaking. The dialogs will be
- // recreated from mLaunchIntentsPerId in onStart().
+ // Dismiss all the dialogs without removing it from mLaunchIntentsPerId to prevent window
+ // leaking. The dialogs will be recreated from mLaunchIntentsPerId in onStart().
for (int i = 0; i < mActiveDialogsPerId.size(); i++) {
Dialog dialog = mActiveDialogsPerId.valueAt(i);
// Set the dismiss listener to null to prevent removing the Intent from
diff --git a/apex/Android.bp b/apex/Android.bp
index 276d8166ff..a878695458 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -121,6 +121,7 @@ bootclasspath_fragment {
"android.net.wifi.hotspot2",
"android.net.wifi.p2p",
"android.net.wifi.rtt",
+ "android.net.wifi.twt",
"android.net.wifi.util",
"com.android.wifi",
],
diff --git a/flags/Android.bp b/flags/Android.bp
index ba7141dcb6..f73608a5d8 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -21,6 +21,7 @@ package {
aconfig_declarations {
name: "wifi_aconfig_flags",
package: "com.android.wifi.flags",
+ container: "com.android.wifi",
srcs: ["wifi_flags.aconfig"],
}
@@ -37,4 +38,16 @@ java_aconfig_library {
"//packages/modules/Wifi:__subpackages__",
"//cts/tests/tests/wifi:__subpackages__",
],
-} \ No newline at end of file
+}
+
+java_aconfig_library {
+ name: "wifi_framework_aconfig_flags_lib",
+ aconfig_declarations: "wifi_aconfig_flags",
+ defaults: ["wifi-framework-aconfig-java-defaults"],
+}
+
+java_defaults {
+ name: "wifi-framework-aconfig-java-defaults",
+ sdk_version: "core_platform",
+ libs: ["fake_device_config"],
+}
diff --git a/flags/wifi_flags.aconfig b/flags/wifi_flags.aconfig
index a35702ca92..1b92fff3a8 100644
--- a/flags/wifi_flags.aconfig
+++ b/flags/wifi_flags.aconfig
@@ -1,4 +1,5 @@
package: "com.android.wifi.flags"
+container: "com.android.wifi"
flag {
name: "test_flag_function"
@@ -8,14 +9,6 @@ flag {
}
flag {
- name: "runtime_disable_pno_scan"
- namespace: "wifi"
- description: "Control the API to disable the PNO runtime"
- bug: "282821585"
-}
-
-
-flag {
name: "delay_save_to_store"
namespace: "wifi"
description: "Control the feature delay the save to store in batch to reduce the blocking time"
@@ -30,49 +23,8 @@ flag {
}
flag {
- name: "vendor_parcelable_parameters"
- namespace: "wifi"
- description: "Control the APIs that allow additional vendor-specific parcelables"
- bug: "296069900"
-}
-
-flag {
- name: "verbose_logging_for_aware_only"
- namespace: "wifi"
- description: "Control the API that allow only enable verbose logging for Wifi Aware"
- bug: "289273616"
-}
-
-flag {
- name: "add_channel_stats_per_link"
- namespace: "wifi"
- description: "Control the API that get the channel stats per link from WifiUsabilityStatsEntry"
- bug: "276385220"
-}
-
-flag {
- name: "mlo_link_capabilities_info"
- namespace: "wifi"
- description: "Control the API that get the MLO link capabilities"
- bug: "262643386"
-}
-
-flag {
- name: "disable_reason_unwanted_low_rssi"
- namespace: "wifi"
- description: "Control the API that as disable because of unwanted network under sufficient rssi"
- bug: "262643386"
-}
-
-flag {
- name: "low_latency_lock_listener"
- namespace: "wifi"
- description: "Control the API that add/remove the low latency lock listener"
- bug: "277556184"
-}
-
-flag {
name: "network_provider_battery_charging_status"
+ is_exported: true
namespace: "wifi"
description: "Control the API that allows setting / reading the NetworkProviderInfo's battery charging status"
bug: "305067231"
@@ -80,6 +32,7 @@ flag {
flag {
name: "shared_connectivity_broadcast_receiver_test_api"
+ is_exported: true
namespace: "wifi"
description: "Control the test API for SharedConnectivityManager's getBroadcastReceiver() method"
bug: "305067231"
@@ -93,22 +46,18 @@ flag {
}
flag {
- name: "wep_usage"
- namespace: "wifi"
- description: "Control the API for wep usage"
- bug: "275367422"
-}
-
-flag {
- name: "wpa_personal_usage"
+ name: "android_v_wifi_api"
+ is_exported: true
namespace: "wifi"
- description: "Control the API for wpa personal usage"
- bug: "275367422"
+ description: "For new API added to Android V"
+ bug: "319927407"
+ is_fixed_read_only: true
}
flag {
- name: "add_subscription_id"
+ name: "d2d_when_infra_sta_off"
namespace: "wifi"
- description: "Add new API to set the subscription id in the Wifi Info"
- bug: "236669534"
+ description: "Add new API to configure d2d when infra sta is off"
+ bug: "295792510"
+ is_fixed_read_only: true
}
diff --git a/framework/Android.bp b/framework/Android.bp
index 250b7535a6..4cc0613dbd 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -45,6 +45,7 @@ filegroup {
":framework-wifi-updatable-java-sources",
":framework-wifi-updatable-exported-aidl-sources",
":module-utils-os-aidls",
+ ":wifi_framework_aconfig_flags_lib{.generated_srcjars}",
],
}
@@ -112,6 +113,9 @@ java_defaults {
"androidx.annotation_annotation",
"unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
"app-compat-annotations",
+ // Add aconfig-annotations-lib as a dependency for the optimization
+ "aconfig-annotations-lib",
+ "framework-configinfrastructure",
],
aidl: {
generate_get_transaction_name: true,
@@ -155,7 +159,6 @@ java_sdk_library {
],
impl_only_libs: [
- "framework-location.stubs.module_lib",
"framework-connectivity.stubs.module_lib",
"framework-location.stubs.module_lib",
"framework-tethering.stubs.module_lib",
@@ -182,6 +185,9 @@ java_sdk_library {
"framework-tethering.stubs.module_lib",
],
},
+ api_srcs: [
+ ":wifi_javadoc_only_files",
+ ],
jarjar_rules: ":wifi-jarjar-rules",
diff --git a/framework/aidl-export/android/net/wifi/MscsParams.aidl b/framework/aidl-export/android/net/wifi/MscsParams.aidl
new file mode 100644
index 0000000000..96d378bc9d
--- /dev/null
+++ b/framework/aidl-export/android/net/wifi/MscsParams.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2023, 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 android.net.wifi;
+
+parcelable MscsParams;
diff --git a/framework/aidl-export/android/net/wifi/OuiKeyedData.aidl b/framework/aidl-export/android/net/wifi/OuiKeyedData.aidl
new file mode 100644
index 0000000000..802c5e7b36
--- /dev/null
+++ b/framework/aidl-export/android/net/wifi/OuiKeyedData.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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 android.net.wifi;
+
+parcelable OuiKeyedData;
diff --git a/framework/aidl-export/android/net/wifi/p2p/WifiP2pGroupList.aidl b/framework/aidl-export/android/net/wifi/p2p/WifiP2pGroupList.aidl
new file mode 100644
index 0000000000..eb52254a5a
--- /dev/null
+++ b/framework/aidl-export/android/net/wifi/p2p/WifiP2pGroupList.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2023, 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 android.net.wifi.p2p;
+
+parcelable WifiP2pGroupList;
diff --git a/framework/aidl-export/android/net/wifi/twt/TwtRequest.aidl b/framework/aidl-export/android/net/wifi/twt/TwtRequest.aidl
new file mode 100644
index 0000000000..59b415855f
--- /dev/null
+++ b/framework/aidl-export/android/net/wifi/twt/TwtRequest.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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 android.net.wifi.twt;
+
+parcelable TwtRequest;
diff --git a/framework/api/current.txt b/framework/api/current.txt
index 40d2765497..f48cfe84f1 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -52,8 +52,10 @@ package android.net.wifi {
method @NonNull public int[] getSecurityTypes();
method @Nullable public android.net.wifi.WifiSsid getWifiSsid();
method public int getWifiStandard();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean is80211azNtbResponder();
method public boolean is80211mcResponder();
method public boolean isPasspointNetwork();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean isTwtResponder();
method public void writeToParcel(android.os.Parcel, int);
field public String BSSID;
field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3
@@ -389,6 +391,7 @@ package android.net.wifi {
method public int getNetworkId();
method @Nullable public String getPasspointFqdn();
method @Nullable public String getPasspointProviderFriendlyName();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @Nullable public String getPasspointUniqueId();
method public int getRssi();
method @IntRange(from=0xffffffff) public int getRxLinkSpeedMbps();
method public String getSSID();
@@ -427,7 +430,7 @@ package android.net.wifi {
method @NonNull public android.net.wifi.WifiInfo.Builder setNetworkId(int);
method @NonNull public android.net.wifi.WifiInfo.Builder setRssi(int);
method @NonNull public android.net.wifi.WifiInfo.Builder setSsid(@NonNull byte[]);
- method @FlaggedApi("com.android.wifi.flags.add_subscription_id") @NonNull public android.net.wifi.WifiInfo.Builder setSubscriptionId(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.WifiInfo.Builder setSubscriptionId(int);
}
public class WifiManager {
@@ -463,6 +466,7 @@ package android.net.wifi {
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiNetworkSuggestion> getNetworkSuggestions();
method public void getNumberOfEnabledTdlsSessions(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @Deprecated public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void getPerSsidRoamingModes(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.lang.Integer>>);
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public java.util.List<android.net.wifi.ScanResult> getScanResults();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getStaConcurrencyForMultiInternetMode();
method @NonNull @RequiresPermission(android.Manifest.permission.NEARBY_WIFI_DEVICES) public java.util.List<android.net.wifi.WifiAvailableChannel> getUsableChannels(int, int);
@@ -471,9 +475,11 @@ package android.net.wifi {
method public boolean is5GHzBandSupported();
method public boolean is60GHzBandSupported();
method public boolean is6GHzBandSupported();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean isAggressiveRoamingModeSupported();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isAutoWakeupEnabled();
method public boolean isBridgedApConcurrencySupported();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isCarrierNetworkOffloadEnabled(int, boolean);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean isD2dSupportedWhenInfraStaDisabled();
method public boolean isDecoratedIdentitySupported();
method @Deprecated public boolean isDeviceToApRttSupported();
method public boolean isDualBandSimultaneousSupported();
@@ -499,7 +505,7 @@ package android.net.wifi {
method public boolean isTlsV13Supported();
method public boolean isTrustOnFirstUseSupported();
method public boolean isWapiSupported();
- method @FlaggedApi("com.android.wifi.flags.wep_usage") public boolean isWepSupported();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean isWepSupported();
method public boolean isWifiDisplayR2Supported();
method public boolean isWifiEnabled();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiPasspointEnabled();
@@ -508,9 +514,10 @@ package android.net.wifi {
method public boolean isWpa3SaePublicKeySupported();
method public boolean isWpa3SaeSupported();
method public boolean isWpa3SuiteBSupported();
- method @FlaggedApi("com.android.wifi.flags.wpa_personal_usage") public boolean isWpaPersonalSupported();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean isWpaPersonalSupported();
method @Deprecated public boolean pingSupplicant();
method public void queryAutojoinGlobal(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void querySendDhcpHostnameRestriction(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
method @Deprecated public boolean reassociate();
method @Deprecated public boolean reconnect();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void registerScanResultsCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.ScanResultsCallback);
@@ -521,10 +528,13 @@ package android.net.wifi {
method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public int removeNetworkSuggestions(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>, int);
method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean removeNonCallerConfiguredNetworks();
method @Deprecated public void removePasspointConfiguration(String);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void removePerSsidRoamingMode(@NonNull android.net.wifi.WifiSsid);
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionConnectionStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionConnectionStatusListener);
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeSuggestionUserApprovalStatusListener(@NonNull android.net.wifi.WifiManager.SuggestionUserApprovalStatusListener);
method @RequiresPermission(allOf={android.Manifest.permission.MANAGE_WIFI_INTERFACES, android.Manifest.permission.ACCESS_WIFI_STATE}) public void reportCreateInterfaceImpact(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.BiConsumer<java.lang.Boolean,java.util.Set<android.net.wifi.WifiManager.InterfaceCreationImpact>>);
method @Deprecated public boolean saveConfiguration();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void setPerSsidRoamingMode(@NonNull android.net.wifi.WifiSsid, int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setSendDhcpHostnameRestriction(int);
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabled(@NonNull java.net.InetAddress, boolean, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void setTdlsEnabledWithMacAddress(String, boolean);
@@ -558,8 +568,13 @@ package android.net.wifi {
field @Deprecated public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
field @Deprecated public static final String EXTRA_WIFI_INFO = "wifiInfo";
field public static final String EXTRA_WIFI_STATE = "wifi_state";
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN = 1; // 0x1
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_SECURE = 2; // 0x2
field public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
field public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int ROAMING_MODE_AGGRESSIVE = 2; // 0x2
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int ROAMING_MODE_NONE = 0; // 0x0
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int ROAMING_MODE_NORMAL = 1; // 0x1
field public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
field public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
field public static final int STATUS_LOCAL_ONLY_CONNECTION_FAILURE_ASSOCIATION = 1; // 0x1
@@ -751,6 +766,7 @@ package android.net.wifi {
method public boolean isRestricted();
method public boolean isUntrusted();
method public boolean isUserInteractionRequired();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean isWifi7Enabled();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSuggestion> CREATOR;
field public static final int RANDOMIZATION_NON_PERSISTENT = 1; // 0x1
@@ -781,6 +797,7 @@ package android.net.wifi {
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setUntrusted(boolean);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiEnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWapiPassphrase(@NonNull String);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWifi7Enabled(boolean);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWifiSsid(@NonNull android.net.wifi.WifiSsid);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setWpa2Passphrase(@NonNull String);
@@ -1267,6 +1284,7 @@ package android.net.wifi.p2p {
ctor public WifiP2pDevice();
ctor public WifiP2pDevice(android.net.wifi.p2p.WifiP2pDevice);
method public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @Nullable public java.net.InetAddress getIpAddress();
method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getVendorElements();
method @Nullable public android.net.wifi.p2p.WifiP2pWfdInfo getWfdInfo();
method public boolean isGroupOwner();
@@ -1299,6 +1317,20 @@ package android.net.wifi.p2p {
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDeviceList> CREATOR;
}
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final class WifiP2pDiscoveryConfig implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getFrequencyMhz();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getScanType();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pDiscoveryConfig> CREATOR;
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class WifiP2pDiscoveryConfig.Builder {
+ ctor @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public WifiP2pDiscoveryConfig.Builder(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.p2p.WifiP2pDiscoveryConfig build();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.p2p.WifiP2pDiscoveryConfig.Builder setFrequencyMhz(@IntRange(from=0) int);
+ }
+
public class WifiP2pGroup implements android.os.Parcelable {
ctor public WifiP2pGroup();
ctor public WifiP2pGroup(android.net.wifi.p2p.WifiP2pGroup);
@@ -1349,6 +1381,7 @@ package android.net.wifi.p2p {
method public boolean isGroupClientRemovalSupported();
method public boolean isGroupOwnerIPv6LinkLocalAddressProvided();
method public boolean isSetVendorElementsSupported();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(allOf={android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.ACCESS_WIFI_STATE}, conditional=true) public void registerWifiP2pListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.p2p.WifiP2pManager.WifiP2pListener);
method public void removeClient(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.MacAddress, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void removeExternalApprover(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.MacAddress, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
method public void removeGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
@@ -1369,8 +1402,10 @@ package android.net.wifi.p2p {
method @RequiresPermission(allOf={android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setVendorElements(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull java.util.List<android.net.wifi.ScanResult.InformationElement>, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setWfdInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pWfdInfo, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
method @RequiresPermission(allOf={android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public void startListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(allOf={android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public void startPeerDiscovery(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pDiscoveryConfig, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
method public void stopListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
method public void stopPeerDiscovery(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void unregisterWifiP2pListener(@NonNull android.net.wifi.p2p.WifiP2pManager.WifiP2pListener);
field public static final String ACTION_WIFI_P2P_LISTEN_STATE_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_LISTEN_STATE_CHANGED";
field public static final String ACTION_WIFI_P2P_REQUEST_RESPONSE_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_REQUEST_RESPONSE_CHANGED";
field public static final int BUSY = 2; // 0x2
@@ -1389,6 +1424,12 @@ package android.net.wifi.p2p {
field public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo";
field public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
field public static final String EXTRA_WIFI_STATE = "wifi_p2p_state";
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int GROUP_CREATION_FAILURE_REASON_CONNECTION_CANCELLED = 0; // 0x0
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int GROUP_CREATION_FAILURE_REASON_GROUP_REMOVED = 4; // 0x4
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int GROUP_CREATION_FAILURE_REASON_INVITATION_FAILED = 5; // 0x5
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED = 3; // 0x3
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int GROUP_CREATION_FAILURE_REASON_TIMED_OUT = 1; // 0x1
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int GROUP_CREATION_FAILURE_REASON_USER_REJECTED = 2; // 0x2
field public static final int NO_SERVICE_REQUESTS = 3; // 0x3
field public static final int P2P_UNSUPPORTED = 1; // 0x1
field public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION = "android.net.wifi.p2p.CONNECTION_STATE_CHANGE";
@@ -1398,6 +1439,9 @@ package android.net.wifi.p2p {
field public static final int WIFI_P2P_LISTEN_STARTED = 2; // 0x2
field public static final int WIFI_P2P_LISTEN_STOPPED = 1; // 0x1
field public static final String WIFI_P2P_PEERS_CHANGED_ACTION = "android.net.wifi.p2p.PEERS_CHANGED";
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int WIFI_P2P_SCAN_FULL = 0; // 0x0
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int WIFI_P2P_SCAN_SINGLE_FREQ = 2; // 0x2
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int WIFI_P2P_SCAN_SOCIAL = 1; // 0x1
field public static final String WIFI_P2P_STATE_CHANGED_ACTION = "android.net.wifi.p2p.STATE_CHANGED";
field public static final int WIFI_P2P_STATE_DISABLED = 1; // 0x1
field public static final int WIFI_P2P_STATE_ENABLED = 2; // 0x2
@@ -1475,6 +1519,22 @@ package android.net.wifi.p2p {
method public void onUpnpServiceAvailable(java.util.List<java.lang.String>, android.net.wifi.p2p.WifiP2pDevice);
}
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static interface WifiP2pManager.WifiP2pListener {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onDeviceConfigurationChanged(@Nullable android.net.wifi.p2p.WifiP2pDevice);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onDiscoveryStateChanged(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onFrequencyChanged(@NonNull android.net.wifi.p2p.WifiP2pInfo, @NonNull android.net.wifi.p2p.WifiP2pGroup);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupCreated(@NonNull android.net.wifi.p2p.WifiP2pInfo, @NonNull android.net.wifi.p2p.WifiP2pGroup);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupCreating();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupCreationFailed(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupNegotiationRejectedByUser();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupRemoved();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onListenStateChanged(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onP2pStateChanged(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onPeerClientDisconnected(@NonNull android.net.wifi.p2p.WifiP2pInfo, @NonNull android.net.wifi.p2p.WifiP2pGroup);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onPeerClientJoined(@NonNull android.net.wifi.p2p.WifiP2pInfo, @NonNull android.net.wifi.p2p.WifiP2pGroup);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onPeerListChanged(@NonNull android.net.wifi.p2p.WifiP2pDeviceList);
+ }
+
public final class WifiP2pWfdInfo implements android.os.Parcelable {
ctor public WifiP2pWfdInfo();
ctor public WifiP2pWfdInfo(@Nullable android.net.wifi.p2p.WifiP2pWfdInfo);
@@ -1627,11 +1687,19 @@ package android.net.wifi.rtt {
public final class RangingResult implements android.os.Parcelable {
method public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int get80211azInitiatorTxLtfRepetitionsCount();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int get80211azNumberOfRxSpatialStreams();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int get80211azNumberOfTxSpatialStreams();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int get80211azResponderTxLtfRepetitionsCount();
method public int getDistanceMm();
method public int getDistanceStdDevMm();
+ method @NonNull public byte[] getLci();
+ method @NonNull public byte[] getLcr();
method @Nullable public android.net.MacAddress getMacAddress();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public long getMaxTimeBetweenNtbMeasurementsMicros();
method public int getMeasurementBandwidth();
method public int getMeasurementChannelFrequencyMHz();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public long getMinTimeBetweenNtbMeasurementsMicros();
method public int getNumAttemptedMeasurements();
method public int getNumSuccessfulMeasurements();
method @Nullable public android.net.wifi.aware.PeerHandle getPeerHandle();
@@ -1639,6 +1707,7 @@ package android.net.wifi.rtt {
method public int getRssi();
method public int getStatus();
method @Nullable public android.net.wifi.rtt.ResponderLocation getUnverifiedResponderLocation();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean is80211azNtbMeasurement();
method public boolean is80211mcMeasurement();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.RangingResult> CREATOR;
@@ -1648,6 +1717,33 @@ package android.net.wifi.rtt {
field public static final int UNSPECIFIED = -1; // 0xffffffff
}
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class RangingResult.Builder {
+ ctor public RangingResult.Builder();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult build();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder set80211azInitiatorTxLtfRepetitionsCount(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder set80211azNtbMeasurement(boolean);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder set80211azNumberOfRxSpatialStreams(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder set80211azNumberOfTxSpatialStreams(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder set80211azResponderTxLtfRepetitionsCount(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder set80211mcMeasurement(boolean);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setDistanceMm(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setDistanceStdDevMm(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setLci(@Nullable byte[]);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setLcr(@Nullable byte[]);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setMacAddress(@Nullable android.net.MacAddress);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setMaxTimeBetweenNtbMeasurementsMicros(long);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setMeasurementBandwidth(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setMeasurementChannelFrequencyMHz(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setMinTimeBetweenNtbMeasurementsMicros(long);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setNumAttemptedMeasurements(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setNumSuccessfulMeasurements(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setPeerHandle(@Nullable android.net.wifi.aware.PeerHandle);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setRangingTimestampMillis(long);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setRssi(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setStatus(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setUnverifiedResponderLocation(@Nullable android.net.wifi.rtt.ResponderLocation);
+ }
+
public abstract class RangingResultCallback {
ctor public RangingResultCallback();
method public abstract void onRangingFailure(int);
@@ -1666,6 +1762,7 @@ package android.net.wifi.rtt {
method @Nullable public android.net.MacAddress getMacAddress();
method public int getPreamble();
method public int getResponderType();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean is80211azNtbSupported();
method public boolean is80211mcSupported();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderConfig> CREATOR;
@@ -1676,6 +1773,7 @@ package android.net.wifi.rtt {
public static final class ResponderConfig.Builder {
ctor public ResponderConfig.Builder();
method @NonNull public android.net.wifi.rtt.ResponderConfig build();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.ResponderConfig.Builder set80211azNtbSupported(boolean);
method @NonNull public android.net.wifi.rtt.ResponderConfig.Builder set80211mcSupported(boolean);
method @NonNull public android.net.wifi.rtt.ResponderConfig.Builder setCenterFreq0Mhz(@IntRange(from=0) int);
method @NonNull public android.net.wifi.rtt.ResponderConfig.Builder setCenterFreq1Mhz(@IntRange(from=0) int);
@@ -1733,6 +1831,7 @@ package android.net.wifi.rtt {
field public static final String ACTION_WIFI_RTT_STATE_CHANGED = "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED";
field public static final String CHARACTERISTICS_KEY_BOOLEAN_LCI = "key_lci";
field public static final String CHARACTERISTICS_KEY_BOOLEAN_LCR = "key_lcr";
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final String CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR = "key_ntb_initiator";
field public static final String CHARACTERISTICS_KEY_BOOLEAN_ONE_SIDED_RTT = "key_one_sided_rtt";
field public static final String CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER = "key_sta_responder";
}
diff --git a/framework/api/lint-baseline.txt b/framework/api/lint-baseline.txt
index f44824210d..5c8c1f713b 100644
--- a/framework/api/lint-baseline.txt
+++ b/framework/api/lint-baseline.txt
@@ -77,6 +77,8 @@ RequiresPermission: android.net.wifi.p2p.WifiP2pManager#requestPeers(android.net
Method 'requestPeers' documentation mentions permissions already declared by @RequiresPermission
RequiresPermission: android.net.wifi.p2p.WifiP2pManager#startListening(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener):
Method 'startListening' documentation mentions permissions already declared by @RequiresPermission
+RequiresPermission: android.net.wifi.p2p.WifiP2pManager#startPeerDiscovery(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pDiscoveryConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+ Method 'startPeerDiscovery' documentation mentions permissions already declared by @RequiresPermission
RequiresPermission: android.net.wifi.rtt.WifiRttManager#startRanging(android.net.wifi.rtt.RangingRequest, java.util.concurrent.Executor, android.net.wifi.rtt.RangingResultCallback):
Method 'startRanging' documentation mentions permissions already declared by @RequiresPermission
diff --git a/framework/api/module-lib-lint-baseline.txt b/framework/api/module-lib-lint-baseline.txt
index 24552e0c46..1e141e3355 100644
--- a/framework/api/module-lib-lint-baseline.txt
+++ b/framework/api/module-lib-lint-baseline.txt
@@ -139,6 +139,8 @@ RequiresPermission: android.net.wifi.p2p.WifiP2pManager#requestPersistentGroupIn
Method 'requestPersistentGroupInfo' documentation mentions permissions already declared by @RequiresPermission
RequiresPermission: android.net.wifi.p2p.WifiP2pManager#startListening(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener):
Method 'startListening' documentation mentions permissions already declared by @RequiresPermission
+RequiresPermission: android.net.wifi.p2p.WifiP2pManager#startPeerDiscovery(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pDiscoveryConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+ Method 'startPeerDiscovery' documentation mentions permissions already declared by @RequiresPermission
RequiresPermission: android.net.wifi.rtt.WifiRttManager#startRanging(android.net.wifi.rtt.RangingRequest, java.util.concurrent.Executor, android.net.wifi.rtt.RangingResultCallback):
Method 'startRanging' documentation mentions permissions already declared by @RequiresPermission
RequiresPermission: android.net.wifi.rtt.WifiRttManager#startRanging(android.os.WorkSource, android.net.wifi.rtt.RangingRequest, java.util.concurrent.Executor, android.net.wifi.rtt.RangingResultCallback):
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index d99b5b8a19..444356b641 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -29,17 +29,82 @@ package android.net.wifi {
field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0
}
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") public final class OuiKeyedData implements android.os.Parcelable {
- method @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") public int describeContents();
- method @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") @NonNull public android.os.PersistableBundle getData();
- method @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") public int getOui();
- method @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") public void writeToParcel(@NonNull android.os.Parcel, int);
- field @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.OuiKeyedData> CREATOR;
- }
-
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") public static final class OuiKeyedData.Builder {
- ctor @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") public OuiKeyedData.Builder(int, @NonNull android.os.PersistableBundle);
- method @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") @NonNull public android.net.wifi.OuiKeyedData build();
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final class MscsParams implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getFrameClassifierFields();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=0, to=0x3938700) public int getStreamTimeoutUs();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getUserPriorityBitmap();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=0, to=7) public int getUserPriorityLimit();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.MscsParams> CREATOR;
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FRAME_CLASSIFIER_DSCP = 32; // 0x20
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FRAME_CLASSIFIER_DST_IP_ADDR = 4; // 0x4
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FRAME_CLASSIFIER_DST_PORT = 16; // 0x10
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FRAME_CLASSIFIER_FLOW_LABEL = 128; // 0x80
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FRAME_CLASSIFIER_IP_VERSION = 1; // 0x1
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FRAME_CLASSIFIER_PROTOCOL_NEXT_HDR = 64; // 0x40
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FRAME_CLASSIFIER_SRC_IP_ADDR = 2; // 0x2
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int FRAME_CLASSIFIER_SRC_PORT = 8; // 0x8
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class MscsParams.Builder {
+ ctor @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public MscsParams.Builder();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.MscsParams build();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.MscsParams.Builder setFrameClassifierFields(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.MscsParams.Builder setStreamTimeoutUs(@IntRange(from=0, to=0x3938700) int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.MscsParams.Builder setUserPriorityBitmap(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.MscsParams.Builder setUserPriorityLimit(@IntRange(from=0, to=7) int);
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final class OuiKeyedData implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.os.PersistableBundle getData();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getOui();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.OuiKeyedData> CREATOR;
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class OuiKeyedData.Builder {
+ ctor @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public OuiKeyedData.Builder(int, @NonNull android.os.PersistableBundle);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.OuiKeyedData build();
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final class QosCharacteristics implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getBurstSizeOctets();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=0, to=15) public int getCountExponent();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getDelayBoundMicros();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getDeliveryRatio();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=1, to=java.lang.Short.MAX_VALUE) public int getMaxMsduSizeOctets();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMaxServiceIntervalMicros();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMeanDataRateKbps();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMinDataRateKbps();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMinServiceIntervalMicros();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=1, to=java.lang.Short.MAX_VALUE) public int getMsduLifetimeMillis();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getServiceStartTimeLinkId();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=0, to=java.lang.Integer.MAX_VALUE) public int getServiceStartTimeMicros();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.QosCharacteristics> CREATOR;
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DELIVERY_RATIO_95 = 0; // 0x0
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DELIVERY_RATIO_96 = 1; // 0x1
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DELIVERY_RATIO_97 = 2; // 0x2
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DELIVERY_RATIO_98 = 3; // 0x3
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DELIVERY_RATIO_99 = 5; // 0x5
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DELIVERY_RATIO_99_9 = 6; // 0x6
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DELIVERY_RATIO_99_99 = 7; // 0x7
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DELIVERY_RATIO_99_999 = 8; // 0x8
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DELIVERY_RATIO_99_9999 = 9; // 0x9
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class QosCharacteristics.Builder {
+ ctor @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public QosCharacteristics.Builder(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int, @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int, @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int, @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.QosCharacteristics build();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.QosCharacteristics.Builder setBurstSizeOctets(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.QosCharacteristics.Builder setMaxMsduSizeOctets(@IntRange(from=1, to=java.lang.Short.MAX_VALUE) int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.QosCharacteristics.Builder setMeanDataRateKbps(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.QosCharacteristics.Builder setMsduDeliveryInfo(int, @IntRange(from=0, to=15) int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.QosCharacteristics.Builder setMsduLifetimeMillis(@IntRange(from=1, to=java.lang.Short.MAX_VALUE) int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.QosCharacteristics.Builder setServiceStartTimeInfo(@IntRange(from=0, to=java.lang.Integer.MAX_VALUE) int, int);
}
public final class QosPolicyParams implements android.os.Parcelable {
@@ -53,6 +118,7 @@ package android.net.wifi {
method public int getIpVersion();
method @IntRange(from=1, to=255) public int getPolicyId();
method public int getProtocol();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @Nullable public android.net.wifi.QosCharacteristics getQosCharacteristics();
method @Nullable public java.net.InetAddress getSourceAddress();
method @IntRange(from=android.net.DscpPolicy.SOURCE_PORT_ANY, to=65535) public int getSourcePort();
method public int getUserPriority();
@@ -90,6 +156,7 @@ package android.net.wifi {
method @NonNull public android.net.wifi.QosPolicyParams.Builder setFlowLabel(@Nullable byte[]);
method @NonNull public android.net.wifi.QosPolicyParams.Builder setIpVersion(int);
method @NonNull public android.net.wifi.QosPolicyParams.Builder setProtocol(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.QosPolicyParams.Builder setQosCharacteristics(@Nullable android.net.wifi.QosCharacteristics);
method @NonNull public android.net.wifi.QosPolicyParams.Builder setSourceAddress(@Nullable java.net.InetAddress);
method @NonNull public android.net.wifi.QosPolicyParams.Builder setSourcePort(@IntRange(from=android.net.DscpPolicy.SOURCE_PORT_ANY, to=65535) int);
method @NonNull public android.net.wifi.QosPolicyParams.Builder setUserPriority(int);
@@ -362,7 +429,7 @@ package android.net.wifi {
method public int getMaxNumberOfClients();
method @NonNull public android.net.MacAddress getPersistentRandomizedMacAddress();
method public long getShutdownTimeoutMillis();
- method @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
method @NonNull public java.util.List<android.net.wifi.ScanResult.InformationElement> getVendorElements();
method public boolean isAutoShutdownEnabled();
method public boolean isBridgedModeOpportunisticShutdownEnabled();
@@ -407,7 +474,7 @@ package android.net.wifi {
method @NonNull public android.net.wifi.SoftApConfiguration.Builder setPassphrase(@Nullable String, int);
method @NonNull public android.net.wifi.SoftApConfiguration.Builder setShutdownTimeoutMillis(@IntRange(from=0xffffffff) long);
method @Deprecated @NonNull public android.net.wifi.SoftApConfiguration.Builder setSsid(@Nullable String);
- method @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters") @NonNull public android.net.wifi.SoftApConfiguration.Builder setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.SoftApConfiguration.Builder setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
method @NonNull public android.net.wifi.SoftApConfiguration.Builder setVendorElements(@NonNull java.util.List<android.net.wifi.ScanResult.InformationElement>);
method @NonNull public android.net.wifi.SoftApConfiguration.Builder setWifiSsid(@Nullable android.net.wifi.WifiSsid);
}
@@ -418,7 +485,9 @@ package android.net.wifi {
method public int getBandwidth();
method @Nullable public android.net.MacAddress getBssid();
method public int getFrequency();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
method public int getWifiStandard();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field public static final int CHANNEL_WIDTH_160MHZ = 6; // 0x6
field public static final int CHANNEL_WIDTH_20MHZ = 2; // 0x2
@@ -446,6 +515,18 @@ package android.net.wifi {
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApState> CREATOR;
}
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final class UriParserResults implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @Nullable public String getInformation();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @Nullable public String getPublicKey();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getUriScheme();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @Nullable public android.net.wifi.WifiConfiguration getWifiConfiguration();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.UriParserResults> CREATOR;
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int URI_SCHEME_DPP = 2; // 0x2
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG = 1; // 0x1
+ }
+
public final class WifiClient implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.net.MacAddress getMacAddress();
@@ -467,15 +548,21 @@ package android.net.wifi {
method @Deprecated @NonNull public String getPrintableSsid();
method @Deprecated @NonNull public String getProfileKey();
method @Deprecated public int getRecentFailureReason();
+ method @Deprecated @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
method @Deprecated public boolean hasNoInternetAccess();
method @Deprecated public boolean isEphemeral();
method @Deprecated public static boolean isMetered(@Nullable android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiInfo);
method @Deprecated public boolean isNoInternetAccessExpected();
method @Deprecated public boolean isRepeaterEnabled();
+ method @Deprecated @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean isSendDhcpHostnameEnabled();
+ method @Deprecated @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean isWifi7Enabled();
method @Deprecated public void setBssidAllowlist(@Nullable java.util.List<android.net.MacAddress>);
method @Deprecated public void setDeletionPriority(int) throws java.lang.IllegalArgumentException;
method @Deprecated public void setNetworkSelectionStatus(@NonNull android.net.wifi.WifiConfiguration.NetworkSelectionStatus);
method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setRepeaterEnabled(boolean);
+ method @Deprecated @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setSendDhcpHostnameEnabled(boolean);
+ method @Deprecated @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
+ method @Deprecated @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void setWifi7Enabled(boolean);
field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiConfiguration> CREATOR;
field @Deprecated public static final int INVALID_NETWORK_ID = -1; // 0xffffffff
field @Deprecated public static final int METERED_OVERRIDE_METERED = 1; // 0x1
@@ -540,7 +627,7 @@ package android.net.wifi {
field @Deprecated public static final int DISABLED_NO_INTERNET_PERMANENT = 6; // 0x6
field @Deprecated public static final int DISABLED_NO_INTERNET_TEMPORARY = 4; // 0x4
field @Deprecated public static final int DISABLED_TRANSITION_DISABLE_INDICATION = 13; // 0xd
- field @Deprecated @FlaggedApi("com.android.wifi.flags.disable_reason_unwanted_low_rssi") public static final int DISABLED_UNWANTED_LOW_RSSI = 14; // 0xe
+ field @Deprecated @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int DISABLED_UNWANTED_LOW_RSSI = 14; // 0xe
field @Deprecated public static final int NETWORK_SELECTION_ENABLED = 0; // 0x0
field @Deprecated public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; // 0x2
field @Deprecated public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; // 0x1
@@ -596,6 +683,7 @@ package android.net.wifi {
method public int getScore();
method public double getSuccessfulRxPacketsPerSecond();
method public double getSuccessfulTxPacketsPerSecond();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
method public boolean isApTidToLinkMappingNegotiationSupported();
method public boolean isCarrierMerged();
method public boolean isEphemeral();
@@ -606,6 +694,7 @@ package android.net.wifi {
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean isPrimary();
method public boolean isTrusted();
method @Nullable public static String sanitizeSsid(@Nullable String);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
field public static final int INVALID_RSSI = -127; // 0xffffff81
}
@@ -613,7 +702,7 @@ package android.net.wifi {
public class WifiManager {
method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void addQosPolicies(@NonNull java.util.List<android.net.wifi.QosPolicyParams>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<java.lang.Integer>>);
- method @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void addWifiLowLatencyLockListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiLowLatencyLockListener);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void addWifiLowLatencyLockListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiLowLatencyLockListener);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void addWifiNetworkStateChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiNetworkStateChangedListener);
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void addWifiVerboseLoggingStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiVerboseLoggingStatusChangedListener);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean);
@@ -625,6 +714,8 @@ package android.net.wifi {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK}) public void disableEphemeralNetwork(@NonNull String);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void disableMscs();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void enableMscs(@NonNull android.net.wifi.MscsParams);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset();
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>);
@@ -637,8 +728,8 @@ package android.net.wifi {
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>);
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.Map<android.net.wifi.WifiNetworkSuggestion,java.util.List<android.net.wifi.ScanResult>> getMatchingScanResults(@NonNull java.util.List<android.net.wifi.WifiNetworkSuggestion>, @Nullable java.util.List<android.net.wifi.ScanResult>);
- method @FlaggedApi("com.android.wifi.flags.mlo_link_capabilities_info") @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void getMaxMloAssociationLinkCount(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
- method @FlaggedApi("com.android.wifi.flags.mlo_link_capabilities_info") @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void getMaxMloStrLinkCount(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void getMaxMloAssociationLinkCount(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void getMaxMloStrLinkCount(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method public static int getMaxNumberOfPoliciesPerQosRequest();
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void getMloMode(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void getNetworkSelectionConfig(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.net.wifi.WifiNetworkSelectionConfig>);
@@ -647,7 +738,8 @@ package android.net.wifi {
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}, conditional=true) public android.net.wifi.WifiConfiguration getPrivilegedConnectedNetwork();
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}, conditional=true) public java.util.Set<android.net.wifi.WifiSsid> getSsidsAllowlist();
- method @FlaggedApi("com.android.wifi.flags.mlo_link_capabilities_info") @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void getSupportedSimultaneousBandCombinations(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<int[]>>);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void getSupportedSimultaneousBandCombinations(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<int[]>>);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void getTwtCapabilities(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.os.Bundle>);
method public int getVerboseLoggingLevel();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void getWifiActivityEnergyInfoAsync(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener);
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
@@ -656,7 +748,7 @@ package android.net.wifi {
method public boolean isApMacRandomizationSupported();
method public boolean isConnectedMacRandomizationSupported();
method @Deprecated public boolean isDeviceToDeviceRttSupported();
- method @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener") public boolean isLowLatencyModeSupported();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public boolean isLowLatencyModeSupported();
method public boolean isPortableHotspotSupported();
method public boolean isStaConcurrencyForRestrictedConnectionsSupported();
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public boolean isThirdPartyAppEnablingWifiConfirmationDialogEnabled();
@@ -665,8 +757,9 @@ package android.net.wifi {
method public boolean isWifiScannerSupported();
method @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS) public void notifyMinimumRequiredWifiSecurityLevelChanged(int);
method @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS) public void notifyWifiSsidPolicyChanged(@NonNull android.app.admin.WifiSsidPolicy);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void queryD2dAllowedWhenInfraStaDisabled(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void queryLastConfiguredTetheredApPassphraseSinceBoot(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.String>);
- method @FlaggedApi("com.android.wifi.flags.wep_usage") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void queryWepAllowed(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void queryWepAllowed(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) public void registerActiveCountryCodeChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.ActiveCountryCodeChangedCallback);
method @RequiresPermission(android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS) public void registerCoexCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.CoexCallback);
method @RequiresPermission(android.Manifest.permission.NEARBY_WIFI_DEVICES) public void registerLocalOnlyHotspotSoftApCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback);
@@ -677,19 +770,22 @@ package android.net.wifi {
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void removeAppState(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void removeQosPolicies(@NonNull int[]);
- method @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener") public void removeWifiLowLatencyLockListener(@NonNull android.net.wifi.WifiManager.WifiLowLatencyLockListener);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void removeWifiLowLatencyLockListener(@NonNull android.net.wifi.WifiManager.WifiLowLatencyLockListener);
method public void removeWifiNetworkStateChangedListener(@NonNull android.net.wifi.WifiManager.WifiNetworkStateChangedListener);
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void removeWifiVerboseLoggingStatusChangedListener(@NonNull android.net.wifi.WifiManager.WifiVerboseLoggingStatusChangedListener);
method @RequiresPermission(android.Manifest.permission.RESTART_WIFI_SUBSYSTEM) public void restartWifiSubsystem();
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreBackupData(@NonNull byte[]);
method @Nullable @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public android.net.wifi.SoftApConfiguration restoreSoftApBackupData(@NonNull byte[]);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreSupplicantBackupData(@NonNull byte[], @NonNull byte[]);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void restoreWifiBackupData(@NonNull byte[]);
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveBackupData();
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveSoftApBackupData();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void retrieveWifiBackupData(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setAutoWakeupEnabled(boolean);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setCarrierNetworkOffloadEnabled(int, boolean, boolean);
method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS) public void setCoexUnsafeChannels(@NonNull java.util.List<android.net.wifi.CoexUnsafeChannel>, int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setD2dAllowedWhenInfraStaDisabled(boolean);
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_COUNTRY_CODE) public void setDefaultCountryCode(@NonNull String);
method @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(int);
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION}) public void setExternalPnoScanRequest(@NonNull java.util.List<android.net.wifi.WifiSsid>, @Nullable int[], @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.PnoScanResultsCallback);
@@ -700,7 +796,7 @@ package android.net.wifi {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void setOneShotScreenOnConnectivityScanDelayMillis(@IntRange(from=0) int);
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_COUNTRY_CODE) public void setOverrideCountryCode(@NonNull String);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setPasspointMeteredOverride(@NonNull String, int);
- method @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setPnoScanState(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setPnoScanState(int);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanAlwaysAvailable(boolean);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanThrottleEnabled(boolean);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void setScreenOnScanSchedule(@Nullable java.util.List<android.net.wifi.WifiManager.ScreenOnScanSchedule>);
@@ -710,11 +806,12 @@ package android.net.wifi {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setThirdPartyAppEnablingWifiConfirmationDialogEnabled(boolean);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.DUMP}) public void setVerboseLoggingEnabled(boolean);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.DUMP}) public void setVerboseLoggingLevel(int);
- method @FlaggedApi("com.android.wifi.flags.wep_usage") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setWepAllowed(boolean);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setWepAllowed(boolean);
method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) public boolean setWifiConnectedNetworkScorer(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiConnectedNetworkScorer);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setWifiPasspointEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public boolean setWifiScoringEnabled(boolean);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void setupTwtSession(@NonNull android.net.wifi.twt.TwtRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.twt.TwtSessionCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeResponder(@Nullable String, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
@@ -722,7 +819,7 @@ package android.net.wifi {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startRestrictingAutoJoinToSubscriptionId(int);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(android.os.WorkSource);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startTetheredHotspot(@Nullable android.net.wifi.SoftApConfiguration);
+ method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startTetheredHotspot(@Nullable android.net.wifi.SoftApConfiguration);
method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startTetheredHotspotRequest(@NonNull android.net.TetheringManager.TetheringRequest);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopRestrictingAutoJoinToSubscriptionId();
@@ -756,6 +853,7 @@ package android.net.wifi {
field public static final int API_P2P_DISCOVER_PEERS = 21; // 0x15
field public static final int API_P2P_DISCOVER_PEERS_ON_SOCIAL_CHANNELS = 22; // 0x16
field public static final int API_P2P_DISCOVER_PEERS_ON_SPECIFIC_FREQUENCY = 23; // 0x17
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int API_P2P_DISCOVER_PEERS_WITH_CONFIG_PARAMS = 37; // 0x25
field public static final int API_P2P_REMOVE_GROUP = 29; // 0x1d
field public static final int API_P2P_SET_CHANNELS = 32; // 0x20
field public static final int API_P2P_START_LISTENING = 30; // 0x1e
@@ -765,7 +863,7 @@ package android.net.wifi {
field public static final int API_SCANNING_ENABLED = 1; // 0x1
field public static final int API_SET_NETWORK_SELECTION_CONFIG = 8; // 0x8
field public static final int API_SET_ONE_SHOT_SCREEN_ON_CONNECTIVITY_SCAN_DELAY = 7; // 0x7
- field @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan") public static final int API_SET_PNO_SCAN_ENABLED = 36; // 0x24
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int API_SET_PNO_SCAN_ENABLED = 36; // 0x24
field public static final int API_SET_SCAN_SCHEDULE = 6; // 0x6
field public static final int API_SET_TDLS_ENABLED = 34; // 0x22
field public static final int API_SET_TDLS_ENABLED_WITH_MAC_ADDRESS = 35; // 0x23
@@ -819,9 +917,9 @@ package android.net.wifi {
field public static final int MLO_MODE_LOW_POWER = 3; // 0x3
field public static final int PASSPOINT_HOME_NETWORK = 0; // 0x0
field public static final int PASSPOINT_ROAMING_NETWORK = 1; // 0x1
- field @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan") public static final int PNO_SCAN_STATE_DISABLED_UNTIL_REBOOT = 0; // 0x0
- field @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan") public static final int PNO_SCAN_STATE_DISABLED_UNTIL_WIFI_TOGGLE = 1; // 0x1
- field @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan") public static final int PNO_SCAN_STATE_ENABLED = 2; // 0x2
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int PNO_SCAN_STATE_DISABLED_UNTIL_REBOOT = 0; // 0x0
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int PNO_SCAN_STATE_DISABLED_UNTIL_WIFI_TOGGLE = 1; // 0x1
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int PNO_SCAN_STATE_ENABLED = 2; // 0x2
field public static final int QOS_REQUEST_STATUS_ALREADY_ACTIVE = 1; // 0x1
field public static final int QOS_REQUEST_STATUS_FAILURE_UNKNOWN = 4; // 0x4
field public static final int QOS_REQUEST_STATUS_INSUFFICIENT_RESOURCES = 2; // 0x2
@@ -833,10 +931,15 @@ package android.net.wifi {
field public static final int SAP_START_FAILURE_NO_CHANNEL = 1; // 0x1
field public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; // 0x2
field public static final int SAP_START_FAILURE_USER_REJECTED = 3; // 0x3
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final String TWT_CAPABILITIES_KEY_BOOLEAN_TWT_REQUESTER = "key_requester";
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final String TWT_CAPABILITIES_KEY_INT_MAX_WAKE_DURATION_MICROS = "key_max_wake_duration";
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final String TWT_CAPABILITIES_KEY_INT_MIN_WAKE_DURATION_MICROS = "key_min_wake_duration";
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final String TWT_CAPABILITIES_KEY_LONG_MAX_WAKE_INTERVAL_MICROS = "key_max_wake_interval";
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final String TWT_CAPABILITIES_KEY_LONG_MIN_WAKE_INTERVAL_MICROS = "key_min_wake_interval";
field public static final int VERBOSE_LOGGING_LEVEL_DISABLED = 0; // 0x0
field public static final int VERBOSE_LOGGING_LEVEL_ENABLED = 1; // 0x1
field public static final int VERBOSE_LOGGING_LEVEL_ENABLED_SHOW_KEY = 2; // 0x2
- field @FlaggedApi("com.android.wifi.flags.verbose_logging_for_aware_only") public static final int VERBOSE_LOGGING_LEVEL_WIFI_AWARE_ENABLED_ONLY = 3; // 0x3
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final int VERBOSE_LOGGING_LEVEL_WIFI_AWARE_ENABLED_ONLY = 3; // 0x3
field @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public static final String WIFI_AP_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED";
field public static final int WIFI_AP_STATE_DISABLED = 11; // 0xb
field public static final int WIFI_AP_STATE_DISABLING = 10; // 0xa
@@ -945,10 +1048,10 @@ package android.net.wifi {
method public void onStop(int);
}
- @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener") public static interface WifiManager.WifiLowLatencyLockListener {
- method @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener") public void onActivatedStateChanged(boolean);
- method @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener") public default void onActiveUsersChanged(@NonNull int[]);
- method @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener") public default void onOwnershipChanged(@NonNull int[]);
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static interface WifiManager.WifiLowLatencyLockListener {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void onActivatedStateChanged(boolean);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onActiveUsersChanged(@NonNull int[]);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onOwnershipChanged(@NonNull int[]);
}
public static interface WifiManager.WifiNetworkStateChangedListener {
@@ -1029,6 +1132,7 @@ package android.net.wifi {
method @Deprecated public void configureWifiChange(int, int, int, int, int, android.net.wifi.WifiScanner.BssidInfo[]);
method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
method @NonNull @RequiresPermission(android.Manifest.permission.NEARBY_WIFI_DEVICES) public java.util.List<java.lang.Integer> getAvailableChannels(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.LOCATION_HARDWARE}) public void getCachedScanData(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.net.wifi.WifiScanner.ScanData>);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults();
method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.net.wifi.ScanResult> getSingleScanResults();
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean isScanning();
@@ -1192,6 +1296,10 @@ package android.net.wifi {
field @Deprecated public int unchangedSampleSize;
}
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public class WifiUriParser {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public static android.net.wifi.UriParserResults parseUri(@NonNull String);
+ }
+
public final class WifiUsabilityStatsEntry implements android.os.Parcelable {
method public int describeContents();
method public int getCellularDataNetworkType();
@@ -1220,12 +1328,12 @@ package android.net.wifi {
method public long getTotalBeaconRx();
method public long getTotalBeaconRx(int);
method public long getTotalCcaBusyFreqTimeMillis();
- method @FlaggedApi("com.android.wifi.flags.add_channel_stats_per_link") public long getTotalCcaBusyFreqTimeMillis(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public long getTotalCcaBusyFreqTimeMillis(int);
method public long getTotalHotspot2ScanTimeMillis();
method public long getTotalNanScanTimeMillis();
method public long getTotalPnoScanTimeMillis();
method public long getTotalRadioOnFreqTimeMillis();
- method @FlaggedApi("com.android.wifi.flags.add_channel_stats_per_link") public long getTotalRadioOnFreqTimeMillis(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public long getTotalRadioOnFreqTimeMillis(int);
method public long getTotalRadioOnTimeMillis();
method public long getTotalRadioRxTimeMillis();
method public long getTotalRadioTxTimeMillis();
@@ -1350,6 +1458,19 @@ package android.net.wifi.aware {
field public static final int UNSET_PARAMETER = -1; // 0xffffffff
}
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final class ConfigRequest implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.ConfigRequest> CREATOR;
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class ConfigRequest.Builder {
+ ctor public ConfigRequest.Builder();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.aware.ConfigRequest build();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.aware.ConfigRequest.Builder setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
+ }
+
public class DiscoverySession implements java.lang.AutoCloseable {
method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]);
method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void resume();
@@ -1364,22 +1485,31 @@ package android.net.wifi.aware {
}
public final class PublishConfig implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
method public boolean isSuspendable();
}
public static final class PublishConfig.Builder {
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public android.net.wifi.aware.PublishConfig.Builder setSuspendable(boolean);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.aware.PublishConfig.Builder setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
+ }
+
+ public final class ServiceDiscoveryInfo {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
}
public final class SubscribeConfig implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
method public boolean isSuspendable();
}
public static final class SubscribeConfig.Builder {
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public android.net.wifi.aware.SubscribeConfig.Builder setSuspendable(boolean);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.aware.SubscribeConfig.Builder setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
}
public class WifiAwareManager {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(allOf={android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}, conditional=true) public void attach(@NonNull android.net.wifi.aware.ConfigRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener);
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void attachOffload(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.aware.AttachCallback);
method @RequiresPermission(allOf={android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void enableInstantCommunicationMode(boolean);
method @RequiresPermission(allOf={android.Manifest.permission.OVERRIDE_WIFI_CONFIG, android.Manifest.permission.CHANGE_WIFI_STATE}) public void setAwareParams(@Nullable android.net.wifi.aware.AwareParams);
@@ -1462,13 +1592,46 @@ package android.net.wifi.hotspot2 {
package android.net.wifi.p2p {
public class WifiP2pConfig implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
method public boolean isJoinExistingGroup();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
}
public static final class WifiP2pConfig.Builder {
method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setJoinExistingGroup(boolean);
}
+ public class WifiP2pDevice implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final class WifiP2pDiscoveryConfig implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class WifiP2pDiscoveryConfig.Builder {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.p2p.WifiP2pDiscoveryConfig.Builder setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final class WifiP2pExtListenParams implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pExtListenParams> CREATOR;
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class WifiP2pExtListenParams.Builder {
+ ctor @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public WifiP2pExtListenParams.Builder();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.p2p.WifiP2pExtListenParams build();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.p2p.WifiP2pExtListenParams.Builder setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
+ }
+
+ public class WifiP2pGroup implements android.os.Parcelable {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
+ }
+
public final class WifiP2pGroupList implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.List<android.net.wifi.p2p.WifiP2pGroup> getGroupList();
@@ -1483,6 +1646,7 @@ package android.net.wifi.p2p {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setDeviceName(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull String, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setMiracastMode(int);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setWifiP2pChannels(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(allOf={android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public void startListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pExtListenParams, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener);
field public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED";
field public static final int MIRACAST_DISABLED = 0; // 0x0
field public static final int MIRACAST_SINK = 2; // 0x2
@@ -1493,17 +1657,29 @@ package android.net.wifi.p2p {
method public void onPersistentGroupInfoAvailable(@NonNull android.net.wifi.p2p.WifiP2pGroupList);
}
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static interface WifiP2pManager.WifiP2pListener {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onPersistentGroupsChanged(@NonNull android.net.wifi.p2p.WifiP2pGroupList);
+ }
+
}
package android.net.wifi.rtt {
public final class RangingRequest implements android.os.Parcelable {
method @NonNull public java.util.List<android.net.wifi.rtt.ResponderConfig> getRttResponders();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
+ }
+
+ public static final class RangingRequest.Builder {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingRequest.Builder setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
}
public final class RangingResult implements android.os.Parcelable {
- method @NonNull public byte[] getLci();
- method @NonNull public byte[] getLcr();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public java.util.List<android.net.wifi.OuiKeyedData> getVendorData();
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class RangingResult.Builder {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.rtt.RangingResult.Builder setVendorData(@NonNull java.util.List<android.net.wifi.OuiKeyedData>);
}
public final class ResponderConfig implements android.os.Parcelable {
@@ -1533,6 +1709,7 @@ package android.net.wifi.rtt {
field @Nullable public final android.net.wifi.aware.PeerHandle peerHandle;
field public final int preamble;
field public final int responderType;
+ field @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final boolean supports80211azNtb;
field public final boolean supports80211mc;
}
@@ -1547,3 +1724,57 @@ package android.net.wifi.rtt {
}
+package android.net.wifi.twt {
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public final class TwtRequest implements android.os.Parcelable {
+ method public int describeContents();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @IntRange(from=android.net.wifi.MloLink.INVALID_MLO_LINK_ID, to=0xf) public int getLinkId();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getMaxWakeDurationMicros();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public long getMaxWakeIntervalMicros();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getMinWakeDurationMicros();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public long getMinWakeIntervalMicros();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.twt.TwtRequest> CREATOR;
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static final class TwtRequest.Builder {
+ ctor @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public TwtRequest.Builder(int, int, long, long);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.twt.TwtRequest build();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @NonNull public android.net.wifi.twt.TwtRequest.Builder setLinkId(@IntRange(from=0x0, to=0xf) int);
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public interface TwtSession {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getMloLinkId();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void getStats(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.os.Bundle>);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public int getWakeDurationMicros();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public long getWakeIntervalMicros();
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void teardown();
+ field public static final String TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS = "key_avg_eosp_dur";
+ field public static final String TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_COUNT = "key_avg_rx_pkt_count";
+ field public static final String TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_SIZE = "key_avg_rx_pkt_size";
+ field public static final String TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_COUNT = "key_avg_tx_pkt_count";
+ field public static final String TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_SIZE = "key_avg_tx_pkt_size";
+ field public static final String TWT_STATS_KEY_INT_EOSP_COUNT = "key_eosp_count";
+ }
+
+ @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public interface TwtSessionCallback {
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void onCreate(@NonNull android.net.wifi.twt.TwtSession);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void onFailure(int);
+ method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void onTeardown(int);
+ field public static final int TWT_ERROR_CODE_AP_NOT_SUPPORTED = 1; // 0x1
+ field public static final int TWT_ERROR_CODE_AP_OUI_BLOCKLISTED = 2; // 0x2
+ field public static final int TWT_ERROR_CODE_AP_REJECTED = 3; // 0x3
+ field public static final int TWT_ERROR_CODE_FAIL = 0; // 0x0
+ field public static final int TWT_ERROR_CODE_INVALID_PARAMS = 4; // 0x4
+ field public static final int TWT_ERROR_CODE_MAX_SESSIONS_REACHED = 5; // 0x5
+ field public static final int TWT_ERROR_CODE_NOT_AVAILABLE = 6; // 0x6
+ field public static final int TWT_ERROR_CODE_NOT_SUPPORTED = 7; // 0x7
+ field public static final int TWT_ERROR_CODE_TIMEOUT = 8; // 0x8
+ field public static final int TWT_REASON_CODE_INTERNALLY_INITIATED = 2; // 0x2
+ field public static final int TWT_REASON_CODE_LOCALLY_REQUESTED = 1; // 0x1
+ field public static final int TWT_REASON_CODE_PEER_INITIATED = 3; // 0x3
+ field public static final int TWT_REASON_CODE_UNKNOWN = 0; // 0x0
+ }
+
+}
+
diff --git a/framework/api/system-lint-baseline.txt b/framework/api/system-lint-baseline.txt
index 8bfe131555..4de89f0285 100644
--- a/framework/api/system-lint-baseline.txt
+++ b/framework/api/system-lint-baseline.txt
@@ -47,6 +47,10 @@ DeprecationMismatch: android.net.wifi.WifiScanner.WifiChangeSettings:
Class android.net.wifi.WifiScanner.WifiChangeSettings: @Deprecated annotation (present) and @deprecated doc tag (not present) do not match
+MissingGetterMatchingBuilder: android.net.wifi.QosCharacteristics.Builder#setMsduDeliveryInfo(int, int):
+ android.net.wifi.QosCharacteristics does not declare a `getMsduDeliveryInfo()` method matching method android.net.wifi.QosCharacteristics.Builder.setMsduDeliveryInfo(int,int)
+MissingGetterMatchingBuilder: android.net.wifi.QosCharacteristics.Builder#setServiceStartTimeInfo(int, int):
+ android.net.wifi.QosCharacteristics does not declare a `getServiceStartTimeInfo()` method matching method android.net.wifi.QosCharacteristics.Builder.setServiceStartTimeInfo(int,int)
MissingGetterMatchingBuilder: android.net.wifi.rtt.RangingRequest.Builder#addResponder(android.net.wifi.rtt.ResponderConfig):
@@ -155,6 +159,8 @@ RequiresPermission: android.net.wifi.p2p.WifiP2pManager#requestPersistentGroupIn
Method 'requestPersistentGroupInfo' documentation mentions permissions already declared by @RequiresPermission
RequiresPermission: android.net.wifi.p2p.WifiP2pManager#startListening(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener):
Method 'startListening' documentation mentions permissions already declared by @RequiresPermission
+RequiresPermission: android.net.wifi.p2p.WifiP2pManager#startPeerDiscovery(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pDiscoveryConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener):
+ Method 'startPeerDiscovery' documentation mentions permissions already declared by @RequiresPermission
RequiresPermission: android.net.wifi.rtt.WifiRttManager#startRanging(android.net.wifi.rtt.RangingRequest, java.util.concurrent.Executor, android.net.wifi.rtt.RangingResultCallback):
Method 'startRanging' documentation mentions permissions already declared by @RequiresPermission
RequiresPermission: android.net.wifi.rtt.WifiRttManager#startRanging(android.os.WorkSource, android.net.wifi.rtt.RangingRequest, java.util.concurrent.Executor, android.net.wifi.rtt.RangingResultCallback):
diff --git a/framework/jarjar-rules.txt b/framework/jarjar-rules.txt
index 8c826dc9c9..f1b4000737 100644
--- a/framework/jarjar-rules.txt
+++ b/framework/jarjar-rules.txt
@@ -86,6 +86,8 @@ 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
+
# Use our statically linked bouncy castle library
rule org.bouncycastle.** com.android.wifi.x.@0
# Use our statically linked protobuf library
diff --git a/framework/java/android/net/wifi/BaseWifiService.java b/framework/java/android/net/wifi/BaseWifiService.java
index 7dc7caccc7..3e8ccdd37f 100644
--- a/framework/java/android/net/wifi/BaseWifiService.java
+++ b/framework/java/android/net/wifi/BaseWifiService.java
@@ -21,9 +21,11 @@ import android.annotation.Nullable;
import android.net.DhcpInfo;
import android.net.DhcpOption;
import android.net.Network;
+import android.net.TetheringManager;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.twt.TwtRequest;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
@@ -470,12 +472,24 @@ public class BaseWifiService extends IWifiManager.Stub {
throw new UnsupportedOperationException();
}
+ /**
+ * Following method is deprecated with
+ * {@link #startTetheredHotspotRequest(TetheringManager.TetheringRequest, String)}
+ * @deprecated This is no longer supported.
+ */
+ @Deprecated
@Override
public boolean startTetheredHotspot(SoftApConfiguration softApConfig, String packageName) {
throw new UnsupportedOperationException();
}
@Override
+ public boolean startTetheredHotspotRequest(
+ TetheringManager.TetheringRequest request, String packageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public boolean stopSoftAp() {
throw new UnsupportedOperationException();
}
@@ -619,6 +633,16 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
+ public void retrieveWifiBackupData(@NonNull IByteArrayListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void restoreWifiBackupData(byte[] data) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public byte[] retrieveBackupData() {
throw new UnsupportedOperationException();
}
@@ -774,11 +798,16 @@ public class BaseWifiService extends IWifiManager.Stub {
throw new UnsupportedOperationException();
}
- @Override
+ /** TO BE REMOVED */
public void connect(WifiConfiguration config, int netId, IActionListener callback,
@NonNull String packageName) {
throw new UnsupportedOperationException();
}
+ @Override
+ public void connect(WifiConfiguration config, int netId, IActionListener callback,
+ @NonNull String packageName, Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
@Override
public void startRestrictingAutoJoinToSubscriptionId(int subId) {
@@ -1103,4 +1132,78 @@ public class BaseWifiService extends IWifiManager.Stub {
public void queryWepAllowed(@NonNull IBooleanListener listener) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public void enableMscs(@NonNull MscsParams mscsParams) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void disableMscs() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setSendDhcpHostnameRestriction(@NonNull String packageName,
+ @WifiManager.SendDhcpHostnameRestriction int restriction) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void querySendDhcpHostnameRestriction(@NonNull String packageName,
+ @NonNull IIntegerListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setPerSsidRoamingMode(WifiSsid ssid, @WifiManager.RoamingMode int roamingMode,
+ @NonNull String packageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void removePerSsidRoamingMode(WifiSsid ssid, @NonNull String packageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void getPerSsidRoamingModes(@NonNull String packageName, IMapListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setupTwtSession(TwtRequest twtRequest, ITwtCallback iTwtCallback, Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void getTwtCapabilities(ITwtCapabilitiesListener listener, Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void getStatsTwtSession(int sessionId, ITwtStatsListener iTwtStatsListener,
+ Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void teardownTwtSession(int sessionId, Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setD2dAllowedWhenInfraStaDisabled(boolean isAllowed) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void queryD2dAllowedWhenInfraStaDisabled(@NonNull IBooleanListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isPnoSupported() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/framework/java/android/net/wifi/IBooleanListener.aidl b/framework/java/android/net/wifi/IBooleanListener.aidl
index c1f83fc161..0d933f5188 100644
--- a/framework/java/android/net/wifi/IBooleanListener.aidl
+++ b/framework/java/android/net/wifi/IBooleanListener.aidl
@@ -24,4 +24,4 @@ package android.net.wifi;
oneway interface IBooleanListener
{
void onResult(boolean value);
-} \ No newline at end of file
+}
diff --git a/framework/java/android/net/wifi/IByteArrayListener.aidl b/framework/java/android/net/wifi/IByteArrayListener.aidl
new file mode 100644
index 0000000000..ab7c59ee93
--- /dev/null
+++ b/framework/java/android/net/wifi/IByteArrayListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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 android.net.wifi;
+
+/**
+ * Interface for IByteArrayListener.
+ *
+ * @hide
+ */
+oneway interface IByteArrayListener
+{
+ void onResult(in byte[] byteArray);
+}
diff --git a/framework/java/android/net/wifi/IMapListener.aidl b/framework/java/android/net/wifi/IMapListener.aidl
new file mode 100644
index 0000000000..eb914eb993
--- /dev/null
+++ b/framework/java/android/net/wifi/IMapListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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 android.net.wifi;
+
+/**
+ * Interface for IMapListener.
+ *
+ * @hide
+ */
+oneway interface IMapListener
+{
+ void onResult(in Map value);
+}
diff --git a/framework/java/android/net/wifi/IScanDataListener.aidl b/framework/java/android/net/wifi/IScanDataListener.aidl
new file mode 100644
index 0000000000..eaf845d0a9
--- /dev/null
+++ b/framework/java/android/net/wifi/IScanDataListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 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 android.net.wifi;
+
+import android.net.wifi.WifiScanner.ScanData;
+
+/** @hide */
+
+oneway interface IScanDataListener
+{
+ void onResult(in ScanData scanData);
+}
diff --git a/framework/java/android/net/wifi/ISoftApCallback.aidl b/framework/java/android/net/wifi/ISoftApCallback.aidl
index 3db0a5dfe9..4190e4f3ad 100644
--- a/framework/java/android/net/wifi/ISoftApCallback.aidl
+++ b/framework/java/android/net/wifi/ISoftApCallback.aidl
@@ -15,10 +15,11 @@
*/
package android.net.wifi;
+
import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApInfo;
-
import android.net.wifi.WifiClient;
+import android.net.wifi.SoftApState;
/**
* Interface for Soft AP callback.
@@ -31,13 +32,9 @@ oneway interface ISoftApCallback
* Service to manager callback providing current soft AP state. The possible
* parameter values listed are defined in WifiManager.java
*
- * @param state new AP state. One of WIFI_AP_STATE_DISABLED,
- * WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED,
- * WIFI_AP_STATE_ENABLING, WIFI_AP_STATE_FAILED
- * @param failureReason reason when in failed state. One of
- * SAP_START_FAILURE_GENERAL, SAP_START_FAILURE_NO_CHANNEL
+ * @param new SoftApState
*/
- void onStateChanged(int state, int failureReason);
+ void onStateChanged(in SoftApState state);
/**
* Service to manager callback providing informations of softap.
diff --git a/framework/java/android/net/wifi/ITwtCallback.aidl b/framework/java/android/net/wifi/ITwtCallback.aidl
new file mode 100644
index 0000000000..8adf79ad68
--- /dev/null
+++ b/framework/java/android/net/wifi/ITwtCallback.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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 android.net.wifi;
+
+/**
+ * Interface for target wake time (TWT) callback
+ *
+ * @hide
+ */
+oneway interface ITwtCallback
+{
+ /**
+ * Called when a TWT session setup operation fails.
+ *
+ * @param errorCode setup error code
+ * @hide
+ */
+ void onFailure(int errorCode);
+ /**
+ * Called when a TWT session is torndown. Can be called as a response to
+ * {@link TwtSession#teardown()} or unsolicited. Check the {@link TwtReasonCode} for more
+ * details.
+ *
+ * @param reasonCode Teardown reason code
+ * @hide
+ */
+ void onTeardown(int reasonCode);
+ /**
+ * Called when the TWT session is created.
+ *
+ * @param wakeDuration TWT session wake duration
+ * @param wakeInterval TWT session wake interval
+ * @param mloLinkId Multi link operation link id
+ * @param owner Owner of this session
+ * @param sessionId TWT session id
+ * @hide
+ */
+ void onCreate(int wakeDuration, long wakeInterval, int mloLinkId, int owner, int sessionId);
+}
diff --git a/framework/java/android/net/wifi/ITwtCapabilitiesListener.aidl b/framework/java/android/net/wifi/ITwtCapabilitiesListener.aidl
new file mode 100644
index 0000000000..d0d93c1d7e
--- /dev/null
+++ b/framework/java/android/net/wifi/ITwtCapabilitiesListener.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 android.net.wifi;
+
+import android.os.Bundle;
+
+/**
+ * Interface for TwtCapabilities callback
+ *
+ * @hide
+ */
+oneway interface ITwtCapabilitiesListener
+{
+ void onResult(in Bundle value);
+}
diff --git a/framework/java/android/net/wifi/ITwtStatsListener.aidl b/framework/java/android/net/wifi/ITwtStatsListener.aidl
new file mode 100644
index 0000000000..3b286f21c0
--- /dev/null
+++ b/framework/java/android/net/wifi/ITwtStatsListener.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 android.net.wifi;
+
+import android.os.Bundle;
+
+/**
+ * Interface for TwtStats callback
+ *
+ * @hide
+ */
+oneway interface ITwtStatsListener
+{
+ void onResult(in Bundle value);
+}
diff --git a/framework/java/android/net/wifi/IWifiManager.aidl b/framework/java/android/net/wifi/IWifiManager.aidl
index 6e62c226fa..e3066d7d4b 100644
--- a/framework/java/android/net/wifi/IWifiManager.aidl
+++ b/framework/java/android/net/wifi/IWifiManager.aidl
@@ -23,9 +23,11 @@ import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.DhcpInfo;
import android.net.DhcpOption;
import android.net.Network;
+import android.net.TetheringManager.TetheringRequest;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.IActionListener;
import android.net.wifi.IBooleanListener;
+import android.net.wifi.IByteArrayListener;
import android.net.wifi.ICoexCallback;
import android.net.wifi.IDppCallback;
import android.net.wifi.IIntegerListener;
@@ -34,6 +36,7 @@ import android.net.wifi.ILastCallerListener;
import android.net.wifi.IListListener;
import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.ILocalOnlyConnectionStatusListener;
+import android.net.wifi.IMapListener;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.IOnWifiActivityEnergyInfoListener;
import android.net.wifi.IOnWifiDriverCountryCodeChangedListener;
@@ -47,11 +50,15 @@ import android.net.wifi.ISubsystemRestartCallback;
import android.net.wifi.ISuggestionConnectionStatusListener;
import android.net.wifi.ISuggestionUserApprovalStatusListener;
import android.net.wifi.ITrafficStateCallback;
+import android.net.wifi.ITwtCallback;
+import android.net.wifi.ITwtCapabilitiesListener;
+import android.net.wifi.ITwtStatsListener;
import android.net.wifi.IWifiBandsListener;
import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.IWifiLowLatencyLockListener;
import android.net.wifi.IWifiNetworkSelectionConfigListener;
import android.net.wifi.IWifiVerboseLoggingStatusChangedListener;
+import android.net.wifi.MscsParams;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
@@ -63,6 +70,8 @@ import android.net.wifi.WifiNetworkSelectionConfig;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiSsid;
+import android.net.wifi.twt.TwtRequest;
+
import android.os.Bundle;
import android.os.Messenger;
import android.os.ResultReceiver;
@@ -226,6 +235,8 @@ interface IWifiManager
boolean startTetheredHotspot(in SoftApConfiguration softApConfig, String packageName);
+ boolean startTetheredHotspotRequest(in TetheringRequest request, String packageName);
+
boolean stopSoftAp();
boolean validateSoftApConfiguration(in SoftApConfiguration config);
@@ -342,7 +353,7 @@ interface IWifiManager
void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec);
- oneway void connect(in WifiConfiguration config, int netId, in IActionListener listener, in String packageName);
+ oneway void connect(in WifiConfiguration config, int netId, in IActionListener listener, in String packageName, in Bundle extras);
oneway void save(in WifiConfiguration config, in IActionListener listener, in String packageName);
@@ -472,4 +483,36 @@ interface IWifiManager
void setWepAllowed(boolean isAllowed);
void queryWepAllowed(in IBooleanListener listener);
+
+ void enableMscs(in MscsParams mscsParams);
+
+ void disableMscs();
+
+ void setSendDhcpHostnameRestriction(String packageName, int restriction);
+
+ void querySendDhcpHostnameRestriction(String packageName, in IIntegerListener listener);
+
+ void setPerSsidRoamingMode(in WifiSsid ssid, int roamingMode, String packageName);
+
+ void removePerSsidRoamingMode(in WifiSsid ssid, String packageName);
+
+ void getPerSsidRoamingModes(String packageName,in IMapListener listener);
+
+ void getTwtCapabilities(in ITwtCapabilitiesListener listener, in Bundle extras);
+
+ void setupTwtSession(in TwtRequest twtRequest, in ITwtCallback callback, in Bundle extras);
+
+ void getStatsTwtSession(in int sessionId, in ITwtStatsListener listener, in Bundle extras);
+
+ void teardownTwtSession(in int sessionId, in Bundle extras);
+
+ void setD2dAllowedWhenInfraStaDisabled(boolean isAllowed);
+
+ void queryD2dAllowedWhenInfraStaDisabled(in IBooleanListener listener);
+
+ void retrieveWifiBackupData(in IByteArrayListener listener);
+
+ void restoreWifiBackupData(in byte[] data);
+
+ boolean isPnoSupported();
}
diff --git a/framework/java/android/net/wifi/IWifiScanner.aidl b/framework/java/android/net/wifi/IWifiScanner.aidl
index c819eea101..a0294fc63c 100644
--- a/framework/java/android/net/wifi/IWifiScanner.aidl
+++ b/framework/java/android/net/wifi/IWifiScanner.aidl
@@ -21,6 +21,7 @@ import android.os.Bundle;
import android.os.WorkSource;
import android.net.wifi.WifiScanner;
import android.net.wifi.ScanResult;
+import android.net.wifi.IScanDataListener;
import android.net.wifi.IWifiScannerListener;
/**
@@ -56,6 +57,8 @@ interface IWifiScanner
List<ScanResult> getSingleScanResults(String packageName, String featureId);
+ void getCachedScanData(String packageName, String featureId, in IScanDataListener listener);
+
void startPnoScan(in IWifiScannerListener listener,
in WifiScanner.ScanSettings scanSettings,
in WifiScanner.PnoSettings pnoSettings,
diff --git a/framework/java/android/net/wifi/MscsParams.java b/framework/java/android/net/wifi/MscsParams.java
new file mode 100644
index 0000000000..ee32ab8e2a
--- /dev/null
+++ b/framework/java/android/net/wifi/MscsParams.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2023 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 android.net.wifi;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+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;
+
+/**
+ * Mirrored Stream Classification Service (MSCS) parameters.
+ * Refer to section 3.1 of the Wi-Fi QoS Management Specification v3.0.
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+public final class MscsParams implements Parcelable {
+ /** IP version used by the traffic stream */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FRAME_CLASSIFIER_IP_VERSION = 1 << 0;
+
+ /** Source IP address used by the traffic stream */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FRAME_CLASSIFIER_SRC_IP_ADDR = 1 << 1;
+
+ /** Destination IP address used by the traffic stream */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FRAME_CLASSIFIER_DST_IP_ADDR = 1 << 2;
+
+ /** Source port used by the traffic stream */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FRAME_CLASSIFIER_SRC_PORT = 1 << 3;
+
+ /** Destination port used by the traffic stream */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FRAME_CLASSIFIER_DST_PORT = 1 << 4;
+
+ /** DSCP value used by the traffic stream */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FRAME_CLASSIFIER_DSCP = 1 << 5;
+
+ /** Indicates Protocol if using IPv4, or Next Header if using IPv6 */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FRAME_CLASSIFIER_PROTOCOL_NEXT_HDR = 1 << 6;
+
+ /** Flow label. Only applicable if using IPv6 */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FRAME_CLASSIFIER_FLOW_LABEL = 1 << 7;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = { "FRAME_CLASSIFIER_" }, value = {
+ FRAME_CLASSIFIER_IP_VERSION,
+ FRAME_CLASSIFIER_SRC_IP_ADDR,
+ FRAME_CLASSIFIER_DST_IP_ADDR,
+ FRAME_CLASSIFIER_SRC_PORT,
+ FRAME_CLASSIFIER_DST_PORT,
+ FRAME_CLASSIFIER_DSCP,
+ FRAME_CLASSIFIER_PROTOCOL_NEXT_HDR,
+ FRAME_CLASSIFIER_FLOW_LABEL,
+ })
+ public @interface FrameClassifierField {}
+
+ /** @hide */
+ public static final int DEFAULT_FRAME_CLASSIFIER_FIELDS =
+ FRAME_CLASSIFIER_IP_VERSION
+ | FRAME_CLASSIFIER_SRC_IP_ADDR
+ | FRAME_CLASSIFIER_DST_IP_ADDR
+ | FRAME_CLASSIFIER_SRC_PORT
+ | FRAME_CLASSIFIER_DST_PORT
+ | FRAME_CLASSIFIER_PROTOCOL_NEXT_HDR;
+ /** @hide */
+ public static final int DEFAULT_USER_PRIORITY_BITMAP = (1 << 6) | (1 << 7);
+ /** @hide */
+ public static final int DEFAULT_USER_PRIORITY_LIMIT = 7; // keep the original priority
+ /** @hide */
+ public static final int MAX_STREAM_TIMEOUT_US = 60_000_000; // 60 seconds
+
+ private final int mFrameClassifierFields;
+ private final int mUserPriorityBitmap;
+ private final int mUserPriorityLimit;
+ private final int mStreamTimeoutUs;
+
+ private MscsParams(int frameClassifierFields, int userPriorityBitmap,
+ int userPriorityLimit, int streamTimeoutUs) {
+ mFrameClassifierFields = frameClassifierFields;
+ mUserPriorityBitmap = userPriorityBitmap;
+ mUserPriorityLimit = userPriorityLimit;
+ mStreamTimeoutUs = streamTimeoutUs;
+ }
+
+ /**
+ * Get the frame classifier fields bitmap.
+ * See {@link Builder#setFrameClassifierFields(int)}
+ *
+ * @return Bitmap of {@link FrameClassifierField} represented as an int.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @FrameClassifierField int getFrameClassifierFields() {
+ return mFrameClassifierFields;
+ }
+
+ /**
+ * Get the user priority bitmap. See {@link Builder#setUserPriorityBitmap(int)}
+ *
+ * @return Bitmap of user priorities represented as an int.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int getUserPriorityBitmap() {
+ return mUserPriorityBitmap;
+ }
+
+ /**
+ * Get the user priority limit. See {@link Builder#setUserPriorityLimit(int)}
+ *
+ * @return User priority limit.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 0, to = 7)
+ public int getUserPriorityLimit() {
+ return mUserPriorityLimit;
+ }
+
+ /**
+ * Get the stream timeout in microseconds. See {@link Builder#setStreamTimeoutUs(int)}
+ *
+ * @return Stream timeout in microseconds.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 0, to = MAX_STREAM_TIMEOUT_US)
+ public int getStreamTimeoutUs() {
+ return mStreamTimeoutUs;
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MscsParams that = (MscsParams) o;
+ return mFrameClassifierFields == that.mFrameClassifierFields
+ && mUserPriorityBitmap == that.mUserPriorityBitmap
+ && mUserPriorityLimit == that.mUserPriorityLimit
+ && mStreamTimeoutUs == that.mStreamTimeoutUs;
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Override
+ public int hashCode() {
+ return Objects.hash(mFrameClassifierFields, mUserPriorityBitmap,
+ mUserPriorityLimit, mStreamTimeoutUs);
+ }
+
+ @Override
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mFrameClassifierFields);
+ dest.writeInt(mUserPriorityBitmap);
+ dest.writeInt(mUserPriorityLimit);
+ dest.writeInt(mStreamTimeoutUs);
+ }
+
+ /** @hide */
+ MscsParams(@NonNull Parcel in) {
+ this.mFrameClassifierFields = in.readInt();
+ this.mUserPriorityBitmap = in.readInt();
+ this.mUserPriorityLimit = in.readInt();
+ this.mStreamTimeoutUs = in.readInt();
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final @NonNull Parcelable.Creator<MscsParams> CREATOR =
+ new Parcelable.Creator<MscsParams>() {
+ @Override
+ public MscsParams createFromParcel(Parcel in) {
+ return new MscsParams(in);
+ }
+
+ @Override
+ public MscsParams[] newArray(int size) {
+ return new MscsParams[size];
+ }
+ };
+
+ /** Builder for {@link MscsParams}. */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final class Builder {
+ private int mFrameClassifierFields = DEFAULT_FRAME_CLASSIFIER_FIELDS;
+ private int mUserPriorityBitmap = DEFAULT_USER_PRIORITY_BITMAP;
+ private int mUserPriorityLimit = DEFAULT_USER_PRIORITY_LIMIT;
+ private int mStreamTimeoutUs = MAX_STREAM_TIMEOUT_US;
+
+ /**
+ * Constructor for {@link Builder}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public Builder() {}
+
+ /**
+ * Sets a bitmap of {@link FrameClassifierField} indicating which TCLAS Type 4 frame
+ * classifier fields should be used to build a classifier.
+ *
+ * @param frameClassifierFields Bitmap indicating the requested fields.
+ * @throws IllegalArgumentException if any bits other than bits 0-7 are set.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setFrameClassifierFields(@FrameClassifierField int frameClassifierFields) {
+ if ((frameClassifierFields & 0xFFFFFF00) != 0) {
+ throw new IllegalArgumentException("frameClassifierFields can only use bits 0-7");
+ }
+ mFrameClassifierFields = frameClassifierFields;
+ return this;
+ }
+
+ /**
+ * Sets a bitmap indicating which User Priorities (UPs) should be classified using MSCS.
+ * The least significant bit corresponds to UP 0, and the most significant
+ * bit to UP 7. Setting a bit to 1 indicates that UP should be classified.
+ *
+ * @param userPriorityBitmap Bitmap indicating which UPs should be classified.
+ * @throws IllegalArgumentException if any bits other than bits 0-7 are set.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setUserPriorityBitmap(int userPriorityBitmap) {
+ if ((userPriorityBitmap & 0xFFFFFF00) != 0) {
+ throw new IllegalArgumentException("userPriorityBitmap can only use bits 0-7");
+ }
+ mUserPriorityBitmap = userPriorityBitmap;
+ return this;
+ }
+
+ /**
+ * Sets the maximum user priority that can be assigned using the MSCS service.
+ * Value must be between 0 and 7 (inclusive).
+ *
+ * @param userPriorityLimit Maximum user priority that can be assigned by MSCS.
+ * @throws IllegalArgumentException if the provided value is outside the expected range of
+ * 0-7 (inclusive).
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setUserPriorityLimit(@IntRange(from = 0, to = 7) int userPriorityLimit) {
+ if (userPriorityLimit < 0 || userPriorityLimit > 7) {
+ throw new IllegalArgumentException(
+ "userPriorityLimit must be between 0-7 (inclusive)");
+ }
+ mUserPriorityLimit = userPriorityLimit;
+ return this;
+ }
+
+ /**
+ * Set the minimum timeout (in microseconds) to keep this request in the MSCS list.
+ *
+ * @param streamTimeoutUs Minimum timeout in microseconds.
+ * @throws IllegalArgumentException if the provided value is outside the expected range of
+ * 0-60 seconds (inclusive).
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setStreamTimeoutUs(
+ @IntRange(from = 0, to = MAX_STREAM_TIMEOUT_US) int streamTimeoutUs) {
+ if (streamTimeoutUs < 0 || streamTimeoutUs > MAX_STREAM_TIMEOUT_US) {
+ throw new IllegalArgumentException("streamTimeoutUs must be 60 seconds or less");
+ }
+ mStreamTimeoutUs = streamTimeoutUs;
+ return this;
+ }
+
+ /**
+ * Construct an MscsParams object using the specified parameters.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public MscsParams build() {
+ return new MscsParams(mFrameClassifierFields, mUserPriorityBitmap,
+ mUserPriorityLimit, mStreamTimeoutUs);
+ }
+ }
+}
diff --git a/framework/java/android/net/wifi/OuiKeyedData.java b/framework/java/android/net/wifi/OuiKeyedData.java
index 8f2a153a33..8cd599a5da 100644
--- a/framework/java/android/net/wifi/OuiKeyedData.java
+++ b/framework/java/android/net/wifi/OuiKeyedData.java
@@ -25,6 +25,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
+import com.android.wifi.flags.Flags;
+
import java.util.Objects;
/**
@@ -32,7 +34,7 @@ import java.util.Objects;
*
* @hide
*/
-@FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
public final class OuiKeyedData implements Parcelable {
private static final String TAG = "OuiKeyedData";
@@ -52,7 +54,7 @@ public final class OuiKeyedData implements Parcelable {
*
* <p>See {@link Builder#Builder(int, PersistableBundle)}}
*/
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public int getOui() {
return mOui;
}
@@ -62,7 +64,7 @@ public final class OuiKeyedData implements Parcelable {
*
* <p>See {@link Builder#Builder(int, PersistableBundle)}}
*/
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public @NonNull PersistableBundle getData() {
return mData;
}
@@ -82,7 +84,7 @@ public final class OuiKeyedData implements Parcelable {
return validateOui(mOui) && (getData() != null);
}
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
public boolean equals(@Nullable Object o) {
if (this == o) return true;
@@ -91,25 +93,25 @@ public final class OuiKeyedData implements Parcelable {
return mOui == that.mOui && PersistableBundleUtils.isEqual(mData, that.mData);
}
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
public int hashCode() {
return Objects.hash(mOui, PersistableBundleUtils.getHashCode(mData));
}
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
public String toString() {
return "{oui=" + Integer.toHexString(mOui) + ", data=" + getData() + "}";
}
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
public int describeContents() {
return 0;
}
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mOui);
@@ -122,7 +124,7 @@ public final class OuiKeyedData implements Parcelable {
this.mData = in.readPersistableBundle();
}
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@NonNull
public static final Parcelable.Creator<OuiKeyedData> CREATOR =
new Parcelable.Creator<OuiKeyedData>() {
@@ -138,7 +140,7 @@ public final class OuiKeyedData implements Parcelable {
};
/** Builder for {@link OuiKeyedData}. */
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public static final class Builder {
private final int mOui;
private final @NonNull PersistableBundle mData;
@@ -152,14 +154,14 @@ public final class OuiKeyedData implements Parcelable {
* should be provided by the vendor, and should be known to both the caller and to the
* vendor's implementation of the Wi-Fi HALs.
*/
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public Builder(int oui, @NonNull PersistableBundle data) {
mOui = oui;
mData = data;
}
/** Construct an OuiKeyedData object with the specified parameters. */
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@NonNull
public OuiKeyedData build() {
OuiKeyedData ouiKeyedData = new OuiKeyedData(mOui, mData);
diff --git a/framework/java/android/net/wifi/ParcelUtil.java b/framework/java/android/net/wifi/ParcelUtil.java
index a26877d9b0..470f8a435a 100644
--- a/framework/java/android/net/wifi/ParcelUtil.java
+++ b/framework/java/android/net/wifi/ParcelUtil.java
@@ -16,8 +16,11 @@
package android.net.wifi;
+import android.annotation.NonNull;
import android.os.Parcel;
+import com.android.modules.utils.build.SdkLevel;
+
import java.io.ByteArrayInputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
@@ -28,6 +31,8 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.List;
/**
* Provides utilities for writing/reading a non-Parcelable objects to/from
@@ -162,4 +167,16 @@ public class ParcelUtil {
}
return certs;
}
+
+ /** Read List<OuiKeyedData> from a Parcel. */
+ @NonNull
+ public static List<OuiKeyedData> readOuiKeyedDataList(@NonNull Parcel in) {
+ List<OuiKeyedData> dataList = new ArrayList<>();
+ if (SdkLevel.isAtLeastT()) {
+ in.readList(dataList, OuiKeyedData.class.getClassLoader(), OuiKeyedData.class);
+ } else {
+ in.readList(dataList, OuiKeyedData.class.getClassLoader());
+ }
+ return dataList;
+ }
}
diff --git a/framework/java/android/net/wifi/QosCharacteristics.java b/framework/java/android/net/wifi/QosCharacteristics.java
new file mode 100644
index 0000000000..210d212418
--- /dev/null
+++ b/framework/java/android/net/wifi/QosCharacteristics.java
@@ -0,0 +1,726 @@
+/*
+ * 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 android.net.wifi;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.android.wifi.flags.Flags;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Additional QoS parameters as defined in Section 9.4.2.316
+ * of the IEEE P802.11be/D4.0 Standard.
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+public final class QosCharacteristics implements Parcelable {
+ private static final String TAG = "QosCharacteristics";
+
+ /**
+ * Maximum size of an MSDU.
+ * @hide
+ */
+ public static final int MAX_MSDU_SIZE = 1 << 0;
+
+ /**
+ * Anticipated time and link ID indicating when traffic starts for the associated TID.
+ * @hide
+ */
+ public static final int SERVICE_START_TIME = 1 << 1;
+
+
+ /**
+ * Data rate specified for transport of MSDUs or A-MSDUs belonging to the traffic flow.
+ * @hide
+ */
+ public static final int MEAN_DATA_RATE = 1 << 2;
+
+ /**
+ * Maximum burst of the MSDUs or A-MSDUs belonging to the traffic flow.
+ * @hide
+ */
+ public static final int BURST_SIZE = 1 << 3;
+
+ /**
+ * Maximum amount of time beyond which the MSDU is not useful.
+ * @hide
+ */
+ public static final int MSDU_LIFETIME = 1 << 4;
+
+ /**
+ * MSDU delivery information.
+ * @hide
+ */
+ public static final int MSDU_DELIVERY_INFO = 1 << 5;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, value = {
+ MAX_MSDU_SIZE,
+ SERVICE_START_TIME,
+ MEAN_DATA_RATE,
+ BURST_SIZE,
+ MSDU_LIFETIME,
+ MSDU_DELIVERY_INFO,
+ })
+ public @interface QosCharacteristicsOptionalField {}
+
+ /**
+ * Indicates that 95% of MSDUs are expected to be delivered.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int DELIVERY_RATIO_95 = 0;
+
+ /**
+ * Indicates that 96% of MSDUs are expected to be delivered.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int DELIVERY_RATIO_96 = 1;
+
+ /**
+ * Indicates that 97% of MSDUs are expected to be delivered.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int DELIVERY_RATIO_97 = 2;
+
+ /**
+ * Indicates that 98% of MSDUs are expected to be delivered.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int DELIVERY_RATIO_98 = 3;
+
+ /**
+ * Indicates that 99% of MSDUs are expected to be delivered.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int DELIVERY_RATIO_99 = 5;
+
+ /**
+ * Indicates that 99.9% of MSDUs are expected to be delivered.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int DELIVERY_RATIO_99_9 = 6;
+
+ /**
+ * Indicates that 99.99% of MSDUs are expected to be delivered.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int DELIVERY_RATIO_99_99 = 7;
+
+ /**
+ * Indicates that 99.999% of MSDUs are expected to be delivered.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int DELIVERY_RATIO_99_999 = 8;
+
+ /**
+ * Indicates that 99.9999% of MSDUs are expected to be delivered.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int DELIVERY_RATIO_99_9999 = 9;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ DELIVERY_RATIO_95,
+ DELIVERY_RATIO_96,
+ DELIVERY_RATIO_97,
+ DELIVERY_RATIO_98,
+ DELIVERY_RATIO_99,
+ DELIVERY_RATIO_99_9,
+ DELIVERY_RATIO_99_99,
+ DELIVERY_RATIO_99_999,
+ DELIVERY_RATIO_99_9999,
+ })
+ public @interface DeliveryRatio {}
+
+ private final int mMinServiceIntervalMicros;
+ private final int mMaxServiceIntervalMicros;
+ private final int mMinDataRateKbps;
+ private final int mDelayBoundMicros;
+ private final int mOptionalFieldBitmap;
+ private final int mMaxMsduSizeOctets;
+ private final int mServiceStartTimeMicros;
+ private final int mServiceStartTimeLinkId;
+ private final int mMeanDataRateKbps;
+ private final int mBurstSizeOctets;
+ private final int mMsduLifetimeMillis;
+ private final @DeliveryRatio int mDeliveryRatio;
+ private final int mCountExponent;
+
+ private QosCharacteristics(int minServiceIntervalMicros, int maxServiceIntervalMicros,
+ int minDataRateKbps, int delayBoundMicros, int optionalFieldBitmap,
+ int maxMsduSizeOctets, int serviceStartTimeMicros, int serviceStartTimeLinkId,
+ int meanDataRateKbps, int burstSizeOctets, int msduLifetimeMillis,
+ @DeliveryRatio int deliveryRatio, int countExponent) {
+ mMinServiceIntervalMicros = minServiceIntervalMicros;
+ mMaxServiceIntervalMicros = maxServiceIntervalMicros;
+ mMinDataRateKbps = minDataRateKbps;
+ mDelayBoundMicros = delayBoundMicros;
+ mOptionalFieldBitmap = optionalFieldBitmap;
+ mMaxMsduSizeOctets = maxMsduSizeOctets;
+ mServiceStartTimeMicros = serviceStartTimeMicros;
+ mServiceStartTimeLinkId = serviceStartTimeLinkId;
+ mMeanDataRateKbps = meanDataRateKbps;
+ mBurstSizeOctets = burstSizeOctets;
+ mMsduLifetimeMillis = msduLifetimeMillis;
+ mDeliveryRatio = deliveryRatio;
+ mCountExponent = countExponent;
+ }
+
+ /**
+ * Check whether this instance contains the indicated optional field.
+ * @hide
+ */
+ public boolean containsOptionalField(@QosCharacteristicsOptionalField int field) {
+ return (mOptionalFieldBitmap & field) != 0;
+ }
+
+ /**
+ * Check that the value can be cast to an unsigned integer of size |expectedSizeInBits|.
+ */
+ private static boolean checkSizeInBits(int value, int expectedSizeInBits) {
+ int bitmask = (0x1 << expectedSizeInBits) - 1;
+ return (bitmask & value) == value;
+ }
+
+ /**
+ * Check that the value falls within the provided inclusive range.
+ */
+ private static boolean checkIntRange(int value, int min, int max) {
+ return (value >= min) && (value <= max);
+ }
+
+ /**
+ * Validate the parameters in this instance.
+ * @hide
+ */
+ public boolean validate() {
+ if (mMinServiceIntervalMicros <= 0 || mMaxServiceIntervalMicros <= 0
+ || mMinDataRateKbps <= 0 || mDelayBoundMicros <= 0) {
+ Log.e(TAG, "All mandatory fields must be positive integers");
+ return false;
+ }
+ if (mMinServiceIntervalMicros > mMaxServiceIntervalMicros) {
+ Log.e(TAG, "Minimum service interval must be less than or equal to"
+ + " the maximum service interval");
+ return false;
+ }
+ if (containsOptionalField(MAX_MSDU_SIZE)
+ && !checkIntRange(mMaxMsduSizeOctets, 1, Short.MAX_VALUE)) {
+ Log.e(TAG, "Invalid value provided for maxMsduSize");
+ return false;
+ }
+ if (containsOptionalField(SERVICE_START_TIME)
+ && (mServiceStartTimeMicros < 0
+ || !checkSizeInBits(mServiceStartTimeLinkId, 4))) {
+ Log.e(TAG, "serviceStartTime information is invalid");
+ return false;
+ }
+ if (containsOptionalField(MEAN_DATA_RATE) && mMeanDataRateKbps <= 0) {
+ Log.e(TAG, "meanDataRateKbps must be a positive integer");
+ return false;
+ }
+ if (containsOptionalField(BURST_SIZE) && mBurstSizeOctets == 0) {
+ Log.e(TAG, "burstSizeOctets must be non-zero");
+ return false;
+ }
+ if (containsOptionalField(MSDU_LIFETIME)
+ && !checkIntRange(mMsduLifetimeMillis, 1, Short.MAX_VALUE)) {
+ Log.e(TAG, "Invalid value provided for msduLifetimeMillis");
+ return false;
+ }
+ if (containsOptionalField(MSDU_LIFETIME)
+ && (mMsduLifetimeMillis * 1000) < mDelayBoundMicros) {
+ Log.e(TAG, "MSDU lifetime must be greater than or equal to the delay bound");
+ return false;
+ }
+ if (containsOptionalField(MSDU_DELIVERY_INFO)
+ && !checkIntRange(mDeliveryRatio, DELIVERY_RATIO_95, DELIVERY_RATIO_99_9999)) {
+ Log.e(TAG, "MSDU delivery ratio must be a valid enum value");
+ return false;
+ }
+ if (containsOptionalField(MSDU_DELIVERY_INFO)
+ && !checkIntRange(mCountExponent, 0, 15)) {
+ Log.e(TAG, "MSDU count exponent must be between 0 and 15 (inclusive)");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Get the minimum service interval in microseconds.
+ *
+ * See {@link Builder#Builder(int, int, int, int)} for more information.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 1, to = Integer.MAX_VALUE)
+ public int getMinServiceIntervalMicros() {
+ return mMinServiceIntervalMicros;
+ }
+
+ /**
+ * Get the maximum service interval in microseconds.
+ *
+ * See {@link Builder#Builder(int, int, int, int)} for more information.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 1, to = Integer.MAX_VALUE)
+ public int getMaxServiceIntervalMicros() {
+ return mMaxServiceIntervalMicros;
+ }
+
+ /**
+ * Get the minimum data rate in kilobits per second.
+ *
+ * See {@link Builder#Builder(int, int, int, int)} for more information.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 1, to = Integer.MAX_VALUE)
+ public int getMinDataRateKbps() {
+ return mMinDataRateKbps;
+ }
+
+ /**
+ * Get the delay bound in microseconds.
+ *
+ * See {@link Builder#Builder(int, int, int, int)} for more information.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 1, to = Integer.MAX_VALUE)
+ public int getDelayBoundMicros() {
+ return mDelayBoundMicros;
+ }
+
+ /**
+ * Get the maximum MSDU size in octets. See {@link Builder#setMaxMsduSizeOctets(int)}
+ * for more information.
+ *
+ * @throws IllegalStateException if this field was not set in the Builder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 1, to = Short.MAX_VALUE)
+ public int getMaxMsduSizeOctets() {
+ if (!containsOptionalField(MAX_MSDU_SIZE)) {
+ throw new IllegalStateException("maxMsduSize was not provided in the builder");
+ }
+ return mMaxMsduSizeOctets;
+ }
+
+ /**
+ * Get the service start time in microseconds.
+ * See {@link Builder#setServiceStartTimeInfo(int, int)} for more information.
+ *
+ * @throws IllegalStateException if this field was not set in the Builder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 0, to = Integer.MAX_VALUE)
+ public int getServiceStartTimeMicros() {
+ if (!containsOptionalField(SERVICE_START_TIME)) {
+ throw new IllegalStateException("serviceStartTime was not provided in the builder");
+ }
+ return mServiceStartTimeMicros;
+ }
+
+ /**
+ * Get the service start time link ID. See {@link Builder#setServiceStartTimeInfo(int, int)}
+ * for more information.
+ *
+ * @throws IllegalStateException if this field was not set in the Builder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int getServiceStartTimeLinkId() {
+ if (!containsOptionalField(SERVICE_START_TIME)) {
+ throw new IllegalStateException("serviceStartTime was not provided in the builder");
+ }
+ return mServiceStartTimeLinkId;
+ }
+
+ /**
+ * Get the mean data rate in kilobits per second. See {@link Builder#setMeanDataRateKbps(int)}
+ * for more information.
+ *
+ * @throws IllegalStateException if this field was not set in the Builder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 1, to = Integer.MAX_VALUE)
+ public int getMeanDataRateKbps() {
+ if (!containsOptionalField(MEAN_DATA_RATE)) {
+ throw new IllegalStateException("meanDataRate was not provided in the builder");
+ }
+ return mMeanDataRateKbps;
+ }
+
+ /**
+ * Get the burst size in octets. See {@link Builder#setBurstSizeOctets(int)} for
+ * more information.
+ *
+ * @throws IllegalStateException if this field was not set in the Builder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 1, to = Integer.MAX_VALUE)
+ public int getBurstSizeOctets() {
+ if (!containsOptionalField(BURST_SIZE)) {
+ throw new IllegalStateException("burstSize was not provided in the builder");
+ }
+ return mBurstSizeOctets;
+ }
+
+ /**
+ * Get the MSDU lifetime in milliseconds. See {@link Builder#setMsduLifetimeMillis(int)}
+ * for more information.
+ *
+ * @throws IllegalStateException if this field was not set in the Builder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 1, to = Short.MAX_VALUE)
+ public int getMsduLifetimeMillis() {
+ if (!containsOptionalField(MSDU_LIFETIME)) {
+ throw new IllegalStateException("msduLifetime was not provided in the builder");
+ }
+ return mMsduLifetimeMillis;
+ }
+
+ /**
+ * Get the delivery ratio enum. See {@link Builder#setMsduDeliveryInfo(int, int)} for
+ * more information.
+ *
+ * @throws IllegalStateException if this field was not set in the Builder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @DeliveryRatio int getDeliveryRatio() {
+ if (!containsOptionalField(MSDU_DELIVERY_INFO)) {
+ throw new IllegalStateException("msduDeliveryInfo was not provided in the builder");
+ }
+ return mDeliveryRatio;
+ }
+
+ /**
+ * Get the count exponent. See {@link Builder#setMsduDeliveryInfo(int, int)} for
+ * more information.
+ *
+ * @throws IllegalStateException if this field was not set in the Builder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @IntRange(from = 0, to = 15)
+ public int getCountExponent() {
+ if (!containsOptionalField(MSDU_DELIVERY_INFO)) {
+ throw new IllegalStateException("msduDeliveryInfo was not provided in the builder");
+ }
+ return mCountExponent;
+ }
+
+ @Override
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ QosCharacteristics that = (QosCharacteristics) o;
+ return mMinServiceIntervalMicros == that.mMinServiceIntervalMicros
+ && mMaxServiceIntervalMicros == that.mMaxServiceIntervalMicros
+ && mMinDataRateKbps == that.mMinDataRateKbps
+ && mDelayBoundMicros == that.mDelayBoundMicros
+ && mOptionalFieldBitmap == that.mOptionalFieldBitmap
+ && mMaxMsduSizeOctets == that.mMaxMsduSizeOctets
+ && mServiceStartTimeMicros == that.mServiceStartTimeMicros
+ && mServiceStartTimeLinkId == that.mServiceStartTimeLinkId
+ && mMeanDataRateKbps == that.mMeanDataRateKbps
+ && mBurstSizeOctets == that.mBurstSizeOctets
+ && mMsduLifetimeMillis == that.mMsduLifetimeMillis
+ && mDeliveryRatio == that.mDeliveryRatio
+ && mCountExponent == that.mCountExponent;
+ }
+
+ @Override
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int hashCode() {
+ return Objects.hash(mMinServiceIntervalMicros, mMaxServiceIntervalMicros, mMinDataRateKbps,
+ mDelayBoundMicros, mOptionalFieldBitmap, mMaxMsduSizeOctets,
+ mServiceStartTimeMicros, mServiceStartTimeLinkId, mMeanDataRateKbps,
+ mBurstSizeOctets, mMsduLifetimeMillis, mDeliveryRatio, mCountExponent);
+ }
+
+ @Override
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public String toString() {
+ StringBuilder sb = new StringBuilder("{");
+ sb.append("mMinServiceIntervalMicros=").append(mMinServiceIntervalMicros);
+ sb.append(", mMaxServiceIntervalMicros=").append(mMaxServiceIntervalMicros);
+ sb.append(", mMinDataRateKbps=").append(mMinDataRateKbps);
+ sb.append(", mDelayBoundMicros=").append(mDelayBoundMicros);
+ sb.append(", mOptionalFieldBitmap=").append(String.format("%02x", mOptionalFieldBitmap));
+ if (containsOptionalField(MAX_MSDU_SIZE)) {
+ sb.append(", mMaxMsduSizeOctets=").append(mMaxMsduSizeOctets);
+ }
+ if (containsOptionalField(SERVICE_START_TIME)) {
+ sb.append(", mServiceStartTimeMicros=").append(mServiceStartTimeMicros);
+ sb.append(", mServiceStartTimeLinkId=");
+ sb.append(String.format("%01x", mServiceStartTimeLinkId));
+ }
+ if (containsOptionalField(MEAN_DATA_RATE)) {
+ sb.append(", mMeanDataRateKbps=").append(mMeanDataRateKbps);
+ }
+ if (containsOptionalField(BURST_SIZE)) {
+ sb.append(", mBurstSizeOctets=").append(mBurstSizeOctets);
+ }
+ if (containsOptionalField(MSDU_LIFETIME)) {
+ sb.append(", mMsduLifetimeMillis=").append(mMsduLifetimeMillis);
+ }
+ if (containsOptionalField(MSDU_DELIVERY_INFO)) {
+ sb.append(", mDeliveryRatio=").append(mDeliveryRatio);
+ sb.append(", mCountExponent=").append(mCountExponent);
+ }
+ return sb.append("}").toString();
+ }
+
+ @Override
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int describeContents() {
+ return 0;
+ }
+
+ /** @hide */
+ @Override
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mMinServiceIntervalMicros);
+ dest.writeInt(mMaxServiceIntervalMicros);
+ dest.writeInt(mMinDataRateKbps);
+ dest.writeInt(mDelayBoundMicros);
+ dest.writeInt(mOptionalFieldBitmap);
+ dest.writeInt(mMaxMsduSizeOctets);
+ dest.writeInt(mServiceStartTimeMicros);
+ dest.writeInt(mServiceStartTimeLinkId);
+ dest.writeInt(mMeanDataRateKbps);
+ dest.writeInt(mBurstSizeOctets);
+ dest.writeInt(mMsduLifetimeMillis);
+ dest.writeInt(mDeliveryRatio);
+ dest.writeInt(mCountExponent);
+ }
+
+ /** @hide */
+ QosCharacteristics(@NonNull Parcel in) {
+ this.mMinServiceIntervalMicros = in.readInt();
+ this.mMaxServiceIntervalMicros = in.readInt();
+ this.mMinDataRateKbps = in.readInt();
+ this.mDelayBoundMicros = in.readInt();
+ this.mOptionalFieldBitmap = in.readInt();
+ this.mMaxMsduSizeOctets = in.readInt();
+ this.mServiceStartTimeMicros = in.readInt();
+ this.mServiceStartTimeLinkId = in.readInt();
+ this.mMeanDataRateKbps = in.readInt();
+ this.mBurstSizeOctets = in.readInt();
+ this.mMsduLifetimeMillis = in.readInt();
+ this.mDeliveryRatio = in.readInt();
+ this.mCountExponent = in.readInt();
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final @NonNull Parcelable.Creator<QosCharacteristics> CREATOR =
+ new Parcelable.Creator<QosCharacteristics>() {
+ @Override
+ public QosCharacteristics createFromParcel(Parcel in) {
+ return new QosCharacteristics(in);
+ }
+
+ @Override
+ public QosCharacteristics[] newArray(int size) {
+ return new QosCharacteristics[size];
+ }
+ };
+
+ /**
+ * Builder for {@link QosCharacteristics}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final class Builder {
+ // Mandatory fields
+ private final int mMinServiceIntervalMicros;
+ private final int mMaxServiceIntervalMicros;
+ private final int mMinDataRateKbps;
+ private final int mDelayBoundMicros;
+
+ // Optional fields
+ private int mOptionalFieldBitmap;
+ private int mMaxMsduSizeOctets;
+ private int mServiceStartTimeMicros;
+ private int mServiceStartTimeLinkId;
+ private int mMeanDataRateKbps;
+ private int mBurstSizeOctets;
+ private int mMsduLifetimeMillis;
+ private @DeliveryRatio int mDeliveryRatio;
+ private int mCountExponent;
+
+ /**
+ * Constructor for {@link Builder}.
+ *
+ * @param minServiceIntervalMicros Positive integer specifying the minimum interval (in
+ * microseconds) between the start of two consecutive service
+ * periods (SPs) that are allocated for frame exchanges.
+ * @param maxServiceIntervalMicros Positive integer specifying the maximum interval (in
+ * microseconds) between the start of two consecutive SPs that
+ * are allocated for frame exchanges.
+ * @param minDataRateKbps Positive integer specifying the lowest data rate (in kilobits/sec)
+ * for the transport of MSDUs or A-MSDUs belonging to the traffic
+ * flow.
+ * @param delayBoundMicros Positive integer specifying the maximum amount of time (in
+ * microseconds) targeted to transport an MSDU or A-MSDU belonging to
+ * the traffic flow.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public Builder(@IntRange(from = 1, to = Integer.MAX_VALUE) int minServiceIntervalMicros,
+ @IntRange(from = 1, to = Integer.MAX_VALUE) int maxServiceIntervalMicros,
+ @IntRange(from = 1, to = Integer.MAX_VALUE) int minDataRateKbps,
+ @IntRange(from = 1, to = Integer.MAX_VALUE) int delayBoundMicros) {
+ mMinServiceIntervalMicros = minServiceIntervalMicros;
+ mMaxServiceIntervalMicros = maxServiceIntervalMicros;
+ mMinDataRateKbps = minDataRateKbps;
+ mDelayBoundMicros = delayBoundMicros;
+ }
+
+ /**
+ * Set the maximum MSDU size in octets.
+ *
+ * @param maxMsduSizeOctets Positive integer specifying the maximum size (in octets)
+ * of an MSDU belonging to the traffic flow.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @NonNull Builder setMaxMsduSizeOctets(
+ @IntRange(from = 1, to = Short.MAX_VALUE) int maxMsduSizeOctets) {
+ mOptionalFieldBitmap |= MAX_MSDU_SIZE;
+ mMaxMsduSizeOctets = maxMsduSizeOctets;
+ return this;
+ }
+
+ /**
+ * Set the service start time information.
+ *
+ * @param serviceStartTimeMicros Integer specifying the anticipated time (in microseconds)
+ * when the traffic starts for the associated TID.
+ * @param serviceStartTimeLinkId Bitmap in which the four LSBs indicate the link identifier
+ * that corresponds to the link for which the TSF timer is
+ * used to indicate the Service Start Time. No other bits
+ * should be used.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @NonNull Builder setServiceStartTimeInfo(
+ @IntRange(from = 0, to = Integer.MAX_VALUE) int serviceStartTimeMicros,
+ int serviceStartTimeLinkId) {
+ mOptionalFieldBitmap |= SERVICE_START_TIME;
+ mServiceStartTimeMicros = serviceStartTimeMicros;
+ mServiceStartTimeLinkId = serviceStartTimeLinkId;
+ return this;
+ }
+
+ /**
+ * Set the mean data rate in kilobits per second.
+ *
+ * @param meanDataRateKbps Positive integer indicating the data rate specified (in
+ * kilobits/sec) for transport of MSDUs or A-MSDUs belonging to the
+ * traffic flow.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @NonNull Builder setMeanDataRateKbps(
+ @IntRange(from = 1, to = Integer.MAX_VALUE) int meanDataRateKbps) {
+ mOptionalFieldBitmap |= MEAN_DATA_RATE;
+ mMeanDataRateKbps = meanDataRateKbps;
+ return this;
+ }
+
+ /**
+ * Set the burst size in octets.
+ *
+ * @param burstSizeOctets Positive integer specifying the maximum burst (in octets) of
+ * the MSDUs or A-MSDUs belonging to the traffic flow that arrive at
+ * the MAC SAP within any time duration equal to the value specified
+ * in the |delayBound| field.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @NonNull Builder setBurstSizeOctets(
+ @IntRange(from = 1, to = Integer.MAX_VALUE) int burstSizeOctets) {
+ mOptionalFieldBitmap |= BURST_SIZE;
+ mBurstSizeOctets = burstSizeOctets;
+ return this;
+ }
+
+ /**
+ * Set the MSDU lifetime in milliseconds.
+ *
+ * @param msduLifetimeMillis Positive integer specifying the maximum amount of time (in
+ * milliseconds) since the arrival of the MSDU at the MAC data service
+ * interface beyond which the MSDU is not useful even if received by
+ * the receiver. The amount of time specified in this field is larger
+ * than or equal to the amount of time specified in the |delayBound|
+ * field, if present.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @NonNull Builder setMsduLifetimeMillis(
+ @IntRange(from = 1, to = Short.MAX_VALUE) int msduLifetimeMillis) {
+ mOptionalFieldBitmap |= MSDU_LIFETIME;
+ mMsduLifetimeMillis = msduLifetimeMillis;
+ return this;
+ }
+
+ /**
+ * Set the MSDU delivery information.
+ *
+ * @param deliveryRatio Enum indicating the percentage of the MSDUs that are expected to be
+ * delivered successfully.
+ * @param countExponent Exponent from which the number of incoming MSDUs is computed. The
+ * number of incoming MSDUs is 10^|countExponent|, and is used to
+ * determine the MSDU delivery ratio. Must be a number between
+ * 0 and 15 (inclusive).
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @NonNull Builder setMsduDeliveryInfo(
+ @DeliveryRatio int deliveryRatio, @IntRange(from = 0, to = 15) int countExponent) {
+ mOptionalFieldBitmap |= MSDU_DELIVERY_INFO;
+ mDeliveryRatio = deliveryRatio;
+ mCountExponent = countExponent;
+ return this;
+ }
+
+ /**
+ * Construct a QosCharacteristics object with the specified parameters.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @NonNull QosCharacteristics build() {
+ QosCharacteristics qosCharacteristics = new QosCharacteristics(
+ mMinServiceIntervalMicros, mMaxServiceIntervalMicros,
+ mMinDataRateKbps, mDelayBoundMicros, mOptionalFieldBitmap,
+ mMaxMsduSizeOctets, mServiceStartTimeMicros, mServiceStartTimeLinkId,
+ mMeanDataRateKbps, mBurstSizeOctets, mMsduLifetimeMillis,
+ mDeliveryRatio, mCountExponent);
+ if (!qosCharacteristics.validate()) {
+ throw new IllegalArgumentException("Provided parameters are invalid");
+ }
+ return qosCharacteristics;
+ }
+ }
+}
diff --git a/framework/java/android/net/wifi/QosPolicyParams.java b/framework/java/android/net/wifi/QosPolicyParams.java
index b46abf87e2..29e853bd42 100644
--- a/framework/java/android/net/wifi/QosPolicyParams.java
+++ b/framework/java/android/net/wifi/QosPolicyParams.java
@@ -16,16 +16,23 @@
package android.net.wifi;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.DscpPolicy;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.Inet4Address;
@@ -229,10 +236,14 @@ public final class QosPolicyParams implements Parcelable {
// Flow label. Only applicable to downlink requests using IPv6.
private final @Nullable byte[] mFlowLabel;
+ // QoS characteristics. Mandatory for uplink requests.
+ private final @Nullable QosCharacteristics mQosCharacteristics;
+
private QosPolicyParams(int policyId, int dscp, @UserPriority int userPriority,
@Nullable InetAddress srcIp, @Nullable InetAddress dstIp, int srcPort,
@Protocol int protocol, @Nullable int[] dstPortRange, @Direction int direction,
- @IpVersion int ipVersion, int dstPort, @Nullable byte[] flowLabel) {
+ @IpVersion int ipVersion, int dstPort, @Nullable byte[] flowLabel,
+ @Nullable QosCharacteristics qosCharacteristics) {
this.mPolicyId = policyId;
this.mDscp = dscp;
this.mUserPriority = userPriority;
@@ -245,6 +256,7 @@ public final class QosPolicyParams implements Parcelable {
this.mDirection = direction;
this.mIpVersion = ipVersion;
this.mFlowLabel = flowLabel;
+ this.mQosCharacteristics = qosCharacteristics;
}
/**
@@ -309,11 +321,15 @@ public final class QosPolicyParams implements Parcelable {
return false;
}
}
+ if (mQosCharacteristics != null && !mQosCharacteristics.validate()) {
+ Log.e(TAG, "Invalid QoS characteristics provided");
+ return false;
+ }
// Check required parameters based on direction.
if (mDirection == DIRECTION_UPLINK) {
- if (mDscp == DSCP_ANY) {
- Log.e(TAG, "DSCP must be provided for uplink requests");
+ if (mQosCharacteristics == null) {
+ Log.e(TAG, "QoS characteristics must be provided for uplink requests");
return false;
}
if (mIpVersion != IP_VERSION_ANY) {
@@ -509,6 +525,22 @@ public final class QosPolicyParams implements Parcelable {
return mFlowLabel;
}
+ /**
+ * Get the QoS characteristics for this policy.
+ *
+ * See {@link Builder#setQosCharacteristics(QosCharacteristics)} for more information.
+ *
+ * @return QoS characteristics object, or null if not assigned.
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @Nullable QosCharacteristics getQosCharacteristics() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mQosCharacteristics;
+ }
+
@Override
public boolean equals(@Nullable Object o) {
if (this == o) return true;
@@ -525,14 +557,15 @@ public final class QosPolicyParams implements Parcelable {
&& Arrays.equals(mDstPortRange, that.mDstPortRange)
&& mDirection == that.mDirection
&& mIpVersion == that.mIpVersion
- && mFlowLabel == that.mFlowLabel;
+ && mFlowLabel == that.mFlowLabel
+ && Objects.equals(mQosCharacteristics, that.mQosCharacteristics);
}
@Override
public int hashCode() {
return Objects.hash(mPolicyId, mDscp, mUserPriority, mSrcIp, mDstIp, mSrcPort,
mProtocol, Arrays.hashCode(mDstPortRange), mDirection, mIpVersion, mDstPort,
- Arrays.hashCode(mFlowLabel));
+ Arrays.hashCode(mFlowLabel), mQosCharacteristics);
}
@Override
@@ -548,7 +581,8 @@ public final class QosPolicyParams implements Parcelable {
+ "dstPortRange=" + Arrays.toString(mDstPortRange) + ", "
+ "direction=" + mDirection + ", "
+ "ipVersion=" + mIpVersion + ", "
- + "flowLabel=" + Arrays.toString(mFlowLabel) + "}";
+ + "flowLabel=" + Arrays.toString(mFlowLabel) + ", "
+ + "qosCharacteristics=" + mQosCharacteristics + "}";
}
/** @hide */
@@ -581,6 +615,9 @@ public final class QosPolicyParams implements Parcelable {
dest.writeInt(mDirection);
dest.writeInt(mIpVersion);
dest.writeByteArray(mFlowLabel);
+ if (SdkLevel.isAtLeastV()) {
+ dest.writeParcelable(mQosCharacteristics, 0);
+ }
}
/** @hide */
@@ -597,6 +634,12 @@ public final class QosPolicyParams implements Parcelable {
this.mDirection = in.readInt();
this.mIpVersion = in.readInt();
this.mFlowLabel = in.createByteArray();
+ if (SdkLevel.isAtLeastV()) {
+ this.mQosCharacteristics = in.readParcelable(
+ QosCharacteristics.class.getClassLoader(), QosCharacteristics.class);
+ } else {
+ this.mQosCharacteristics = null;
+ }
}
public static final @NonNull Parcelable.Creator<QosPolicyParams> CREATOR =
@@ -628,6 +671,7 @@ public final class QosPolicyParams implements Parcelable {
private @Nullable int[] mDstPortRange;
private @IpVersion int mIpVersion = IP_VERSION_ANY;
private byte[] mFlowLabel;
+ private @Nullable QosCharacteristics mQosCharacteristics;
/**
* Constructor for {@link Builder}.
@@ -737,12 +781,27 @@ public final class QosPolicyParams implements Parcelable {
}
/**
+ * Specifies traffic flow parameters to use for this policy request.
+ * This argument is mandatory for uplink requests, but optional for downlink requests.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ public @NonNull Builder setQosCharacteristics(
+ @Nullable QosCharacteristics qosCharacteristics) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ mQosCharacteristics = qosCharacteristics;
+ return this;
+ }
+
+ /**
* Construct a QosPolicyParams object with the specified parameters.
*/
public @NonNull QosPolicyParams build() {
QosPolicyParams params = new QosPolicyParams(mPolicyId, mDscp, mUserPriority, mSrcIp,
mDstIp, mSrcPort, mProtocol, mDstPortRange, mDirection, mIpVersion, mDstPort,
- mFlowLabel);
+ mFlowLabel, mQosCharacteristics);
if (!params.validate()) {
throw new IllegalArgumentException("Provided parameters are invalid");
}
diff --git a/framework/java/android/net/wifi/ScanResult.java b/framework/java/android/net/wifi/ScanResult.java
index 1eb35e4c9c..161928fac2 100644
--- a/framework/java/android/net/wifi/ScanResult.java
+++ b/framework/java/android/net/wifi/ScanResult.java
@@ -16,6 +16,7 @@
package android.net.wifi;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -32,6 +33,7 @@ import android.os.Parcelable;
import android.util.Log;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -729,6 +731,11 @@ public final class ScanResult implements Parcelable {
/** {@hide} */
public static final long FLAG_80211mc_RESPONDER = 0x0000000000000002;
+ /** @hide */
+ public static final long FLAG_80211az_NTB_RESPONDER = 0x0000000000000004;
+
+ /** @hide */
+ public static final long FLAG_TWT_RESPONDER = 0x0000000000000008;
/*
* These flags are specific to the ScanResult class, and are not related to the |flags|
* field of the per-BSS scan results from WPA supplicant.
@@ -762,11 +769,27 @@ public final class ScanResult implements Parcelable {
return (flags & FLAG_80211mc_RESPONDER) != 0;
}
+ /**
+ * @return whether AP is a IEEE802.11az Non-Trigger based Ranging Responder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public boolean is80211azNtbResponder() {
+ return (flags & FLAG_80211az_NTB_RESPONDER) != 0;
+ }
+
public boolean isPasspointNetwork() {
return (flags & FLAG_PASSPOINT_NETWORK) != 0;
}
/**
+ * @return whether AP is Target Wake Time (TWT) Responder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public boolean isTwtResponder() {
+ return (flags & FLAG_TWT_RESPONDER) != 0;
+ }
+
+ /**
* Indicates venue name (such as 'San Francisco Airport') published by access point; only
* available on Passpoint network and if published by access point.
* @deprecated - This information is not provided
@@ -1410,7 +1433,235 @@ public final class ScanResult implements Parcelable {
return true;
}
- /** {@hide} */
+ /**
+ * Builder class used to construct {@link ScanResult} objects.
+ *
+ * @hide
+ */
+ public static final class Builder {
+ private WifiSsid mWifiSsid;
+ private String mBssid;
+ private long mHessid = 0;
+ private int mAnqpDomainId = 0;
+ private byte[] mOsuProviders = null;
+ private String mCaps = null;
+ private int mRssi = UNSPECIFIED;
+ private int mFrequency = UNSPECIFIED;
+ private long mTsf = 0;
+ private int mDistanceCm = UNSPECIFIED;
+ private int mDistanceSdCm = UNSPECIFIED;
+ private @ChannelWidth int mChannelWidth = ScanResult.CHANNEL_WIDTH_20MHZ;
+ private int mCenterFreq0 = UNSPECIFIED;
+ private int mCenterFreq1 = UNSPECIFIED;
+ private boolean mIs80211McRTTResponder = false;
+ private boolean mIs80211azNtbRTTResponder = false;
+ private boolean mIsTwtResponder = false;
+ /** @hide */
+ @NonNull
+ public Builder setHessid(long hessid) {
+ mHessid = hessid;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setOsuProviders(@Nullable byte[] osuProviders) {
+ mOsuProviders = osuProviders;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setAnqpDomainId(int anqpDomainId) {
+ mAnqpDomainId = anqpDomainId;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setCaps(@Nullable String caps) {
+ mCaps = caps;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setRssi(int rssi) {
+ mRssi = rssi;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setFrequency(int frequency) {
+ mFrequency = frequency;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setTsf(long tsf) {
+ mTsf = tsf;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setDistanceCm(int distanceCm) {
+ mDistanceCm = distanceCm;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setDistanceSdCm(int distanceSdCm) {
+ mDistanceSdCm = distanceSdCm;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setChannelWidth(@ChannelWidth int channelWidth) {
+ mChannelWidth = channelWidth;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setCenterFreq0(int centerFreq0) {
+ mCenterFreq0 = centerFreq0;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setCenterFreq1(int centerFreq1) {
+ mCenterFreq1 = centerFreq1;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setIs80211McRTTResponder(boolean is80211McRTTResponder) {
+ mIs80211McRTTResponder = is80211McRTTResponder;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setIs80211azNtbRTTResponder(boolean is80211azNtbRTTResponder) {
+ mIs80211azNtbRTTResponder = is80211azNtbRTTResponder;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setIsTwtResponder(boolean isTwtResponder) {
+ mIsTwtResponder = isTwtResponder;
+ return this;
+ }
+
+ /** @hide */
+ public Builder(WifiSsid wifiSsid, String bssid) {
+ mWifiSsid = wifiSsid;
+ mBssid = bssid;
+ }
+
+ /**
+ * @hide
+ *
+ */
+ public Builder() {
+
+ }
+
+ /**
+ * @hide
+ */
+ public Builder setWifiSsid(WifiSsid wifiSsid) {
+ mWifiSsid = wifiSsid;
+ return this;
+ }
+
+ /**
+ * @hide
+ */
+ public Builder setBssid(String bssid) {
+ mBssid = bssid;
+ return this;
+ }
+
+ /**
+ * @hide
+ */
+ public void clear() {
+ mWifiSsid = null;
+ mBssid = null;
+ mHessid = 0;
+ mAnqpDomainId = 0;
+ mOsuProviders = null;
+ mCaps = null;
+ mRssi = UNSPECIFIED;
+ mFrequency = UNSPECIFIED;
+ mTsf = 0;
+ mDistanceCm = UNSPECIFIED;
+ mDistanceSdCm = UNSPECIFIED;
+ mChannelWidth = ScanResult.CHANNEL_WIDTH_20MHZ;
+ mCenterFreq0 = UNSPECIFIED;
+ mCenterFreq1 = UNSPECIFIED;
+ mIs80211McRTTResponder = false;
+ mIs80211azNtbRTTResponder = false;
+ mIsTwtResponder = false;
+ }
+
+ /** @hide */
+ public ScanResult build() {
+ return new ScanResult(this);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ private ScanResult(Builder builder) {
+ this.wifiSsid = builder.mWifiSsid;
+ if (wifiSsid != null && isHiddenSsid(wifiSsid)) {
+ // Retain the legacy behavior of setting SSID to "" if the SSID is all zero values.
+ this.SSID = "";
+ } else {
+ final CharSequence utf8Ssid = (wifiSsid != null) ? wifiSsid.getUtf8Text() : null;
+ this.SSID = (utf8Ssid != null) ? utf8Ssid.toString() : WifiManager.UNKNOWN_SSID;
+ }
+ this.BSSID = builder.mBssid;
+ this.hessid = builder.mHessid;
+ this.anqpDomainId = builder.mAnqpDomainId;
+ if (builder.mOsuProviders != null) {
+ this.anqpElements = new AnqpInformationElement[1];
+ this.anqpElements[0] = new AnqpInformationElement(
+ AnqpInformationElement.HOTSPOT20_VENDOR_ID,
+ AnqpInformationElement.HS_OSU_PROVIDERS, builder.mOsuProviders);
+ }
+ this.capabilities = builder.mCaps;
+ this.level = builder.mRssi;
+ this.frequency = builder.mFrequency;
+ this.timestamp = builder.mTsf;
+ this.distanceCm = builder.mDistanceCm;
+ this.distanceSdCm = builder.mDistanceSdCm;
+ this.channelWidth = builder.mChannelWidth;
+ this.centerFreq0 = builder.mCenterFreq0;
+ this.centerFreq1 = builder.mCenterFreq1;
+ this.flags = 0;
+ this.flags |= (builder.mIs80211McRTTResponder) ? FLAG_80211mc_RESPONDER : 0;
+ this.flags |= (builder.mIs80211azNtbRTTResponder) ? FLAG_80211az_NTB_RESPONDER : 0;
+ this.flags |= (builder.mIsTwtResponder) ? FLAG_TWT_RESPONDER : 0;
+ this.radioChainInfos = null;
+ this.mApMldMacAddress = null;
+ }
+
+ /**
+ * @hide
+ * @deprecated Use {@link ScanResult.Builder}
+ */
public ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId,
byte[] osuProviders, String caps, int level, int frequency, long tsf) {
this.wifiSsid = wifiSsid;
@@ -1444,7 +1695,10 @@ public final class ScanResult implements Parcelable {
this.mApMldMacAddress = null;
}
- /** {@hide} */
+ /**
+ * @hide
+ * @deprecated Use {@link ScanResult.Builder}
+ */
public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
long tsf, int distCm, int distSdCm) {
this.wifiSsid = wifiSsid;
@@ -1470,7 +1724,10 @@ public final class ScanResult implements Parcelable {
this.mApMldMacAddress = null;
}
- /** {@hide} */
+ /**
+ * @hide
+ * @deprecated Use {@link ScanResult.Builder}
+ */
public ScanResult(String Ssid, String BSSID, long hessid, int anqpDomainId, String caps,
int level, int frequency,
long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1,
@@ -1497,7 +1754,10 @@ public final class ScanResult implements Parcelable {
this.mApMldMacAddress = null;
}
- /** {@hide} */
+ /**
+ * @hide
+ * @deprecated Use {@link ScanResult.Builder}
+ */
public ScanResult(WifiSsid wifiSsid, String Ssid, String BSSID, long hessid, int anqpDomainId,
String caps, int level,
int frequency, long tsf, int distCm, int distSdCm, int channelWidth,
@@ -1576,6 +1836,11 @@ public final class ScanResult implements Parcelable {
sb.append(", standard: ").append(wifiStandardToString(mWifiStandard));
sb.append(", 80211mcResponder: ");
sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported");
+ sb.append(", 80211azNtbResponder: ");
+ sb.append(
+ ((flags & FLAG_80211az_NTB_RESPONDER) != 0) ? "is supported" : "is not supported");
+ sb.append(", TWT Responder: ");
+ sb.append(((flags & FLAG_TWT_RESPONDER) != 0) ? "yes" : "no");
sb.append(", Radio Chain Infos: ").append(Arrays.toString(radioChainInfos));
sb.append(", interface name: ").append(ifaceName);
@@ -1683,80 +1948,78 @@ public final class ScanResult implements Parcelable {
/** Implement the Parcelable interface */
public static final @NonNull Creator<ScanResult> CREATOR =
- new Creator<ScanResult>() {
- public ScanResult createFromParcel(Parcel in) {
- WifiSsid wifiSsid = null;
- if (in.readInt() == 1) {
- wifiSsid = WifiSsid.CREATOR.createFromParcel(in);
- }
- ScanResult sr = new ScanResult(
- wifiSsid,
- in.readString(), /* SSID */
- in.readString(), /* BSSID */
- in.readLong(), /* HESSID */
- in.readInt(), /* ANQP Domain ID */
- in.readString(), /* capabilities */
- in.readInt(), /* level */
- in.readInt(), /* frequency */
- in.readLong(), /* timestamp */
- in.readInt(), /* distanceCm */
- in.readInt(), /* distanceSdCm */
- in.readInt(), /* channelWidth */
- in.readInt(), /* centerFreq0 */
- in.readInt(), /* centerFreq1 */
- false /* rtt responder,
+ new Creator<ScanResult>() {
+ public ScanResult createFromParcel(Parcel in) {
+ WifiSsid wifiSsid = null;
+ if (in.readInt() == 1) {
+ wifiSsid = WifiSsid.CREATOR.createFromParcel(in);
+ }
+ ScanResult sr = new ScanResult(
+ wifiSsid,
+ in.readString(), /* SSID */
+ in.readString(), /* BSSID */
+ in.readLong(), /* HESSID */
+ in.readInt(), /* ANQP Domain ID */
+ in.readString(), /* capabilities */
+ in.readInt(), /* level */
+ in.readInt(), /* frequency */
+ in.readLong(), /* timestamp */
+ in.readInt(), /* distanceCm */
+ in.readInt(), /* distanceSdCm */
+ in.readInt(), /* channelWidth */
+ in.readInt(), /* centerFreq0 */
+ in.readInt(), /* centerFreq1 */
+ false /* rtt responder,
fixed with flags below */
- );
-
- sr.mWifiStandard = in.readInt();
- sr.seen = in.readLong();
- sr.untrusted = in.readInt() != 0;
- sr.numUsage = in.readInt();
- sr.venueName = in.readString();
- sr.operatorFriendlyName = in.readString();
- sr.flags = in.readLong();
- sr.informationElements = in.createTypedArray(InformationElement.CREATOR);
-
- int n = in.readInt();
- if (n != 0) {
- sr.anqpLines = new ArrayList<String>();
- for (int i = 0; i < n; i++) {
- sr.anqpLines.add(in.readString());
+ );
+
+ sr.mWifiStandard = in.readInt();
+ sr.seen = in.readLong();
+ sr.untrusted = in.readInt() != 0;
+ sr.numUsage = in.readInt();
+ sr.venueName = in.readString();
+ sr.operatorFriendlyName = in.readString();
+ sr.flags = in.readLong();
+ sr.informationElements = in.createTypedArray(InformationElement.CREATOR);
+
+ int n = in.readInt();
+ if (n != 0) {
+ sr.anqpLines = new ArrayList<String>();
+ for (int i = 0; i < n; i++) {
+ sr.anqpLines.add(in.readString());
+ }
}
- }
- n = in.readInt();
- if (n != 0) {
- sr.anqpElements = new AnqpInformationElement[n];
- for (int i = 0; i < n; i++) {
- int vendorId = in.readInt();
- int elementId = in.readInt();
- int len = in.readInt();
- byte[] payload = new byte[len];
- in.readByteArray(payload);
- sr.anqpElements[i] =
- new AnqpInformationElement(vendorId, elementId, payload);
+ n = in.readInt();
+ if (n != 0) {
+ sr.anqpElements = new AnqpInformationElement[n];
+ for (int i = 0; i < n; i++) {
+ int vendorId = in.readInt();
+ int elementId = in.readInt();
+ int len = in.readInt();
+ byte[] payload = new byte[len];
+ in.readByteArray(payload);
+ sr.anqpElements[i] =
+ new AnqpInformationElement(vendorId, elementId, payload);
+ }
}
- }
- n = in.readInt();
- if (n != 0) {
- sr.radioChainInfos = new RadioChainInfo[n];
- for (int i = 0; i < n; i++) {
- sr.radioChainInfos[i] = new RadioChainInfo();
- sr.radioChainInfos[i].id = in.readInt();
- sr.radioChainInfos[i].level = in.readInt();
+ n = in.readInt();
+ if (n != 0) {
+ sr.radioChainInfos = new RadioChainInfo[n];
+ for (int i = 0; i < n; i++) {
+ sr.radioChainInfos[i] = new RadioChainInfo();
+ sr.radioChainInfos[i].id = in.readInt();
+ sr.radioChainInfos[i].level = in.readInt();
+ }
}
- }
- sr.ifaceName = in.readString();
+ sr.ifaceName = in.readString();
+ // Read MLO related attributes
+ sr.mApMldMacAddress = in.readParcelable(MacAddress.class.getClassLoader());
+ sr.mApMloLinkId = in.readInt();
+ sr.mAffiliatedMloLinks = in.createTypedArrayList(MloLink.CREATOR);
- // Read MLO related attributes
- sr.mApMldMacAddress = in.readParcelable(MacAddress.class.getClassLoader());
- sr.mApMloLinkId = in.readInt();
- sr.mAffiliatedMloLinks = in.createTypedArrayList(MloLink.CREATOR);
-
- return sr;
- }
-
+ return sr;
+ }
public ScanResult[] newArray(int size) {
return new ScanResult[size];
}
diff --git a/framework/java/android/net/wifi/SoftApConfiguration.java b/framework/java/android/net/wifi/SoftApConfiguration.java
index dde9891d9d..5432484b6a 100644
--- a/framework/java/android/net/wifi/SoftApConfiguration.java
+++ b/framework/java/android/net/wifi/SoftApConfiguration.java
@@ -39,6 +39,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.internal.util.Preconditions;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -1206,7 +1207,7 @@ public final class SoftApConfiguration implements Parcelable {
* @hide
*/
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@NonNull
@SystemApi
public List<OuiKeyedData> getVendorData() {
@@ -2312,7 +2313,7 @@ public final class SoftApConfiguration implements Parcelable {
* @return Builder for chaining.
*/
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
- @FlaggedApi("com.android.wifi.flags.vendor_parcelable_parameters")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@NonNull
public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) {
if (!SdkLevel.isAtLeastV()) {
diff --git a/framework/java/android/net/wifi/SoftApInfo.java b/framework/java/android/net/wifi/SoftApInfo.java
index 89d4782ff9..f4440e9e74 100644
--- a/framework/java/android/net/wifi/SoftApInfo.java
+++ b/framework/java/android/net/wifi/SoftApInfo.java
@@ -16,6 +16,7 @@
package android.net.wifi;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -28,11 +29,17 @@ import androidx.annotation.RequiresApi;
import com.android.internal.util.Preconditions;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Objects;
/**
- * A class representing information about SoftAp.
+ * A class representing information about a specific SoftAP instance. A SoftAP instance may be a
+ * single band AP or a bridged AP (across multiple bands). To get the state of the AP interface
+ * itself, use {@link android.net.wifi.WifiManager.SoftApCallback#onStateChanged(SoftApState)}.
* {@see WifiManager}
*
* @hide
@@ -156,6 +163,9 @@ public final class SoftApInfo implements Parcelable {
*/
private long mIdleShutdownTimeoutMillis;
+ /** List of {@link OuiKeyedData} containing vendor-specific configuration data. */
+ private List<OuiKeyedData> mVendorData = Collections.emptyList();
+
/**
* Get the frequency which AP resides on.
*/
@@ -307,6 +317,44 @@ public final class SoftApInfo implements Parcelable {
}
/**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the
+ * vendor-provided configuration data. Note that multiple elements with
+ * the same OUI are allowed.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public void setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = new ArrayList<>(vendorData);
+ }
+
+ /**
+ * Get the vendor-provided configuration data, if it exists.
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
+ /**
* @hide
*/
public SoftApInfo(@Nullable SoftApInfo source) {
@@ -317,6 +365,7 @@ public final class SoftApInfo implements Parcelable {
mWifiStandard = source.mWifiStandard;
mApInstanceIdentifier = source.mApInstanceIdentifier;
mIdleShutdownTimeoutMillis = source.mIdleShutdownTimeoutMillis;
+ mVendorData = new ArrayList<>(source.mVendorData);
}
}
@@ -341,6 +390,7 @@ public final class SoftApInfo implements Parcelable {
dest.writeInt(mWifiStandard);
dest.writeString(mApInstanceIdentifier);
dest.writeLong(mIdleShutdownTimeoutMillis);
+ dest.writeList(mVendorData);
}
@NonNull
@@ -354,6 +404,7 @@ public final class SoftApInfo implements Parcelable {
info.mWifiStandard = in.readInt();
info.mApInstanceIdentifier = in.readString();
info.mIdleShutdownTimeoutMillis = in.readLong();
+ info.mVendorData = ParcelUtil.readOuiKeyedDataList(in);
return info;
}
@@ -373,6 +424,7 @@ public final class SoftApInfo implements Parcelable {
sbuf.append(", wifiStandard= ").append(mWifiStandard);
sbuf.append(", mApInstanceIdentifier= ").append(mApInstanceIdentifier);
sbuf.append(", mIdleShutdownTimeoutMillis= ").append(mIdleShutdownTimeoutMillis);
+ sbuf.append(", mVendorData= ").append(mVendorData);
sbuf.append("}");
return sbuf.toString();
}
@@ -387,12 +439,13 @@ public final class SoftApInfo implements Parcelable {
&& Objects.equals(mBssid, softApInfo.mBssid)
&& mWifiStandard == softApInfo.mWifiStandard
&& Objects.equals(mApInstanceIdentifier, softApInfo.mApInstanceIdentifier)
- && mIdleShutdownTimeoutMillis == softApInfo.mIdleShutdownTimeoutMillis;
+ && mIdleShutdownTimeoutMillis == softApInfo.mIdleShutdownTimeoutMillis
+ && Objects.equals(mVendorData, softApInfo.mVendorData);
}
@Override
public int hashCode() {
return Objects.hash(mFrequency, mBandwidth, mBssid, mWifiStandard, mApInstanceIdentifier,
- mIdleShutdownTimeoutMillis);
+ mIdleShutdownTimeoutMillis, mVendorData);
}
}
diff --git a/framework/java/android/net/wifi/SoftApState.aidl b/framework/java/android/net/wifi/SoftApState.aidl
new file mode 100644
index 0000000000..61a27f1be9
--- /dev/null
+++ b/framework/java/android/net/wifi/SoftApState.aidl
@@ -0,0 +1,21 @@
+/*
+ * 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 android.net.wifi;
+
+import android.net.wifi.SoftApState;
+
+parcelable SoftApState;
diff --git a/framework/java/android/net/wifi/SoftApState.java b/framework/java/android/net/wifi/SoftApState.java
index 54dc45cc59..07e194c234 100644
--- a/framework/java/android/net/wifi/SoftApState.java
+++ b/framework/java/android/net/wifi/SoftApState.java
@@ -25,6 +25,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.util.Objects;
@@ -34,19 +35,32 @@ import java.util.Objects;
*
* @hide
*/
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
-@FlaggedApi("com.android.wifi.flags.android_v_wifi_api")
public final class SoftApState implements Parcelable {
+ @WifiManager.WifiApState
final int mState;
+ @WifiManager.SapStartFailure
final int mFailureReason;
+ @Nullable
final TetheringManager.TetheringRequest mTetheringRequest;
+ @Nullable
final String mIface;
/**
+ * SoftApState constructor.
+ *
+ * @param state Current state of the Soft AP.
+ * @param failureReason Failure reason if the current state is
+ * {@link WifiManager#WIFI_AP_STATE_FAILED}.
+ * @param tetheringRequest TetheringRequest if one was specified when Soft AP was requested,
+ * else {@code null}.
+ * @param iface Interface name if an interface was created, else {@code null}.
* @hide
*/
- public SoftApState(int state, int failureReason,
+ public SoftApState(@WifiManager.WifiApState int state,
+ @WifiManager.SapStartFailure int failureReason,
@Nullable TetheringManager.TetheringRequest tetheringRequest,
@Nullable String iface) {
mState = state;
@@ -108,7 +122,8 @@ public final class SoftApState implements Parcelable {
* {@link WifiManager#WIFI_AP_STATE_ENABLING},
* {@link WifiManager#WIFI_AP_STATE_FAILED}
*/
- public @WifiManager.WifiApState int getState() {
+ @WifiManager.WifiApState
+ public int getState() {
return mState;
}
@@ -119,13 +134,29 @@ public final class SoftApState implements Parcelable {
* {@link WifiManager#SAP_START_FAILURE_NO_CHANNEL},
* {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION},
* {@link WifiManager#SAP_START_FAILURE_USER_REJECTED}
+ * @throws IllegalStateException if the state is not {@link WifiManager#WIFI_AP_STATE_FAILED}.
+ */
+ @WifiManager.SapStartFailure
+ public int getFailureReason() {
+ if (mState != WifiManager.WIFI_AP_STATE_FAILED) {
+ throw new IllegalStateException("Called getFailureReason() when state is not"
+ + " WIFI_AP_STATE_FAILED. Actual state is " + mState);
+ }
+ return getFailureReasonInternal();
+ }
+
+ /**
+ * @hide
*/
- public @WifiManager.SapStartFailure int getFailureReason() {
+ @WifiManager.SapStartFailure
+ public int getFailureReasonInternal() {
return mFailureReason;
}
/**
- * Gets the TetheringRequest of the Soft AP.
+ * Gets the TetheringRequest of the Soft AP, if one was specified via
+ * {@link WifiManager#startTetheredHotspotRequest(TetheringManager.TetheringRequest)}.
+ * Otherwise, returns {@code null}.
*/
@Nullable
public TetheringManager.TetheringRequest getTetheringRequest() {
@@ -133,7 +164,10 @@ public final class SoftApState implements Parcelable {
}
/**
- * Gets the iface of the Soft AP.
+ * Gets the interface name of the Soft AP (e.g. "wlan0") once the Soft AP starts enabling, i.e.
+ * {@link #getState()} returns {@link WifiManager#WIFI_AP_STATE_ENABLING}). Returns {@code null}
+ * if the Soft AP hasn't started enabling yet, or if it failed with
+ * {@link WifiManager#WIFI_AP_STATE_FAILED} without starting enabling.
*/
@Nullable
public String getIface() {
diff --git a/framework/java/android/net/wifi/UriParserResults.java b/framework/java/android/net/wifi/UriParserResults.java
new file mode 100644
index 0000000000..75086c840e
--- /dev/null
+++ b/framework/java/android/net/wifi/UriParserResults.java
@@ -0,0 +1,212 @@
+/*
+ * 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 android.net.wifi;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.wifi.flags.Flags;
+
+import java.util.Objects;
+
+/**
+ * Contains information extracted from URI
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+@SystemApi
+public final class UriParserResults implements Parcelable {
+
+ /**
+ * Return value for {@link #getUriScheme()} indicating that the URI contains
+ * a ZXing WiFi configuration.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG = 1;
+
+ /**
+ * Return value for {@link #getUriScheme()} indicating that the URI contains
+ * a DPP (Easy Connect) configuration.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int URI_SCHEME_DPP = 2;
+
+ /**
+ * URI_SCHEME_DPP for standard Wi-Fi device provision protocol;
+ * URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG for ZXing reader library's Wi-Fi Network config format.
+ */
+ @WifiAnnotations.UriScheme private int mScheme;
+
+ /** Public key from parsed Wi-Fi DPP URI, it is valid when mScheme is URI_SCHEME_DPP. */
+ @Nullable private String mPublicKey;
+
+ /**
+ * Optional device specific information from the Wi-Fi DPP URI,
+ * it is valid when mScheme is URI_SCHEME_DPP
+ */
+ @Nullable private String mInformation;
+
+ /**
+ * WifiConfiguration from parsed ZXing reader library's Wi-Fi Network config format. Valid or
+ * Not null when mScheme is URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG
+ */
+ @Nullable private WifiConfiguration mWifiConfig;
+
+ /** @hide */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public UriParserResults(
+ int scheme,
+ @Nullable String publicKey,
+ @Nullable String information,
+ @Nullable WifiConfiguration config) {
+ mScheme = scheme;
+ mPublicKey = publicKey;
+ mInformation = information;
+ if (config != null) {
+ mWifiConfig = new WifiConfiguration(config);
+ }
+ }
+
+ /**
+ * The scheme described by the URI.
+ *
+ * <p>URI_SCHEME_DPP for standard Wi-Fi device provision protocol.
+ * URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG for ZXing reader library's Wi-Fi Network config format.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @WifiAnnotations.UriScheme
+ public int getUriScheme() {
+ return mScheme;
+ }
+
+ /**
+ * The public key of the DPP (Wi-Fi Easy Connect).
+ *
+ * If {@code getUriScheme()} returns URI_SCHEME_DPP, this field contains the public key
+ * of the DPP (Wi-Fi Easy Connect). Otherwise, it is null.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Nullable
+ public String getPublicKey() {
+ return mPublicKey;
+ }
+
+ /**
+ * The information of the DPP (Wi-Fi Easy Connect).
+ *
+ * If {@code getUriScheme()} returns URI_SCHEME_DPP, this field contains the information
+ * of the DPP (Wi-Fi Easy Connect). Otherwise, it is null.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Nullable
+ public String getInformation() {
+ return mInformation;
+ }
+
+ /**
+ * The WifiConfiguration of the zxing wifi network.
+ *
+ * If {@code getUriScheme()} returns URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG, this field contains
+ * the WifiConfiguration of the zxing wifi network. Otherwise, it is null.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Nullable
+ public WifiConfiguration getWifiConfiguration() {
+ return mWifiConfig;
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Override
+ /**
+ * Implement the Parcelable interface.
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Override
+ /**
+ * Implement the Parcelable interface.
+ */
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mScheme);
+ dest.writeString(mPublicKey);
+ dest.writeString(mInformation);
+ dest.writeParcelable(mWifiConfig, flags);
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ /**
+ * Implement the Parcelable interface.
+ */
+ public static final Creator<UriParserResults> CREATOR =
+ new Creator<UriParserResults>() {
+ public UriParserResults createFromParcel(Parcel in) {
+ return new UriParserResults(
+ in.readInt(),
+ in.readString(),
+ in.readString(),
+ in.readParcelable(WifiConfiguration.class.getClassLoader()));
+ }
+
+ public UriParserResults[] newArray(int size) {
+ return new UriParserResults[size];
+ }
+ };
+
+ @NonNull
+ @Override
+ public String toString() {
+ StringBuilder sbuf = new StringBuilder();
+ sbuf.append("UriParserResults{");
+ sbuf.append(", mScheme= ").append(mScheme);
+ sbuf.append(", mPublicKey= ").append(mPublicKey);
+ sbuf.append(", mInformation= ").append(mInformation);
+ if (mWifiConfig != null) sbuf.append(", mWifiConfig=").append(mWifiConfig.toString());
+ sbuf.append("}");
+ return sbuf.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof UriParserResults)) return false;
+ UriParserResults results = (UriParserResults) o;
+ return mScheme == results.mScheme
+ && Objects.equals(mPublicKey, results.mPublicKey)
+ && Objects.equals(mInformation, results.mInformation)
+ && Objects.equals(
+ mWifiConfig != null ? mWifiConfig.toString() : null,
+ results.mWifiConfig != null ? results.mWifiConfig.toString() : null);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ mScheme,
+ mPublicKey,
+ mInformation,
+ mWifiConfig != null ? mWifiConfig.toString() : null);
+ }
+}
diff --git a/framework/java/android/net/wifi/WifiAnnotations.java b/framework/java/android/net/wifi/WifiAnnotations.java
index 602226da4a..2a92c31361 100644
--- a/framework/java/android/net/wifi/WifiAnnotations.java
+++ b/framework/java/android/net/wifi/WifiAnnotations.java
@@ -166,4 +166,14 @@ public final class WifiAnnotations {
WifiInfo.SECURITY_TYPE_DPP,
})
public @interface SecurityType {}
+
+ /**
+ * The type of wifi uri scheme.
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"URI_SCHEME_"}, value = {
+ UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG,
+ UriParserResults.URI_SCHEME_DPP,
+ })
+ public @interface UriScheme {}
}
diff --git a/framework/java/android/net/wifi/WifiConfiguration.java b/framework/java/android/net/wifi/WifiConfiguration.java
index 0b63780ca2..88582dde76 100644
--- a/framework/java/android/net/wifi/WifiConfiguration.java
+++ b/framework/java/android/net/wifi/WifiConfiguration.java
@@ -45,9 +45,12 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
+import androidx.annotation.RequiresApi;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.MacAddressUtils;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -62,6 +65,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
/**
@@ -1192,9 +1196,8 @@ public class WifiConfiguration implements Parcelable {
/**
* Four WEP keys. For each of the four values, provide either an ASCII
- * string enclosed in double quotation marks (e.g., {@code "abcdef"}),
- * a string of hex digits (e.g., {@code 0102030405}), or an empty string
- * (e.g., {@code ""}).
+ * string enclosed in double quotation marks (e.g., {@code "abcdef"})
+ * or a string of hex digits (e.g., {@code 0102030405}).
* <p/>
* When the value of one of these keys is read, the actual key is
* not returned, just a "*" if the key has a value, or the null
@@ -1474,6 +1477,12 @@ public class WifiConfiguration implements Parcelable {
public boolean allowAutojoin = true;
/**
+ * Wi-Fi7 is enabled by user for this network.
+ * Default true.
+ */
+ private boolean mWifi7Enabled = true;
+
+ /**
* @hide
*/
public void setIpProvisioningTimedOut(boolean value) {
@@ -1972,6 +1981,34 @@ public class WifiConfiguration implements Parcelable {
mRandomizedMacAddress = mac;
}
+ private boolean mIsSendDhcpHostnameEnabled = true;
+
+ /**
+ * Set whether to send the hostname of the device to this network's DHCP server.
+ *
+ * @param enabled {@code true} to send the hostname during DHCP,
+ * {@code false} to not send the hostname during DHCP.
+ * @hide
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_SETUP_WIZARD})
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public void setSendDhcpHostnameEnabled(boolean enabled) {
+ mIsSendDhcpHostnameEnabled = enabled;
+ }
+
+ /**
+ * Whether to send the hostname of the device to this network's DHCP server.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public boolean isSendDhcpHostnameEnabled() {
+ return mIsSendDhcpHostnameEnabled;
+ }
+
/**
* This network supports DPP AKM and the device is configured to
* onboard peer enrollee devices with {@link #SECURITY_TYPE_DPP}
@@ -2150,7 +2187,8 @@ public class WifiConfiguration implements Parcelable {
DISABLED_AUTHENTICATION_PRIVATE_EAP_ERROR,
DISABLED_NETWORK_NOT_FOUND,
DISABLED_CONSECUTIVE_FAILURES,
- DISABLED_UNWANTED_LOW_RSSI})
+ DISABLED_UNWANTED_LOW_RSSI,
+ DISABLED_REPEATED_NUD_FAILURES})
public @interface NetworkSelectionDisableReason {}
// Quality Network disabled reasons
@@ -2204,13 +2242,18 @@ public class WifiConfiguration implements Parcelable {
/**
* This network is temporarily disabled because of unwanted network under sufficient rssi.
*/
- @FlaggedApi("com.android.wifi.flags.disable_reason_unwanted_low_rssi")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public static final int DISABLED_UNWANTED_LOW_RSSI = 14;
/**
+ * This network is temporarily disabled due to repeated IP reachability failures.
+ * @hide
+ */
+ public static final int DISABLED_REPEATED_NUD_FAILURES = 15;
+ /**
* All other disable reasons should be strictly less than this value.
* @hide
*/
- public static final int NETWORK_SELECTION_DISABLED_MAX = 15;
+ public static final int NETWORK_SELECTION_DISABLED_MAX = 16;
/**
* Get an integer that is equal to the maximum integer value of all the
@@ -2388,6 +2431,10 @@ public class WifiConfiguration implements Parcelable {
new DisableReasonInfo("NETWORK_SELECTION_DISABLED_UNWANTED_LOW_RSSI",
1,
30 * 1000));
+ reasons.append(DISABLED_REPEATED_NUD_FAILURES,
+ new DisableReasonInfo("NETWORK_SELECTION_DISABLED_REPEATED_NUD_FAILURES",
+ 1,
+ 15 * 60 * 1000));
return reasons;
}
@@ -3280,6 +3327,9 @@ public class WifiConfiguration implements Parcelable {
*/
public HashMap<String, Integer> linkedConfigurations;
+ /** List of {@link OuiKeyedData} providing vendor-specific configuration data. */
+ private @NonNull List<OuiKeyedData> mVendorData;
+
public WifiConfiguration() {
networkId = INVALID_NETWORK_ID;
SSID = null;
@@ -3332,6 +3382,7 @@ public class WifiConfiguration implements Parcelable {
mEncryptedPreSharedKey = new byte[0];
mEncryptedPreSharedKeyIv = new byte[0];
mIpProvisioningTimedOut = false;
+ mVendorData = Collections.emptyList();
}
/**
@@ -3490,6 +3541,8 @@ public class WifiConfiguration implements Parcelable {
sbuf.append(" randomizedMacLastModifiedTimeMs: ")
.append(randomizedMacLastModifiedTimeMs == 0 ? "<none>"
: logTimeOfDay(randomizedMacLastModifiedTimeMs)).append("\n");
+ sbuf.append(" mIsSendDhcpHostnameEnabled: ").append(mIsSendDhcpHostnameEnabled)
+ .append("\n");
sbuf.append(" deletionPriority: ").append(mDeletionPriority).append("\n");
sbuf.append(" KeyMgmt:");
for (int k = 0; k < this.allowedKeyManagement.size(); k++) {
@@ -3657,8 +3710,15 @@ public class WifiConfiguration implements Parcelable {
sbuf.append("bssidAllowlist unset");
}
sbuf.append("\n");
+ if (mVendorData != null && !mVendorData.isEmpty()) {
+ sbuf.append("vendorData: ").append(mVendorData);
+ } else {
+ sbuf.append("vendorData unset");
+ }
+ sbuf.append("\n");
sbuf.append("IsDppConfigurator: ").append(this.mIsDppConfigurator).append("\n");
sbuf.append("HasEncryptedPreSharedKey: ").append(hasEncryptedPreSharedKey()).append("\n");
+ sbuf.append(" setWifi7Enabled=").append(mWifi7Enabled);
return sbuf.toString();
}
@@ -4081,6 +4141,7 @@ public class WifiConfiguration implements Parcelable {
macRandomizationSetting = source.macRandomizationSetting;
randomizedMacExpirationTimeMs = source.randomizedMacExpirationTimeMs;
randomizedMacLastModifiedTimeMs = source.randomizedMacLastModifiedTimeMs;
+ mIsSendDhcpHostnameEnabled = source.mIsSendDhcpHostnameEnabled;
requirePmf = source.requirePmf;
updateIdentifier = source.updateIdentifier;
carrierId = source.carrierId;
@@ -4105,6 +4166,8 @@ public class WifiConfiguration implements Parcelable {
mEncryptedPreSharedKeyIv = source.mEncryptedPreSharedKeyIv != null
? source.mEncryptedPreSharedKeyIv.clone() : new byte[0];
mIpProvisioningTimedOut = source.mIpProvisioningTimedOut;
+ mVendorData = new ArrayList<>(source.mVendorData);
+ mWifi7Enabled = source.mWifi7Enabled;
}
}
@@ -4182,6 +4245,7 @@ public class WifiConfiguration implements Parcelable {
dest.writeLong(recentFailure.getLastUpdateTimeSinceBootMillis());
dest.writeParcelable(mRandomizedMacAddress, flags);
dest.writeInt(macRandomizationSetting);
+ dest.writeBoolean(mIsSendDhcpHostnameEnabled);
dest.writeInt(osu ? 1 : 0);
dest.writeLong(randomizedMacExpirationTimeMs);
dest.writeLong(randomizedMacLastModifiedTimeMs);
@@ -4202,131 +4266,141 @@ public class WifiConfiguration implements Parcelable {
dest.writeByteArray(mEncryptedPreSharedKey);
dest.writeByteArray(mEncryptedPreSharedKeyIv);
dest.writeBoolean(mIpProvisioningTimedOut);
+ dest.writeList(mVendorData);
+ dest.writeBoolean(mWifi7Enabled);
}
/** Implement the Parcelable interface {@hide} */
@SystemApi
public static final @android.annotation.NonNull Creator<WifiConfiguration> CREATOR =
- new Creator<WifiConfiguration>() {
- public WifiConfiguration createFromParcel(Parcel in) {
- WifiConfiguration config = new WifiConfiguration();
- config.networkId = in.readInt();
- config.status = in.readInt();
- config.mNetworkSelectionStatus.readFromParcel(in);
- config.SSID = in.readString();
- config.BSSID = in.readString();
- config.apBand = in.readInt();
- config.apChannel = in.readInt();
- config.FQDN = in.readString();
- config.providerFriendlyName = in.readString();
- config.isHomeProviderNetwork = in.readInt() != 0;
- int numRoamingConsortiumIds = in.readInt();
- config.roamingConsortiumIds = new long[numRoamingConsortiumIds];
- for (int i = 0; i < numRoamingConsortiumIds; i++) {
- config.roamingConsortiumIds[i] = in.readLong();
- }
- config.preSharedKey = in.readString();
- for (int i = 0; i < config.wepKeys.length; i++) {
- config.wepKeys[i] = in.readString();
- }
- config.wepTxKeyIndex = in.readInt();
- config.priority = in.readInt();
- config.mDeletionPriority = in.readInt();
- config.hiddenSSID = in.readInt() != 0;
- config.requirePmf = in.readInt() != 0;
- config.updateIdentifier = in.readString();
-
- config.allowedKeyManagement = readBitSet(in);
- config.allowedProtocols = readBitSet(in);
- config.allowedAuthAlgorithms = readBitSet(in);
- config.allowedPairwiseCiphers = readBitSet(in);
- config.allowedGroupCiphers = readBitSet(in);
- config.allowedGroupManagementCiphers = readBitSet(in);
- config.allowedSuiteBCiphers = readBitSet(in);
-
- int numSecurityParams = in.readInt();
- for (int i = 0; i < numSecurityParams; i++) {
- config.mSecurityParamsList.add(in.readParcelable(null));
+ new Creator<WifiConfiguration>() {
+ public WifiConfiguration createFromParcel(Parcel in) {
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = in.readInt();
+ config.status = in.readInt();
+ config.mNetworkSelectionStatus.readFromParcel(in);
+ config.SSID = in.readString();
+ config.BSSID = in.readString();
+ config.apBand = in.readInt();
+ config.apChannel = in.readInt();
+ config.FQDN = in.readString();
+ config.providerFriendlyName = in.readString();
+ config.isHomeProviderNetwork = in.readInt() != 0;
+ int numRoamingConsortiumIds = in.readInt();
+ config.roamingConsortiumIds = new long[numRoamingConsortiumIds];
+ for (int i = 0; i < numRoamingConsortiumIds; i++) {
+ config.roamingConsortiumIds[i] = in.readLong();
+ }
+ config.preSharedKey = in.readString();
+ for (int i = 0; i < config.wepKeys.length; i++) {
+ config.wepKeys[i] = in.readString();
+ }
+ config.wepTxKeyIndex = in.readInt();
+ config.priority = in.readInt();
+ config.mDeletionPriority = in.readInt();
+ config.hiddenSSID = in.readInt() != 0;
+ config.requirePmf = in.readInt() != 0;
+ config.updateIdentifier = in.readString();
+
+ config.allowedKeyManagement = readBitSet(in);
+ config.allowedProtocols = readBitSet(in);
+ config.allowedAuthAlgorithms = readBitSet(in);
+ config.allowedPairwiseCiphers = readBitSet(in);
+ config.allowedGroupCiphers = readBitSet(in);
+ config.allowedGroupManagementCiphers = readBitSet(in);
+ config.allowedSuiteBCiphers = readBitSet(in);
+
+ int numSecurityParams = in.readInt();
+ for (int i = 0; i < numSecurityParams; i++) {
+ config.mSecurityParamsList.add(
+ in.readParcelable(SecurityParams.class.getClassLoader()));
+ }
+
+ config.enterpriseConfig = in.readParcelable(
+ WifiEnterpriseConfig.class.getClassLoader());
+ config.setIpConfiguration(
+ in.readParcelable(IpConfiguration.class.getClassLoader()));
+ config.dhcpServer = in.readString();
+ config.defaultGwMacAddress = in.readString();
+ config.validatedInternetAccess = in.readInt() != 0;
+ config.isLegacyPasspointConfig = in.readInt() != 0;
+ config.ephemeral = in.readInt() != 0;
+ config.trusted = in.readInt() != 0;
+ config.oemPaid = in.readInt() != 0;
+ config.oemPrivate = in.readInt() != 0;
+ config.carrierMerged = in.readInt() != 0;
+ config.fromWifiNetworkSuggestion = in.readInt() != 0;
+ config.fromWifiNetworkSpecifier = in.readInt() != 0;
+ config.meteredHint = in.readInt() != 0;
+ config.mIsRepeaterEnabled = in.readBoolean();
+ config.meteredOverride = in.readInt();
+ config.useExternalScores = in.readInt() != 0;
+ config.creatorUid = in.readInt();
+ config.lastConnectUid = in.readInt();
+ config.lastUpdateUid = in.readInt();
+ config.creatorName = in.readString();
+ config.lastUpdateName = in.readString();
+ config.numScorerOverride = in.readInt();
+ config.numScorerOverrideAndSwitchedNetwork = in.readInt();
+ config.numAssociation = in.readInt();
+ config.allowAutojoin = in.readBoolean();
+ config.numNoInternetAccessReports = in.readInt();
+ config.noInternetAccessExpected = in.readInt() != 0;
+ config.shared = in.readInt() != 0;
+ config.mPasspointManagementObjectTree = in.readString();
+ config.recentFailure.setAssociationStatus(in.readInt(), in.readLong());
+ config.mRandomizedMacAddress = in.readParcelable(
+ MacAddress.class.getClassLoader());
+ config.macRandomizationSetting = in.readInt();
+ config.mIsSendDhcpHostnameEnabled = in.readBoolean();
+ config.osu = in.readInt() != 0;
+ config.randomizedMacExpirationTimeMs = in.readLong();
+ config.randomizedMacLastModifiedTimeMs = in.readLong();
+ config.carrierId = in.readInt();
+ config.mPasspointUniqueId = in.readString();
+ config.subscriptionId = in.readInt();
+ config.restricted = in.readBoolean();
+ config.mSubscriptionGroup = in.readParcelable(
+ ParcelUuid.class.getClassLoader());
+ config.mBssidAllowlist = in.readArrayList(MacAddress.class.getClassLoader());
+ config.mIsDppConfigurator = in.readBoolean();
+ config.mDppPrivateEcKey = in.createByteArray();
+ if (config.mDppPrivateEcKey == null) {
+ config.mDppPrivateEcKey = new byte[0];
+ }
+ config.mDppConnector = in.createByteArray();
+ if (config.mDppConnector == null) {
+ config.mDppConnector = new byte[0];
+ }
+ config.mDppCSignKey = in.createByteArray();
+ if (config.mDppCSignKey == null) {
+ config.mDppCSignKey = new byte[0];
+ }
+ config.mDppNetAccessKey = in.createByteArray();
+ if (config.mDppNetAccessKey == null) {
+ config.mDppNetAccessKey = new byte[0];
+ }
+ config.isCurrentlyConnected = in.readBoolean();
+ config.mIsUserSelected = in.readBoolean();
+ config.mHasPreSharedKeyChanged = in.readBoolean();
+ config.mEncryptedPreSharedKey = in.createByteArray();
+ if (config.mEncryptedPreSharedKey == null) {
+ config.mEncryptedPreSharedKey = new byte[0];
+ }
+ config.mEncryptedPreSharedKeyIv = in.createByteArray();
+ if (config.mEncryptedPreSharedKeyIv == null) {
+ config.mEncryptedPreSharedKeyIv = new byte[0];
+ }
+ config.mIpProvisioningTimedOut = in.readBoolean();
+ config.mVendorData = ParcelUtil.readOuiKeyedDataList(in);
+ config.mWifi7Enabled = in.readBoolean();
+ return config;
}
- config.enterpriseConfig = in.readParcelable(null);
- config.setIpConfiguration(in.readParcelable(null));
- config.dhcpServer = in.readString();
- config.defaultGwMacAddress = in.readString();
- config.validatedInternetAccess = in.readInt() != 0;
- config.isLegacyPasspointConfig = in.readInt() != 0;
- config.ephemeral = in.readInt() != 0;
- config.trusted = in.readInt() != 0;
- config.oemPaid = in.readInt() != 0;
- config.oemPrivate = in.readInt() != 0;
- config.carrierMerged = in.readInt() != 0;
- config.fromWifiNetworkSuggestion = in.readInt() != 0;
- config.fromWifiNetworkSpecifier = in.readInt() != 0;
- config.meteredHint = in.readInt() != 0;
- config.mIsRepeaterEnabled = in.readBoolean();
- config.meteredOverride = in.readInt();
- config.useExternalScores = in.readInt() != 0;
- config.creatorUid = in.readInt();
- config.lastConnectUid = in.readInt();
- config.lastUpdateUid = in.readInt();
- config.creatorName = in.readString();
- config.lastUpdateName = in.readString();
- config.numScorerOverride = in.readInt();
- config.numScorerOverrideAndSwitchedNetwork = in.readInt();
- config.numAssociation = in.readInt();
- config.allowAutojoin = in.readBoolean();
- config.numNoInternetAccessReports = in.readInt();
- config.noInternetAccessExpected = in.readInt() != 0;
- config.shared = in.readInt() != 0;
- config.mPasspointManagementObjectTree = in.readString();
- config.recentFailure.setAssociationStatus(in.readInt(), in.readLong());
- config.mRandomizedMacAddress = in.readParcelable(null);
- config.macRandomizationSetting = in.readInt();
- config.osu = in.readInt() != 0;
- config.randomizedMacExpirationTimeMs = in.readLong();
- config.randomizedMacLastModifiedTimeMs = in.readLong();
- config.carrierId = in.readInt();
- config.mPasspointUniqueId = in.readString();
- config.subscriptionId = in.readInt();
- config.restricted = in.readBoolean();
- config.mSubscriptionGroup = in.readParcelable(null);
- config.mBssidAllowlist = in.readArrayList(MacAddress.class.getClassLoader());
- config.mIsDppConfigurator = in.readBoolean();
- config.mDppPrivateEcKey = in.createByteArray();
- if (config.mDppPrivateEcKey == null) {
- config.mDppPrivateEcKey = new byte[0];
- }
- config.mDppConnector = in.createByteArray();
- if (config.mDppConnector == null) {
- config.mDppConnector = new byte[0];
- }
- config.mDppCSignKey = in.createByteArray();
- if (config.mDppCSignKey == null) {
- config.mDppCSignKey = new byte[0];
- }
- config.mDppNetAccessKey = in.createByteArray();
- if (config.mDppNetAccessKey == null) {
- config.mDppNetAccessKey = new byte[0];
- }
- config.isCurrentlyConnected = in.readBoolean();
- config.mIsUserSelected = in.readBoolean();
- config.mHasPreSharedKeyChanged = in.readBoolean();
- config.mEncryptedPreSharedKey = in.createByteArray();
- if (config.mEncryptedPreSharedKey == null) {
- config.mEncryptedPreSharedKey = new byte[0];
- }
- config.mEncryptedPreSharedKeyIv = in.createByteArray();
- if (config.mEncryptedPreSharedKeyIv == null) {
- config.mEncryptedPreSharedKeyIv = new byte[0];
+ public WifiConfiguration[] newArray(int size) {
+ return new WifiConfiguration[size];
}
- config.mIpProvisioningTimedOut = in.readBoolean();
- return config;
- }
-
- public WifiConfiguration[] newArray(int size) {
- return new WifiConfiguration[size];
- }
- };
+ };
/**
* Passpoint Unique identifier
@@ -4630,4 +4704,67 @@ public class WifiConfiguration implements Parcelable {
public @Nullable ParcelUuid getSubscriptionGroup() {
return this.mSubscriptionGroup;
}
+
+ /**
+ * Return the vendor-provided configuration data, if it exists. See also {@link
+ * #setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ @SystemApi
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * Setting this field requires the MANAGE_WIFI_NETWORK_SELECTION permission. Otherwise,
+ * if this data is set, the configuration will be rejected upon add or update.
+ *
+ * @param vendorData List of {@link OuiKeyedData} containing the vendor-provided
+ * configuration data. Note that multiple elements with the same OUI are allowed.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public void setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ Objects.requireNonNull(vendorData);
+ mVendorData = new ArrayList<>(vendorData);
+ }
+
+ /**
+ * Whether Wi-Fi 7 is enabled for this network.
+ *
+ * @return true if enabled; false otherwise
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public boolean isWifi7Enabled() {
+ return mWifi7Enabled;
+ }
+
+ /**
+ * Sets whether Wi-Fi 7 is enabled for this network.
+ *
+ * @param enabled true if enabled; false otherwise
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void setWifi7Enabled(boolean enabled) {
+ mWifi7Enabled = enabled;
+ }
}
diff --git a/framework/java/android/net/wifi/WifiInfo.java b/framework/java/android/net/wifi/WifiInfo.java
index 82ab9ace78..8e233d74d6 100644
--- a/framework/java/android/net/wifi/WifiInfo.java
+++ b/framework/java/android/net/wifi/WifiInfo.java
@@ -48,6 +48,7 @@ import androidx.annotation.RequiresApi;
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.Inet4AddressUtils;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -492,6 +493,9 @@ public class WifiInfo implements TransportInfo, Parcelable {
*/
private String mNetworkKey;
+ /** List of {@link OuiKeyedData} providing vendor-specific configuration data. */
+ private @NonNull List<OuiKeyedData> mVendorData;
+
/** @hide */
@UnsupportedAppUsage
public WifiInfo() {
@@ -510,6 +514,7 @@ public class WifiInfo implements TransportInfo, Parcelable {
mIsPrimary = IS_PRIMARY_FALSE;
mNetworkKey = null;
mApMloLinkId = MloLink.INVALID_MLO_LINK_ID;
+ mVendorData = Collections.emptyList();
}
/** @hide */
@@ -555,6 +560,7 @@ public class WifiInfo implements TransportInfo, Parcelable {
mNetworkKey = null;
resetMultiLinkInfo();
enableApTidToLinkMappingNegotiationSupport(false);
+ mVendorData = Collections.emptyList();
}
/** @hide */
@@ -646,6 +652,7 @@ public class WifiInfo implements TransportInfo, Parcelable {
? null : source.mNetworkKey;
mApTidToLinkMappingNegotiationSupported =
source.mApTidToLinkMappingNegotiationSupported;
+ mVendorData = new ArrayList<>(source.mVendorData);
}
}
@@ -729,7 +736,7 @@ public class WifiInfo implements TransportInfo, Parcelable {
* Set the subscription ID.
* @see WifiInfo#getSubscriptionId()
*/
- @FlaggedApi("com.android.wifi.flags.add_subscription_id")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@NonNull
public Builder setSubscriptionId(int subId) {
mWifiInfo.setSubscriptionId(subId);
@@ -1544,7 +1551,7 @@ public class WifiInfo implements TransportInfo, Parcelable {
.append(", Security type: ").append(mSecurityType)
.append(", Supplicant state: ")
.append(mSupplicantState == null ? none : mSupplicantState)
- .append(", Wi-Fi standard: ").append(mWifiStandard)
+ .append(", Wi-Fi standard: ").append(ScanResult.wifiStandardToString(mWifiStandard))
.append(", RSSI: ").append(mRssi)
.append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS)
.append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS)
@@ -1581,7 +1588,9 @@ public class WifiInfo implements TransportInfo, Parcelable {
.append(", AP MLO Link Id: ").append(
mApMldMacAddress == null ? none : mApMloLinkId)
.append(", AP MLO Affiliated links: ").append(
- mApMldMacAddress == null ? none : mAffiliatedMloLinks);
+ mApMldMacAddress == null ? none : mAffiliatedMloLinks)
+ .append(", Vendor Data: ").append(
+ mVendorData == null || mVendorData.isEmpty() ? none : mVendorData);
return sb.toString();
}
@@ -1662,6 +1671,7 @@ public class WifiInfo implements TransportInfo, Parcelable {
dest.writeInt(mApMloLinkId);
dest.writeTypedList(mAffiliatedMloLinks);
dest.writeBoolean(mApTidToLinkMappingNegotiationSupported);
+ dest.writeList(mVendorData);
}
/** Implement the Parcelable interface {@hide} */
@@ -1725,6 +1735,7 @@ public class WifiInfo implements TransportInfo, Parcelable {
info.mApMloLinkId = in.readInt();
info.mAffiliatedMloLinks = in.createTypedArrayList(MloLink.CREATOR);
info.mApTidToLinkMappingNegotiationSupported = in.readBoolean();
+ info.mVendorData = ParcelUtil.readOuiKeyedDataList(in);
return info;
}
@@ -1746,9 +1757,9 @@ public class WifiInfo implements TransportInfo, Parcelable {
/**
* Get the Passpoint unique identifier for the current connection
*
- * @return Passpoint unique identifier
- * @hide
+ * @return Passpoint unique identifier, or null if this connection is not Passpoint.
*/
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public @Nullable String getPasspointUniqueId() {
return mPasspointUniqueId;
}
@@ -1894,7 +1905,8 @@ public class WifiInfo implements TransportInfo, Parcelable {
&& mRestricted == thatWifiInfo.mRestricted
&& Objects.equals(mNetworkKey, thatWifiInfo.mNetworkKey)
&& mApTidToLinkMappingNegotiationSupported
- == thatWifiInfo.mApTidToLinkMappingNegotiationSupported;
+ == thatWifiInfo.mApTidToLinkMappingNegotiationSupported
+ && Objects.equals(mVendorData, thatWifiInfo.mVendorData);
}
@Override
@@ -1946,7 +1958,8 @@ public class WifiInfo implements TransportInfo, Parcelable {
mSecurityType,
mRestricted,
mNetworkKey,
- mApTidToLinkMappingNegotiationSupported);
+ mApTidToLinkMappingNegotiationSupported,
+ mVendorData);
}
/**
@@ -2116,4 +2129,42 @@ public class WifiInfo implements TransportInfo, Parcelable {
public void enableApTidToLinkMappingNegotiationSupport(boolean enable) {
mApTidToLinkMappingNegotiationSupported = enable;
}
+
+ /**
+ * Return the vendor-provided configuration data, if it exists. See also {@link
+ * #setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ @SystemApi
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link OuiKeyedData} containing the vendor-provided
+ * configuration data. Note that multiple elements with the same OUI are allowed.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public void setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = new ArrayList<>(vendorData);
+ }
}
diff --git a/framework/java/android/net/wifi/WifiManager.java b/framework/java/android/net/wifi/WifiManager.java
index e8cf5fc111..411a0f8615 100644
--- a/framework/java/android/net/wifi/WifiManager.java
+++ b/framework/java/android/net/wifi/WifiManager.java
@@ -36,6 +36,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.StringDef;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
@@ -62,7 +63,11 @@ import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.ProvisioningCallback;
import android.net.wifi.p2p.WifiP2pConfig;
+import android.net.wifi.p2p.WifiP2pDiscoveryConfig;
import android.net.wifi.p2p.WifiP2pManager;
+import android.net.wifi.twt.TwtRequest;
+import android.net.wifi.twt.TwtSession;
+import android.net.wifi.twt.TwtSessionCallback;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -89,6 +94,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.HandlerExecutor;
import com.android.modules.utils.ParceledListSlice;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -108,6 +114,7 @@ import java.util.StringTokenizer;
import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
+import java.util.function.IntConsumer;
/**
* This class provides the primary API for managing all aspects of Wi-Fi
@@ -391,7 +398,7 @@ public class WifiManager {
* Disable PNO scan until device reboot.
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
public static final int PNO_SCAN_STATE_DISABLED_UNTIL_REBOOT = 0;
@@ -399,7 +406,7 @@ public class WifiManager {
* Disable PNO scan until device reboot or Wi-Fi is toggled.
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
public static final int PNO_SCAN_STATE_DISABLED_UNTIL_WIFI_TOGGLE = 1;
@@ -407,7 +414,7 @@ public class WifiManager {
* Enable PNO scan.
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
public static final int PNO_SCAN_STATE_ENABLED = 2;
@@ -532,7 +539,8 @@ public class WifiManager {
API_P2P_SET_CHANNELS,
API_WIFI_SCANNER_START_SCAN,
API_SET_TDLS_ENABLED,
- API_SET_TDLS_ENABLED_WITH_MAC_ADDRESS
+ API_SET_TDLS_ENABLED_WITH_MAC_ADDRESS,
+ API_P2P_DISCOVER_PEERS_WITH_CONFIG_PARAMS
})
public @interface ApiType {}
@@ -889,15 +897,26 @@ public class WifiManager {
*
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
public static final int API_SET_PNO_SCAN_ENABLED = 36;
/**
+ * A constant used in {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of {@link WifiP2pManager#discoverPeersWithConfigParams(
+ * WifiP2pManager.Channel, WifiP2pDiscoveryConfig, WifiP2pManager.ActionListener)}
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public static final int API_P2P_DISCOVER_PEERS_WITH_CONFIG_PARAMS = 37;
+
+ /**
* Used internally to keep track of boundary.
* @hide
*/
- public static final int API_MAX = 37;
+ public static final int API_MAX = 38;
/**
* Broadcast intent action indicating that a Passpoint provider icon has been received.
@@ -2136,6 +2155,38 @@ public class WifiManager {
}
/**
+ * Roaming is disabled.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int ROAMING_MODE_NONE = 0;
+
+ /**
+ * Chipset has roaming trigger capability based on the score calculated
+ * using multiple parameters. If device is configured to this mode then it
+ * will be using chipset's normal (default) roaming.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int ROAMING_MODE_NORMAL = 1;
+
+ /**
+ * Allows the device to roam more quickly than the normal roaming mode.
+ * Used in cases such as where APs are installed in a high density.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int ROAMING_MODE_AGGRESSIVE = 2;
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"ROAMING_MODE_"}, value = {
+ ROAMING_MODE_NONE,
+ ROAMING_MODE_NORMAL,
+ ROAMING_MODE_AGGRESSIVE})
+ public @interface RoamingMode {
+ }
+
+ /**
* Create a new WifiManager instance.
* Applications will almost always want to use
* {@link android.content.Context#getSystemService Context.getSystemService} to retrieve
@@ -3968,6 +4019,18 @@ public class WifiManager {
*/
public static final long WIFI_FEATURE_WPA_PERSONAL = 1L << 60;
+ /**
+ * Support for Roaming Mode
+ * @hide
+ */
+ public static final long WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT = 1L << 61;
+
+ /**
+ * Supports device-to-device connections when infra STA is disabled.
+ * @hide
+ */
+ public static final long WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED = 1L << 62;
+
private long getSupportedFeatures() {
try {
return mService.getSupportedFeatures();
@@ -4109,7 +4172,11 @@ public class WifiManager {
* @return true if this adapter supports offloaded connectivity scan
*/
public boolean isPreferredNetworkOffloadSupported() {
- return isFeatureSupported(WIFI_FEATURE_PNO);
+ try {
+ return mService.isPnoSupported();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
@@ -4156,7 +4223,7 @@ public class WifiManager {
* @return true if this device supports Low latency mode.
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
public boolean isLowLatencyModeSupported() {
return isFeatureSupported(WIFI_FEATURE_LOW_LATENCY);
@@ -4249,6 +4316,15 @@ public class WifiManager {
}
/**
+ * @return true if this devices supports device-to-device (D2d) Wi-Fi use-cases
+ * such as Wi-Fi Direct when infra station (STA) is disabled.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public boolean isD2dSupportedWhenInfraStaDisabled() {
+ return isFeatureSupported(WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED);
+ }
+
+ /**
* Interface for Wi-Fi activity energy info listener. Should be implemented by applications and
* set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}.
*
@@ -5612,6 +5688,8 @@ public class WifiManager {
* using {@link WifiManager#setSoftApConfiguration(SoftApConfiguration)}.
* @return {@code true} if the operation succeeded, {@code false} otherwise
*
+ * @deprecated Use {@link #startTetheredHotspotRequest(TetheringManager.TetheringRequest)}
+ * instead.
* @hide
*/
@SystemApi
@@ -5619,6 +5697,7 @@ public class WifiManager {
android.Manifest.permission.NETWORK_STACK,
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
})
+ @Deprecated
public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) {
try {
return mService.startTetheredHotspot(softApConfig, mContext.getOpPackageName());
@@ -5648,14 +5727,18 @@ public class WifiManager {
*
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.android_v_wifi_api")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
@RequiresPermission(anyOf = {
android.Manifest.permission.NETWORK_STACK,
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
})
public boolean startTetheredHotspotRequest(@NonNull TetheringManager.TetheringRequest request) {
- throw new UnsupportedOperationException("Not supported before API 35");
+ try {
+ return mService.startTetheredHotspotRequest(request, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
@@ -6550,10 +6633,14 @@ public class WifiManager {
/**
* Called when soft AP state changes.
+ * <p>
+ * This provides the same state and failure reason as {@link #onStateChanged(int, int)}, but
+ * also provides extra information such as interface name and TetheringRequest in order to
+ * replace usage of the WIFI_AP_STATE_CHANGED_ACTION broadcast.
*
* @param state the new state.
*/
- @FlaggedApi("com.android.wifi.flags.android_v_wifi_api")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
default void onStateChanged(@NonNull SoftApState state) {}
/**
@@ -6690,15 +6777,16 @@ public class WifiManager {
}
@Override
- public void onStateChanged(int state, int failureReason) {
+ public void onStateChanged(SoftApState state) {
if (mVerboseLoggingEnabled) {
- Log.v(TAG, "SoftApCallbackProxy on mode " + mIpMode + ", onStateChanged: state="
- + state + ", failureReason=" + failureReason);
+ Log.v(TAG, "SoftApCallbackProxy on mode " + mIpMode
+ + ", onStateChanged: " + state);
}
Binder.clearCallingIdentity();
mExecutor.execute(() -> {
- mCallback.onStateChanged(state, failureReason);
+ mCallback.onStateChanged(state);
+ mCallback.onStateChanged(state.getState(), state.getFailureReasonInternal());
});
}
@@ -7275,7 +7363,12 @@ public class WifiManager {
listenerProxy = new ActionListenerProxy("connect", mLooper, listener);
}
try {
- mService.connect(config, networkId, listenerProxy, mContext.getOpPackageName());
+ Bundle extras = new Bundle();
+ if (SdkLevel.isAtLeastS()) {
+ extras.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE,
+ mContext.getAttributionSource());
+ }
+ mService.connect(config, networkId, listenerProxy, mContext.getOpPackageName(), extras);
} catch (RemoteException e) {
if (listenerProxy != null) {
listenerProxy.onFailure(ActionListener.FAILURE_INTERNAL_ERROR);
@@ -7921,7 +8014,7 @@ public class WifiManager {
*
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
public interface WifiLowLatencyLockListener {
/**
@@ -7930,7 +8023,7 @@ public class WifiManager {
*
* <p>Note: Always called with current state when a new listener gets registered.
*/
- @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
void onActivatedStateChanged(boolean activated);
/**
@@ -7942,7 +8035,7 @@ public class WifiManager {
*
* @param ownerUids An array of UIDs.
*/
- @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
default void onOwnershipChanged(@NonNull int[] ownerUids) {}
/**
@@ -7958,7 +8051,7 @@ public class WifiManager {
*
* @param activeUids An array of UIDs.
*/
- @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
default void onActiveUsersChanged(@NonNull int[] activeUids) {}
}
@@ -8015,7 +8108,7 @@ public class WifiManager {
* @throws SecurityException if the caller is not allowed to call this API
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@RequiresPermission(
@@ -8053,7 +8146,7 @@ public class WifiManager {
* @throws IllegalArgumentException if incorrect input arguments are provided.
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.low_latency_lock_listener")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
public void removeWifiLowLatencyLockListener(@NonNull WifiLowLatencyLockListener listener) {
@@ -8453,6 +8546,60 @@ public class WifiManager {
/**
* Returns a byte stream representing the data that needs to be backed up to save the
* current Wifi state.
+ * This Wifi state can be restored by calling {@link #restoreWifiBackupData(byte[])}.
+ * @hide
+ */
+ @SystemApi
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void retrieveWifiBackupData(@NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<byte[]> resultsCallback) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+
+ Objects.requireNonNull(executor, "executor cannot be null");
+ Objects.requireNonNull(resultsCallback, "resultsCallback cannot be null");
+ try {
+ mService.retrieveWifiBackupData(
+ new IByteArrayListener.Stub() {
+ @Override
+ public void onResult(byte[] value) {
+ Binder.clearCallingIdentity();
+ executor.execute(() -> {
+ resultsCallback.accept(value);
+ });
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Restore state from the backed up data.
+ * @param data byte stream in the same format produced by {@link #retrieveWifiBackupData()}
+ * @hide
+ */
+ @SystemApi
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void restoreWifiBackupData(@NonNull byte[] data) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ mService.restoreWifiBackupData(data);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns a byte stream representing the data that needs to be backed up to save the
+ * current Wifi state.
* This Wifi state can be restored by calling {@link #restoreBackupData(byte[])}.
* @hide
*/
@@ -8873,7 +9020,7 @@ public class WifiManager {
/**
* @return true if this device supports connections to Wi-Fi WEP networks.
*/
- @FlaggedApi("com.android.wifi.flags.wep_usage")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public boolean isWepSupported() {
return isFeatureSupported(WIFI_FEATURE_WEP);
}
@@ -8884,7 +9031,7 @@ public class WifiManager {
* Note that this is the older and less secure WPA-Personal protocol, not WPA2-Personal
* or later protocols.
*/
- @FlaggedApi("com.android.wifi.flags.wpa_personal_usage")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public boolean isWpaPersonalSupported() {
return isFeatureSupported(WIFI_FEATURE_WPA_PERSONAL);
}
@@ -9099,7 +9246,7 @@ public class WifiManager {
*
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.verbose_logging_for_aware_only")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
public static final int VERBOSE_LOGGING_LEVEL_WIFI_AWARE_ENABLED_ONLY = 3;
@@ -10446,7 +10593,7 @@ public class WifiManager {
* @throws SecurityException if the caller does not have permission.
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.runtime_disable_pno_scan")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
@RequiresPermission(
anyOf = {MANAGE_WIFI_NETWORK_SELECTION, NETWORK_SETTINGS, NETWORK_SETUP_WIZARD})
@@ -11673,7 +11820,9 @@ public class WifiManager {
*
* Note: All policies in a single request must have the same {@link QosPolicyParams.Direction}.
*
- * Note: Currently, only the {@link QosPolicyParams#DIRECTION_DOWNLINK} direction is supported.
+ * Note: Support for the {@link QosPolicyParams#DIRECTION_UPLINK} direction is added in
+ * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}. For earlier releases,
+ * only the {@link QosPolicyParams#DIRECTION_DOWNLINK} direction is supported.
*
* @param policyParamsList List of {@link QosPolicyParams} objects describing the requested
* policies. Must have a maximum length of
@@ -11926,7 +12075,7 @@ public class WifiManager {
* @hide
*/
@SystemApi
- @FlaggedApi("com.android.wifi.flags.mlo_link_capabilities_info")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@RequiresPermission(MANAGE_WIFI_NETWORK_SELECTION)
public void getMaxMloAssociationLinkCount(@NonNull @CallbackExecutor Executor executor,
@@ -11973,7 +12122,7 @@ public class WifiManager {
* @hide
*/
@SystemApi
- @FlaggedApi("com.android.wifi.flags.mlo_link_capabilities_info")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@RequiresPermission(MANAGE_WIFI_NETWORK_SELECTION)
public void getMaxMloStrLinkCount(@NonNull @CallbackExecutor Executor executor,
@@ -12016,7 +12165,7 @@ public class WifiManager {
* @hide
*/
@SystemApi
- @FlaggedApi("com.android.wifi.flags.mlo_link_capabilities_info")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@RequiresPermission(MANAGE_WIFI_NETWORK_SELECTION)
public void getSupportedSimultaneousBandCombinations(
@@ -12060,7 +12209,7 @@ public class WifiManager {
* @throws SecurityException if the caller does not have permission.
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.wep_usage")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
@RequiresPermission(anyOf = {
android.Manifest.permission.NETWORK_SETTINGS,
@@ -12087,10 +12236,9 @@ public class WifiManager {
* whether wep network support is enabled/disabled.
*
* @throws SecurityException if the caller does not have permission.
- * @throws NullPointerException if the caller provided invalid inputs.
* @hide
*/
- @FlaggedApi("com.android.wifi.flags.wep_usage")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@SystemApi
@RequiresPermission(anyOf = {
android.Manifest.permission.NETWORK_SETTINGS,
@@ -12115,4 +12263,556 @@ public class WifiManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Enable Mirrored Stream Classification Service (MSCS) and configure using
+ * the provided configuration values.
+ *
+ * If MSCS has already been enabled/configured, this will override the
+ * existing configuration.
+ *
+ * Refer to Section 11.25.3 of the IEEE 802.11-2020 standard for more information.
+ *
+ * @param mscsParams {@link MscsParams} object containing the configuration parameters.
+ * @hide
+ */
+ @SystemApi
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @RequiresPermission(anyOf = {MANAGE_WIFI_NETWORK_SELECTION})
+ public void enableMscs(@NonNull MscsParams mscsParams) {
+ Objects.requireNonNull(mscsParams);
+ try {
+ mService.enableMscs(mscsParams);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Disable Mirrored Stream Classification Service (MSCS).
+ *
+ * If MSCS is enabled/configured, this will send a remove request to the AP.
+ *
+ * Refer to Section 11.25.3 of the IEEE 802.11-2020 standard for more information.
+ * @hide
+ */
+ @SystemApi
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @RequiresPermission(anyOf = {MANAGE_WIFI_NETWORK_SELECTION})
+ public void disableMscs() {
+ try {
+ mService.disableMscs();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Do not send the DHCP hostname to open networks.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN = 1 << 0;
+
+ /**
+ * Do not send the DHCP hostname to secure network.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_SECURE = 1 << 1;
+
+ /** @hide */
+ @IntDef(flag = true, prefix = { "FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_" }, value = {
+ FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN,
+ FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_SECURE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SendDhcpHostnameRestriction {}
+
+ /**
+ * Sets the global restrictions on which networks to send the device hostname to during DHCP.
+ *
+ * @param restriction Bitmask of {@link SendDhcpHostnameRestriction}, or none to indicate no
+ * restriction.
+ * @throws IllegalArgumentException if input is invalid
+ * @throws SecurityException if the calling app is not a Device Owner (DO), or a privileged app
+ * that has one of the permissions required by this API.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_SETUP_WIZARD
+ })
+ public void setSendDhcpHostnameRestriction(@SendDhcpHostnameRestriction int restriction) {
+ try {
+ mService.setSendDhcpHostnameRestriction(mContext.getOpPackageName(), restriction);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Query the global restriction on which networks to send the device hostname to during DHCP.
+ * @see #setSendDhcpHostnameRestriction(int)
+ *
+ * @param executor The executor on which callback will be invoked.
+ * @param resultsCallback An asynchronous callback that will return a bitmask of
+ * {@link SendDhcpHostnameRestriction}.
+ *
+ * @throws SecurityException if the calling app is not a Device Owner (DO), or a privileged app
+ * that has one of the permissions required by this API.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_SETUP_WIZARD
+ })
+ public void querySendDhcpHostnameRestriction(@NonNull @CallbackExecutor Executor executor,
+ @NonNull IntConsumer resultsCallback) {
+ Objects.requireNonNull(executor, "executor cannot be null");
+ Objects.requireNonNull(resultsCallback, "resultsCallback cannot be null");
+ try {
+ mService.querySendDhcpHostnameRestriction(mContext.getOpPackageName(),
+ new IIntegerListener.Stub() {
+ @Override
+ public void onResult(int value) {
+ Binder.clearCallingIdentity();
+ executor.execute(() -> {
+ resultsCallback.accept(value);
+ });
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @return true if this device supports Aggressive roaming mode
+ * {@link #setPerSsidRoamingMode(WifiSsid, int)}
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public boolean isAggressiveRoamingModeSupported() {
+ return isFeatureSupported(WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT);
+ }
+
+ /**
+ * This API allows a privileged application to set roaming mode per SSID.
+ *
+ * Available for DO/COPE apps.
+ * 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}.
+ * @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()}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @SuppressLint("RequiresPermission")
+ public void setPerSsidRoamingMode(@NonNull WifiSsid ssid, @RoamingMode int roamingMode) {
+ if (roamingMode < ROAMING_MODE_NONE || roamingMode > ROAMING_MODE_AGGRESSIVE) {
+ throw new IllegalArgumentException("invalid roaming mode: " + roamingMode);
+ }
+ Objects.requireNonNull(ssid, "ssid cannot be null");
+ try {
+ mService.setPerSsidRoamingMode(ssid, roamingMode, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * This API allows a privileged application to remove roaming mode policy
+ * configured using the {@link #setPerSsidRoamingMode(WifiSsid, int)}.
+ *
+ * Available for DO/COPE apps.
+ * 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()}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @SuppressLint("RequiresPermission")
+ public void removePerSsidRoamingMode(@NonNull WifiSsid ssid) {
+ Objects.requireNonNull(ssid, "ssid cannot be null");
+ try {
+ mService.removePerSsidRoamingMode(ssid, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * This API allows a privileged application to get roaming mode policies
+ * configured using the {@link #setPerSsidRoamingMode(WifiSsid, int)}.
+ *
+ * Available for DO/COPE apps.
+ * Other apps require {@code android.Manifest.permission#NETWORK_SETTINGS} or
+ * {@code android.Manifest.permission#MANAGE_WIFI_NETWORK_SELECTION} permission.
+ *
+ * @param executor The executor on which callback will be invoked.
+ * @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()}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @SuppressLint("RequiresPermission")
+ public void getPerSsidRoamingModes(@NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<Map<String, Integer>> resultsCallback) {
+ Objects.requireNonNull(executor, "executor cannot be null");
+ Objects.requireNonNull(resultsCallback, "resultsCallback cannot be null");
+ try {
+ mService.getPerSsidRoamingModes(mContext.getOpPackageName(), new IMapListener.Stub() {
+ @Override
+ public void onResult(Map roamingPolicies) {
+ Binder.clearCallingIdentity();
+ executor.execute(() -> {
+ resultsCallback.accept(roamingPolicies);
+ });
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Bundle key to check target wake time requester mode supported or not
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final String TWT_CAPABILITIES_KEY_BOOLEAN_TWT_REQUESTER =
+ "key_requester";
+
+ /**
+ * Bundle key to get minimum wake duration supported in microseconds
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final String TWT_CAPABILITIES_KEY_INT_MIN_WAKE_DURATION_MICROS =
+ "key_min_wake_duration";
+ /**
+ * Bundle key to get maximum wake duration supported in microseconds
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final String TWT_CAPABILITIES_KEY_INT_MAX_WAKE_DURATION_MICROS =
+ "key_max_wake_duration";
+ /**
+ * Bundle key to get minimum wake interval supported in microseconds
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final String TWT_CAPABILITIES_KEY_LONG_MIN_WAKE_INTERVAL_MICROS =
+ "key_min_wake_interval";
+ /**
+ * Bundle key to get maximum wake interval supported in microseconds
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final String TWT_CAPABILITIES_KEY_LONG_MAX_WAKE_INTERVAL_MICROS =
+ "key_max_wake_interval";
+
+ /** @hide */
+ @StringDef(prefix = { "TWT_CAPABILITIES_KEY_"}, value = {
+ TWT_CAPABILITIES_KEY_BOOLEAN_TWT_REQUESTER,
+ TWT_CAPABILITIES_KEY_INT_MIN_WAKE_DURATION_MICROS,
+ TWT_CAPABILITIES_KEY_INT_MAX_WAKE_DURATION_MICROS,
+ TWT_CAPABILITIES_KEY_LONG_MIN_WAKE_INTERVAL_MICROS,
+ TWT_CAPABILITIES_KEY_LONG_MAX_WAKE_INTERVAL_MICROS,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TwtCapabilities {}
+
+ /**
+ * Get target wake time (TWT) capabilities of the primary station interface.
+ *
+ * Note: Target wake time feature is only supported for primary station. If Wi-Fi is off or the
+ * capability is not available the asynchronous callback will be called with the bundle
+ * with values { false, -1, -1, -1, -1 }.
+ *
+ * @param executor Executor to execute listener callback
+ * @param resultCallback An asynchronous callback that will return a bundle for target wake time
+ * capabilities. See {@link TwtCapabilities} for the string keys for
+ * the bundle.
+ * @throws SecurityException if the caller does not have permission.
+ * @throws NullPointerException if the caller provided null inputs.
+ * @throws UnsupportedOperationException if the API is not supported.
+ * @hide
+ */
+ @SystemApi
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @RequiresPermission(MANAGE_WIFI_NETWORK_SELECTION)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void getTwtCapabilities(@NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<Bundle> resultCallback) {
+ Objects.requireNonNull(executor, "executor cannot be null");
+ Objects.requireNonNull(resultCallback, "resultCallback cannot be null");
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ Bundle extras = new Bundle();
+ extras.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE,
+ mContext.getAttributionSource());
+ mService.getTwtCapabilities(
+ new ITwtCapabilitiesListener.Stub() {
+ @Override
+ public void onResult(Bundle value) {
+ Binder.clearCallingIdentity();
+ executor.execute(() -> {
+ resultCallback.accept(value);
+ });
+ }
+ }, extras);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ private class TwtCallbackProxy extends ITwtCallback.Stub {
+ private final Executor mExecutor;
+ private final TwtSessionCallback mCallback;
+
+ private TwtCallbackProxy(Executor executor, TwtSessionCallback callback) {
+ mExecutor = executor;
+ mCallback = callback;
+ }
+
+ @Override
+ public void onFailure(@TwtSessionCallback.TwtErrorCode int errorCode)
+ throws RemoteException {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "TwtCallbackProxy: onFailure(errorCode = " + errorCode + " )");
+ }
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onFailure(errorCode));
+ }
+
+ @Override
+ public void onTeardown(@TwtSessionCallback.TwtReasonCode int reasonCode)
+ throws RemoteException {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "TwtCallbackProxy: onTeardown(errorCode = " + reasonCode + " )");
+ }
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onTeardown(reasonCode));
+ }
+
+ @Override
+ public void onCreate(int wakeDuration, long wakeInterval, int mloLinkId, int owner,
+ int sessionId) throws RemoteException {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "TwtCallbackProxy: onCreate " + sessionId);
+ }
+
+ WifiTwtSession wifiTwtSession = new WifiTwtSession(WifiManager.this, wakeDuration,
+ wakeInterval, mloLinkId, owner, sessionId);
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mCallback.onCreate(wifiTwtSession));
+ }
+ }
+
+ /**
+ * Set up a TWT session with a TWT responder capable AP. Only supported for primary connected
+ * station which is a TWT requester. See {@link #getTwtCapabilities(Executor, Consumer)} and
+ * {@link ScanResult#isTwtResponder()} to check station and AP support.
+ *
+ * Following callbacks are invoked,
+ * - {@link TwtSessionCallback#onFailure(int)} upon error with error code.
+ * - {@link TwtSessionCallback#onCreate(TwtSession)} upon TWT session creation.
+ * - {@link TwtSessionCallback#onTeardown(int)} upon TWT session teardown.
+ *
+ * Note: {@link #getTwtCapabilities(Executor, Consumer)} gives {@link TwtCapabilities} which can
+ * be used to fill in the valid TWT wake interval and duration ranges for {@link TwtRequest}.
+ *
+ * @param twtRequest TWT request
+ * @param executor Executor to execute listener callback on
+ * @param callback Callback to register
+ * @throws SecurityException if the caller does not have permission.
+ * @throws NullPointerException if the caller provided null inputs.
+ * @throws UnsupportedOperationException if the API is not supported.
+ * @hide
+ */
+ @SystemApi
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @RequiresPermission(MANAGE_WIFI_NETWORK_SELECTION)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void setupTwtSession(@NonNull TwtRequest twtRequest,
+ @NonNull @CallbackExecutor Executor executor, @NonNull TwtSessionCallback callback) {
+ Objects.requireNonNull(executor, "executor cannot be null");
+ Objects.requireNonNull(callback, "callback cannot be null");
+ Objects.requireNonNull(twtRequest, "twtRequest cannot be null");
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ ITwtCallback.Stub binderCallback = new TwtCallbackProxy(executor, callback);
+ Bundle extras = new Bundle();
+ extras.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE,
+ mContext.getAttributionSource());
+ mService.setupTwtSession(twtRequest, binderCallback, extras);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get stats of the target wake time session.
+ *
+ * Note: For Internal use only. Expected to be called through
+ * {@link TwtSession#getStats(Executor, Consumer)}. If the command fails, -1 will be returned
+ * for all stats values.
+ *
+ * @param sessionId TWT session id
+ * @param executor The executor on which callback will be invoked.
+ * @param resultCallback The asynchronous callback that will return bundle with key string
+ * {@link TwtSession.TwtStats}.
+ *
+ * @throws SecurityException if the caller does not have permission.
+ * @throws NullPointerException if the caller provided null inputs.
+ * @throws UnsupportedOperationException if the API is not supported or primary station is
+ * not connected.
+ * @hide
+ */
+ public void getStatsTwtSession(@NonNull int sessionId, @NonNull Executor executor,
+ @NonNull Consumer<Bundle> resultCallback) {
+ Objects.requireNonNull(executor, "executor cannot be null");
+ Objects.requireNonNull(resultCallback, "resultsCallback cannot be null");
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ Bundle extras = new Bundle();
+ if (SdkLevel.isAtLeastS()) {
+ extras.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE,
+ mContext.getAttributionSource());
+ }
+ mService.getStatsTwtSession(sessionId,
+ new ITwtStatsListener.Stub() {
+ @Override
+ public void onResult(Bundle value) {
+ Binder.clearCallingIdentity();
+ executor.execute(() -> {
+ resultCallback.accept(value);
+ });
+ }
+ }, extras);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Teardown the target wake time session. Only owner can teardown the session.
+ *
+ * Note: For internal use only. Expected to be called through
+ * {@link TwtSessionCallback#onTeardown(int)}.
+ *
+ * @param sessionId TWT session id
+ * @throws SecurityException if the caller does not have permission.
+ * @throws UnsupportedOperationException if the API is not supported or primary station is not
+ * connected.
+ * @hide
+ */
+ public void teardownTwtSession(int sessionId) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ Bundle extras = new Bundle();
+ if (SdkLevel.isAtLeastS()) {
+ extras.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE,
+ mContext.getAttributionSource());
+ }
+ mService.teardownTwtSession(sessionId, extras);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Allows a privileged application to set whether or not this device allows
+ * device-to-device connections when infra STA is disabled. Callers can use
+ * {@link #queryD2dAllowedWhenInfraStaDisabled(Executor, Consumer)} to check the currently
+ * set value.
+ *
+ * Note: This functionality is supported only when the device support device-to-device
+ * when infra STA is disabled. Use {@link #isD2dSupportedWhenInfraStaDisabled()} to
+ * know if device supported device-to-device when infra STA is disabled.
+ *
+ * @param isAllowed whether or not the device allows to device-to-device connectivity when
+ * infra STA is disabled.
+ * @throws SecurityException if the caller does not have permission.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_SETUP_WIZARD
+ })
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ public void setD2dAllowedWhenInfraStaDisabled(boolean isAllowed) {
+ try {
+ mService.setD2dAllowedWhenInfraStaDisabled(isAllowed);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Query whether or not this device is configured to allow D2d connection when
+ * infra STA is disabled.
+ * see: {@link #setD2dAllowedWhenInfraStaDisabled(boolean)}.
+ *
+ *
+ * @param executor The executor on which callback will be invoked.
+ * @param resultsCallback An asynchronous callback that will return {@code Boolean} indicating
+ * whether device-to-device connection is allowed or disallowed
+ * when infra STA is disabled.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public void queryD2dAllowedWhenInfraStaDisabled(@NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<Boolean> resultsCallback) {
+ Objects.requireNonNull(executor, "executor cannot be null");
+ Objects.requireNonNull(resultsCallback, "resultsCallback cannot be null");
+ try {
+ mService.queryD2dAllowedWhenInfraStaDisabled(
+ new IBooleanListener.Stub() {
+ @Override
+ public void onResult(boolean value) {
+ Binder.clearCallingIdentity();
+ executor.execute(() -> {
+ resultsCallback.accept(value);
+ });
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/framework/java/android/net/wifi/WifiNetworkSuggestion.java b/framework/java/android/net/wifi/WifiNetworkSuggestion.java
index be666815aa..eb7405f36c 100644
--- a/framework/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/framework/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -18,6 +18,7 @@ package android.net.wifi;
import static com.android.internal.util.Preconditions.checkNotNull;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -40,6 +41,7 @@ import android.text.TextUtils;
import androidx.annotation.RequiresApi;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -232,6 +234,11 @@ public final class WifiNetworkSuggestion implements Parcelable {
*/
private boolean mIsNetworkRestricted;
+ /**
+ * Whether enable Wi-Fi 7 for this network
+ */
+ private boolean mIsWifi7Enabled;
+
/**
* The Subscription group UUID identifies the SIM cards for which this network configuration
@@ -269,6 +276,7 @@ public final class WifiNetworkSuggestion implements Parcelable {
mIsNetworkRestricted = false;
mSubscriptionGroup = null;
mWifiSsid = null;
+ mIsWifi7Enabled = true;
}
/**
@@ -862,6 +870,17 @@ public final class WifiNetworkSuggestion implements Parcelable {
}
/**
+ * Sets whether Wi-Fi 7 is enabled for this network.
+ *
+ * @param enabled Enable Wi-Fi 7 if true, otherwise disable Wi-Fi 7
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @NonNull Builder setWifi7Enabled(boolean enabled) {
+ mIsWifi7Enabled = enabled;
+ return this;
+ }
+ /**
* Specifies whether the system will bring up the network (if selected) as OEM paid. An
* OEM paid network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID} capability
* added.
@@ -1080,6 +1099,7 @@ public final class WifiNetworkSuggestion implements Parcelable {
wifiConfiguration.subscriptionId = mSubscriptionId;
wifiConfiguration.restricted = mIsNetworkRestricted;
wifiConfiguration.setSubscriptionGroup(mSubscriptionGroup);
+ wifiConfiguration.setWifi7Enabled(mIsWifi7Enabled);
return wifiConfiguration;
}
@@ -1119,6 +1139,7 @@ public final class WifiNetworkSuggestion implements Parcelable {
: WifiConfiguration.RANDOMIZATION_PERSISTENT;
wifiConfiguration.restricted = mIsNetworkRestricted;
wifiConfiguration.setSubscriptionGroup(mSubscriptionGroup);
+ wifiConfiguration.setWifi7Enabled(mIsWifi7Enabled);
mPasspointConfiguration.setCarrierId(mCarrierId);
mPasspointConfiguration.setSubscriptionId(mSubscriptionId);
mPasspointConfiguration.setSubscriptionGroup(mSubscriptionGroup);
@@ -1709,4 +1730,12 @@ public final class WifiNetworkSuggestion implements Parcelable {
}
return wifiConfiguration.getSubscriptionGroup();
}
+
+ /**
+ * See {@link Builder#setWifi7Enabled(boolean)}
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public boolean isWifi7Enabled() {
+ return wifiConfiguration.isWifi7Enabled();
+ }
}
diff --git a/framework/java/android/net/wifi/WifiScanner.java b/framework/java/android/net/wifi/WifiScanner.java
index 526ca7c360..93ea0b0bad 100644
--- a/framework/java/android/net/wifi/WifiScanner.java
+++ b/framework/java/android/net/wifi/WifiScanner.java
@@ -16,10 +16,13 @@
package android.net.wifi;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.Manifest.permission.LOCATION_HARDWARE;
import static android.Manifest.permission.NEARBY_WIFI_DEVICES;
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -44,6 +47,7 @@ import androidx.annotation.RequiresApi;
import com.android.internal.util.Protocol;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -54,6 +58,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
* This class provides a way to scan the Wifi universe around the device
@@ -835,7 +840,8 @@ public class WifiScanner {
/** all scan results discovered in this scan, sorted by timestamp in ascending order */
private final List<ScanResult> mResults;
- ScanData() {
+ /** {@hide} */
+ public ScanData() {
mResults = new ArrayList<>();
}
@@ -1560,6 +1566,41 @@ public class WifiScanner {
}
}
+ /**
+ * Retrieve the scan data cached by the hardware.
+ *
+ * @param executor The executor on which callback will be invoked.
+ * @param resultsCallback An asynchronous callback that will return the cached scan data.
+ *
+ * @throws UnsupportedOperationException if the API is not supported on this SDK version.
+ * @throws SecurityException if the caller does not have permission.
+ * @throws NullPointerException if the caller provided invalid inputs.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, LOCATION_HARDWARE})
+ public void getCachedScanData(@NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<ScanData> resultsCallback) {
+ Objects.requireNonNull(executor, "executor cannot be null");
+ Objects.requireNonNull(resultsCallback, "resultsCallback cannot be null");
+ try {
+ mService.getCachedScanData(mContext.getPackageName(),
+ mContext.getAttributionTag(),
+ new IScanDataListener.Stub() {
+ @Override
+ public void onResult(@NonNull ScanData scanData) {
+ Binder.clearCallingIdentity();
+ executor.execute(() -> {
+ resultsCallback.accept(scanData);
+ });
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+
private void startPnoScan(PnoScanListener listener, Executor executor,
ScanSettings scanSettings, PnoSettings pnoSettings) {
// Set the PNO scan flag.
@@ -1854,6 +1895,8 @@ public class WifiScanner {
/** @hide */
public static final int CMD_SCAN_RESULT = BASE + 5;
/** @hide */
+ public static final int CMD_CACHED_SCAN_DATA = BASE + 6;
+ /** @hide */
public static final int CMD_OP_SUCCEEDED = BASE + 17;
/** @hide */
public static final int CMD_OP_FAILED = BASE + 18;
diff --git a/framework/java/android/net/wifi/WifiTwtSession.java b/framework/java/android/net/wifi/WifiTwtSession.java
new file mode 100644
index 0000000000..0967415d42
--- /dev/null
+++ b/framework/java/android/net/wifi/WifiTwtSession.java
@@ -0,0 +1,107 @@
+/*
+ * 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 android.net.wifi;
+
+import android.net.wifi.twt.TwtSession;
+import android.os.Binder;
+import android.os.Bundle;
+import android.util.CloseGuard;
+import android.util.Log;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Implementation of the interface {@link TwtSession}
+ *
+ * @hide
+ */
+public class WifiTwtSession implements TwtSession {
+ private static final String TAG = "WifiTwtSession";
+ public static final int MAX_TWT_SESSIONS = 8;
+ private final int mWakeDurationMicros;
+ private final long mWakeIntervalMicros;
+ private final int mMloLinkId;
+ private final int mOwner;
+ private final int mSessionId;
+ private final WeakReference<WifiManager> mMgr;
+ private final CloseGuard mCloseGuard = new CloseGuard();
+
+ @Override
+ public int getWakeDurationMicros() {
+ return mWakeDurationMicros;
+ }
+
+ @Override
+ public long getWakeIntervalMicros() {
+ return mWakeIntervalMicros;
+ }
+
+ @Override
+ public int getMloLinkId() {
+ return mMloLinkId;
+ }
+
+ public int getOwner() {
+ return mOwner;
+ }
+
+ public int getSessionId() {
+ return mSessionId;
+ }
+
+ @Override
+ public void getStats(Executor executor, Consumer<Bundle> resultCallback) {
+ WifiManager mgr = mMgr.get();
+ if (mgr == null) {
+ Log.e(TAG, "getStats: called post garbage collection");
+ return;
+ }
+ if (Binder.getCallingUid() != mOwner) {
+ throw new SecurityException("TWT session is not owned by the caller");
+ }
+ mgr.getStatsTwtSession(mSessionId, executor, resultCallback);
+ }
+
+ public WifiTwtSession(WifiManager wifiManager, int wakeDurationMicros, long wakeIntervalMicros,
+ int mloLinkId, int owner, int sessionId) {
+ mMgr = new WeakReference<>(wifiManager);
+ mWakeDurationMicros = wakeDurationMicros;
+ mWakeIntervalMicros = wakeIntervalMicros;
+ mMloLinkId = mloLinkId;
+ mOwner = owner;
+ mSessionId = sessionId;
+ mCloseGuard.open("teardown");
+ }
+
+ @Override
+ public void teardown() {
+ try {
+ WifiManager mgr = mMgr.get();
+ if (mgr == null) {
+ Log.w(TAG, "close: called post garbage collection");
+ return;
+ }
+ mgr.teardownTwtSession(mSessionId);
+ mMgr.clear();
+ mCloseGuard.close();
+ } finally {
+ Reference.reachabilityFence(this);
+ }
+ }
+}
diff --git a/framework/java/android/net/wifi/WifiUriParser.java b/framework/java/android/net/wifi/WifiUriParser.java
new file mode 100644
index 0000000000..926678a314
--- /dev/null
+++ b/framework/java/android/net/wifi/WifiUriParser.java
@@ -0,0 +1,280 @@
+/*
+ * 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 android.net.wifi;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.text.TextUtils;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.wifi.flags.Flags;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * Supports to parse 2 types of Wifi Uri
+ *
+ * <p>1. Standard Wi-Fi Easy Connect (DPP) bootstrapping information or 2. ZXing reader library's
+ * Wi-Fi Network config format described in
+ * https://github.com/zxing/zxing/wiki/Barcode-Contents#wi-fi-network-config-android-ios-11
+ *
+ * <p>ZXing reader library's Wi-Fi Network config format example:
+ *
+ * <p>WIFI:T:WPA;S:mynetwork;P:mypass;;
+ *
+ * <p>parameter Example Description T WPA Authentication type; can be WEP, WPA, SAE or 'nopass' for
+ * no password. Or, omit for no password. S mynetwork Network SSID. Required. Enclose in double
+ * quotes if it is an ASCII name, but could be interpreted as hex (i.e. "ABCD") P mypass Password,
+ * ignored if T is "nopass" (in which case it may be omitted). Enclose in double quotes if it is an
+ * ASCII name, but could be interpreted as hex (i.e. "ABCD") H true Optional. True if the network
+ * SSID is hidden.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+@SystemApi
+public class WifiUriParser {
+ static final String TAG = "WifiUriParser";
+ static final String SCHEME_DPP = "DPP";
+ static final String SCHEME_ZXING_WIFI_NETWORK_CONFIG = "WIFI";
+ static final String PREFIX_DPP = "DPP:";
+ static final String PREFIX_ZXING_WIFI_NETWORK_CONFIG = "WIFI:";
+
+ static final String PREFIX_DPP_PUBLIC_KEY = "K:";
+ static final String PREFIX_DPP_INFORMATION = "I:";
+
+ static final String PREFIX_ZXING_SECURITY = "T:";
+ static final String PREFIX_ZXING_SSID = "S:";
+ static final String PREFIX_ZXING_PASSWORD = "P:";
+ static final String PREFIX_ZXING_HIDDEN_SSID = "H:";
+
+ static final String DELIMITER_QR_CODE = ";";
+
+ // Ignores password if security is SECURITY_NO_PASSWORD or absent
+ static final String SECURITY_NO_PASSWORD = "nopass"; // open network or OWE
+ static final String SECURITY_WEP = "WEP";
+ static final String SECURITY_WPA_PSK = "WPA";
+ static final String SECURITY_SAE = "SAE";
+
+ private WifiUriParser() {}
+
+ /**
+ * Returns parsed result from given uri.
+ *
+ * @param uri URI of the configuration that was obtained out of band(QR code scanning, BLE).
+ * @throws IllegalArgumentException when parse failed.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public static UriParserResults parseUri(@NonNull String uri) {
+ if (TextUtils.isEmpty(uri)) {
+ throw new IllegalArgumentException("Empty Wifi Uri");
+ }
+
+ if (uri.startsWith(PREFIX_DPP)) {
+ return parseWifiDppUri(uri);
+ } else if (uri.startsWith(PREFIX_ZXING_WIFI_NETWORK_CONFIG)) {
+ return parseZxingWifiUriParser(uri);
+ } else {
+ throw new IllegalArgumentException("Unsupport scheme (Not start with "
+ + PREFIX_DPP + "/" + PREFIX_ZXING_WIFI_NETWORK_CONFIG + ")");
+ }
+ }
+
+ /** Parses Wi-Fi Easy Connect (DPP) Wifi Uri string */
+ private static UriParserResults parseWifiDppUri(String uri) throws IllegalArgumentException {
+ List<String> keyValueList = getKeyValueList(uri, PREFIX_DPP, DELIMITER_QR_CODE);
+
+ String publicKey = getValueOrNull(keyValueList, PREFIX_DPP_PUBLIC_KEY);
+ if (TextUtils.isEmpty(publicKey)) {
+ throw new IllegalArgumentException("Invalid format, publicKey is empty");
+ }
+
+ String information = getValueOrNull(keyValueList, PREFIX_DPP_INFORMATION);
+
+ return new UriParserResults(UriParserResults.URI_SCHEME_DPP, publicKey, information, null);
+ }
+
+ /** Parses ZXing reader library's Wi-Fi Network config format */
+ private static UriParserResults parseZxingWifiUriParser(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);
+ boolean hiddenSsid = "true".equalsIgnoreCase(hiddenSsidString);
+
+ // "\", ";", "," 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(
+ security, ssid, password, hiddenSsid, WifiConfiguration.INVALID_NETWORK_ID);
+ }
+
+ if (config == null) {
+ throw new IllegalArgumentException("Invalid format, can't generate WifiConfiguration");
+ }
+ return new UriParserResults(UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG,
+ null, null, config);
+ }
+
+ /**
+ * Splits key/value pairs from uri
+ *
+ * @param uri the Wifi Uri raw string
+ * @param prefixUri the string before all key/value pairs in uri
+ * @param delimiter the string to split key/value pairs, can't contain a backslash
+ * @return a list contains string of key/value (e.g. K:key1)
+ */
+ private static List<String> getKeyValueList(String uri, String prefixUri, String delimiter) {
+ String keyValueString = uri.substring(prefixUri.length());
+
+ // Should not treat \delimiter as a delimiter
+ String regex = "(?<!\\\\)" + Pattern.quote(delimiter);
+
+ return Arrays.asList(keyValueString.split(regex));
+ }
+
+ private static String getValueOrNull(List<String> keyValueList, String prefix) {
+ for (String keyValue : keyValueList) {
+ String strippedKeyValue = keyValue.stripLeading();
+ if (strippedKeyValue.startsWith(prefix)) {
+ return strippedKeyValue.substring(prefix.length());
+ }
+ }
+
+ return null;
+ }
+
+ @VisibleForTesting
+ static String removeBackSlash(String input) {
+ if (input == null) {
+ return null;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ boolean backSlash = false;
+ for (int i = 0; i < input.length(); i++) {
+ char ch = input.charAt(i);
+ if (ch != '\\') {
+ sb.append(ch);
+ backSlash = false;
+ } else {
+ if (backSlash) {
+ sb.append(ch);
+ backSlash = false;
+ continue;
+ }
+
+ backSlash = true;
+ }
+ }
+
+ return sb.toString();
+ }
+
+ private static String addQuotationIfNeeded(String input) {
+ if (TextUtils.isEmpty(input)) {
+ return "";
+ }
+
+ if (input.length() >= 2 && input.startsWith("\"") && input.endsWith("\"")) {
+ return input;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("\"").append(input).append("\"");
+ return sb.toString();
+ }
+
+ private static boolean isValidConfig(String security, String ssid, String preSharedKey) {
+ if (!TextUtils.isEmpty(security) && !SECURITY_NO_PASSWORD.equals(security)) {
+ if (TextUtils.isEmpty(preSharedKey)) {
+ return false;
+ }
+ }
+
+ if (TextUtils.isEmpty(ssid)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * This is a simplified method from {@code WifiConfigController.getConfig()}
+ *
+ * @return WifiConfiguration from parsing result
+ */
+ private static WifiConfiguration generatetWifiConfiguration(
+ String security, String ssid, String preSharedKey, boolean hiddenSsid, int networkId) {
+ final WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.SSID = addQuotationIfNeeded(ssid);
+ wifiConfiguration.hiddenSSID = hiddenSsid;
+ wifiConfiguration.networkId = networkId;
+
+ if (TextUtils.isEmpty(security) || SECURITY_NO_PASSWORD.equals(security)) {
+ List<SecurityParams> securityParamsList = new ArrayList<>();
+ securityParamsList.add(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_OPEN));
+ securityParamsList.add(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_OWE));
+ wifiConfiguration.setSecurityParams(securityParamsList);
+ return wifiConfiguration;
+ }
+
+ if (security.startsWith(SECURITY_WEP)) {
+ wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WEP);
+
+ // WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
+ final int length = preSharedKey.length();
+ if ((length == 10 || length == 26 || length == 58)
+ && preSharedKey.matches("[0-9A-Fa-f]*")) {
+ wifiConfiguration.wepKeys[0] = preSharedKey;
+ } else {
+ wifiConfiguration.wepKeys[0] = addQuotationIfNeeded(preSharedKey);
+ }
+ } else if (security.startsWith(SECURITY_WPA_PSK)) {
+ wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
+
+ if (preSharedKey.matches("[0-9A-Fa-f]{64}")) {
+ wifiConfiguration.preSharedKey = preSharedKey;
+ } else {
+ wifiConfiguration.preSharedKey = addQuotationIfNeeded(preSharedKey);
+ }
+ } else if (security.startsWith(SECURITY_SAE)) {
+ wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
+ if (preSharedKey.length() != 0) {
+ wifiConfiguration.preSharedKey = addQuotationIfNeeded(preSharedKey);
+ }
+ } else {
+ throw new IllegalArgumentException("Unsupported security");
+ }
+
+ return wifiConfiguration;
+ }
+}
diff --git a/framework/java/android/net/wifi/WifiUsabilityStatsEntry.java b/framework/java/android/net/wifi/WifiUsabilityStatsEntry.java
index e147b500db..435bf4fcfe 100644
--- a/framework/java/android/net/wifi/WifiUsabilityStatsEntry.java
+++ b/framework/java/android/net/wifi/WifiUsabilityStatsEntry.java
@@ -29,6 +29,8 @@ import android.util.SparseArray;
import androidx.annotation.Nullable;
+import com.android.wifi.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
@@ -1180,7 +1182,7 @@ public final class WifiUsabilityStatsEntry implements Parcelable {
* @return total time CCA is on busy status for the link in ms.
* @throws NoSuchElementException if linkId is invalid.
*/
- @FlaggedApi("com.android.wifi.flags.add_channel_stats_per_link")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public long getTotalCcaBusyFreqTimeMillis(int linkId) {
if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTotalCcaBusyFreqTimeMillis;
throw new NoSuchElementException("linkId is invalid - " + linkId);
@@ -1202,7 +1204,7 @@ public final class WifiUsabilityStatsEntry implements Parcelable {
* @return The total radio on time for the link in ms.
* @throws NoSuchElementException if linkId is invalid.
*/
- @FlaggedApi("com.android.wifi.flags.add_channel_stats_per_link")
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public long getTotalRadioOnFreqTimeMillis(int linkId) {
if (mLinkStats.contains(linkId)) return mLinkStats.get(linkId).mTotalRadioOnFreqTimeMillis;
throw new NoSuchElementException("linkId is invalid - " + linkId);
diff --git a/framework/java/android/net/wifi/aware/ConfigRequest.java b/framework/java/android/net/wifi/aware/ConfigRequest.java
index c954a86166..decdbeedef 100644
--- a/framework/java/android/net/wifi/aware/ConfigRequest.java
+++ b/framework/java/android/net/wifi/aware/ConfigRequest.java
@@ -16,10 +16,23 @@
package android.net.wifi.aware;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.RequiresApi;
+import android.annotation.SystemApi;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.ParcelUtil;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
+
import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
/**
* Defines a request object to configure a Wi-Fi Aware network. Built using
@@ -31,72 +44,98 @@ import java.util.Arrays;
*
* @hide
*/
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+@SystemApi
public final class ConfigRequest implements Parcelable {
/**
* Lower range of possible cluster ID.
+ * @hide
*/
public static final int CLUSTER_ID_MIN = 0;
/**
* Upper range of possible cluster ID.
+ * @hide
*/
public static final int CLUSTER_ID_MAX = 0xFFFF;
/**
* Indices for configuration variables which are specified per band.
+ * @hide
*/
public static final int NAN_BAND_24GHZ = 0;
+
+ /** @hide */
public static final int NAN_BAND_5GHZ = 1;
+
+ /** @hide */
public static final int NAN_BAND_6GHZ = 2;
/**
* Magic values for Discovery Window (DW) interval configuration
+ * @hide
*/
public static final int DW_INTERVAL_NOT_INIT = -1;
+
+ /** @hide */
public static final int DW_DISABLE = 0; // only valid for 5GHz
/**
* Indicates whether 5G band support is requested.
+ * @hide
*/
public final boolean mSupport5gBand;
/**
* Indicates whether 6G band support is requested.
+ * @hide
*/
public final boolean mSupport6gBand;
/**
* Specifies the desired master preference.
+ * @hide
*/
public int mMasterPreference;
/**
- * Specifies the desired lower range of the cluster ID. Must be lower then
+ * Specifies the desired lower range of the cluster ID. Must be lower than
* {@link ConfigRequest#mClusterHigh}.
+ * @hide
*/
public final int mClusterLow;
/**
- * Specifies the desired higher range of the cluster ID. Must be higher then
+ * Specifies the desired higher range of the cluster ID. Must be higher than
* {@link ConfigRequest#mClusterLow}.
+ * @hide
*/
public final int mClusterHigh;
/**
* Specifies the discovery window interval for the device on NAN_BAND_*.
+ * @hide
*/
public final int mDiscoveryWindowInterval[];
+ /**
+ * List of {@link OuiKeyedData} providing vendor-specific configuration data.
+ */
+ private final List<OuiKeyedData> mVendorData;
+
private ConfigRequest(boolean support5gBand, boolean support6gBand, int masterPreference,
- int clusterLow, int clusterHigh, int[] discoveryWindowInterval) {
+ int clusterLow, int clusterHigh, int[] discoveryWindowInterval,
+ @NonNull List<OuiKeyedData> vendorData) {
mSupport5gBand = support5gBand;
mSupport6gBand = support6gBand;
mMasterPreference = masterPreference;
mClusterLow = clusterLow;
mClusterHigh = clusterHigh;
mDiscoveryWindowInterval = discoveryWindowInterval;
+ mVendorData = vendorData;
}
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
public String toString() {
return "ConfigRequest [mSupport5gBand=" + mSupport5gBand
@@ -104,24 +143,30 @@ public final class ConfigRequest implements Parcelable {
+ ", mMasterPreference=" + mMasterPreference
+ ", mClusterLow=" + mClusterLow
+ ", mClusterHigh=" + mClusterHigh
- + ", mDiscoveryWindowInterval=" + Arrays.toString(mDiscoveryWindowInterval) + "]";
+ + ", mDiscoveryWindowInterval=" + Arrays.toString(mDiscoveryWindowInterval)
+ + ", mVendorData=" + mVendorData
+ + "]";
}
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
public int describeContents() {
return 0;
}
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mSupport5gBand ? 1 : 0);
dest.writeInt(mSupport6gBand ? 1 : 0);
dest.writeInt(mMasterPreference);
dest.writeInt(mClusterLow);
dest.writeInt(mClusterHigh);
dest.writeIntArray(mDiscoveryWindowInterval);
+ dest.writeList(mVendorData);
}
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public static final @android.annotation.NonNull Creator<ConfigRequest> CREATOR = new Creator<ConfigRequest>() {
@Override
public ConfigRequest[] newArray(int size) {
@@ -136,12 +181,14 @@ public final class ConfigRequest implements Parcelable {
int clusterLow = in.readInt();
int clusterHigh = in.readInt();
int discoveryWindowInterval[] = in.createIntArray();
+ List<OuiKeyedData> vendorData = ParcelUtil.readOuiKeyedDataList(in);
return new ConfigRequest(support5gBand, support6gBand, masterPreference, clusterLow,
- clusterHigh, discoveryWindowInterval);
+ clusterHigh, discoveryWindowInterval, vendorData);
}
};
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -158,9 +205,11 @@ public final class ConfigRequest implements Parcelable {
&& mSupport6gBand == lhs.mSupport6gBand
&& mMasterPreference == lhs.mMasterPreference
&& mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh
- && Arrays.equals(mDiscoveryWindowInterval, lhs.mDiscoveryWindowInterval);
+ && Arrays.equals(mDiscoveryWindowInterval, lhs.mDiscoveryWindowInterval)
+ && Objects.equals(mVendorData, lhs.mVendorData);
}
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@Override
public int hashCode() {
int result = 17;
@@ -171,6 +220,7 @@ public final class ConfigRequest implements Parcelable {
result = 31 * result + mClusterLow;
result = 31 * result + mClusterHigh;
result = 31 * result + Arrays.hashCode(mDiscoveryWindowInterval);
+ result = 31 * result + mVendorData.hashCode();
return result;
}
@@ -178,6 +228,7 @@ public final class ConfigRequest implements Parcelable {
/**
* Verifies that the contents of the ConfigRequest are valid. Otherwise
* throws an IllegalArgumentException.
+ * @hide
*/
public void validate() throws IllegalArgumentException {
if (mMasterPreference < 0) {
@@ -226,11 +277,33 @@ public final class ConfigRequest implements Parcelable {
throw new IllegalArgumentException(
"Invalid discovery window interval for 6GHz: valid is UNSET or [0,5]");
}
+ if (mVendorData == null) {
+ throw new IllegalArgumentException("Vendor data list must be non-null");
+ }
+ }
+
+ /**
+ * Get the vendor-provided configuration data, if it exists. See {@link
+ * Builder#setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData != null ? mVendorData : Collections.emptyList();
}
/**
* Builder used to build {@link ConfigRequest} objects.
*/
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public static final class Builder {
private boolean mSupport5gBand = true;
private boolean mSupport6gBand = false;
@@ -239,6 +312,7 @@ public final class ConfigRequest implements Parcelable {
private int mClusterHigh = CLUSTER_ID_MAX;
private int[] mDiscoveryWindowInterval = {DW_INTERVAL_NOT_INIT, DW_INTERVAL_NOT_INIT,
DW_INTERVAL_NOT_INIT};
+ private List<OuiKeyedData> mVendorData = Collections.emptyList();
/**
* Specify whether 5G band support is required in this request. Disabled by default.
@@ -247,6 +321,7 @@ public final class ConfigRequest implements Parcelable {
*
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
+ * @hide
*/
public Builder setSupport5gBand(boolean support5gBand) {
mSupport5gBand = support5gBand;
@@ -260,6 +335,7 @@ public final class ConfigRequest implements Parcelable {
*
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
+ * @hide
*/
public Builder setSupport6gBand(boolean support6gBand) {
mSupport6gBand = support6gBand;
@@ -274,6 +350,7 @@ public final class ConfigRequest implements Parcelable {
*
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
+ * @hide
*/
public Builder setMasterPreference(int masterPreference) {
if (masterPreference < 0) {
@@ -301,6 +378,7 @@ public final class ConfigRequest implements Parcelable {
*
* @return The builder to facilitate chaining
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
+ * @hide
*/
public Builder setClusterLow(int clusterLow) {
if (clusterLow < CLUSTER_ID_MIN) {
@@ -326,6 +404,7 @@ public final class ConfigRequest implements Parcelable {
*
* @return The builder to facilitate chaining
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
+ * @hide
*/
public Builder setClusterHigh(int clusterHigh) {
if (clusterHigh < CLUSTER_ID_MIN) {
@@ -352,6 +431,7 @@ public final class ConfigRequest implements Parcelable {
*
* @return The builder itself to facilitate chaining operations
* {@code builder.setDiscoveryWindowInterval(...).setMasterPreference(...)}.
+ * @hide
*/
public Builder setDiscoveryWindowInterval(int band, int interval) {
if (band != NAN_BAND_24GHZ && band != NAN_BAND_5GHZ && band != NAN_BAND_6GHZ) {
@@ -369,9 +449,35 @@ public final class ConfigRequest implements Parcelable {
}
/**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the
+ * vendor-provided configuration data. Note that multiple elements with
+ * the same OUI are allowed.
+ * @return Builder for chaining.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = vendorData;
+ return this;
+ }
+
+ /**
* Build {@link ConfigRequest} given the current requests made on the
* builder.
*/
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
public ConfigRequest build() {
if (mClusterLow > mClusterHigh) {
throw new IllegalArgumentException(
@@ -379,7 +485,7 @@ public final class ConfigRequest implements Parcelable {
}
return new ConfigRequest(mSupport5gBand, mSupport6gBand, mMasterPreference, mClusterLow,
- mClusterHigh, mDiscoveryWindowInterval);
+ mClusterHigh, mDiscoveryWindowInterval, mVendorData);
}
}
}
diff --git a/framework/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl b/framework/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
index 2ab88b3535..392ec6cc2e 100644
--- a/framework/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
+++ b/framework/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
@@ -17,6 +17,7 @@
package android.net.wifi.aware;
import android.net.wifi.aware.AwarePairingConfig;
+import android.net.wifi.OuiKeyedData;
/**
* Callback interface that WifiAwareManager implements
@@ -36,10 +37,10 @@ oneway interface IWifiAwareDiscoverySessionCallback
void onMatch(int peerId, in byte[] serviceSpecificInfo, in byte[] matchFilter,
int peerCipherSuite, in byte[] scid, String pairingAlias,
- in AwarePairingConfig pairingConfig);
+ in AwarePairingConfig pairingConfig, in OuiKeyedData[] vendorData);
void onMatchWithDistance(int peerId, in byte[] serviceSpecificInfo, in byte[] matchFilter,
int distanceMm, int peerCipherSuite, in byte[] scid, String pairingAlias,
- in AwarePairingConfig pairingConfig);
+ in AwarePairingConfig pairingConfig, in OuiKeyedData[] vendorData);
void onMessageSendSuccess(int messageId);
void onMessageSendFail(int messageId, int reason);
diff --git a/framework/java/android/net/wifi/aware/PublishConfig.java b/framework/java/android/net/wifi/aware/PublishConfig.java
index 3f82aed5a2..aa43cdbb99 100644
--- a/framework/java/android/net/wifi/aware/PublishConfig.java
+++ b/framework/java/android/net/wifi/aware/PublishConfig.java
@@ -18,11 +18,14 @@ package android.net.wifi.aware;
import static android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.ParcelUtil;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiScanner;
import android.net.wifi.util.HexEncoding;
@@ -33,11 +36,13 @@ import android.os.Parcelable;
import androidx.annotation.RequiresApi;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -104,12 +109,15 @@ public final class PublishConfig implements Parcelable {
private final boolean mIsSuspendable;
+ private final List<OuiKeyedData> mVendorData;
+
/** @hide */
public PublishConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
int publishType, int ttlSec, boolean enableTerminateNotification,
boolean enableRanging, boolean enableInstantMode, @WifiScanner.WifiBand int
band, WifiAwareDataPathSecurityConfig securityConfig,
- AwarePairingConfig pairingConfig, boolean isSuspendable) {
+ AwarePairingConfig pairingConfig, boolean isSuspendable,
+ @NonNull List<OuiKeyedData> vendorData) {
mServiceName = serviceName;
mServiceSpecificInfo = serviceSpecificInfo;
mMatchFilter = matchFilter;
@@ -122,6 +130,7 @@ public final class PublishConfig implements Parcelable {
mSecurityConfig = securityConfig;
mPairingConfig = pairingConfig;
mIsSuspendable = isSuspendable;
+ mVendorData = vendorData;
}
@Override
@@ -142,7 +151,8 @@ public final class PublishConfig implements Parcelable {
+ ", mBand=" + mBand
+ ", mSecurityConfig" + mSecurityConfig
+ ", mPairingConfig" + mPairingConfig
- + ", mIsSuspendable=" + mIsSuspendable;
+ + ", mIsSuspendable=" + mIsSuspendable
+ + ", mVendorData=" + mVendorData + "]";
}
@Override
@@ -164,6 +174,7 @@ public final class PublishConfig implements Parcelable {
dest.writeParcelable(mSecurityConfig, flags);
dest.writeParcelable(mPairingConfig, flags);
dest.writeBoolean(mIsSuspendable);
+ dest.writeList(mVendorData);
}
@NonNull
@@ -189,10 +200,11 @@ public final class PublishConfig implements Parcelable {
AwarePairingConfig pairingConfig = in
.readParcelable(AwarePairingConfig.class.getClassLoader());
boolean isSuspendable = in.readBoolean();
+ List<OuiKeyedData> vendorData = ParcelUtil.readOuiKeyedDataList(in);
return new PublishConfig(serviceName, ssi, matchFilter, publishType, ttlSec,
enableTerminateNotification, enableRanging, enableInstantMode,
- band, securityConfig, pairingConfig, isSuspendable);
+ band, securityConfig, pairingConfig, isSuspendable, vendorData);
}
};
@@ -218,7 +230,8 @@ public final class PublishConfig implements Parcelable {
&& mBand == lhs.mBand
&& mIsSuspendable == lhs.mIsSuspendable
&& Objects.equals(mSecurityConfig, lhs.mSecurityConfig)
- && Objects.equals(mPairingConfig, lhs.mPairingConfig);
+ && Objects.equals(mPairingConfig, lhs.mPairingConfig)
+ && Objects.equals(mVendorData, lhs.mVendorData);
}
@Override
@@ -226,7 +239,7 @@ public final class PublishConfig implements Parcelable {
return Objects.hash(Arrays.hashCode(mServiceName), Arrays.hashCode(mServiceSpecificInfo),
Arrays.hashCode(mMatchFilter), mPublishType, mTtlSec, mEnableTerminateNotification,
mEnableRanging, mEnableInstantMode, mBand, mSecurityConfig, mPairingConfig,
- mIsSuspendable);
+ mIsSuspendable, mVendorData);
}
/**
@@ -353,6 +366,24 @@ public final class PublishConfig implements Parcelable {
}
/**
+ * Return the vendor-provided configuration data, if it exists. See also {@link
+ * Builder#setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ @SystemApi
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData != null ? mVendorData : Collections.emptyList();
+ }
+
+ /**
* Builder used to build {@link PublishConfig} objects.
*/
public static final class Builder {
@@ -368,6 +399,7 @@ public final class PublishConfig implements Parcelable {
private WifiAwareDataPathSecurityConfig mSecurityConfig = null;
private AwarePairingConfig mPairingConfig = null;
private boolean mIsSuspendable = false;
+ private @NonNull List<OuiKeyedData> mVendorData = Collections.emptyList();
/**
* Specify the service name of the publish session. The actual on-air
@@ -630,13 +662,36 @@ public final class PublishConfig implements Parcelable {
}
/**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link OuiKeyedData} containing the vendor-provided
+ * configuration data. Note that multiple elements with the same OUI are allowed.
+ * @return Builder for chaining.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ @SystemApi
+ public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = vendorData;
+ return this;
+ }
+
+ /**
* Build {@link PublishConfig} given the current requests made on the
* builder.
*/
public PublishConfig build() {
return new PublishConfig(mServiceName, mServiceSpecificInfo, mMatchFilter, mPublishType,
mTtlSec, mEnableTerminateNotification, mEnableRanging, mEnableInstantMode,
- mBand, mSecurityConfig, mPairingConfig, mIsSuspendable);
+ mBand, mSecurityConfig, mPairingConfig, mIsSuspendable, mVendorData);
}
}
}
diff --git a/framework/java/android/net/wifi/aware/ServiceDiscoveryInfo.java b/framework/java/android/net/wifi/aware/ServiceDiscoveryInfo.java
index 48b9a2b0bf..6b2191c550 100644
--- a/framework/java/android/net/wifi/aware/ServiceDiscoveryInfo.java
+++ b/framework/java/android/net/wifi/aware/ServiceDiscoveryInfo.java
@@ -16,9 +16,19 @@
package android.net.wifi.aware;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresApi;
+import android.annotation.SystemApi;
+import android.net.wifi.OuiKeyedData;
+import android.os.Build;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
+
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
/**
@@ -34,6 +44,7 @@ public final class ServiceDiscoveryInfo {
private final PeerHandle mPeerHandle;
private final String mPairingAlias;
private final AwarePairingConfig mPairingConfig;
+ private final List<OuiKeyedData> mVendorData;
/**
* @hide
@@ -41,7 +52,7 @@ public final class ServiceDiscoveryInfo {
public ServiceDiscoveryInfo(PeerHandle peerHandle, int peerCipherSuite,
@Nullable byte[] serviceSpecificInfo,
@NonNull List<byte[]> matchFilter, @Nullable byte[] scid, String pairingAlias,
- AwarePairingConfig pairingConfig) {
+ AwarePairingConfig pairingConfig, @Nullable OuiKeyedData[] vendorData) {
mServiceSpecificInfo = serviceSpecificInfo;
mMatchFilters = matchFilter;
mPeerCipherSuite = peerCipherSuite;
@@ -49,6 +60,7 @@ public final class ServiceDiscoveryInfo {
mPeerHandle = peerHandle;
mPairingAlias = pairingAlias;
mPairingConfig = pairingConfig;
+ mVendorData = vendorData != null ? Arrays.asList(vendorData) : Collections.emptyList();
}
/**
@@ -130,4 +142,21 @@ public final class ServiceDiscoveryInfo {
public AwarePairingConfig getPairingConfig() {
return mPairingConfig;
}
+
+ /**
+ * Get the vendor-provided configuration data, if it exists.
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData != null ? mVendorData : Collections.emptyList();
+ }
}
diff --git a/framework/java/android/net/wifi/aware/SubscribeConfig.java b/framework/java/android/net/wifi/aware/SubscribeConfig.java
index 1fc29521fb..ea99d819cd 100644
--- a/framework/java/android/net/wifi/aware/SubscribeConfig.java
+++ b/framework/java/android/net/wifi/aware/SubscribeConfig.java
@@ -18,11 +18,14 @@ package android.net.wifi.aware;
import static android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.ParcelUtil;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiScanner;
import android.net.wifi.util.HexEncoding;
@@ -33,11 +36,13 @@ import android.os.Parcelable;
import androidx.annotation.RequiresApi;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -108,13 +113,15 @@ public final class SubscribeConfig implements Parcelable {
private final AwarePairingConfig mPairingConfig;
private final boolean mIsSuspendable;
+ private final List<OuiKeyedData> mVendorData;
/** @hide */
public SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
int subscribeType, int ttlSec, boolean enableTerminateNotification,
boolean minDistanceMmSet, int minDistanceMm, boolean maxDistanceMmSet,
int maxDistanceMm, boolean enableInstantMode, @WifiScanner.WifiBand int band,
- AwarePairingConfig pairingConfig, boolean isSuspendable) {
+ AwarePairingConfig pairingConfig, boolean isSuspendable,
+ @NonNull List<OuiKeyedData> vendorData) {
mServiceName = serviceName;
mServiceSpecificInfo = serviceSpecificInfo;
mMatchFilter = matchFilter;
@@ -129,6 +136,7 @@ public final class SubscribeConfig implements Parcelable {
mBand = band;
mPairingConfig = pairingConfig;
mIsSuspendable = isSuspendable;
+ mVendorData = vendorData;
}
@Override
@@ -151,7 +159,8 @@ public final class SubscribeConfig implements Parcelable {
+ ", mEnableInstantMode=" + mEnableInstantMode
+ ", mBand=" + mBand
+ ", mPairingConfig" + mPairingConfig
- + ", mIsSuspendable=" + mIsSuspendable;
+ + ", mIsSuspendable=" + mIsSuspendable
+ + ", mVendorData=" + mVendorData + "]";
}
@Override
@@ -175,6 +184,7 @@ public final class SubscribeConfig implements Parcelable {
dest.writeInt(mBand);
dest.writeParcelable(mPairingConfig, flags);
dest.writeBoolean(mIsSuspendable);
+ dest.writeList(mVendorData);
}
@NonNull
@@ -201,10 +211,12 @@ public final class SubscribeConfig implements Parcelable {
AwarePairingConfig pairingConfig = in.readParcelable(
AwarePairingConfig.class.getClassLoader());
boolean isSuspendable = in.readBoolean();
+ List<OuiKeyedData> vendorData = ParcelUtil.readOuiKeyedDataList(in);
return new SubscribeConfig(serviceName, ssi, matchFilter, subscribeType, ttlSec,
enableTerminateNotification, minDistanceMmSet, minDistanceMm, maxDistanceMmSet,
- maxDistanceMm, enableInstantMode, band, pairingConfig, isSuspendable);
+ maxDistanceMm, enableInstantMode, band, pairingConfig, isSuspendable,
+ vendorData);
}
};
@@ -228,7 +240,8 @@ public final class SubscribeConfig implements Parcelable {
&& mMaxDistanceMmSet == lhs.mMaxDistanceMmSet
&& mEnableInstantMode == lhs.mEnableInstantMode
&& mBand == lhs.mBand
- && mIsSuspendable == lhs.mIsSuspendable)) {
+ && mIsSuspendable == lhs.mIsSuspendable
+ && Objects.equals(mVendorData, lhs.mVendorData))) {
return false;
}
@@ -248,7 +261,7 @@ public final class SubscribeConfig implements Parcelable {
int result = Objects.hash(Arrays.hashCode(mServiceName),
Arrays.hashCode(mServiceSpecificInfo), Arrays.hashCode(mMatchFilter),
mSubscribeType, mTtlSec, mEnableTerminateNotification, mMinDistanceMmSet,
- mMaxDistanceMmSet, mEnableInstantMode, mBand, mIsSuspendable);
+ mMaxDistanceMmSet, mEnableInstantMode, mBand, mIsSuspendable, mVendorData);
if (mMinDistanceMmSet) {
result = Objects.hash(result, mMinDistanceMm);
@@ -378,6 +391,24 @@ public final class SubscribeConfig implements Parcelable {
}
/**
+ * Return the vendor-provided configuration data, if it exists. See also {@link
+ * Builder#setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ @SystemApi
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData != null ? mVendorData : Collections.emptyList();
+ }
+
+ /**
* Builder used to build {@link SubscribeConfig} objects.
*/
public static final class Builder {
@@ -395,6 +426,7 @@ public final class SubscribeConfig implements Parcelable {
private int mBand = WifiScanner.WIFI_BAND_24_GHZ;
private AwarePairingConfig mPairingConfig;
private boolean mIsSuspendable = false;
+ private @NonNull List<OuiKeyedData> mVendorData = Collections.emptyList();
/**
* Specify the service name of the subscribe session. The actual on-air
@@ -669,6 +701,29 @@ public final class SubscribeConfig implements Parcelable {
}
/**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link OuiKeyedData} containing the vendor-provided
+ * configuration data. Note that multiple elements with the same OUI are allowed.
+ * @return Builder for chaining.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ @SystemApi
+ public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = vendorData;
+ return this;
+ }
+
+ /**
* Build {@link SubscribeConfig} given the current requests made on the
* builder.
*/
@@ -676,7 +731,7 @@ public final class SubscribeConfig implements Parcelable {
return new SubscribeConfig(mServiceName, mServiceSpecificInfo, mMatchFilter,
mSubscribeType, mTtlSec, mEnableTerminateNotification,
mMinDistanceMmSet, mMinDistanceMm, mMaxDistanceMmSet, mMaxDistanceMm,
- mEnableInstantMode, mBand, mPairingConfig, mIsSuspendable);
+ mEnableInstantMode, mBand, mPairingConfig, mIsSuspendable, mVendorData);
}
}
}
diff --git a/framework/java/android/net/wifi/aware/WifiAwareManager.java b/framework/java/android/net/wifi/aware/WifiAwareManager.java
index 74551f0d32..2edf792b16 100644
--- a/framework/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/framework/java/android/net/wifi/aware/WifiAwareManager.java
@@ -19,12 +19,14 @@ package android.net.wifi.aware;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.ACCESS_WIFI_STATE;
import static android.Manifest.permission.CHANGE_WIFI_STATE;
+import static android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION;
import static android.Manifest.permission.NEARBY_WIFI_DEVICES;
import static android.Manifest.permission.OVERRIDE_WIFI_CONFIG;
import static android.net.wifi.ScanResult.WIFI_BAND_24_GHZ;
import static android.net.wifi.ScanResult.WIFI_BAND_5_GHZ;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -41,6 +43,7 @@ import android.net.NetworkSpecifier;
import android.net.wifi.IBooleanListener;
import android.net.wifi.IIntegerListener;
import android.net.wifi.IListListener;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.WifiManager;
import android.net.wifi.util.HexEncoding;
import android.os.Binder;
@@ -55,6 +58,7 @@ import androidx.annotation.RequiresApi;
import com.android.modules.utils.HandlerExecutor;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -518,6 +522,40 @@ public class WifiAwareManager {
attach(handler, null, attachCallback, identityChangedListener, false, null);
}
+ /**
+ * Attach to the Wi-Fi Aware service - enabling the application to create discovery sessions or
+ * create connections to peers. See {@link #attach(AttachCallback, IdentityChangedListener,
+ * Handler)} for more information.
+ *
+ * This version allows callers to provide an instance of {@link ConfigRequest}.
+ *
+ * @param configRequest Parameters for this request.
+ * @param executor The executor to execute the listener of the {@code attachCallback} object.
+ * @param attachCallback A callback for attach events, extended from {@link AttachCallback}.
+ * @param identityChangedListener A callback for changed identity or cluster ID, extended from
+ * {@link IdentityChangedListener}.
+ * @hide
+ */
+ @RequiresPermission(allOf = {
+ ACCESS_WIFI_STATE,
+ CHANGE_WIFI_STATE,
+ ACCESS_FINE_LOCATION,
+ NEARBY_WIFI_DEVICES,
+ MANAGE_WIFI_NETWORK_SELECTION}, conditional = true)
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public void attach(@NonNull ConfigRequest configRequest,
+ @NonNull @CallbackExecutor Executor executor, @NonNull AttachCallback attachCallback,
+ @NonNull IdentityChangedListener identityChangedListener) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ Objects.requireNonNull(configRequest);
+ Objects.requireNonNull(executor);
+ attach(null, configRequest, attachCallback, identityChangedListener, false, executor);
+ }
+
/** @hide */
public void attach(Handler handler, ConfigRequest configRequest,
AttachCallback attachCallback,
@@ -1068,7 +1106,7 @@ public class WifiAwareManager {
@Override
public void onMatch(int peerId, byte[] serviceSpecificInfo, byte[] matchFilter,
int peerCipherSuite, byte[] scid, String pairingAlias,
- AwarePairingConfig pairingConfig) {
+ AwarePairingConfig pairingConfig, @Nullable OuiKeyedData[] vendorData) {
if (VDBG) Log.v(TAG, "onMatch: peerId=" + peerId);
mHandler.post(() -> {
@@ -1078,7 +1116,7 @@ public class WifiAwareManager {
mOriginalCallback.onServiceDiscovered(
new ServiceDiscoveryInfo(new PeerHandle(peerId), peerCipherSuite,
serviceSpecificInfo, matchFilterList, scid, pairingAlias,
- pairingConfig));
+ pairingConfig, vendorData));
});
}
@@ -1098,7 +1136,7 @@ public class WifiAwareManager {
@Override
public void onMatchWithDistance(int peerId, byte[] serviceSpecificInfo, byte[] matchFilter,
int distanceMm, int peerCipherSuite, byte[] scid, String pairingAlias,
- AwarePairingConfig pairingConfig) {
+ AwarePairingConfig pairingConfig, @Nullable OuiKeyedData[] vendorData) {
if (VDBG) {
Log.v(TAG, "onMatchWithDistance: peerId=" + peerId + ", distanceMm=" + distanceMm);
}
@@ -1116,7 +1154,8 @@ public class WifiAwareManager {
matchFilterList,
scid,
pairingAlias,
- pairingConfig),
+ pairingConfig,
+ vendorData),
distanceMm);
});
}
diff --git a/framework/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java b/framework/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
index 7ad74d09c5..d98afbfa30 100644
--- a/framework/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
+++ b/framework/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
@@ -424,7 +424,7 @@ public final class PpsMoParser {
try {
config = parsePpsNode(child);
} catch (ParsingException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
return null;
}
break;
diff --git a/framework/java/android/net/wifi/p2p/IWifiP2pListener.aidl b/framework/java/android/net/wifi/p2p/IWifiP2pListener.aidl
new file mode 100644
index 0000000000..084050be42
--- /dev/null
+++ b/framework/java/android/net/wifi/p2p/IWifiP2pListener.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 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 android.net.wifi.p2p;
+
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pDeviceList;
+import android.net.wifi.p2p.WifiP2pInfo;
+import android.net.wifi.p2p.WifiP2pGroup;
+import android.net.wifi.p2p.WifiP2pGroupList;
+
+/**
+ * Interface for Wi-Fi p2p listener.
+ * @hide
+ */
+oneway interface IWifiP2pListener
+{
+ void onP2pStateChanged(int state);
+ void onDiscoveryStateChanged(int state);
+ void onListenStateChanged(int state);
+ void onDeviceConfigurationChanged(in WifiP2pDevice p2pDevice);
+ void onPeerListChanged(in WifiP2pDeviceList p2pDeviceList);
+ void onPersistentGroupsChanged(in WifiP2pGroupList p2pGroupList);
+ void onGroupCreating();
+ void onGroupNegotiationRejectedByUser();
+ void onGroupCreationFailed(int reason);
+ void onGroupCreated(in WifiP2pInfo p2pInfo, in WifiP2pGroup p2pGroup);
+ void onPeerClientJoined(in WifiP2pInfo p2pInfo, in WifiP2pGroup p2pGroup);
+ void onPeerClientDisconnected(in WifiP2pInfo p2pInfo, in WifiP2pGroup p2pGroup);
+ void onFrequencyChanged(in WifiP2pInfo p2pInfo, in WifiP2pGroup p2pGroup);
+ void onGroupRemoved();
+}
diff --git a/framework/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/framework/java/android/net/wifi/p2p/IWifiP2pManager.aidl
index f29a9b3c3a..088ead4927 100644
--- a/framework/java/android/net/wifi/p2p/IWifiP2pManager.aidl
+++ b/framework/java/android/net/wifi/p2p/IWifiP2pManager.aidl
@@ -16,6 +16,8 @@
package android.net.wifi.p2p;
+import android.net.wifi.p2p.IWifiP2pListener;
+
import android.os.Bundle;
import android.os.Messenger;
@@ -32,5 +34,7 @@ interface IWifiP2pManager
void setMiracastMode(int mode);
void checkConfigureWifiDisplayPermission();
long getSupportedFeatures();
+ void registerWifiP2pListener(in IWifiP2pListener listener, in String packageName, in Bundle extras);
+ void unregisterWifiP2pListener(in IWifiP2pListener listener);
}
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pConfig.java b/framework/java/android/net/wifi/p2p/WifiP2pConfig.java
index 895773223c..d2775fee1b 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -16,6 +16,7 @@
package android.net.wifi.p2p;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -23,6 +24,8 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.ParcelUtil;
import android.net.wifi.WpsInfo;
import android.os.Build;
import android.os.Parcel;
@@ -32,10 +35,14 @@ import android.text.TextUtils;
import androidx.annotation.RequiresApi;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.regex.PatternSyntaxException;
/**
@@ -194,6 +201,48 @@ public class WifiP2pConfig implements Parcelable {
return netId;
}
+ /** List of {@link OuiKeyedData} providing vendor-specific configuration data. */
+ private @NonNull List<OuiKeyedData> mVendorData = Collections.emptyList();
+
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the
+ * vendor-provided configuration data. Note that multiple elements with
+ * the same OUI are allowed.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public void setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = new ArrayList<>(vendorData);
+ }
+
+ /**
+ * Return the vendor-provided configuration data, if it exists. See also {@link
+ * #setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
public WifiP2pConfig() {
//set defaults
wps = new WpsInfo();
@@ -269,6 +318,7 @@ public class WifiP2pConfig implements Parcelable {
sbuf.append("\n groupOwnerBand: ").append(groupOwnerBand);
sbuf.append("\n groupClientIpProvisioningMode: ").append(mGroupClientIpProvisioningMode);
sbuf.append("\n joinExistingGroup: ").append(mJoinExistingGroup);
+ sbuf.append("\n vendorData: ").append(mVendorData);
return sbuf.toString();
}
@@ -289,6 +339,7 @@ public class WifiP2pConfig implements Parcelable {
groupOwnerBand = source.groupOwnerBand;
mGroupClientIpProvisioningMode = source.mGroupClientIpProvisioningMode;
mJoinExistingGroup = source.mJoinExistingGroup;
+ mVendorData = new ArrayList<>(source.mVendorData);
}
}
@@ -303,6 +354,7 @@ public class WifiP2pConfig implements Parcelable {
dest.writeInt(groupOwnerBand);
dest.writeInt(mGroupClientIpProvisioningMode);
dest.writeBoolean(mJoinExistingGroup);
+ dest.writeList(mVendorData);
}
/** Implement the Parcelable interface */
@@ -320,6 +372,7 @@ public class WifiP2pConfig implements Parcelable {
config.groupOwnerBand = in.readInt();
config.mGroupClientIpProvisioningMode = in.readInt();
config.mJoinExistingGroup = in.readBoolean();
+ config.mVendorData = ParcelUtil.readOuiKeyedDataList(in);
return config;
}
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pDevice.java b/framework/java/android/net/wifi/p2p/WifiP2pDevice.java
index 214eb35a0d..75ae83d286 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -16,17 +16,27 @@
package android.net.wifi.p2p;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
+import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.ParcelUtil;
import android.net.wifi.ScanResult;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
+import androidx.annotation.RequiresApi;
+
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -53,6 +63,15 @@ public class WifiP2pDevice implements Parcelable {
* The device MAC address uniquely identifies a Wi-Fi p2p device
*/
public String deviceAddress = "";
+ /**
+ * The device interface MAC address. This field is valid when the device is a part of the group
+ */
+ @Nullable private MacAddress mInterfaceMacAddress;
+
+ /**
+ * The IP address of the device. This field is valid when the device is a part of the group.
+ */
+ @Nullable private InetAddress mIpAddress;
/**
* Primary device type identifies the type of device. For example, an application
@@ -175,6 +194,26 @@ public class WifiP2pDevice implements Parcelable {
"(?:[0-9a-f]{2}:){5}[0-9a-f]{2} p2p_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
);
+ /** List of {@link OuiKeyedData} providing vendor-specific configuration data. */
+ private @NonNull List<OuiKeyedData> mVendorData = Collections.emptyList();
+
+ /**
+ * Return the vendor-provided configuration data, if it exists. See also {@link
+ * #setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
public WifiP2pDevice() {
}
@@ -325,6 +364,7 @@ public class WifiP2pDevice implements Parcelable {
if (!deviceAddress.equals(device.deviceAddress)) {
throw new IllegalArgumentException("deviceAddress does not match");
}
+ mInterfaceMacAddress = device.mInterfaceMacAddress;
deviceName = device.deviceName;
primaryDeviceType = device.primaryDeviceType;
secondaryDeviceType = device.secondaryDeviceType;
@@ -348,6 +388,27 @@ public class WifiP2pDevice implements Parcelable {
}
/**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the
+ * vendor-provided configuration data. Note that multiple elements with
+ * the same OUI are allowed.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public void setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = vendorData;
+ }
+
+ /**
* Get the vendor-specific information elements received as part of the discovery
* of the peer device.
*
@@ -360,6 +421,52 @@ public class WifiP2pDevice implements Parcelable {
return new ArrayList<>(mVendorElements);
}
+ /**
+ * Get the device interface MAC address if the device is a part of the group; otherwise null.
+ *
+ * @return the interface MAC address if the device is a part of the group; otherwise null.
+ * @hide
+ */
+ @Nullable public MacAddress getInterfaceMacAddress() {
+ return mInterfaceMacAddress;
+ }
+
+ /**
+ * Set the device interface MAC address.
+ * @hide
+ */
+ public void setInterfaceMacAddress(@Nullable MacAddress interfaceAddress) {
+ mInterfaceMacAddress = interfaceAddress;
+ }
+
+ /**
+ * Get the IP address of the connected client device.
+ * The application should listen to {@link WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}
+ * broadcast to obtain the IP address of the connected client. When system assigns the IP
+ * address, the connected P2P device information ({@link WifiP2pGroup#getClientList()}) in the
+ * group is updated with the IP address and broadcast the group information using
+ * {@link WifiP2pManager#EXTRA_WIFI_P2P_GROUP} extra of the
+ * {@link WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION} broadcast intent.
+ *
+ * Alternatively, the application can request for the group details with
+ * {@link WifiP2pManager#requestGroupInfo} and use ({@link WifiP2pGroup#getClientList()}) to
+ * obtain the connected client details.
+ *
+ * @return the IP address if the device is a part of the group; otherwise null.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Nullable public InetAddress getIpAddress() {
+ return mIpAddress;
+ }
+
+ /**
+ * Set the IP address of the device.
+ * @hide
+ */
+ public void setIpAddress(InetAddress ipAddress) {
+ mIpAddress = ipAddress;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -382,6 +489,10 @@ public class WifiP2pDevice implements Parcelable {
StringBuffer sbuf = new StringBuffer();
sbuf.append("Device: ").append(deviceName);
sbuf.append("\n deviceAddress: ").append(deviceAddress);
+ sbuf.append("\n interfaceMacAddress: ")
+ .append(mInterfaceMacAddress == null ? "none" : mInterfaceMacAddress.toString());
+ sbuf.append("\n ipAddress: ")
+ .append(mIpAddress == null ? "none" : mIpAddress.getHostAddress());
sbuf.append("\n primary type: ").append(primaryDeviceType);
sbuf.append("\n secondary type: ").append(secondaryDeviceType);
sbuf.append("\n wps: ").append(wpsConfigMethodsSupported);
@@ -390,6 +501,7 @@ public class WifiP2pDevice implements Parcelable {
sbuf.append("\n status: ").append(status);
sbuf.append("\n wfdInfo: ").append(wfdInfo);
sbuf.append("\n vendorElements: ").append(mVendorElements);
+ sbuf.append("\n vendorData: ").append(mVendorData);
return sbuf.toString();
}
@@ -404,6 +516,8 @@ public class WifiP2pDevice implements Parcelable {
if (source != null) {
deviceName = source.deviceName;
deviceAddress = source.deviceAddress;
+ mInterfaceMacAddress = source.mInterfaceMacAddress;
+ mIpAddress = source.mIpAddress;
primaryDeviceType = source.primaryDeviceType;
secondaryDeviceType = source.secondaryDeviceType;
wpsConfigMethodsSupported = source.wpsConfigMethodsSupported;
@@ -416,6 +530,7 @@ public class WifiP2pDevice implements Parcelable {
if (null != source.mVendorElements) {
mVendorElements = new ArrayList<>(source.mVendorElements);
}
+ mVendorData = new ArrayList<>(source.mVendorData);
}
}
@@ -424,6 +539,13 @@ public class WifiP2pDevice implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(deviceName);
dest.writeString(deviceAddress);
+ dest.writeParcelable(mInterfaceMacAddress, flags);
+ if (mIpAddress != null) {
+ dest.writeByte((byte) 1);
+ dest.writeByteArray(mIpAddress.getAddress());
+ } else {
+ dest.writeByte((byte) 0);
+ }
dest.writeString(primaryDeviceType);
dest.writeString(secondaryDeviceType);
dest.writeInt(wpsConfigMethodsSupported);
@@ -437,6 +559,7 @@ public class WifiP2pDevice implements Parcelable {
dest.writeInt(0);
}
dest.writeTypedList(mVendorElements);
+ dest.writeList(mVendorData);
}
/** Implement the Parcelable interface */
@@ -447,6 +570,15 @@ public class WifiP2pDevice implements Parcelable {
WifiP2pDevice device = new WifiP2pDevice();
device.deviceName = in.readString();
device.deviceAddress = in.readString();
+ device.mInterfaceMacAddress = in.readParcelable(MacAddress.class.getClassLoader());
+ if (in.readByte() == 1) {
+ try {
+ device.mIpAddress = InetAddress.getByAddress(in.createByteArray());
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ return new WifiP2pDevice();
+ }
+ }
device.primaryDeviceType = in.readString();
device.secondaryDeviceType = in.readString();
device.wpsConfigMethodsSupported = in.readInt();
@@ -458,6 +590,7 @@ public class WifiP2pDevice implements Parcelable {
}
device.mVendorElements = in.createTypedArrayList(
ScanResult.InformationElement.CREATOR);
+ device.mVendorData = ParcelUtil.readOuiKeyedDataList(in);
return device;
}
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pDiscoveryConfig.java b/framework/java/android/net/wifi/p2p/WifiP2pDiscoveryConfig.java
new file mode 100644
index 0000000000..bb84006c72
--- /dev/null
+++ b/framework/java/android/net/wifi/p2p/WifiP2pDiscoveryConfig.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2023 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 android.net.wifi.p2p;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.RequiresApi;
+import android.annotation.SystemApi;
+import android.net.wifi.OuiKeyedData;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A class representing a Wi-Fi P2P scan configuration for setting up discovery.
+ */
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+public final class WifiP2pDiscoveryConfig implements Parcelable {
+ /** Type of this P2P scan. */
+ private final @WifiP2pManager.WifiP2pScanType int mScanType;
+
+ /** Frequency to scan in MHz. */
+ private final int mFrequencyMhz;
+
+ /** List of {@link OuiKeyedData} providing vendor-specific configuration data. */
+ private final @NonNull List<OuiKeyedData> mVendorData;
+
+ private WifiP2pDiscoveryConfig(@WifiP2pManager.WifiP2pScanType int scanType, int frequencyMhz,
+ @NonNull List<OuiKeyedData> vendorData) {
+ mScanType = scanType;
+ mFrequencyMhz = frequencyMhz;
+ mVendorData = new ArrayList<>(vendorData);
+ }
+
+ /**
+ * Get the type of this scan. See {@link Builder#Builder(int)}}
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public @WifiP2pManager.WifiP2pScanType int getScanType() {
+ return mScanType;
+ }
+
+ /**
+ * Get the frequency to scan in MHz. See {@link Builder#setFrequencyMhz(int)}
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int getFrequencyMhz() {
+ return mFrequencyMhz;
+ }
+
+ /**
+ * Get the vendor-provided configuration data, if it exists. See {@link
+ * Builder#setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Override
+ public String toString() {
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.append("\n scanType: ").append(mScanType);
+ sbuf.append("\n frequencyMhz: ").append(mFrequencyMhz);
+ sbuf.append("\n vendorData: ").append(mVendorData);
+ return sbuf.toString();
+ }
+
+ /** Implement the Parcelable interface */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int describeContents() {
+ return 0;
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mScanType);
+ dest.writeInt(mFrequencyMhz);
+ dest.writeList(mVendorData);
+ }
+
+ /* Read List<OuiKeyedData> from Parcel */
+ @NonNull
+ private static List<OuiKeyedData> readOuiKeyedDataList(@NonNull Parcel in) {
+ List<OuiKeyedData> dataList = new ArrayList<>();
+ if (SdkLevel.isAtLeastT()) {
+ in.readList(dataList, OuiKeyedData.class.getClassLoader(), OuiKeyedData.class);
+ } else {
+ in.readList(dataList, OuiKeyedData.class.getClassLoader());
+ }
+ return dataList;
+ }
+
+ /** @hide */
+ WifiP2pDiscoveryConfig(@NonNull Parcel in) {
+ this.mScanType = in.readInt();
+ this.mFrequencyMhz = in.readInt();
+ this.mVendorData = readOuiKeyedDataList(in);
+ }
+
+ /** Implement the Parcelable interface */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public static final Creator<WifiP2pDiscoveryConfig> CREATOR =
+ new Creator<WifiP2pDiscoveryConfig>() {
+ public WifiP2pDiscoveryConfig createFromParcel(Parcel in) {
+ return new WifiP2pDiscoveryConfig(in);
+ }
+
+ public WifiP2pDiscoveryConfig[] newArray(int size) {
+ return new WifiP2pDiscoveryConfig[size];
+ }
+ };
+
+ /**
+ * Builder for {@link WifiP2pDiscoveryConfig}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final class Builder {
+
+ private final int mScanType;
+ private int mFrequencyMhz = 0;
+ private @NonNull List<OuiKeyedData> mVendorData = new ArrayList<>();
+
+ /**
+ * Constructor for {@link Builder}.
+ *
+ * @param scanType Type of this P2P scan.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public Builder(@WifiP2pManager.WifiP2pScanType int scanType) {
+ mScanType = scanType;
+ }
+
+ /**
+ * Set the frequency to scan. Only applicable if the scan type is
+ * {@link WifiP2pManager#WIFI_P2P_SCAN_SINGLE_FREQ}.
+ *
+ * @param frequencyMhz Frequency to scan in MHz.
+ * @return Builder for chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setFrequencyMhz(@IntRange(from = 0) int frequencyMhz) {
+ if (frequencyMhz <= 0) {
+ throw new IllegalArgumentException("Frequency must be greater than 0");
+ }
+ mFrequencyMhz = frequencyMhz;
+ return this;
+ }
+
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the
+ * vendor-provided configuration data. Note that multiple elements with
+ * the same OUI are allowed.
+ * @return Builder for chaining.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = vendorData;
+ return this;
+ }
+
+ /**
+ * Build {@link WifiP2pDiscoveryConfig} given the current requests made on the builder.
+ * @return {@link WifiP2pDiscoveryConfig} constructed based on builder method calls.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public WifiP2pDiscoveryConfig build() {
+ if (mScanType < WifiP2pManager.WIFI_P2P_SCAN_FULL
+ || mScanType > WifiP2pManager.WIFI_P2P_SCAN_SINGLE_FREQ) {
+ throw new IllegalArgumentException("Invalid scan type " + mScanType);
+ }
+ if (mScanType == WifiP2pManager.WIFI_P2P_SCAN_SINGLE_FREQ && mFrequencyMhz == 0) {
+ throw new IllegalArgumentException(
+ "Scan type is single frequency, but no frequency was provided");
+ }
+ return new WifiP2pDiscoveryConfig(mScanType, mFrequencyMhz, mVendorData);
+ }
+ }
+}
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pExtListenParams.java b/framework/java/android/net/wifi/p2p/WifiP2pExtListenParams.java
new file mode 100644
index 0000000000..720d674dbd
--- /dev/null
+++ b/framework/java/android/net/wifi/p2p/WifiP2pExtListenParams.java
@@ -0,0 +1,149 @@
+/*
+ * 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 android.net.wifi.p2p;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.RequiresApi;
+import android.annotation.SystemApi;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.ParcelUtil;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class representing Wi-Fi P2P extended listen parameters.
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+public final class WifiP2pExtListenParams implements Parcelable {
+ /** List of {@link OuiKeyedData} providing vendor-specific configuration data. */
+ private @NonNull List<OuiKeyedData> mVendorData;
+
+ private WifiP2pExtListenParams(@NonNull List<OuiKeyedData> vendorData) {
+ mVendorData = new ArrayList<>(vendorData);
+ }
+
+ /**
+ * Get the vendor-provided configuration data, if it exists. See {@link
+ * Builder#setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Override
+ public String toString() {
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.append("\n vendorData: ").append(mVendorData);
+ return sbuf.toString();
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeList(mVendorData);
+ }
+
+ /** @hide */
+ WifiP2pExtListenParams(@NonNull Parcel in) {
+ this.mVendorData = ParcelUtil.readOuiKeyedDataList(in);
+ }
+
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public static final Creator<WifiP2pExtListenParams> CREATOR =
+ new Creator<WifiP2pExtListenParams>() {
+ public WifiP2pExtListenParams createFromParcel(Parcel in) {
+ return new WifiP2pExtListenParams(in);
+ }
+
+ public WifiP2pExtListenParams[] newArray(int size) {
+ return new WifiP2pExtListenParams[size];
+ }
+ };
+
+ /**
+ * Builder for {@link WifiP2pExtListenParams}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final class Builder {
+ private @NonNull List<OuiKeyedData> mVendorData = Collections.emptyList();
+
+ /**
+ * Constructor for {@link Builder}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public Builder() {
+ }
+
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the
+ * vendor-provided configuration data. Note that multiple elements with
+ * the same OUI are allowed.
+ * @return Builder for chaining.
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = vendorData;
+ return this;
+ }
+
+ /**
+ * Construct a WifiP2pExtListenParams object with the specified parameters.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public WifiP2pExtListenParams build() {
+ return new WifiP2pExtListenParams(mVendorData);
+ }
+ }
+}
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pGroup.java b/framework/java/android/net/wifi/p2p/WifiP2pGroup.java
index bdd6519002..fe9ad03e08 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pGroup.java
@@ -16,12 +16,26 @@
package android.net.wifi.p2p;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
+import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.ParcelUtil;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Log;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.net.Inet4Address;
+import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -90,6 +104,9 @@ public class WifiP2pGroup implements Parcelable {
/** The frequency (in MHz) used by this group */
private int mFrequency;
+ /** List of {@link OuiKeyedData} providing vendor-specific configuration data. */
+ private @NonNull List<OuiKeyedData> mVendorData = Collections.emptyList();
+
/**
* P2P Client IPV4 address allocated via EAPOL-Key exchange.
* @hide
@@ -261,7 +278,33 @@ public class WifiP2pGroup implements Parcelable {
for (WifiP2pDevice client : mClients) {
if (client.equals(device)) return;
}
- mClients.add(device);
+ mClients.add(new WifiP2pDevice(device));
+ }
+
+ /** @hide */
+ public void setClientInterfaceMacAddress(@NonNull String deviceAddress,
+ @NonNull final MacAddress interfaceMacAddress) {
+ for (WifiP2pDevice client : mClients) {
+ if (client.deviceAddress.equals(deviceAddress)) {
+ Log.i("setClientInterfaceMacAddress", " device: " + deviceAddress
+ + " interfaceAddress: " + interfaceMacAddress.toString());
+ client.setInterfaceMacAddress(interfaceMacAddress);
+ break;
+ }
+ }
+ }
+ /** @hide */
+ public void setClientIpAddress(@NonNull final MacAddress interfaceMacAddress,
+ @NonNull final InetAddress ipAddress) {
+ for (WifiP2pDevice client : mClients) {
+ if (client.getInterfaceMacAddress().equals(interfaceMacAddress)) {
+ Log.i("setClientIpAddress", "Update the IP address"
+ + " device: " + client.deviceAddress + " interfaceAddress: "
+ + interfaceMacAddress.toString() + " IP: " + ipAddress.getHostAddress());
+ client.setIpAddress(ipAddress);
+ break;
+ }
+ }
}
/** @hide */
@@ -340,6 +383,44 @@ public class WifiP2pGroup implements Parcelable {
this.mFrequency = freq;
}
+ /**
+ * Return the vendor-provided configuration data, if it exists. See also {@link
+ * #setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ @SystemApi
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link OuiKeyedData} containing the vendor-provided
+ * configuration data. Note that multiple elements with the same OUI are allowed.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ public void setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = new ArrayList<>(vendorData);
+ }
+
public String toString() {
StringBuffer sbuf = new StringBuffer();
sbuf.append("network: ").append(mNetworkName);
@@ -351,6 +432,7 @@ public class WifiP2pGroup implements Parcelable {
sbuf.append("\n interface: ").append(mInterface);
sbuf.append("\n networkId: ").append(mNetId);
sbuf.append("\n frequency: ").append(mFrequency);
+ sbuf.append("\n vendorData: ").append(mVendorData);
return sbuf.toString();
}
@@ -370,6 +452,9 @@ public class WifiP2pGroup implements Parcelable {
mInterface = source.getInterface();
mNetId = source.getNetworkId();
mFrequency = source.getFrequency();
+ if (SdkLevel.isAtLeastV()) {
+ mVendorData = new ArrayList<>(source.getVendorData());
+ }
}
}
@@ -386,6 +471,9 @@ public class WifiP2pGroup implements Parcelable {
dest.writeString(mInterface);
dest.writeInt(mNetId);
dest.writeInt(mFrequency);
+ if (SdkLevel.isAtLeastV()) {
+ dest.writeList(mVendorData);
+ }
}
/** Implement the Parcelable interface */
@@ -404,6 +492,9 @@ public class WifiP2pGroup implements Parcelable {
group.setInterface(in.readString());
group.setNetworkId(in.readInt());
group.setFrequency(in.readInt());
+ if (SdkLevel.isAtLeastV()) {
+ group.setVendorData(ParcelUtil.readOuiKeyedDataList(in));
+ }
return group;
}
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pInfo.java b/framework/java/android/net/wifi/p2p/WifiP2pInfo.java
index 33bc37e155..a287da52c8 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pInfo.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pInfo.java
@@ -16,8 +16,8 @@
package android.net.wifi.p2p;
-import android.os.Parcelable;
import android.os.Parcel;
+import android.os.Parcelable;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -45,7 +45,8 @@ public class WifiP2pInfo implements Parcelable {
StringBuffer sbuf = new StringBuffer();
sbuf.append("groupFormed: ").append(groupFormed)
.append(" isGroupOwner: ").append(isGroupOwner)
- .append(" groupOwnerAddress: ").append(groupOwnerAddress);
+ .append(" groupOwnerIpAddress: ")
+ .append(groupOwnerAddress == null ? "none" : groupOwnerAddress.getHostAddress());
return sbuf.toString();
}
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pManager.java b/framework/java/android/net/wifi/p2p/WifiP2pManager.java
index d552fd8dbc..7213bbe5c6 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -17,6 +17,7 @@
package android.net.wifi.p2p;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -50,6 +51,7 @@ import android.os.RemoteException;
import android.text.TextUtils;
import android.util.CloseGuard;
import android.util.Log;
+import android.util.SparseArray;
import android.view.Display;
import androidx.annotation.RequiresApi;
@@ -57,6 +59,7 @@ import androidx.annotation.RequiresApi;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -226,6 +229,20 @@ public class WifiP2pManager {
"android.net.wifi.p2p.EXTRA_PARAM_KEY_INFORMATION_ELEMENT_LIST";
/**
+ * Extra for transporting discovery config with vendor-specific data
+ * @hide
+ */
+ public static final String EXTRA_PARAM_KEY_DISCOVERY_CONFIG =
+ "android.net.wifi.p2p.EXTRA_PARAM_KEY_DISCOVERY_CONFIG";
+
+ /**
+ * Extra for transporting extended listening parameters
+ * @hide
+ */
+ public static final String EXTRA_PARAM_KEY_EXT_LISTEN_PARAMS =
+ "android.net.wifi.p2p.EXTRA_PARAM_KEY_EXT_LISTEN_PARAMS";
+
+ /**
* Key for transporting a bundle of extra information.
* @hide
*/
@@ -522,22 +539,28 @@ public class WifiP2pManager {
/**
* Run P2P scan on all channels.
- * @hide
*/
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public static final int WIFI_P2P_SCAN_FULL = 0;
/**
* Run P2P scan only on social channels.
- * @hide
*/
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public static final int WIFI_P2P_SCAN_SOCIAL = 1;
/**
* Run P2P scan only on a specific channel.
- * @hide
*/
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
public static final int WIFI_P2P_SCAN_SINGLE_FREQ = 2;
+ /**
+ * Run P2P scan with config Params.
+ * @hide
+ */
+ public static final int WIFI_P2P_SCAN_WITH_CONFIG_PARAMS = 3;
+
/** @hide */
@IntDef(prefix = {"WIFI_P2P_SCAN_"}, value = {
WIFI_P2P_SCAN_FULL,
@@ -548,6 +571,12 @@ public class WifiP2pManager {
}
/**
+ * Enter the P2P listen state with additional parameters.
+ * @hide
+ */
+ public static final int WIFI_P2P_EXT_LISTEN_WITH_PARAMS = 1;
+
+ /**
* No channel specified for discover Peers APIs. Let lower layer decide the frequencies to scan
* based on the WifiP2pScanType.
* @hide
@@ -560,6 +589,8 @@ public class WifiP2pManager {
*/
private static final int WIFI_P2P_VENDOR_ELEMENTS_MAXIMUM_LENGTH = 512;
+ private Context mContext;
+
IWifiP2pManager mService;
private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER;
@@ -833,6 +864,7 @@ public class WifiP2pManager {
/** @hide */
public static final int RESPONSE_GET_LISTEN_STATE = BASE + 118;
+ private static final SparseArray<IWifiP2pListener> sWifiP2pListenerMap = new SparseArray<>();
/**
* Create a new WifiP2pManager instance. Applications use
* {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -1219,6 +1251,376 @@ public class WifiP2pManager {
void onPinGenerated(@NonNull MacAddress deviceAddress, @NonNull String pin);
}
+ /**
+ * Interface used to listen to Wi-Fi p2p various changes such as device state change,
+ * discovery started/stopped, connection change, etc.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public interface WifiP2pListener {
+ /**
+ * Called when Wi-Fi p2p has been enabled or disabled.
+ * @see #WIFI_P2P_STATE_CHANGED_ACTION
+ * @see #requestP2pState(Channel, P2pStateListener)
+ *
+ * @param state indicates whether Wi-Fi p2p is enabled or disabled.
+ * @see #WIFI_P2P_STATE_ENABLED
+ * @see #WIFI_P2P_STATE_DISABLED
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onP2pStateChanged(@WifiP2pState int state) {
+ }
+
+ /**
+ * Called when peer discovery has either started or stopped.
+ * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION
+ * @see #requestDiscoveryState(Channel, DiscoveryStateListener)
+ *
+ * @param state indicates whether discovery has started or stopped.
+ * @see #WIFI_P2P_DISCOVERY_STARTED
+ * @see #WIFI_P2P_DISCOVERY_STOPPED
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onDiscoveryStateChanged(@WifiP2pDiscoveryState int state) {
+ }
+
+ /**
+ * Called when peer listen has either started or stopped.
+ * @see #ACTION_WIFI_P2P_LISTEN_STATE_CHANGED
+ * @see #getListenState(Channel, Executor, Consumer)
+ *
+ * @param state indicates whether listen has started or stopped.
+ * @see #WIFI_P2P_LISTEN_STARTED
+ * @see #WIFI_P2P_LISTEN_STOPPED
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onListenStateChanged(@WifiP2pListenState int state) {
+ }
+
+ /**
+ * Called when this device details have changed.
+ * @see #WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
+ * @see #requestDeviceInfo(Channel, DeviceInfoListener)
+ *
+ * @param p2pDevice provides this device details.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onDeviceConfigurationChanged(@Nullable WifiP2pDevice p2pDevice) {
+ }
+
+ /**
+ * Called when the available peer list has changed. This can be sent as a result of peers
+ * being found, lost or updated.
+ * @see #WIFI_P2P_PEERS_CHANGED_ACTION
+ * @see #requestPeers(Channel, PeerListListener)
+ *
+ * @param p2pDeviceList provides the full list of current peers.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onPeerListChanged(@NonNull WifiP2pDeviceList p2pDeviceList) {
+ }
+
+ /**
+ * Called when remembered persistent groups have changed.
+ * @see #ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED
+ * @see #requestPersistentGroupInfo(Channel, PersistentGroupInfoListener)
+ *
+ * @param p2pGroupList provides the full list of p2p group.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onPersistentGroupsChanged(@NonNull WifiP2pGroupList p2pGroupList) {
+ }
+
+ /**
+ * Called when either group owner or group client is creating p2p group.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onGroupCreating() {
+ }
+
+ /**
+ * Called when group negotiation has been rejected by user.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onGroupNegotiationRejectedByUser() {
+ }
+
+ /**
+ * Called when group creation has failed.
+ *
+ * @param reason provides the group creation failure reason.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onGroupCreationFailed(@GroupCreationFailureReason int reason) {
+ }
+
+ /**
+ * Called when either group owner or group client has created p2p group successfully.
+ *
+ * @param p2pInfo provides the p2p connection info.
+ * @param p2pGroup provides the details of the group.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onGroupCreated(@NonNull WifiP2pInfo p2pInfo,
+ @NonNull WifiP2pGroup p2pGroup) {
+ }
+
+ /**
+ * Called to indicate group owner that a group client has joined p2p group successfully.
+ *
+ * @param p2pInfo provides the p2p connection info.
+ * @param p2pGroup provides the details of the group.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onPeerClientJoined(@NonNull WifiP2pInfo p2pInfo,
+ @NonNull WifiP2pGroup p2pGroup) {
+ }
+
+ /**
+ * Called to indicate group owner that a group client has disconnected.
+ *
+ * @param p2pInfo provides the p2p connection info.
+ * @param p2pGroup provides the details of the group.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onPeerClientDisconnected(@NonNull WifiP2pInfo p2pInfo,
+ @NonNull WifiP2pGroup p2pGroup) {
+ }
+
+ /**
+ * Called when the frequency of a formed group has been changed.
+ *
+ * @param p2pInfo provides the p2p connection info.
+ * @param p2pGroup provides the details of the group.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onFrequencyChanged(@NonNull WifiP2pInfo p2pInfo,
+ @NonNull WifiP2pGroup p2pGroup) {
+ }
+
+ /**
+ * Called when p2p group has been removed.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ default void onGroupRemoved() {
+ }
+ }
+
+ /**
+ * P2p group creation failed because the connection has been cancelled.
+ * Used in {@link WifiP2pListener#onGroupCreationFailed(int reason)}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int GROUP_CREATION_FAILURE_REASON_CONNECTION_CANCELLED = 0;
+ /**
+ * P2p group creation failed because it has timed out.
+ * Used in {@link WifiP2pListener#onGroupCreationFailed(int reason)}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int GROUP_CREATION_FAILURE_REASON_TIMED_OUT = 1;
+ /**
+ * P2p group creation failed because user has rejected.
+ * Used in {@link WifiP2pListener#onGroupCreationFailed(int reason)}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int GROUP_CREATION_FAILURE_REASON_USER_REJECTED = 2;
+ /**
+ * P2p group creation failed because provision discovery has failed.
+ * Used in {@link WifiP2pListener#onGroupCreationFailed(int reason)}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED = 3;
+ /**
+ * P2p group creation failed because the group has been removed.
+ * Used in {@link WifiP2pListener#onGroupCreationFailed(int reason)}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int GROUP_CREATION_FAILURE_REASON_GROUP_REMOVED = 4;
+ /**
+ * P2p group creation failed because invitation has failed.
+ * Used in {@link WifiP2pListener#onGroupCreationFailed(int reason)}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final int GROUP_CREATION_FAILURE_REASON_INVITATION_FAILED = 5;
+
+ /**
+ * @hide
+ */
+ @IntDef(prefix = {"GROUP_CREATION_FAILURE_REASON_"}, value = {
+ GROUP_CREATION_FAILURE_REASON_CONNECTION_CANCELLED,
+ GROUP_CREATION_FAILURE_REASON_TIMED_OUT,
+ GROUP_CREATION_FAILURE_REASON_USER_REJECTED,
+ GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED,
+ GROUP_CREATION_FAILURE_REASON_GROUP_REMOVED,
+ GROUP_CREATION_FAILURE_REASON_INVITATION_FAILED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface GroupCreationFailureReason {
+ }
+
+ /**
+ * Helper class to support wifi p2p listener.
+ */
+ private static class OnWifiP2pListenerProxy extends IWifiP2pListener.Stub {
+ @NonNull
+ private Executor mExecutor;
+ @NonNull
+ private WifiP2pListener mListener;
+
+ OnWifiP2pListenerProxy(@NonNull Executor executor,
+ @NonNull WifiP2pListener listener) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(listener);
+ mExecutor = executor;
+ mListener = listener;
+ }
+
+ @Override
+ public void onP2pStateChanged(@WifiP2pState int state) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onP2pStateChanged(state));
+ }
+
+ @Override
+ public void onDiscoveryStateChanged(@WifiP2pDiscoveryState int state) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onDiscoveryStateChanged(state));
+ }
+
+ @Override
+ public void onListenStateChanged(@WifiP2pListenState int state) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onListenStateChanged(state));
+ }
+
+ @Override
+ public void onDeviceConfigurationChanged(WifiP2pDevice p2pDevice) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onDeviceConfigurationChanged(p2pDevice));
+ }
+
+ @Override
+ public void onPeerListChanged(WifiP2pDeviceList p2pDeviceList) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onPeerListChanged(p2pDeviceList));
+ }
+
+ @Override
+ public void onPersistentGroupsChanged(WifiP2pGroupList p2pGroupList) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onPersistentGroupsChanged(p2pGroupList));
+ }
+
+ @Override
+ public void onGroupCreating() {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onGroupCreating());
+ }
+
+ @Override
+ public void onGroupNegotiationRejectedByUser() {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onGroupNegotiationRejectedByUser());
+ }
+
+ @Override
+ public void onGroupCreationFailed(@GroupCreationFailureReason int reason) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onGroupCreationFailed(reason));
+ }
+
+ @Override
+ public void onGroupCreated(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onGroupCreated(p2pInfo, p2pGroup));
+ }
+
+ @Override
+ public void onPeerClientJoined(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onPeerClientJoined(p2pInfo, p2pGroup));
+ }
+
+ @Override
+ public void onPeerClientDisconnected(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onPeerClientDisconnected(p2pInfo, p2pGroup));
+ }
+
+ @Override
+ public void onFrequencyChanged(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onFrequencyChanged(p2pInfo, p2pGroup));
+ }
+
+ @Override
+ public void onGroupRemoved() {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> mListener.onGroupRemoved());
+ }
+ }
+
+ /**
+ * Add a listener to listen to Wi-Fi p2p various changes.
+ *
+ * @param executor the Executor on which to execute the callbacks.
+ * @param listener listener for the Wi-Fi p2p connection changes.
+ * @throws SecurityException if the caller is missing required permissions.
+ * @throws IllegalArgumentException if incorrect input arguments are provided.
+ */
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.NEARBY_WIFI_DEVICES,
+ android.Manifest.permission.ACCESS_WIFI_STATE
+ }, conditional = true)
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void registerWifiP2pListener(@NonNull @CallbackExecutor Executor executor,
+ @NonNull WifiP2pListener listener) {
+ Log.d(TAG, "registerWifiP2pListener: listener=" + listener + ", executor=" + executor);
+ final int listenerIdentifier = System.identityHashCode(listener);
+ synchronized (sWifiP2pListenerMap) {
+ try {
+ IWifiP2pListener.Stub listenerProxy = new OnWifiP2pListenerProxy(executor,
+ listener);
+ sWifiP2pListenerMap.put(listenerIdentifier, listenerProxy);
+ Bundle extras = prepareExtrasBundleWithAttributionSource(mContext);
+ mService.registerWifiP2pListener(listenerProxy, mContext.getOpPackageName(),
+ extras);
+ } catch (RemoteException e) {
+ sWifiP2pListenerMap.remove(listenerIdentifier);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Remove a listener added using
+ * {@link #registerWifiP2pListener(Executor, WifiP2pListener)}
+ *
+ * @param listener the listener to be removed.
+ * @throws IllegalArgumentException if incorrect input arguments are provided.
+ */
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void unregisterWifiP2pListener(@NonNull WifiP2pListener listener) {
+ Log.d(TAG, "unregisterWifiP2pListener: listener=" + listener);
+ final int listenerIdentifier = System.identityHashCode(listener);
+ synchronized (sWifiP2pListenerMap) {
+ try {
+ if (!sWifiP2pListenerMap.contains(listenerIdentifier)) {
+ Log.w(TAG, "Unknown external listener " + listenerIdentifier);
+ return;
+ }
+ mService.unregisterWifiP2pListener(sWifiP2pListenerMap.get(listenerIdentifier));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } finally {
+ sWifiP2pListenerMap.remove(listenerIdentifier);
+ }
+ }
+ }
/**
* A channel that connects the application to the Wifi p2p framework.
@@ -1618,6 +2020,7 @@ public class WifiP2pManager {
extras.putInt(EXTRA_PARAM_KEY_DISPLAY_ID, displayId);
Channel channel = initializeChannel(srcContext, srcLooper, listener,
getMessenger(binder, srcContext.getOpPackageName(), extras), binder);
+ mContext = srcContext;
return channel;
}
@@ -1822,6 +2225,45 @@ public class WifiP2pManager {
}
/**
+ * Initiate peer discovery. A discovery process involves scanning for available Wi-Fi peers
+ * for the purpose of establishing a connection. See {@link #discoverPeers(
+ * Channel, ActionListener)} for more details.
+ *
+ * This method accepts a {@link WifiP2pDiscoveryConfig} object specifying the desired
+ * parameters for the peer discovery. The configuration object allows the specification of the
+ * scan type (ex. FULL, SOCIAL) and the inclusion of vendor-specific configuration data.
+ *
+ * The application must have {@link android.Manifest.permission#NEARBY_WIFI_DEVICES} with
+ * android:usesPermissionFlags="neverForLocation". If the application does not declare
+ * android:usesPermissionFlags="neverForLocation", then it must also have
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION}.
+ *
+ * @param channel is the channel created at {@link #initialize}
+ * @param config is the configuration for this peer discovery
+ * @param listener for callbacks on success or failure.
+ */
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.NEARBY_WIFI_DEVICES,
+ android.Manifest.permission.ACCESS_FINE_LOCATION
+ }, conditional = true)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void startPeerDiscovery(
+ @NonNull Channel channel,
+ @NonNull WifiP2pDiscoveryConfig config,
+ @Nullable ActionListener listener) {
+ if (!isChannelConstrainedDiscoverySupported()) {
+ throw new UnsupportedOperationException();
+ }
+ checkChannel(channel);
+ Objects.requireNonNull(config);
+ Bundle extras = prepareExtrasBundle(channel);
+ extras.putParcelable(EXTRA_PARAM_KEY_DISCOVERY_CONFIG, config);
+ channel.mAsyncChannel.sendMessage(prepareMessage(DISCOVER_PEERS,
+ WIFI_P2P_SCAN_WITH_CONFIG_PARAMS,
+ channel.putListener(listener), extras, channel.mContext));
+ }
+
+ /**
* Stop an ongoing peer discovery
*
* <p> The function call immediately returns after sending a stop request
@@ -2043,6 +2485,38 @@ public class WifiP2pManager {
}
/**
+ * Force P2P to enter the listen state. See {@link #startListening(Channel, ActionListener)}
+ * for more details.
+ *
+ * This method accepts a {@link WifiP2pExtListenParams} object containing additional
+ * parameters.
+ *
+ * @param channel is the channel created at @link #initialize(Context, Looper, ChannelListener)}
+ * @param params are the parameters for this listen request.
+ * @param listener for callbacks on success or failure.
+ * @hide
+ */
+ @SystemApi
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.NEARBY_WIFI_DEVICES,
+ android.Manifest.permission.ACCESS_FINE_LOCATION
+ }, conditional = true)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public void startListening(
+ @NonNull Channel channel,
+ @NonNull WifiP2pExtListenParams params,
+ @Nullable ActionListener listener) {
+ checkChannel(channel);
+ Bundle extras = prepareExtrasBundle(channel);
+ Objects.requireNonNull(params);
+ extras.putParcelable(EXTRA_PARAM_KEY_EXT_LISTEN_PARAMS, params);
+ channel.mAsyncChannel.sendMessage(prepareMessage(START_LISTEN,
+ WIFI_P2P_EXT_LISTEN_WITH_PARAMS, channel.putListener(listener), extras,
+ channel.mContext));
+ }
+
+ /**
* Force p2p to exit listen state.
*
* When this API is called, this device will stop entering LISTENING state periodically
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java b/framework/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
index d0fe92d524..481075b9ac 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
@@ -16,7 +16,17 @@
package android.net.wifi.p2p;
+import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
+import android.net.wifi.OuiKeyedData;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+
+import java.util.Collections;
+import java.util.List;
/**
* A class representing a Wi-Fi p2p provisional discovery request/response
@@ -44,12 +54,49 @@ public class WifiP2pProvDiscEvent {
@UnsupportedAppUsage
public String pin;
+ /** List of {@link OuiKeyedData} providing vendor-specific configuration data. */
+ private @NonNull List<OuiKeyedData> mVendorData = Collections.emptyList();
+
+ /**
+ * Return the vendor-provided configuration data, if it exists. See also {@link
+ * #setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @NonNull
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
@UnsupportedAppUsage
public WifiP2pProvDiscEvent() {
device = new WifiP2pDevice();
}
/**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the
+ * vendor-provided configuration data. Note that multiple elements with
+ * the same OUI are allowed.
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @NonNull
+ public void setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = vendorData;
+ }
+
+ /**
* @param string formats supported include
*
* P2P-PROV-DISC-PBC-REQ 42:fc:89:e1:e2:27
@@ -87,6 +134,7 @@ public class WifiP2pProvDiscEvent {
sbuf.append(device);
sbuf.append("\n event: ").append(event);
sbuf.append("\n pin: ").append(pin);
+ sbuf.append("\n vendorData: ").append(mVendorData);
return sbuf.toString();
}
}
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/framework/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
index b7411e82d4..3411d6a198 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
@@ -446,7 +446,7 @@ public final class WifiP2pWfdInfo implements Parcelable {
public String toString() {
StringBuffer sbuf = new StringBuffer();
sbuf.append("WFD enabled: ").append(mEnabled);
- sbuf.append("WFD DeviceInfo: ").append(mDeviceInfo);
+ sbuf.append("\n WFD DeviceInfo: ").append(mDeviceInfo);
sbuf.append("\n WFD CtrlPort: ").append(mCtrlPort);
sbuf.append("\n WFD MaxThroughput: ").append(mMaxThroughput);
sbuf.append("\n WFD R2 DeviceInfo: ").append(mR2DeviceInfo);
diff --git a/framework/java/android/net/wifi/rtt/RangingRequest.java b/framework/java/android/net/wifi/rtt/RangingRequest.java
index aebe0d338e..8360dc466a 100644
--- a/framework/java/android/net/wifi/rtt/RangingRequest.java
+++ b/framework/java/android/net/wifi/rtt/RangingRequest.java
@@ -16,21 +16,31 @@
package android.net.wifi.rtt;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.ParcelUtil;
import android.net.wifi.ScanResult;
import android.net.wifi.aware.AttachCallback;
import android.net.wifi.aware.DiscoverySessionCallback;
import android.net.wifi.aware.IdentityChangedListener;
import android.net.wifi.aware.PeerHandle;
import android.net.wifi.aware.WifiAwareManager;
+import android.os.Build;
import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
+
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
@@ -96,10 +106,17 @@ public final class RangingRequest implements Parcelable {
/** @hide */
public final int mRttBurstSize;
+ /**
+ * List of {@link OuiKeyedData} providing vendor-specific configuration data.
+ */
+ private @NonNull List<OuiKeyedData> mVendorData;
+
/** @hide */
- private RangingRequest(List<ResponderConfig> rttPeers, int rttBurstSize) {
+ private RangingRequest(List<ResponderConfig> rttPeers, int rttBurstSize,
+ @NonNull List<OuiKeyedData> vendorData) {
mRttPeers = rttPeers;
mRttBurstSize = rttBurstSize;
+ mVendorData = new ArrayList<>(vendorData);
}
/**
@@ -124,6 +141,24 @@ public final class RangingRequest implements Parcelable {
return mRttBurstSize;
}
+ /**
+ * Return the vendor-provided configuration data, if it exists. See also {@link
+ * Builder#setVendorData(List)}
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ @SystemApi
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -133,6 +168,7 @@ public final class RangingRequest implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(mRttPeers);
dest.writeInt(mRttBurstSize);
+ dest.writeList(mVendorData);
}
public static final @android.annotation.NonNull Creator<RangingRequest> CREATOR = new Creator<RangingRequest>() {
@@ -143,7 +179,8 @@ public final class RangingRequest implements Parcelable {
@Override
public RangingRequest createFromParcel(Parcel in) {
- return new RangingRequest(in.readArrayList(null), in.readInt());
+ return new RangingRequest(in.readArrayList(null), in.readInt(),
+ ParcelUtil.readOuiKeyedDataList(in));
}
};
@@ -155,6 +192,7 @@ public final class RangingRequest implements Parcelable {
sj.add(rc.toString());
}
sj.add("mRttBurstSize=" + mRttBurstSize);
+ sj.add("mVendorData=" + mVendorData);
return sj.toString();
}
@@ -172,6 +210,9 @@ public final class RangingRequest implements Parcelable {
if (mRttBurstSize < getMinRttBurstSize() || mRttBurstSize > getMaxRttBurstSize()) {
throw new IllegalArgumentException("RTT burst size is out of range");
}
+ if (mVendorData == null) {
+ throw new IllegalArgumentException("Vendor data must be non-null");
+ }
}
/**
@@ -180,6 +221,7 @@ public final class RangingRequest implements Parcelable {
public static final class Builder {
private List<ResponderConfig> mRttPeers = new ArrayList<>();
private int mRttBurstSize = DEFAULT_RTT_BURST_SIZE;
+ private @NonNull List<OuiKeyedData> mVendorData = Collections.emptyList();
/**
* Set the RTT Burst size for the ranging request.
@@ -190,6 +232,14 @@ public final class RangingRequest implements Parcelable {
* {@link #getMaxRttBurstSize()} inclusively, or a
* {@link java.lang.IllegalArgumentException} will be thrown.
*
+ * Note: RTT burst size is applicable to IEEE 802.11mc, and for one special case it is
+ * also applicable to IEEE 802.11az to generate multiple NTB ranging requests per
+ * measurement. It is applicable for IEEE 802.11az based ranging requests when MIMO is
+ * not available, with the transmit and receive spatial streams between the initiator and
+ * responder station is equal to 1. See
+ * {@link RangingResult#get80211azNumberOfRxSpatialStreams()} and
+ * {@link RangingResult#get80211azNumberOfTxSpatialStreams()}.
+ *
* @param rttBurstSize The number of FTM packets used to estimate a range.
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
@@ -208,10 +258,15 @@ public final class RangingRequest implements Parcelable {
* which to measure range. The total number of peers added to a request cannot exceed the
* limit specified by {@link #getMaxPeers()}.
* <p>
- * Two-sided Ranging will be supported if the Access Point supports IEEE 802.11mc, also
- * known as two-sided RTT, and this is determined by the method
- * {@link ScanResult#is80211mcResponder()}. If not supported, one-sided RTT will be
- * performed with no correction for the AP packet turnaround time.
+ * Two-sided Ranging will be performed if the local device and the AP support IEEE 802.11az
+ * (non-trigger based ranging) or IEEE 802.11mc. AP capability is determined by the method
+ * {@link ScanResult#is80211azNtbResponder()} or {@link ScanResult#is80211mcResponder()}.
+ *
+ * If both 11az and 11mc are supported by the local device and the AP, 11az non-trigger
+ * based ranging will be performed.
+ *
+ * If two-sided ranging is not supported, one-sided RTT will be performed with no
+ * correction for the AP packet turnaround time.
*
* @param apInfo Information about an Access Point (AP) obtained in a Scan Result.
* @return The builder to facilitate chaining
@@ -230,10 +285,15 @@ public final class RangingRequest implements Parcelable {
* which to measure range. The total number of peers added to a request cannot exceed the
* limit specified by {@link #getMaxPeers()}.
* <p>
- * Two-sided Ranging will be supported if the Access Point supports IEEE 802.11mc, also
- * known as two-sided RTT, and this is determined by the method
- * {@link ScanResult#is80211mcResponder()}. If not supported, one-sided RTT will be
- * performed with no correction for the AP packet turnaround time.
+ * Two-sided Ranging will be performed if the local device and the AP support IEEE 802.11az
+ * (non-trigger based ranging) or IEEE 802.11mc. AP capability is determined by the method
+ * {@link ScanResult#is80211azNtbResponder()} or {@link ScanResult#is80211mcResponder()}.
+ *
+ * If both 11az and 11mc are supported by the local device and the AP, 11az non-trigger
+ * based ranging will be performed.
+ *
+ * If two-sided ranging is not supported, one-sided RTT will be performed with no
+ * correction for the AP packet turnaround time.
*
* @param apInfos Information about Access Points (APs) obtained in a Scan Result.
* @return The builder to facilitate chaining
@@ -255,10 +315,15 @@ public final class RangingRequest implements Parcelable {
* with which to measure range. The total number of peers added to the request cannot exceed
* the limit specified by {@link #getMaxPeers()}.
* <p>
- * Two-sided Ranging will be supported if an Access Point supports IEEE 802.11mc, also
- * known as two-sided RTT, and this is specified in the {@link ResponderConfig} builder.
- * If not supported, one-sided RTT will be performed with no correction for
- * the AP packet turnaround time.
+ * Two-sided Ranging will be performed if the local device and the AP support IEEE 802.11az
+ * (non-trigger based ranging) or IEEE 802.11mc. AP capability is determined by the method
+ * {@link ScanResult#is80211azNtbResponder()} or {@link ScanResult#is80211mcResponder()}.
+ *
+ * If both 11az and 11mc are supported by the local device and the AP, 11az non-trigger
+ * based ranging will be performed.
+ *
+ * If two-sided ranging is not supported, one-sided RTT will be performed with no
+ * correction for the AP packet turnaround time.
*
* @param responder Information on the RTT Responder.
* @return The builder, to facilitate chaining {@code builder.setXXX(..).setXXX(..)}.
@@ -278,10 +343,15 @@ public final class RangingRequest implements Parcelable {
* which to measure range. The total number of peers added to a request cannot exceed the
* limit specified by {@link #getMaxPeers()}.
* <p>
- * Two-sided Ranging will be supported if an Access Point supports IEEE 802.11mc, also
- * known as two-sided RTT, and this is specified in the {@link ResponderConfig} builder.
- * If not supported, one-sided RTT will be performed with no correction for the AP packet
- * turnaround time.
+ * Two-sided Ranging will be performed if the local device and the AP support IEEE 802.11az
+ * (non-trigger based ranging) or IEEE 802.11mc. AP capability is determined by the method
+ * {@link ScanResult#is80211azNtbResponder()} or {@link ScanResult#is80211mcResponder()}.
+ *
+ * If both 11az and 11mc are supported by the local device and the AP, 11az non-trigger
+ * based ranging will be performed.
+ *
+ * If two-sided ranging is not supported, one-sided RTT will be performed with no
+ * correction for the AP packet turnaround time.
*
* @param responders Information representing the set of access points to be ranged
* @return The builder to facilitate chaining
@@ -299,17 +369,18 @@ public final class RangingRequest implements Parcelable {
}
/**
- * Add the non-802.11mc capable device specified by the {@link ScanResult} to the list of
- * devices with which to measure range. The total number of peers added to a request cannot
- * exceed the limit specified by {@link #getMaxPeers()}.
+ * Add the non-802.11mc and non-802.11az capable device specified by the {@link ScanResult}
+ * to the list of devices with which to measure range. The total number of peers added to a
+ * request cannot exceed the limit specified by {@link #getMaxPeers()}.
* <p>
- * Accurate ranging cannot be supported if the Access Point does not support IEEE 802.11mc,
- * and instead an alternate protocol called one-sided RTT will be used with lower
- * accuracy. Use {@link ScanResult#is80211mcResponder()} to verify the Access Point)s) are
- * not 802.11mc capable.
+ * Accurate ranging cannot be supported if the Access Point does not support IEEE 802.11mc
+ * and IEEE 802.11az, and instead an alternate protocol called one-sided RTT will be used
+ * with lower accuracy. Use {@link ScanResult#is80211mcResponder()} to verify the Access
+ * Point(s) are not 802.11mc capable. Use {@link ScanResult#is80211azNtbResponder()} ()} to
+ * verify the Access Point)s) are not 802.11az capable.
* <p>
* One-sided RTT does not subtract the RTT turnaround time at the Access Point, which can
- * add hundreds of meters to the estimate. With experimentation it is possible to use this
+ * add hundreds of meters to the estimate. With experimentation, it is possible to use this
* information to make a statistical estimate of the range by taking multiple measurements
* to several Access Points and normalizing the result. For some applications this can be
* used to improve range estimates based on Receive Signal Strength Indication (RSSI), but
@@ -327,24 +398,26 @@ public final class RangingRequest implements Parcelable {
if (apInfo == null) {
throw new IllegalArgumentException("Null ScanResult!");
}
- if (apInfo.is80211mcResponder()) {
- throw new IllegalArgumentException("AP supports the 802.11mc protocol.");
+ if (apInfo.is80211mcResponder() || apInfo.is80211azNtbResponder()) {
+ throw new IllegalArgumentException(
+ "AP supports the 802.11mc or 8022.11az protocol.");
}
return addResponder(ResponderConfig.fromScanResult(apInfo));
}
/**
- * Add the non-802.11mc capable devices specified by the {@link ScanResult} to the list of
- * devices with which to measure range. The total number of peers added to a request cannot
- * exceed the limit specified by {@link #getMaxPeers()}.
+ * Add the non-802.11mc and non-802.11az capable devices specified by the {@link ScanResult}
+ * to the list of devices with which to measure range. The total number of peers added to a
+ * request cannot exceed the limit specified by {@link #getMaxPeers()}.
* <p>
- * Accurate ranging cannot be supported if the Access Point does not support IEEE 802.11mc,
- * and instead an alternate protocol called one-sided RTT will be used with lower
- * accuracy. Use {@link ScanResult#is80211mcResponder()} to verify the Access Point)s) are
- * not 802.11mc capable.
+ * Accurate ranging cannot be supported if the Access Point does not support IEEE 802.11mc
+ * and IEEE 802.11az, and instead an alternate protocol called one-sided RTT will be used
+ * with lower accuracy. Use {@link ScanResult#is80211mcResponder()} to verify the Access
+ * Point(s) are not 802.11mc capable. Use {@link ScanResult#is80211azNtbResponder()} ()} to
+ * verify the Access Point(s) are not 802.11az capable.
* <p>
* One-sided RTT does not subtract the RTT turnaround time at the Access Point, which can
- * add hundreds of meters to the estimate. With experimentation it is possible to use this
+ * add hundreds of meters to the estimate. With experimentation, it is possible to use this
* information to make a statistical estimate of the range by taking multiple measurements
* to several Access Points and normalizing the result. For some applications this can be
* used to improve range estimates based on Receive Signal Strength Indication (RSSI), but
@@ -363,9 +436,9 @@ public final class RangingRequest implements Parcelable {
throw new IllegalArgumentException("Null list of ScanResults!");
}
for (ScanResult scanResult : apInfos) {
- if (scanResult.is80211mcResponder()) {
+ if (scanResult.is80211mcResponder() || scanResult.is80211azNtbResponder()) {
throw new IllegalArgumentException(
- "At least one AP supports the 802.11mc protocol.");
+ "At least one AP supports the 802.11mc or 802.11az protocol.");
}
addAccessPoint(scanResult);
}
@@ -427,13 +500,35 @@ public final class RangingRequest implements Parcelable {
return addResponder(ResponderConfig.fromWifiAwarePeerHandleWithDefaults(peerHandle));
}
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link OuiKeyedData} containing the vendor-provided
+ * configuration data. Note that multiple elements with the same OUI are allowed.
+ * @return Builder for chaining.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ @SystemApi
+ public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = vendorData;
+ return this;
+ }
/**
* Build {@link RangingRequest} given the current configurations made on the
* builder.
*/
public RangingRequest build() {
- return new RangingRequest(mRttPeers, mRttBurstSize);
+ return new RangingRequest(mRttPeers, mRttBurstSize, mVendorData);
}
}
@@ -451,11 +546,12 @@ public final class RangingRequest implements Parcelable {
return mRttPeers.size() == lhs.mRttPeers.size()
&& mRttPeers.containsAll(lhs.mRttPeers)
- && mRttBurstSize == lhs.mRttBurstSize;
+ && mRttBurstSize == lhs.mRttBurstSize
+ && Objects.equals(mVendorData, lhs.mVendorData);
}
@Override
public int hashCode() {
- return Objects.hash(mRttPeers, mRttBurstSize);
+ return Objects.hash(mRttPeers, mRttBurstSize, mVendorData);
}
}
diff --git a/framework/java/android/net/wifi/rtt/RangingResult.java b/framework/java/android/net/wifi/rtt/RangingResult.java
index 32a83cfe8c..87b1ed9af3 100644
--- a/framework/java/android/net/wifi/rtt/RangingResult.java
+++ b/framework/java/android/net/wifi/rtt/RangingResult.java
@@ -16,20 +16,32 @@
package android.net.wifi.rtt;
+import android.annotation.ElapsedRealtimeLong;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.ParcelUtil;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiAnnotations.ChannelWidth;
import android.net.wifi.aware.PeerHandle;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -79,126 +91,454 @@ public final class RangingResult implements Parcelable {
*/
public static final int UNSPECIFIED = -1;
- /** @hide */
- public final int mStatus;
+ private final @RangeResultStatus int mStatus;
+ private final MacAddress mMac;
+ private final PeerHandle mPeerHandle;
+ private final int mDistanceMm;
+ private final int mDistanceStdDevMm;
+ private final int mRssi;
+ private final int mNumAttemptedMeasurements;
+ private final int mNumSuccessfulMeasurements;
+ private final byte[] mLci;
+ private final byte[] mLcr;
+ private final ResponderLocation mResponderLocation;
+ private final long mTimestamp;
+ private final boolean mIs80211mcMeasurement;
+ private final int mFrequencyMHz;
+ private final int mPacketBw;
+ private final boolean mIs80211azNtbMeasurement;
+ private final long mNtbMinMeasurementTime;
+ private final long mNtbMaxMeasurementTime;
+ private final int mI2rTxLtfRepetitions;
+ private final int mR2iTxLtfRepetitions;
+ private final int mNumTxSpatialStreams;
+ private final int mNumRxSpatialStreams;
+ private List<OuiKeyedData> mVendorData;
- /** @hide */
- public final MacAddress mMac;
+ /**
+ * Builder class used to construct {@link RangingResult} objects.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final class Builder {
+ private @RangeResultStatus int mStatus = STATUS_FAIL;
+ private MacAddress mMac = null;
+ private PeerHandle mPeerHandle = null;
+ private int mDistanceMm = 0;
+ private int mDistanceStdDevMm = 0;
+ private int mRssi = -127;
+ private int mNumAttemptedMeasurements = 0;
+ private int mNumSuccessfulMeasurements = 0;
+ private byte[] mLci = null;
+ private byte[] mLcr = null;
+ private ResponderLocation mResponderLocation = null;
+ private long mTimestamp = 0;
+ private boolean mIs80211mcMeasurement = false;
+ private int mFrequencyMHz = UNSPECIFIED;
+ private int mPacketBw = UNSPECIFIED;
+ private boolean mIs80211azNtbMeasurement = false;
+ private long mNtbMinMeasurementTime = UNSPECIFIED;
+ private long mNtbMaxMeasurementTime = UNSPECIFIED;
+ private int mI2rTxLtfRepetitions = UNSPECIFIED;
+ private int mR2iTxLtfRepetitions = UNSPECIFIED;
+ private int mNumTxSpatialStreams = UNSPECIFIED;
+ private int mNumRxSpatialStreams = UNSPECIFIED;
+ private List<OuiKeyedData> mVendorData = Collections.emptyList();
- /** @hide */
- public final PeerHandle mPeerHandle;
+ /**
+ * Sets the Range result status.
+ *
+ * @param status Ranging result status, if not set defaults to
+ * {@link #STATUS_FAIL}.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setStatus(@RangeResultStatus int status) {
+ mStatus = status;
+ return this;
+ }
- /** @hide */
- public final int mDistanceMm;
+ /**
+ * Sets the MAC address of the ranging result.
+ *
+ * @param macAddress Mac address, if not defaults to null.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setMacAddress(@Nullable MacAddress macAddress) {
+ mMac = macAddress;
+ return this;
+ }
- /** @hide */
- public final int mDistanceStdDevMm;
- /** @hide */
- public final int mRssi;
+ /**
+ * Sets the peer handle. Applicable only for NAN Ranging.
+ *
+ * @param peerHandle Opaque object used to represent a Wi-Fi Aware peer. If not set,
+ * defaults to null.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setPeerHandle(@Nullable PeerHandle peerHandle) {
+ mPeerHandle = peerHandle;
+ return this;
+ }
- /** @hide */
- public final int mNumAttemptedMeasurements;
+ /**
+ * Sets the distance in millimeter.
+ *
+ * @param distanceMm distance. If not set, defaults to 0.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setDistanceMm(int distanceMm) {
+ mDistanceMm = distanceMm;
+ return this;
+ }
- /** @hide */
- public final int mNumSuccessfulMeasurements;
+ /**
+ * Sets the standard deviation of the distance in millimeter.
+ *
+ * @param distanceStdDevMm Standard deviation of the distance measurement. If not set
+ * defaults to 0.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setDistanceStdDevMm(int distanceStdDevMm) {
+ mDistanceStdDevMm = distanceStdDevMm;
+ return this;
+ }
- /** @hide */
- public final byte[] mLci;
+ /**
+ * Sets the average RSSI.
+ *
+ * @param rssi Average RSSI. If not set, defaults to -127.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setRssi(int rssi) {
+ mRssi = rssi;
+ return this;
+ }
- /** @hide */
- public final byte[] mLcr;
+ /**
+ * Sets the total number of RTT measurements attempted.
+ *
+ * @param numAttemptedMeasurements Number of attempted measurements. If not set, default
+ * to 0.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setNumAttemptedMeasurements(int numAttemptedMeasurements) {
+ mNumAttemptedMeasurements = numAttemptedMeasurements;
+ return this;
+ }
- /** @hide */
- public final ResponderLocation mResponderLocation;
+ /**
+ * Sets the total number of successful RTT measurements.
+ *
+ * @param numSuccessfulMeasurements Number of successful measurements. If not set, default
+ * to 0.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setNumSuccessfulMeasurements(int numSuccessfulMeasurements) {
+ mNumSuccessfulMeasurements = numSuccessfulMeasurements;
+ return this;
+ }
- /** @hide */
- public final long mTimestamp;
+ /**
+ * Sets the Location Configuration Information (LCI).
+ *
+ * LCI provides data about the access point's (AP) physical location, such as its
+ * latitude, longitude, and altitude. The format is specified in the IEEE 802.11-2016
+ * specifications, section 9.4.2.22.10.
+ *
+ * @param lci Location configuration information. If not set, defaults to null.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setLci(@Nullable byte[] lci) {
+ mLci = lci;
+ return this;
+ }
- /** @hide */
- public final boolean mIs80211mcMeasurement;
+ /**
+ * Sets the Location Civic Report (LCR).
+ *
+ * LCR provides additional details about the AP's location in a human-readable format,
+ * such as the street address, building name, or floor number. This can be helpful for
+ * users to understand the context of their location within a building or complex.
+ *
+ * The format is
+ * specified in the IEEE 802.11-2016 specifications, section 9.4.2.22.13.
+ *
+ * @param lcr Location civic report. If not set, defaults to null.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setLcr(@Nullable byte[] lcr) {
+ mLcr = lcr;
+ return this;
+ }
- /** @hide */
- public final int mFrequencyMHz;
+ /**
+ * Sets Responder Location.
+ *
+ * ResponderLocation is both a Location Configuration Information (LCI) decoder and a
+ * Location Civic Report (LCR) decoder for information received from a Wi-Fi Access Point
+ * (AP) during Wi-Fi RTT ranging process.
+ *
+ * @param responderLocation Responder location. If not set, defaults to null.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setUnverifiedResponderLocation(
+ @Nullable ResponderLocation responderLocation) {
+ mResponderLocation = responderLocation;
+ return this;
+ }
- /** @hide */
- public final int mPacketBw;
+ /**
+ * Sets the time stamp at which the ranging operation was performed.
+ *
+ * The timestamp is in milliseconds since boot, including time spent in sleep,
+ * corresponding to values provided by {@link android.os.SystemClock#elapsedRealtime()}.
+ *
+ * @param timestamp time stamp in milliseconds. If not set, default to 0.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setRangingTimestampMillis(@ElapsedRealtimeLong long timestamp) {
+ mTimestamp = timestamp;
+ return this;
+ }
- /** @hide */
- public RangingResult(@RangeResultStatus int status, @NonNull MacAddress mac, int distanceMm,
- int distanceStdDevMm, int rssi, int numAttemptedMeasurements,
- int numSuccessfulMeasurements, byte[] lci, byte[] lcr,
- ResponderLocation responderLocation, long timestamp, boolean is80211McMeasurement,
- int frequencyMHz, int packetBw) {
- mStatus = status;
- mMac = mac;
- mPeerHandle = null;
- mDistanceMm = distanceMm;
- mDistanceStdDevMm = distanceStdDevMm;
- mRssi = rssi;
- mNumAttemptedMeasurements = numAttemptedMeasurements;
- mNumSuccessfulMeasurements = numSuccessfulMeasurements;
- mLci = lci == null ? EMPTY_BYTE_ARRAY : lci;
- mLcr = lcr == null ? EMPTY_BYTE_ARRAY : lcr;
- mResponderLocation = responderLocation;
- mTimestamp = timestamp;
- mIs80211mcMeasurement = is80211McMeasurement;
- mFrequencyMHz = frequencyMHz;
- mPacketBw = packetBw;
- }
- /** @hide */
- public RangingResult(@RangeResultStatus int status, @NonNull MacAddress mac, int distanceMm,
- int distanceStdDevMm, int rssi, int numAttemptedMeasurements,
- int numSuccessfulMeasurements, byte[] lci, byte[] lcr,
- ResponderLocation responderLocation, long timestamp, boolean is80211McMeasurement) {
- mStatus = status;
- mMac = mac;
- mPeerHandle = null;
- mDistanceMm = distanceMm;
- mDistanceStdDevMm = distanceStdDevMm;
- mRssi = rssi;
- mNumAttemptedMeasurements = numAttemptedMeasurements;
- mNumSuccessfulMeasurements = numSuccessfulMeasurements;
- mLci = lci == null ? EMPTY_BYTE_ARRAY : lci;
- mLcr = lcr == null ? EMPTY_BYTE_ARRAY : lcr;
- mResponderLocation = responderLocation;
- mTimestamp = timestamp;
- mIs80211mcMeasurement = is80211McMeasurement;
- mFrequencyMHz = UNSPECIFIED;
- mPacketBw = UNSPECIFIED;
+ /**
+ * Sets whether the ranging measurement was performed using IEEE 802.11mc ranging method.
+ * If {@link #set80211mcMeasurement(boolean)} is set as false and
+ * {@link #set80211azNtbMeasurement(boolean)} is also set as false, ranging measurement was
+ * performed using one-side RTT. If not set, default to false.
+ *
+ * @param is80211mcMeasurement true for IEEE 802.11mc measure, otherwise false.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder set80211mcMeasurement(boolean is80211mcMeasurement) {
+ mIs80211mcMeasurement = is80211mcMeasurement;
+ return this;
+ }
+
+ /**
+ * Sets the center frequency of the primary 20 MHz frequency (in MHz) of the channel over
+ * which the measurement frames are sent. If not set, default to
+ * {@link RangingResult#UNSPECIFIED}
+ *
+ * @param frequencyMHz Frequency.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setMeasurementChannelFrequencyMHz(int frequencyMHz) {
+ mFrequencyMHz = frequencyMHz;
+ return this;
+ }
+
+ /**
+ * Sets the bandwidth used to transmit the RTT measurement frame. If not set, default to
+ * {@link RangingResult#UNSPECIFIED}.
+ *
+ * @param measurementBandwidth Measurement bandwidth.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setMeasurementBandwidth(@ChannelWidth int measurementBandwidth) {
+ mPacketBw = measurementBandwidth;
+ return this;
+ }
+
+ /**
+ * Sets whether the ranging measurement was performed using IEEE 802.11az non-trigger
+ * ranging method. If {@link #set80211azNtbMeasurement(boolean)} is set as false and
+ * {@link #set80211mcMeasurement(boolean)} is also set as false, ranging measurement was
+ * performed using one-side RTT. If not set defaults to false.
+ *
+ * @param is80211azNtbMeasurement true for IEEE 802.11az non-trigger based measurement,
+ * otherwise false.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder set80211azNtbMeasurement(boolean is80211azNtbMeasurement) {
+ mIs80211azNtbMeasurement = is80211azNtbMeasurement;
+ return this;
+ }
+
+ /**
+ * Sets minimum time between measurements in microseconds for IEEE 802.11az non-trigger
+ * based ranging. If not set, defaults to {@link RangingResult#UNSPECIFIED}.
+ *
+ * @param ntbMinMeasurementTime non-trigger based ranging minimum measurement time.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setMinTimeBetweenNtbMeasurementsMicros(long ntbMinMeasurementTime) {
+ mNtbMinMeasurementTime = ntbMinMeasurementTime;
+ return this;
+ }
+
+ /**
+ * Sets maximum time between measurements in microseconds for IEEE 802.11az non-trigger
+ * based ranging. If not set, defaults to {@link RangingResult#UNSPECIFIED}.
+ *
+ * @param ntbMaxMeasurementTime non-trigger based ranging maximum measurement time.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder setMaxTimeBetweenNtbMeasurementsMicros(long ntbMaxMeasurementTime) {
+ mNtbMaxMeasurementTime = ntbMaxMeasurementTime;
+ return this;
+ }
+
+ /**
+ * Sets LTF repetitions that the initiator station used in the preamble. If not set,
+ * defaults to {@link RangingResult#UNSPECIFIED}.
+ *
+ * @param i2rTxLtfRepetitions LFT repetition count.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder set80211azInitiatorTxLtfRepetitionsCount(int i2rTxLtfRepetitions) {
+ mI2rTxLtfRepetitions = i2rTxLtfRepetitions;
+ return this;
+ }
+
+ /**
+ * Sets LTF repetitions that the responder station used in the preamble. If not set,
+ * defaults to {@link RangingResult#UNSPECIFIED}.
+ *
+ * @param r2iTxLtfRepetitions LFT repetition count.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder set80211azResponderTxLtfRepetitionsCount(int r2iTxLtfRepetitions) {
+ mR2iTxLtfRepetitions = r2iTxLtfRepetitions;
+ return this;
+ }
+
+ /**
+ * Sets number of transmit spatial streams that the initiator station used for the
+ * ranging result. If not set, defaults to {@link RangingResult#UNSPECIFIED}.
+ *
+ * @param numTxSpatialStreams Number of transmit spatial streams.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder set80211azNumberOfTxSpatialStreams(int numTxSpatialStreams) {
+ mNumTxSpatialStreams = numTxSpatialStreams;
+ return this;
+ }
+
+ /**
+ * Sets number of receive spatial streams that the initiator station used for the ranging
+ * result. If not set, defaults to {@link RangingResult#UNSPECIFIED}.
+ *
+ * @param numRxSpatialStreams Number of receive spatial streams.
+ * @return The builder to facilitate chaining.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder set80211azNumberOfRxSpatialStreams(int numRxSpatialStreams) {
+ mNumRxSpatialStreams = numRxSpatialStreams;
+ return this;
+ }
+
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the
+ * vendor-provided configuration data. Note that multiple elements with
+ * the same OUI are allowed.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ if (vendorData == null) {
+ throw new IllegalArgumentException("setVendorData received a null value");
+ }
+ mVendorData = vendorData;
+ return this;
+ }
+
+ /**
+ * Build {@link RangingResult}
+ * @return an instance of {@link RangingResult}
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public RangingResult build() {
+ if (mMac == null && mPeerHandle == null) {
+ throw new IllegalArgumentException("Either MAC address or Peer handle is needed");
+ }
+ if (mIs80211azNtbMeasurement && mIs80211mcMeasurement) {
+ throw new IllegalArgumentException(
+ "A ranging result cannot use both IEEE 802.11mc and IEEE 802.11az "
+ + "measurements simultaneously");
+ }
+ return new RangingResult(this);
+ }
}
/** @hide */
- public RangingResult(
- @RangeResultStatus int status,
- PeerHandle peerHandle,
- int distanceMm,
- int distanceStdDevMm,
- int rssi,
- int numAttemptedMeasurements,
- int numSuccessfulMeasurements,
- byte[] lci,
- byte[] lcr,
- ResponderLocation responderLocation,
- long timestamp,
- int frequencyMHz,
- int packetBw) {
- mStatus = status;
- mMac = null;
- mPeerHandle = peerHandle;
- mDistanceMm = distanceMm;
- mDistanceStdDevMm = distanceStdDevMm;
- mRssi = rssi;
- mNumAttemptedMeasurements = numAttemptedMeasurements;
- mNumSuccessfulMeasurements = numSuccessfulMeasurements;
- mLci = lci == null ? EMPTY_BYTE_ARRAY : lci;
- mLcr = lcr == null ? EMPTY_BYTE_ARRAY : lcr;
- mResponderLocation = responderLocation;
- mTimestamp = timestamp;
- mIs80211mcMeasurement = true;
- mFrequencyMHz = frequencyMHz;
- mPacketBw = packetBw;
+ private RangingResult(Builder builder) {
+ mStatus = builder.mStatus;
+ mMac = builder.mMac;
+ mPeerHandle = builder.mPeerHandle;
+ mDistanceMm = builder.mDistanceMm;
+ mDistanceStdDevMm = builder.mDistanceStdDevMm;
+ mRssi = builder.mRssi;
+ mNumAttemptedMeasurements = builder.mNumAttemptedMeasurements;
+ mNumSuccessfulMeasurements = builder.mNumSuccessfulMeasurements;
+ mLci = (builder.mLci == null) ? EMPTY_BYTE_ARRAY : builder.mLci;
+ mLcr = (builder.mLcr == null) ? EMPTY_BYTE_ARRAY : builder.mLcr;
+ mResponderLocation = builder.mResponderLocation;
+ mTimestamp = builder.mTimestamp;
+ mIs80211mcMeasurement = builder.mIs80211mcMeasurement;
+ mFrequencyMHz = builder.mFrequencyMHz;
+ mPacketBw = builder.mPacketBw;
+ mIs80211azNtbMeasurement = builder.mIs80211azNtbMeasurement;
+ mNtbMinMeasurementTime = builder.mNtbMinMeasurementTime;
+ mNtbMaxMeasurementTime = builder.mNtbMaxMeasurementTime;
+ mI2rTxLtfRepetitions = builder.mI2rTxLtfRepetitions;
+ mR2iTxLtfRepetitions = builder.mR2iTxLtfRepetitions;
+ mNumRxSpatialStreams = builder.mNumRxSpatialStreams;
+ mNumTxSpatialStreams = builder.mNumTxSpatialStreams;
+ mVendorData = builder.mVendorData;
}
/**
@@ -351,10 +691,8 @@ public final class RangingResult implements Parcelable {
* <p>
* Note: the information is NOT validated - use with caution. Consider validating it with
* other sources of information before using it.
- *
- * @hide
*/
- @SystemApi
+ @SuppressLint("UnflaggedApi") // Flagging API promotion from @SystemApi to public not supported
@NonNull
public byte[] getLci() {
if (mStatus != STATUS_SUCCESS) {
@@ -370,10 +708,8 @@ public final class RangingResult implements Parcelable {
* <p>
* Note: the information is NOT validated - use with caution. Consider validating it with
* other sources of information before using it.
- *
- * @hide
*/
- @SystemApi
+ @SuppressLint("UnflaggedApi") // Flagging API promotion from @SystemApi to public not supported
@NonNull
public byte[] getLcr() {
if (mStatus != STATUS_SUCCESS) {
@@ -402,9 +738,9 @@ public final class RangingResult implements Parcelable {
}
/**
- * @return The result is true if the IEEE 802.11mc protocol was used (also known as
- * two-sided RTT). If the result is false, a one-side RTT result is provided which does not
- * subtract the turnaround time at the responder.
+ * @return The result is true if the IEEE 802.11mc protocol was used. If the result is false,
+ * and {@link #is80211azNtbMeasurement()} is also false a one-side RTT result is provided
+ * which does not subtract the turnaround time at the responder.
* <p>
* Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
* exception.
@@ -419,6 +755,101 @@ public final class RangingResult implements Parcelable {
}
/**
+ * @return The result is true if the IEEE 802.11az non-trigger based protocol was used. If the
+ * result is false, and {@link #is80211mcMeasurement()} is also false a one-side RTT result
+ * is provided which does not subtract the turnaround time at the responder.
+ * <p>.
+ * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an
+ * exception.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public boolean is80211azNtbMeasurement() {
+ if (mStatus != STATUS_SUCCESS) {
+ throw new IllegalStateException(
+ "is80211azNtbMeasurement(): invoked on an invalid result: getStatus()="
+ + mStatus);
+ }
+ return mIs80211azNtbMeasurement;
+ }
+
+ /**
+ * Gets minimum time between measurements in microseconds for IEEE 802.11az non-trigger based
+ * ranging.
+ *
+ * The next 11az ranging measurement request must be invoked after the minimum time from the
+ * last measurement time {@link #getRangingTimestampMillis()} for the peer. Otherwise, cached
+ * ranging result will be returned for the peer.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public long getMinTimeBetweenNtbMeasurementsMicros() {
+ return mNtbMinMeasurementTime;
+ }
+
+ /**
+ * Gets maximum time between measurements in microseconds for IEEE 802.11az non-trigger based
+ * ranging.
+ *
+ * The next 11az ranging request needs to be invoked before the maximum time from the last
+ * measurement time {@link #getRangingTimestampMillis()}. Otherwise, the non-trigger based
+ * ranging session will be terminated and a new ranging negotiation will happen with
+ * the responding station.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public long getMaxTimeBetweenNtbMeasurementsMicros() {
+ return mNtbMaxMeasurementTime;
+ }
+
+ /**
+ * Gets LTF repetitions that the responder station (RSTA) used in the preamble of the
+ * responder to initiator (I2R) null data PPDU (NDP) for this result.
+ *
+ * LTF repetitions is the multiple transmissions of HE-LTF symbols in an HE ranging NDP. An
+ * HE-LTF repetition value of 1 indicates no repetitions.
+ *
+ * @return LTF repetitions count
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int get80211azResponderTxLtfRepetitionsCount() {
+ return mR2iTxLtfRepetitions;
+ }
+
+ /**
+ * Gets LTF repetitions that the initiator station (ISTA) used in the preamble of the
+ * initiator to responder (I2R) null data PPDU (NDP) for this result.
+ *
+ * LTF repetitions is the multiple transmissions of HE-LTF symbols in an HE ranging NDP. An
+ * HE-LTF repetition value of 1 indicates no repetitions.
+ *
+ * @return LTF repetitions count
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int get80211azInitiatorTxLtfRepetitionsCount() {
+ return mI2rTxLtfRepetitions;
+ }
+
+ /**
+ * Gets number of transmit spatial streams that the initiator station (ISTA) used for the
+ * initiator to responder (I2R) null data PPDU (NDP) for this result.
+ *
+ * @return Number of spatial streams
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int get80211azNumberOfTxSpatialStreams() {
+ return mNumTxSpatialStreams;
+ }
+
+ /**
+ * Gets number of receive spatial streams that the initiator station (ISTA) used for the
+ * initiator to responder (I2R) null data PPDU (NDP) for this result.
+ *
+ * @return Number of spatial streams
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int get80211azNumberOfRxSpatialStreams() {
+ return mNumRxSpatialStreams;
+ }
+
+ /**
* The center frequency of the primary 20 MHz frequency (in MHz) of the channel over
* which the measurement frames are sent.
* @return center frequency in Mhz of the channel if available, otherwise {@link #UNSPECIFIED}
@@ -456,6 +887,23 @@ public final class RangingResult implements Parcelable {
return mPacketBw;
}
+ /**
+ * Get the vendor-provided configuration data, if it exists.
+ *
+ * @return Vendor configuration data, or empty list if it does not exist.
+ * @hide
+ */
+ @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @SystemApi
+ @NonNull
+ public List<OuiKeyedData> getVendorData() {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException();
+ }
+ return mVendorData;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -488,6 +936,16 @@ public final class RangingResult implements Parcelable {
dest.writeBoolean(mIs80211mcMeasurement);
dest.writeInt(mFrequencyMHz);
dest.writeInt(mPacketBw);
+ dest.writeBoolean(mIs80211azNtbMeasurement);
+ dest.writeLong(mNtbMinMeasurementTime);
+ dest.writeLong(mNtbMaxMeasurementTime);
+ dest.writeInt(mI2rTxLtfRepetitions);
+ dest.writeInt(mR2iTxLtfRepetitions);
+ dest.writeInt(mNumTxSpatialStreams);
+ dest.writeInt(mNumRxSpatialStreams);
+ if (SdkLevel.isAtLeastV()) {
+ dest.writeList(mVendorData);
+ }
}
public static final @android.annotation.NonNull Creator<RangingResult> CREATOR =
@@ -499,62 +957,36 @@ public final class RangingResult implements Parcelable {
@Override
public RangingResult createFromParcel(Parcel in) {
- int status = in.readInt();
- boolean macAddressPresent = in.readBoolean();
- MacAddress mac = null;
- if (macAddressPresent) {
- mac = MacAddress.CREATOR.createFromParcel(in);
- }
- boolean peerHandlePresent = in.readBoolean();
- PeerHandle peerHandle = null;
- if (peerHandlePresent) {
- peerHandle = new PeerHandle(in.readInt());
- }
- int distanceMm = in.readInt();
- int distanceStdDevMm = in.readInt();
- int rssi = in.readInt();
- int numAttemptedMeasurements = in.readInt();
- int numSuccessfulMeasurements = in.readInt();
- byte[] lci = in.createByteArray();
- byte[] lcr = in.createByteArray();
- ResponderLocation responderLocation =
- in.readParcelable(this.getClass().getClassLoader());
- long timestamp = in.readLong();
- boolean isllmcMeasurement = in.readBoolean();
- int frequencyMHz = in.readInt();
- int packetBw = in.readInt();
- if (peerHandlePresent) {
- return new RangingResult(
- status,
- peerHandle,
- distanceMm,
- distanceStdDevMm,
- rssi,
- numAttemptedMeasurements,
- numSuccessfulMeasurements,
- lci,
- lcr,
- responderLocation,
- timestamp,
- frequencyMHz,
- packetBw);
- } else {
- return new RangingResult(
- status,
- mac,
- distanceMm,
- distanceStdDevMm,
- rssi,
- numAttemptedMeasurements,
- numSuccessfulMeasurements,
- lci,
- lcr,
- responderLocation,
- timestamp,
- isllmcMeasurement,
- frequencyMHz,
- packetBw);
+ RangingResult.Builder builder = new Builder()
+ .setStatus(in.readInt())
+ .setMacAddress(
+ in.readBoolean() ? MacAddress.CREATOR.createFromParcel(in)
+ : null)
+ .setPeerHandle(in.readBoolean() ? new PeerHandle(in.readInt()) : null)
+ .setDistanceMm(in.readInt())
+ .setDistanceStdDevMm(in.readInt())
+ .setRssi(in.readInt())
+ .setNumAttemptedMeasurements(in.readInt())
+ .setNumSuccessfulMeasurements(in.readInt())
+ .setLci(in.createByteArray())
+ .setLcr(in.createByteArray())
+ .setUnverifiedResponderLocation(
+ in.readParcelable(this.getClass().getClassLoader()))
+ .setRangingTimestampMillis(in.readLong())
+ .set80211mcMeasurement(in.readBoolean())
+ .setMeasurementChannelFrequencyMHz(in.readInt())
+ .setMeasurementBandwidth(in.readInt())
+ .set80211azNtbMeasurement(in.readBoolean())
+ .setMinTimeBetweenNtbMeasurementsMicros(in.readLong())
+ .setMaxTimeBetweenNtbMeasurementsMicros(in.readLong())
+ .set80211azInitiatorTxLtfRepetitionsCount(in.readInt())
+ .set80211azResponderTxLtfRepetitionsCount(in.readInt())
+ .set80211azNumberOfTxSpatialStreams(in.readInt())
+ .set80211azNumberOfRxSpatialStreams(in.readInt());
+ if (SdkLevel.isAtLeastV()) {
+ builder.setVendorData(ParcelUtil.readOuiKeyedDataList(in));
}
+ return builder.build();
}
};
@@ -577,6 +1009,14 @@ 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(", vendorData=").append(mVendorData)
.append("]").toString();
}
@@ -602,7 +1042,15 @@ public final class RangingResult implements Parcelable {
&& mIs80211mcMeasurement == lhs.mIs80211mcMeasurement
&& Objects.equals(mResponderLocation, lhs.mResponderLocation)
&& mFrequencyMHz == lhs.mFrequencyMHz
- && mPacketBw == lhs.mPacketBw;
+ && mPacketBw == lhs.mPacketBw
+ && mIs80211azNtbMeasurement == lhs.mIs80211azNtbMeasurement
+ && mNtbMinMeasurementTime == lhs.mNtbMinMeasurementTime
+ && mNtbMaxMeasurementTime == lhs.mNtbMaxMeasurementTime
+ && mI2rTxLtfRepetitions == lhs.mI2rTxLtfRepetitions
+ && mR2iTxLtfRepetitions == lhs.mR2iTxLtfRepetitions
+ && mNumTxSpatialStreams == lhs.mNumTxSpatialStreams
+ && mNumRxSpatialStreams == lhs.mNumRxSpatialStreams
+ && Objects.equals(mVendorData, lhs.mVendorData);
}
@Override
@@ -610,6 +1058,8 @@ public final class RangingResult implements Parcelable {
return Objects.hash(mStatus, mMac, mPeerHandle, mDistanceMm, mDistanceStdDevMm, mRssi,
mNumAttemptedMeasurements, mNumSuccessfulMeasurements, Arrays.hashCode(mLci),
Arrays.hashCode(mLcr), mResponderLocation, mTimestamp, mIs80211mcMeasurement,
- mFrequencyMHz, mPacketBw);
+ mFrequencyMHz, mPacketBw, mIs80211azNtbMeasurement, mNtbMinMeasurementTime,
+ mNtbMaxMeasurementTime, mI2rTxLtfRepetitions, mR2iTxLtfRepetitions,
+ mNumTxSpatialStreams, mR2iTxLtfRepetitions, mVendorData);
}
}
diff --git a/framework/java/android/net/wifi/rtt/ResponderConfig.java b/framework/java/android/net/wifi/rtt/ResponderConfig.java
index c42c47c81f..5db9290b32 100644
--- a/framework/java/android/net/wifi/rtt/ResponderConfig.java
+++ b/framework/java/android/net/wifi/rtt/ResponderConfig.java
@@ -22,6 +22,7 @@ import static android.net.wifi.ScanResult.InformationElement.EID_EXT_HE_CAPABILI
import static android.net.wifi.ScanResult.InformationElement.EID_HT_CAPABILITIES;
import static android.net.wifi.ScanResult.InformationElement.EID_VHT_CAPABILITIES;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -35,6 +36,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
+import com.android.wifi.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
@@ -139,7 +142,6 @@ public final class ResponderConfig implements Parcelable {
@SystemApi
public static final int CHANNEL_WIDTH_320MHZ = 5;
-
/** @hide */
@IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT, PREAMBLE_HE, PREAMBLE_EHT})
@Retention(RetentionPolicy.SOURCE)
@@ -181,6 +183,9 @@ public final class ResponderConfig implements Parcelable {
@SystemApi
public static final int PREAMBLE_EHT = 4;
+ private static final long DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS = 250000;
+ private static final long DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS = 15000000;
+
/**
* The MAC address of the Responder. Will be null if a Wi-Fi Aware peer identifier (the
* peerHandle field) ise used to identify the Responder.
@@ -212,6 +217,14 @@ public final class ResponderConfig implements Parcelable {
public final boolean supports80211mc;
/**
+ * Indicates whether the Responder device supports IEEE 802.11az non-trigger based ranging.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public final boolean supports80211azNtb;
+
+ /**
* Responder channel bandwidth, specified using {@link ChannelWidth}.
* @hide
*/
@@ -249,6 +262,33 @@ public final class ResponderConfig implements Parcelable {
@SystemApi
public final int preamble;
+ private long mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS;
+ private long mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS;
+
+ /**
+ * Constructs Responder configuration from the builder
+ * @param builder See {@link Builder}
+ * @hide
+ */
+ public ResponderConfig(Builder builder) {
+ if (builder.mMacAddress == null && builder.mPeerHandle == null) {
+ throw new IllegalArgumentException(
+ "Invalid ResponderConfig - must specify a MAC address or Peer handle");
+ }
+ this.macAddress = builder.mMacAddress;
+ this.peerHandle = builder.mPeerHandle;
+ this.responderType = builder.mResponderType;
+ this.supports80211mc = builder.mSupports80211Mc;
+ this.supports80211azNtb = builder.mSupports80211azNtb;
+ this.channelWidth = builder.mChannelWidth;
+ this.frequency = builder.mFrequency;
+ this.centerFreq0 = builder.mCenterFreq0;
+ this.centerFreq1 = builder.mCenterFreq1;
+ this.preamble = builder.mPreamble;
+ this.mNtbMinMeasurementTime = builder.mNtbMinMeasurementTime;
+ this.mNtbMaxMeasurementTime = builder.mNtbMaxMeasurementTime;
+ }
+
/**
* Constructs Responder configuration, using a MAC address to identify the Responder.
*
@@ -289,6 +329,9 @@ public final class ResponderConfig implements Parcelable {
this.centerFreq0 = centerFreq0;
this.centerFreq1 = centerFreq1;
this.preamble = preamble;
+ this.supports80211azNtb = false;
+ this.mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS;
+ this.mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS;
}
/**
@@ -326,6 +369,9 @@ public final class ResponderConfig implements Parcelable {
this.centerFreq0 = centerFreq0;
this.centerFreq1 = centerFreq1;
this.preamble = preamble;
+ this.supports80211azNtb = false;
+ this.mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS;
+ this.mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS;
}
/**
@@ -367,6 +413,9 @@ public final class ResponderConfig implements Parcelable {
this.centerFreq0 = centerFreq0;
this.centerFreq1 = centerFreq1;
this.preamble = preamble;
+ this.supports80211azNtb = false;
+ this.mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS;
+ this.mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS;
}
/**
@@ -378,7 +427,8 @@ public final class ResponderConfig implements Parcelable {
MacAddress macAddress = MacAddress.fromString(scanResult.BSSID);
int responderType = RESPONDER_AP;
boolean supports80211mc = scanResult.is80211mcResponder();
- int channelWidth = translateFromScanResultToLocalChannelWidth(scanResult.channelWidth);
+ boolean supports80211azNtbRanging = scanResult.is80211azNtbResponder();
+ int channelWidth = scanResult.channelWidth;
int frequency = scanResult.frequency;
int centerFreq0 = scanResult.centerFreq0;
int centerFreq1 = scanResult.centerFreq1;
@@ -403,30 +453,39 @@ public final class ResponderConfig implements Parcelable {
}
if (ehtCapabilitiesPresent && ScanResult.is6GHz(frequency)) {
- preamble = PREAMBLE_EHT;
+ preamble = ScanResult.PREAMBLE_EHT;
} else if (heCapabilitiesPresent && ScanResult.is6GHz(frequency)) {
- preamble = PREAMBLE_HE;
+ preamble = ScanResult.PREAMBLE_HE;
} else if (vhtCapabilitiesPresent) {
- preamble = PREAMBLE_VHT;
+ preamble = ScanResult.PREAMBLE_VHT;
} else if (htCapabilitiesPresent) {
- preamble = PREAMBLE_HT;
+ preamble = ScanResult.PREAMBLE_HT;
} else {
- preamble = PREAMBLE_LEGACY;
+ preamble = ScanResult.PREAMBLE_LEGACY;
}
} else {
Log.e(TAG, "Scan Results do not contain IEs - using backup method to select preamble");
- if (channelWidth == CHANNEL_WIDTH_320MHZ) {
- preamble = PREAMBLE_EHT;
- } else if (channelWidth == CHANNEL_WIDTH_80MHZ
- || channelWidth == CHANNEL_WIDTH_160MHZ) {
- preamble = PREAMBLE_VHT;
+ if (channelWidth == ScanResult.CHANNEL_WIDTH_320MHZ) {
+ preamble = ScanResult.PREAMBLE_EHT;
+ } else if (channelWidth == ScanResult.CHANNEL_WIDTH_80MHZ
+ || channelWidth == ScanResult.CHANNEL_WIDTH_160MHZ) {
+ preamble = ScanResult.PREAMBLE_VHT;
} else {
- preamble = PREAMBLE_HT;
+ preamble = ScanResult.PREAMBLE_HT;
}
}
- return new ResponderConfig(macAddress, responderType, supports80211mc, channelWidth,
- frequency, centerFreq0, centerFreq1, preamble);
+ return new ResponderConfig.Builder()
+ .setMacAddress(macAddress)
+ .setResponderType(responderType)
+ .set80211mcSupported(supports80211mc)
+ .set80211azNtbSupported(supports80211azNtbRanging)
+ .setChannelWidth(channelWidth)
+ .setFrequencyMhz(frequency)
+ .setCenterFreq0Mhz(centerFreq0)
+ .setCenterFreq1Mhz(centerFreq1)
+ .setPreamble(preamble)
+ .build();
}
/**
@@ -443,8 +502,10 @@ public final class ResponderConfig implements Parcelable {
* (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware
* Unsolicited Publisher with Ranging enabled.
*/
- return new ResponderConfig(macAddress, RESPONDER_AWARE, true, CHANNEL_WIDTH_20MHZ,
- AWARE_BAND_2_DISCOVERY_CHANNEL, 0, 0, PREAMBLE_HT);
+ return new ResponderConfig.Builder()
+ .setMacAddress(macAddress)
+ .setResponderType(RESPONDER_AWARE)
+ .build();
}
/**
@@ -461,8 +522,24 @@ public final class ResponderConfig implements Parcelable {
* (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware
* Unsolicited Publisher with Ranging enabled.
*/
- return new ResponderConfig(peerHandle, RESPONDER_AWARE, true, CHANNEL_WIDTH_20MHZ,
- AWARE_BAND_2_DISCOVERY_CHANNEL, 0, 0, PREAMBLE_HT);
+ return new ResponderConfig.Builder()
+ .setPeerHandle(peerHandle)
+ .setResponderType(RESPONDER_AWARE)
+ .build();
+ }
+
+ private static boolean isResponderTypeSupported(@ResponderType int responderType) {
+ switch (responderType) {
+ case RESPONDER_AP:
+ case RESPONDER_STA:
+ case RESPONDER_AWARE:
+ break;
+ case RESPONDER_P2P_GO:
+ case RESPONDER_P2P_CLIENT:
+ default:
+ return false;
+ }
+ return true;
}
/**
@@ -473,6 +550,7 @@ public final class ResponderConfig implements Parcelable {
* @hide
*/
public boolean isValid(boolean awareSupported) {
+ if (!isResponderTypeSupported(responderType)) return false;
if (macAddress == null && peerHandle == null || macAddress != null && peerHandle != null) {
return false;
}
@@ -491,6 +569,16 @@ public final class ResponderConfig implements Parcelable {
}
/**
+ * @return the peer handle of the responder
+ *
+ * @hide
+ */
+ @Nullable
+ public PeerHandle getPeerHandle() {
+ return peerHandle;
+ }
+
+ /**
* @return true if the Responder supports the 802.11mc protocol, false otherwise.
*/
public boolean is80211mcSupported() {
@@ -498,6 +586,15 @@ public final class ResponderConfig implements Parcelable {
}
/**
+ * @return true if the Responder supports the 802.11az non-trigger based ranging protocol,
+ * false otherwise.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public boolean is80211azNtbSupported() {
+ return supports80211azNtb;
+ }
+
+ /**
* AP Channel bandwidth; one of {@link ScanResult#CHANNEL_WIDTH_20MHZ},
* {@link ScanResult#CHANNEL_WIDTH_40MHZ},
* {@link ScanResult#CHANNEL_WIDTH_80MHZ}, {@link ScanResult#CHANNEL_WIDTH_160MHZ},
@@ -559,17 +656,55 @@ public final class ResponderConfig implements Parcelable {
}
/**
+ * Gets the minimum time between IEEE 802.11az non-trigger based ranging measurements in
+ * microseconds for the responder.
+ *
+ * @hide
+ */
+ public long getNtbMinTimeBetweenMeasurementsMicros() {
+ return mNtbMinMeasurementTime;
+ }
+
+ /**
+ * Gets the maximum time between IEEE 802.11az non-trigger based ranging measurements in
+ * microseconds for the responder.
+ *
+ * @hide
+ */
+ public long getNtbMaxTimeBetweenMeasurementsMicros() {
+ return mNtbMaxMeasurementTime;
+ }
+
+ /**
+ * @hide
+ */
+ public void setNtbMinTimeBetweenMeasurementsMicros(long ntbMinMeasurementTime) {
+ this.mNtbMinMeasurementTime = ntbMinMeasurementTime;
+ }
+
+ /**
+ * @hide
+ */
+ public void setNtbMaxTimeBetweenMeasurementsMicros(long ntbMaxMeasurementTime) {
+ this.mNtbMaxMeasurementTime = ntbMaxMeasurementTime;
+ }
+
+ /**
* Builder class used to construct {@link ResponderConfig} objects.
*/
public static final class Builder {
private MacAddress mMacAddress;
+ private PeerHandle mPeerHandle;
private @ResponderType int mResponderType = RESPONDER_AP;
private boolean mSupports80211Mc = true;
+ private boolean mSupports80211azNtb = false;
private @ChannelWidth int mChannelWidth = CHANNEL_WIDTH_20MHZ;
private int mFrequency = 0;
private int mCenterFreq0 = 0;
private int mCenterFreq1 = 0;
private @PreambleType int mPreamble = PREAMBLE_LEGACY;
+ private long mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS;
+ private long mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS;
/**
* Sets the Responder MAC Address.
@@ -585,6 +720,20 @@ public final class ResponderConfig implements Parcelable {
}
/**
+ * Sets the Responder Peer handle.
+ *
+ * @param peerHandle Peer handle of the resposnde
+ * @return the builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ * @hide
+ */
+ @NonNull
+ public Builder setPeerHandle(@NonNull PeerHandle peerHandle) {
+ this.mPeerHandle = peerHandle;
+ return this;
+ }
+
+ /**
* Sets an indication the access point can to respond to the two-sided Wi-Fi RTT protocol,
* but, if false, indicates only one-sided Wi-Fi RTT is possible.
*
@@ -599,6 +748,23 @@ public final class ResponderConfig implements Parcelable {
}
/**
+ * Sets an indication the access point can to respond to the IEEE 802.11az non-trigger
+ * based ranging protocol, but, if false, indicates only IEEE 802.11mc or one-sided Wi-Fi
+ * RTT is possible.
+ *
+ * @param supports80211azNtb the ability to support the IEEE 802.11az non-trigger based
+ * ranging protocol
+ * @return the builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public Builder set80211azNtbSupported(boolean supports80211azNtb) {
+ this.mSupports80211azNtb = supports80211azNtb;
+ return this;
+ }
+
+ /**
* Sets the channel bandwidth in MHz.
*
* @param channelWidth the bandwidth of the channel in MHz
@@ -679,7 +845,8 @@ public final class ResponderConfig implements Parcelable {
}
/**
- * Sets the responder type, can be {@link #RESPONDER_AP} or {@link #RESPONDER_STA}
+ * Sets the responder type, can be {@link #RESPONDER_AP} or {@link #RESPONDER_STA} or
+ * {@link #RESPONDER_AWARE}
*
* @param responderType the type of the responder, if not set defaults to
* {@link #RESPONDER_AP}
@@ -687,25 +854,80 @@ public final class ResponderConfig implements Parcelable {
*/
@NonNull
public Builder setResponderType(@ResponderType int responderType) {
- if (responderType != RESPONDER_STA && responderType != RESPONDER_AP) {
- throw new IllegalArgumentException("invalid responder type");
+ if (!isResponderTypeSupported(responderType)) {
+ throw new IllegalArgumentException("invalid responder type " + responderType);
}
mResponderType = responderType;
return this;
}
/**
+ * Sets the minimum time between IEEE 802.11az non-trigger based ranging measurements in
+ * microseconds for the responder.
+ *
+ * Note: This should be a multiple of 100 microseconds as per IEEE 802.11 az standard.
+ *
+ * @param ntbMinMeasurementTime Minimum time between non-trigger based IEEE 802.11az
+ * ranging measurements in units of 100 microseconds. Range of
+ * values (0, 419430400).
+ * @hide
+ */
+ public Builder setNtbMinTimeBetweenMeasurementsMicros(long ntbMinMeasurementTime) {
+ if (mNtbMinMeasurementTime == 0 || mNtbMinMeasurementTime >= 419430400) {
+ throw new IllegalArgumentException(
+ "Should be a non-zero number less than 419430400 microseconds");
+ }
+ if (mNtbMinMeasurementTime % 100 != 0) {
+ throw new IllegalArgumentException("Should be a multiple of 100 microseconds");
+ }
+ mNtbMinMeasurementTime = ntbMinMeasurementTime;
+ return this;
+ }
+
+ /**
+ * Sets the maximum time between IEEE 802.11az non-trigger based ranging measurements in
+ * microseconds for the responder.
+ *
+ * Note: This should be a multiple of 10000 microseconds (10 milliseconds) as per
+ * IEEE 802.11 az standard.
+ *
+ * @param ntbMaxMeasurementTime Maximum time between non-trigger based IEEE 802.11az
+ * ranging measurements in units of 10000 microseconds. Range
+ * of values (0, 5242880000).
+ * @hide
+ */
+ public Builder setNtbMaxTimeBetweenMeasurementsMicros(long ntbMaxMeasurementTime) {
+ if (mNtbMaxMeasurementTime % 10000 != 0) {
+ throw new IllegalArgumentException("Should be a multiple of 10000 microseconds");
+ }
+ if (mNtbMaxMeasurementTime == 0 || mNtbMaxMeasurementTime >= 5242880000L) {
+ throw new IllegalArgumentException(
+ "Should be a non-zero number less than 5242880000 microseconds");
+ }
+ mNtbMaxMeasurementTime = ntbMaxMeasurementTime;
+ return this;
+ }
+
+ /**
* Build {@link ResponderConfig} given the current configurations made on the builder.
* @return an instance of {@link ResponderConfig}
*/
@NonNull
public ResponderConfig build() {
- if (mMacAddress == null) {
+ if ((mMacAddress == null && mPeerHandle == null)
+ || (mMacAddress != null && mPeerHandle != null)) {
throw new IllegalArgumentException(
- "Invalid ResponderConfig - must specify a MAC address");
+ "Invalid ResponderConfig - must specify a MAC address or peer handle but "
+ + "not both");
+ }
+ // For Aware, use supported default values
+ if (mResponderType == RESPONDER_AWARE) {
+ mSupports80211Mc = true;
+ mFrequency = AWARE_BAND_2_DISCOVERY_CHANNEL;
+ mChannelWidth = CHANNEL_WIDTH_20MHZ;
+ mPreamble = PREAMBLE_HT;
}
- return new ResponderConfig(mMacAddress, mResponderType, mSupports80211Mc, mChannelWidth,
- mFrequency, mCenterFreq0, mCenterFreq1, mPreamble);
+ return new ResponderConfig(this);
}
}
@@ -729,12 +951,15 @@ public final class ResponderConfig implements Parcelable {
dest.writeInt(peerHandle.peerId);
}
dest.writeInt(responderType);
- dest.writeInt(supports80211mc ? 1 : 0);
+ dest.writeBoolean(supports80211mc);
+ dest.writeBoolean(supports80211azNtb);
dest.writeInt(channelWidth);
dest.writeInt(frequency);
dest.writeInt(centerFreq0);
dest.writeInt(centerFreq1);
dest.writeInt(preamble);
+ dest.writeLong(mNtbMinMeasurementTime);
+ dest.writeLong(mNtbMaxMeasurementTime);
}
public static final @android.annotation.NonNull Creator<ResponderConfig> CREATOR = new Creator<ResponderConfig>() {
@@ -755,21 +980,21 @@ public final class ResponderConfig implements Parcelable {
if (peerHandlePresent) {
peerHandle = new PeerHandle(in.readInt());
}
- int responderType = in.readInt();
- boolean supports80211mc = in.readInt() == 1;
- int channelWidth = in.readInt();
- int frequency = in.readInt();
- int centerFreq0 = in.readInt();
- int centerFreq1 = in.readInt();
- int preamble = in.readInt();
-
- if (peerHandle == null) {
- return new ResponderConfig(macAddress, responderType, supports80211mc, channelWidth,
- frequency, centerFreq0, centerFreq1, preamble);
- } else {
- return new ResponderConfig(peerHandle, responderType, supports80211mc, channelWidth,
- frequency, centerFreq0, centerFreq1, preamble);
- }
+
+ return new ResponderConfig.Builder()
+ .setMacAddress(macAddress)
+ .setPeerHandle(peerHandle)
+ .setResponderType(in.readInt())
+ .set80211mcSupported(in.readBoolean())
+ .set80211azNtbSupported(in.readBoolean())
+ .setChannelWidth(in.readInt())
+ .setFrequencyMhz(in.readInt())
+ .setCenterFreq0Mhz(in.readInt())
+ .setCenterFreq1Mhz(in.readInt())
+ .setPreamble(in.readInt())
+ .setNtbMinTimeBetweenMeasurementsMicros(in.readLong())
+ .setNtbMaxTimeBetweenMeasurementsMicros(in.readLong())
+ .build();
}
};
@@ -789,24 +1014,34 @@ public final class ResponderConfig implements Parcelable {
lhs.peerHandle) && responderType == lhs.responderType
&& supports80211mc == lhs.supports80211mc && channelWidth == lhs.channelWidth
&& frequency == lhs.frequency && centerFreq0 == lhs.centerFreq0
- && centerFreq1 == lhs.centerFreq1 && preamble == lhs.preamble;
+ && centerFreq1 == lhs.centerFreq1 && preamble == lhs.preamble
+ && supports80211azNtb == lhs.supports80211azNtb
+ && mNtbMinMeasurementTime == lhs.mNtbMinMeasurementTime
+ && mNtbMaxMeasurementTime == lhs.mNtbMaxMeasurementTime;
}
@Override
public int hashCode() {
return Objects.hash(macAddress, peerHandle, responderType, supports80211mc, channelWidth,
- frequency, centerFreq0, centerFreq1, preamble);
+ frequency, centerFreq0, centerFreq1, preamble, supports80211azNtb,
+ mNtbMinMeasurementTime, mNtbMaxMeasurementTime);
}
@Override
public String toString() {
- return new StringBuffer("ResponderConfig: macAddress=").append(macAddress).append(
- ", peerHandle=").append(peerHandle == null ? "<null>" : peerHandle.peerId).append(
- ", responderType=").append(responderType).append(", supports80211mc=").append(
- supports80211mc).append(", channelWidth=").append(channelWidth).append(
- ", frequency=").append(frequency).append(", centerFreq0=").append(
- centerFreq0).append(", centerFreq1=").append(centerFreq1).append(
- ", preamble=").append(preamble).toString();
+ return new StringBuffer("ResponderConfig: macAddress=").append(macAddress)
+ .append(", peerHandle=").append(peerHandle == null ? "<null>" : peerHandle.peerId)
+ .append(", responderType=").append(responderType)
+ .append(", supports80211mc=").append(supports80211mc)
+ .append(", channelWidth=").append(channelWidth)
+ .append(", frequency=").append(frequency)
+ .append(", centerFreq0=").append(centerFreq0)
+ .append(", centerFreq1=").append(centerFreq1)
+ .append(", preamble=").append(preamble)
+ .append(", supports80211azNtb=").append(supports80211azNtb)
+ .append(", mNtbMinMeasurementTime ").append(mNtbMinMeasurementTime)
+ .append(", mNtbMaxMeasurementTime ").append(mNtbMaxMeasurementTime)
+ .toString();
}
/**
diff --git a/framework/java/android/net/wifi/rtt/WifiRttManager.java b/framework/java/android/net/wifi/rtt/WifiRttManager.java
index 69bf608f9b..f86eaa4382 100644
--- a/framework/java/android/net/wifi/rtt/WifiRttManager.java
+++ b/framework/java/android/net/wifi/rtt/WifiRttManager.java
@@ -23,6 +23,7 @@ import static android.Manifest.permission.LOCATION_HARDWARE;
import static android.Manifest.permission.NEARBY_WIFI_DEVICES;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -40,6 +41,7 @@ import android.os.WorkSource;
import android.util.Log;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -108,12 +110,19 @@ public class WifiRttManager {
*/
public static final String CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER = "key_sta_responder";
+ /**
+ * Bundle key to access if device supports to be a IEEE 802.11az non-trigger based initiator
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final String CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR = "key_ntb_initiator";
+
/** @hide */
@StringDef(prefix = { "CHARACTERISTICS_KEY_"}, value = {
CHARACTERISTICS_KEY_BOOLEAN_ONE_SIDED_RTT,
CHARACTERISTICS_KEY_BOOLEAN_LCI,
CHARACTERISTICS_KEY_BOOLEAN_LCR,
CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER,
+ CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR,
})
@Retention(RetentionPolicy.SOURCE)
public @interface RttCharacteristicsKey {}
diff --git a/framework/java/android/net/wifi/twt/TwtRequest.java b/framework/java/android/net/wifi/twt/TwtRequest.java
new file mode 100644
index 0000000000..6bad0168d6
--- /dev/null
+++ b/framework/java/android/net/wifi/twt/TwtRequest.java
@@ -0,0 +1,213 @@
+/*
+ * 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 android.net.wifi.twt;
+
+import static android.net.wifi.MloLink.INVALID_MLO_LINK_ID;
+import static android.net.wifi.MloLink.MAX_MLO_LINK_ID;
+import static android.net.wifi.MloLink.MIN_MLO_LINK_ID;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.wifi.MloLink;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.wifi.flags.Flags;
+
+/**
+ * Defines target wake time (TWT) request class.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+public final class TwtRequest implements Parcelable {
+ private final int mMinWakeDurationMicros;
+ private final int mMaxWakeDurationMicros;
+ private final long mMinWakeIntervalMicros;
+ private final long mMaxWakeIntervalMicros;
+ private final int mLinkId;
+
+ private TwtRequest(TwtRequest.Builder builder) {
+ mMinWakeDurationMicros = builder.mMinWakeDurationMicros;
+ mMaxWakeDurationMicros = builder.mMaxWakeDurationMicros;
+ mMinWakeIntervalMicros = builder.mMinWakeIntervalMicros;
+ mMaxWakeIntervalMicros = builder.mMaxWakeIntervalMicros;
+ mLinkId = builder.mLinkId;
+ }
+
+ /**
+ * Get minimum TWT wake duration in microseconds.
+ *
+ * @return Minimum wake duration in microseconds
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int getMinWakeDurationMicros() {
+ return mMinWakeDurationMicros;
+ }
+
+ /**
+ * Get maximum TWT wake duration in microseconds.
+ *
+ * @return Maximum wake duration in microseconds
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int getMaxWakeDurationMicros() {
+ return mMaxWakeDurationMicros;
+ }
+
+ /**
+ * Get minimum TWT wake interval in microseconds.
+ *
+ * @return Minimum wake interval in microseconds
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public long getMinWakeIntervalMicros() {
+ return mMinWakeIntervalMicros;
+ }
+
+ /**
+ * Get maximum TWT wake interval in microseconds.
+ *
+ * @return Maximum wake interval in microseconds
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public long getMaxWakeIntervalMicros() {
+ return mMaxWakeIntervalMicros;
+ }
+
+
+ /**
+ * Get link id (valid only in case of Multi-link operation).
+ *
+ * @return MLO link id in the range {@link MloLink#MIN_MLO_LINK_ID} to
+ * {@link MloLink#MAX_MLO_LINK_ID}. Returns {@link MloLink#INVALID_MLO_LINK_ID} if not set.
+ */
+ @IntRange(from = INVALID_MLO_LINK_ID, to = MAX_MLO_LINK_ID)
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public int getLinkId() {
+ return mLinkId;
+ }
+
+ @NonNull
+ public static final Creator<TwtRequest> CREATOR = new Creator<TwtRequest>() {
+ @Override
+ public TwtRequest createFromParcel(Parcel in) {
+ Builder builder = new TwtRequest.Builder(in.readInt(), in.readInt(), in.readLong(),
+ in.readLong());
+ int mloLinkId = in.readInt();
+ if (mloLinkId >= MIN_MLO_LINK_ID && mloLinkId <= MAX_MLO_LINK_ID) {
+ builder.setLinkId(mloLinkId);
+ }
+ return builder.build();
+ }
+
+ @Override
+ public TwtRequest[] newArray(int size) {
+ return new TwtRequest[size];
+ }
+ };
+
+
+ /**
+ * Describe the kinds of special objects contained in this Parcelable
+ * instance's marshaled representation.
+ *
+ * @return a bitmask indicating the set of special object types marshaled
+ * by this Parcelable object instance.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mMinWakeDurationMicros);
+ dest.writeInt(mMaxWakeDurationMicros);
+ dest.writeLong(mMinWakeIntervalMicros);
+ dest.writeLong(mMinWakeIntervalMicros);
+ dest.writeInt(mLinkId);
+ }
+
+ /**
+ * Builder class used to construct {@link TwtRequest} objects.
+ *
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public static final class Builder {
+ private final int mMinWakeDurationMicros;
+ private final int mMaxWakeDurationMicros;
+ private final long mMinWakeIntervalMicros;
+ private final long mMaxWakeIntervalMicros;
+ private int mLinkId = INVALID_MLO_LINK_ID;
+
+ /**
+ * Set link id (valid only in case of Multi-link operation).
+ *
+ * @param linkId Link id, which should be in the range {@link MloLink#MIN_MLO_LINK_ID} to
+ * {@link MloLink#MAX_MLO_LINK_ID}
+ * @return The builder to facilitate chaining
+ * @throws IllegalArgumentException if argument is invalid
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public TwtRequest.Builder setLinkId(
+ @IntRange(from = MIN_MLO_LINK_ID, to = MAX_MLO_LINK_ID) int linkId) {
+ if (linkId < MIN_MLO_LINK_ID || linkId > MAX_MLO_LINK_ID) {
+ throw new IllegalArgumentException("linkId is out of range");
+ }
+ mLinkId = linkId;
+ return this;
+ }
+
+ /**
+ * Constructor for {@link TwtRequest.Builder}.
+ *
+ * @param minWakeDurationMicros Minimum TWT wake duration in microseconds.
+ * @param maxWakeDurationMicros Maximum TWT wake duration in microseconds
+ * @param minWakeIntervalMicros Minimum TWT wake interval in microseconds
+ * @param maxWakeIntervalMicros Maximum TWT wake interval in microseconds
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ public Builder(int minWakeDurationMicros, int maxWakeDurationMicros,
+ long minWakeIntervalMicros, long maxWakeIntervalMicros) {
+ mMinWakeDurationMicros = minWakeDurationMicros;
+ mMaxWakeDurationMicros = maxWakeDurationMicros;
+ mMinWakeIntervalMicros = minWakeIntervalMicros;
+ mMaxWakeIntervalMicros = maxWakeIntervalMicros;
+ }
+
+ /**
+ * Build {@link TwtRequest} given the current configurations made on the builder.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ @NonNull
+ public TwtRequest build() {
+ return new TwtRequest(this);
+ }
+ }
+}
diff --git a/framework/java/android/net/wifi/twt/TwtSession.java b/framework/java/android/net/wifi/twt/TwtSession.java
new file mode 100644
index 0000000000..7c7f2a3127
--- /dev/null
+++ b/framework/java/android/net/wifi/twt/TwtSession.java
@@ -0,0 +1,126 @@
+/*
+ * 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 android.net.wifi.twt;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.StringDef;
+import android.annotation.SystemApi;
+import android.os.Bundle;
+
+import com.android.wifi.flags.Flags;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Defines a target wake time (TWT) session.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+public interface TwtSession {
+ /**
+ * Bundle key to get average number of received packets in each wake duration
+ */
+ String TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_COUNT = "key_avg_rx_pkt_count";
+ /**
+ * Bundle key to get average number of transmitted packets in each wake duration
+ */
+ String TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_COUNT = "key_avg_tx_pkt_count";
+ /**
+ * Bundle key to get average bytes per received packets in each wake duration
+ */
+ String TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_SIZE = "key_avg_rx_pkt_size";
+ /**
+ * Bundle key to get average bytes per transmitted packets in each wake duration
+ */
+ String TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_SIZE = "key_avg_tx_pkt_size";
+ /**
+ * Bundle key to get average end of service period in microseconds
+ */
+ String TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS = "key_avg_eosp_dur";
+ /**
+ * Bundle key to get count of early termination. Value will be -1 if not available.
+ */
+ String TWT_STATS_KEY_INT_EOSP_COUNT = "key_eosp_count";
+
+ /** @hide */
+ @StringDef(prefix = { "TWT_STATS_KEY_"}, value = {
+ TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_COUNT,
+ TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_COUNT,
+ TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_SIZE,
+ TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_SIZE,
+ TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS,
+ TWT_STATS_KEY_INT_EOSP_COUNT
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface TwtStats {}
+ /**
+ * Get TWT session wake duration in microseconds.
+ *
+ * @return wake duration in microseconds.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ int getWakeDurationMicros();
+
+ /**
+ * Get TWT session wake interval in microseconds.
+ *
+ * @return wake interval in microseconds.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ long getWakeIntervalMicros();
+
+ /**
+ * Get MLO link id if the station connection is Wi-Fi 7, otherwise returns
+ * {@link android.net.wifi.MloLink#INVALID_MLO_LINK_ID}.
+ *
+ * @return MLO link id
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ int getMloLinkId();
+
+ /**
+ * Get stats of the session.
+ *
+ * Note: If the command fails or not available, -1 will be returned for all stats values.
+ *
+ * @param executor The executor on which callback will be invoked.
+ * @param resultCallback An asynchronous callback that will return a bundle for target wake time
+ * stats. See {@link TwtStats} for the string keys for the bundle.
+ * @throws SecurityException if the caller does not have permission.
+ * @throws NullPointerException if the caller provided null inputs.
+ * @throws UnsupportedOperationException if the API is not supported.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ void getStats(@NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<Bundle> resultCallback);
+
+ /**
+ * Teardown the session. See {@link TwtSessionCallback#onTeardown(int)}. Also closes this
+ * session, relinquishing any underlying resources.
+ *
+ * @throws SecurityException if the caller does not have permission.
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ void teardown();
+}
diff --git a/framework/java/android/net/wifi/twt/TwtSessionCallback.java b/framework/java/android/net/wifi/twt/TwtSessionCallback.java
new file mode 100644
index 0000000000..6efedd6cd2
--- /dev/null
+++ b/framework/java/android/net/wifi/twt/TwtSessionCallback.java
@@ -0,0 +1,137 @@
+/*
+ * 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 android.net.wifi.twt;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+import com.android.wifi.flags.Flags;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * API interface for target wake time (TWT) session Callback.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+public interface TwtSessionCallback {
+ /**
+ * Generic error
+ */
+ int TWT_ERROR_CODE_FAIL = 0;
+ /**
+ * AP does not support TWT
+ */
+ int TWT_ERROR_CODE_AP_NOT_SUPPORTED = 1;
+ /**
+ * AP is blocklisted due to interoperability issue reported with TWT
+ */
+ int TWT_ERROR_CODE_AP_OUI_BLOCKLISTED = 2;
+ /**
+ * AP rejects TWT request
+ */
+ int TWT_ERROR_CODE_AP_REJECTED = 3;
+ /**
+ * Invalid parameters
+ */
+ int TWT_ERROR_CODE_INVALID_PARAMS = 4;
+ /**
+ * Maximum TWT sessions reached
+ */
+ int TWT_ERROR_CODE_MAX_SESSIONS_REACHED = 5;
+ /**
+ * TWT is not available now
+ */
+ int TWT_ERROR_CODE_NOT_AVAILABLE = 6;
+ /**
+ * TWT is not supported by the local device
+ */
+ int TWT_ERROR_CODE_NOT_SUPPORTED = 7;
+ /**
+ * TWT operation Timed out
+ */
+ int TWT_ERROR_CODE_TIMEOUT = 8;
+
+ /**
+ * @hide
+ */
+ @IntDef(prefix = {"TWT_ERROR_CODE_"}, value = {TWT_ERROR_CODE_FAIL,
+ TWT_ERROR_CODE_AP_NOT_SUPPORTED, TWT_ERROR_CODE_AP_OUI_BLOCKLISTED,
+ TWT_ERROR_CODE_AP_REJECTED, TWT_ERROR_CODE_INVALID_PARAMS,
+ TWT_ERROR_CODE_MAX_SESSIONS_REACHED, TWT_ERROR_CODE_NOT_AVAILABLE,
+ TWT_ERROR_CODE_NOT_SUPPORTED, TWT_ERROR_CODE_TIMEOUT})
+ @Retention(RetentionPolicy.SOURCE)
+ @interface TwtErrorCode {
+ }
+
+ /**
+ * Unknown reason code
+ */
+ int TWT_REASON_CODE_UNKNOWN = 0;
+ /**
+ * Locally requested
+ */
+ int TWT_REASON_CODE_LOCALLY_REQUESTED = 1;
+ /**
+ * Internally initiated by the driver or firmware
+ */
+ int TWT_REASON_CODE_INTERNALLY_INITIATED = 2;
+ /**
+ * Peer initiated
+ */
+ int TWT_REASON_CODE_PEER_INITIATED = 3;
+
+ /**
+ * @hide
+ */
+ @IntDef(prefix = {"TWT_REASON_CODE_"}, value = {TWT_REASON_CODE_UNKNOWN,
+ TWT_REASON_CODE_LOCALLY_REQUESTED, TWT_REASON_CODE_INTERNALLY_INITIATED,
+ TWT_REASON_CODE_PEER_INITIATED})
+ @Retention(RetentionPolicy.SOURCE)
+ @interface TwtReasonCode {
+ }
+
+ /**
+ * Called when a TWT operation fails.
+ *
+ * @param errorCode error code
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ void onFailure(@TwtSessionCallback.TwtErrorCode int errorCode);
+
+ /**
+ * Called when a TWT session is torn down or closed. Check the
+ * {@link TwtReasonCode} for more details.
+ *
+ * @param reasonCode reason for TWT session teardown
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ void onTeardown(@TwtSessionCallback.TwtReasonCode int reasonCode);
+
+ /**
+ * Called when the TWT session is created.
+ *
+ * @param twtSession TWT session
+ */
+ @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
+ void onCreate(@NonNull TwtSession twtSession);
+}
diff --git a/framework/tests/src/android/net/wifi/MscsParamsTest.java b/framework/tests/src/android/net/wifi/MscsParamsTest.java
new file mode 100644
index 0000000000..701511abde
--- /dev/null
+++ b/framework/tests/src/android/net/wifi/MscsParamsTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2023 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 android.net.wifi;
+
+import static org.junit.Assert.assertEquals;
+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 {
+ private static final int TEST_FRAME_CLASSIFIER_FIELDS =
+ MscsParams.FRAME_CLASSIFIER_IP_VERSION | MscsParams.FRAME_CLASSIFIER_SRC_PORT;
+ private static final int TEST_USER_PRIORITY_BITMAP = 1 << 7;
+ 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()
+ .setFrameClassifierFields(TEST_FRAME_CLASSIFIER_FIELDS)
+ .setUserPriorityBitmap(TEST_USER_PRIORITY_BITMAP)
+ .setUserPriorityLimit(TEST_USER_PRIORITY_LIMIT)
+ .setStreamTimeoutUs(TEST_STREAM_TIMEOUT_US)
+ .build();
+ }
+
+ /** Test that an exception is thrown when invalid values are provided to the builder. */
+ @Test
+ public void testBuilderInvalid() {
+ MscsParams.Builder builder = new MscsParams.Builder();
+
+ // Bitmap arguments can only use bits 0 - 7.
+ assertThrows(IllegalArgumentException.class,
+ () -> builder.setFrameClassifierFields(1 << 8));
+ assertThrows(IllegalArgumentException.class,
+ () -> builder.setUserPriorityBitmap(1 << 8));
+
+ // User priority limit must be between 0 - 7 (inclusive)
+ assertThrows(IllegalArgumentException.class,
+ () -> builder.setUserPriorityLimit(-1));
+ assertThrows(IllegalArgumentException.class,
+ () -> builder.setUserPriorityLimit(8));
+
+ // Stream timeout value must be between 0 - 60 seconds.
+ assertThrows(IllegalArgumentException.class,
+ () -> builder.setStreamTimeoutUs(-1));
+ assertThrows(IllegalArgumentException.class,
+ () -> builder.setStreamTimeoutUs(MscsParams.MAX_STREAM_TIMEOUT_US + 1));
+ }
+
+ /**
+ * Tests that the builder works as expected when provided valid values.
+ * Fields that are unset should be assigned their default value.
+ */
+ @Test
+ public void testBuilderValid() {
+ MscsParams params = new MscsParams.Builder()
+ .setFrameClassifierFields(TEST_FRAME_CLASSIFIER_FIELDS)
+ .setUserPriorityLimit(TEST_USER_PRIORITY_LIMIT)
+ .build();
+ assertEquals(TEST_FRAME_CLASSIFIER_FIELDS, params.getFrameClassifierFields());
+ assertEquals(TEST_USER_PRIORITY_LIMIT, params.getUserPriorityLimit());
+
+ // Fields that were not explicitly assigned should be given a default value.
+ assertEquals(MscsParams.DEFAULT_USER_PRIORITY_BITMAP, params.getUserPriorityBitmap());
+ assertEquals(MscsParams.MAX_STREAM_TIMEOUT_US, params.getStreamTimeoutUs());
+ }
+
+ /**
+ * Tests that all fields are assigned a default value if they are not explicitly
+ * assigned in the builder.
+ */
+ @Test
+ public void testBuilderDefaultValues() {
+ MscsParams params = new MscsParams.Builder().build();
+ assertEquals(MscsParams.DEFAULT_FRAME_CLASSIFIER_FIELDS, params.getFrameClassifierFields());
+ assertEquals(MscsParams.DEFAULT_USER_PRIORITY_BITMAP, params.getUserPriorityBitmap());
+ assertEquals(MscsParams.DEFAULT_USER_PRIORITY_LIMIT, params.getUserPriorityLimit());
+ assertEquals(MscsParams.MAX_STREAM_TIMEOUT_US, params.getStreamTimeoutUs());
+ }
+
+ /** Tests that this class can be properly parceled and unparceled. */
+ @Test
+ public void testParcelReadWrite() {
+ MscsParams params = createTestMscsParams();
+ Parcel parcel = Parcel.obtain();
+ params.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
+ MscsParams unparceledParams = MscsParams.CREATOR.createFromParcel(parcel);
+ assertTrue(unparceledParams.equals(params));
+ }
+
+ /** Tests the equality and hashcode operations on equivalent instances. */
+ @Test
+ public void testSameObjectComparison() {
+ MscsParams params1 = createTestMscsParams();
+ MscsParams params2 = createTestMscsParams();
+ assertTrue(params1.equals(params2));
+ assertEquals(params1.hashCode(), params2.hashCode());
+ }
+
+ /** Tests the equality and hashcode operations on different instances. */
+ @Test
+ public void testDifferentObjectComparison() {
+ MscsParams testParams = createTestMscsParams();
+ MscsParams defaultParams = new MscsParams.Builder().build();
+ assertFalse(testParams.equals(defaultParams));
+ assertNotEquals(testParams.hashCode(), defaultParams.hashCode());
+ }
+}
diff --git a/framework/tests/src/android/net/wifi/OuiKeyedDataUtil.java b/framework/tests/src/android/net/wifi/OuiKeyedDataUtil.java
new file mode 100644
index 0000000000..1fe0d32f86
--- /dev/null
+++ b/framework/tests/src/android/net/wifi/OuiKeyedDataUtil.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 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 android.net.wifi;
+
+import android.os.PersistableBundle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Test utils for {@link OuiKeyedData} */
+public class OuiKeyedDataUtil {
+ private static final String STRING_FIELD_KEY = "stringField";
+ private static final String ARRAY_FIELD_KEY = "arrayField";
+
+ private static final String STRING_FIELD_VALUE = "someString";
+ private static final int[] ARRAY_FIELD_VALUE = new int[] {1, 2, 3};
+
+ /**
+ * Generate a single OuiKeyedData object containing several test fields.
+ */
+ public static OuiKeyedData createTestOuiKeyedData(int oui) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putString(STRING_FIELD_KEY, STRING_FIELD_VALUE);
+ bundle.putIntArray(ARRAY_FIELD_KEY, ARRAY_FIELD_VALUE);
+ return new OuiKeyedData.Builder(oui, bundle).build();
+ }
+
+ /**
+ * Generate a list of OuiKeyedData objects, each containing several test fields.
+ */
+ public static List<OuiKeyedData> createTestOuiKeyedDataList(int size) {
+ List<OuiKeyedData> ouiKeyedDataList = new ArrayList<>();
+ for (int i = 0; i < size; i++) {
+ ouiKeyedDataList.add(createTestOuiKeyedData(i + 1));
+ }
+ return ouiKeyedDataList;
+ }
+}
diff --git a/framework/tests/src/android/net/wifi/QosCharacteristicsTest.java b/framework/tests/src/android/net/wifi/QosCharacteristicsTest.java
new file mode 100644
index 0000000000..4876fc18c6
--- /dev/null
+++ b/framework/tests/src/android/net/wifi/QosCharacteristicsTest.java
@@ -0,0 +1,282 @@
+/*
+ * 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 android.net.wifi;
+
+import static android.net.wifi.QosCharacteristics.DELIVERY_RATIO_95;
+import static android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_9999;
+
+import static junit.framework.Assert.assertFalse;
+
+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 {
+ private static final int TEST_MIN_SERVICE_INTERVAL_MICROS = 2000;
+ private static final int TEST_MAX_SERVICE_INTERVAL_MICROS = 5000;
+ private static final int TEST_MIN_DATA_RATE_KBPS = 500;
+ private static final int TEST_BURST_SIZE_OCTETS = 2;
+ private static final int TEST_DELAY_BOUND_MICROS = 200;
+ private static final int TEST_MAX_MSDU_SIZE_OCTETS = 4;
+ private static final int TEST_SERVICE_START_TIME_MICROS = 250;
+ private static final int TEST_SERVICE_START_TIME_LINK_ID = 0x5;
+ private static final int TEST_MEAN_DATA_RATE_KBPS = 1500;
+ private static final int TEST_MSDU_LIFETIME_MILLIS = 400;
+ 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.
+ */
+ private static QosCharacteristics.Builder getDefaultBuilder() {
+ return new QosCharacteristics.Builder(
+ TEST_MIN_SERVICE_INTERVAL_MICROS, TEST_MAX_SERVICE_INTERVAL_MICROS,
+ TEST_MIN_DATA_RATE_KBPS, TEST_DELAY_BOUND_MICROS);
+ }
+
+ /**
+ * Get a QosCharacteristics with all fields set to the default test values.
+ */
+ private static QosCharacteristics getDefaultQosCharacteristics() {
+ return getDefaultBuilder()
+ .setMaxMsduSizeOctets(TEST_MAX_MSDU_SIZE_OCTETS)
+ .setServiceStartTimeInfo(
+ TEST_SERVICE_START_TIME_MICROS, TEST_SERVICE_START_TIME_LINK_ID)
+ .setMeanDataRateKbps(TEST_MEAN_DATA_RATE_KBPS)
+ .setBurstSizeOctets(TEST_BURST_SIZE_OCTETS)
+ .setMsduLifetimeMillis(TEST_MSDU_LIFETIME_MILLIS)
+ .setMsduDeliveryInfo(TEST_DELIVERY_RATIO, TEST_COUNT_EXPONENT)
+ .build();
+ }
+
+ /**
+ * Verify that all fields in the QosCharacteristics object contain the default test values.
+ */
+ private static void validateDefaultFields(QosCharacteristics qosCharacteristics) {
+ assertEquals(TEST_MIN_SERVICE_INTERVAL_MICROS,
+ qosCharacteristics.getMinServiceIntervalMicros());
+ assertEquals(TEST_MAX_SERVICE_INTERVAL_MICROS,
+ qosCharacteristics.getMaxServiceIntervalMicros());
+ assertEquals(TEST_MIN_DATA_RATE_KBPS, qosCharacteristics.getMinDataRateKbps());
+ assertEquals(TEST_DELAY_BOUND_MICROS, qosCharacteristics.getDelayBoundMicros());
+
+ assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.MAX_MSDU_SIZE));
+ assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.SERVICE_START_TIME));
+ assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.MEAN_DATA_RATE));
+ assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.BURST_SIZE));
+ assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.MSDU_LIFETIME));
+ assertTrue(qosCharacteristics.containsOptionalField(QosCharacteristics.MSDU_DELIVERY_INFO));
+
+ assertEquals(TEST_MAX_MSDU_SIZE_OCTETS, qosCharacteristics.getMaxMsduSizeOctets());
+ assertEquals(TEST_SERVICE_START_TIME_MICROS,
+ qosCharacteristics.getServiceStartTimeMicros());
+ assertEquals(TEST_SERVICE_START_TIME_LINK_ID,
+ qosCharacteristics.getServiceStartTimeLinkId());
+ assertEquals(TEST_MEAN_DATA_RATE_KBPS, qosCharacteristics.getMeanDataRateKbps());
+ assertEquals(TEST_BURST_SIZE_OCTETS, qosCharacteristics.getBurstSizeOctets());
+ assertEquals(TEST_MSDU_LIFETIME_MILLIS, qosCharacteristics.getMsduLifetimeMillis());
+ assertEquals(TEST_DELIVERY_RATIO, qosCharacteristics.getDeliveryRatio());
+ assertEquals(TEST_COUNT_EXPONENT, qosCharacteristics.getCountExponent());
+ }
+
+ /**
+ * Test that the builder works correctly when provided valid values.
+ */
+ @Test
+ public void testBuilderValid() {
+ QosCharacteristics qosCharacteristics = getDefaultQosCharacteristics();
+ validateDefaultFields(qosCharacteristics);
+ }
+
+ /**
+ * Test that an exception is thrown if any of the mandatory fields are assigned an
+ * invalid value.
+ */
+ @Test
+ public void testMandatoryFieldsInvalid() {
+ // All mandatory fields must be positive.
+ assertThrows(IllegalArgumentException.class, () ->
+ new QosCharacteristics.Builder(
+ 0, TEST_MAX_SERVICE_INTERVAL_MICROS,
+ TEST_MIN_DATA_RATE_KBPS, TEST_DELAY_BOUND_MICROS).build());
+ assertThrows(IllegalArgumentException.class, () ->
+ new QosCharacteristics.Builder(
+ TEST_MIN_SERVICE_INTERVAL_MICROS, 0,
+ TEST_MIN_DATA_RATE_KBPS, TEST_DELAY_BOUND_MICROS).build());
+ assertThrows(IllegalArgumentException.class, () ->
+ new QosCharacteristics.Builder(
+ TEST_MIN_SERVICE_INTERVAL_MICROS, TEST_MAX_SERVICE_INTERVAL_MICROS,
+ 0, TEST_DELAY_BOUND_MICROS).build());
+ assertThrows(IllegalArgumentException.class, () ->
+ new QosCharacteristics.Builder(
+ TEST_MIN_SERVICE_INTERVAL_MICROS, TEST_MAX_SERVICE_INTERVAL_MICROS,
+ TEST_MIN_DATA_RATE_KBPS, 0).build());
+
+ // Min service interval must be less than or equal to the max service interval.
+ assertThrows(IllegalArgumentException.class, () ->
+ new QosCharacteristics.Builder(
+ 5000 /* minServiceInterval */, 3000 /* maxServiceInterval */,
+ TEST_MIN_DATA_RATE_KBPS, 0).build());
+ }
+
+ /**
+ * Test that an exception is thrown if any optional values that expect a positive value
+ * are assigned a zero value.
+ */
+ @Test
+ public void testOptionalFieldsInvalid_zeroValue() {
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder().setMaxMsduSizeOctets(0).build());
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder().setMeanDataRateKbps(0).build());
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder().setBurstSizeOctets(0).build());
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder().setMsduLifetimeMillis(0).build());
+ }
+
+ /**
+ * Test that an exception is thrown if any optional values that expect a <32-bit value are
+ * assigned a value that exceeds the expected bit size.
+ */
+ @Test
+ public void testOptionalFieldsInvalid_exceedUpperBound() {
+ // Expects 16-bit value
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder().setMaxMsduSizeOctets(0x1FFFF).build());
+
+ // Expects 16-bit value
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder().setMsduLifetimeMillis(0x1FFFF).build());
+
+ // Expects 4-bit link ID
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder()
+ .setServiceStartTimeInfo(TEST_SERVICE_START_TIME_MICROS, 0x1F).build());
+ }
+
+ /**
+ * Test that an exception is thrown if any additional constraints on the optional fields
+ * are broken.
+ */
+ @Test
+ public void testOptionalFieldsInvalid_additionalConstraints() {
+ // MSDU lifetime should be >= the delay bound
+ int delayBoundUs = 30_000; // 30 ms
+ int msduLifetimeMs = 20;
+ assertThrows(IllegalArgumentException.class, () ->
+ new QosCharacteristics.Builder(
+ TEST_MIN_SERVICE_INTERVAL_MICROS, TEST_MAX_SERVICE_INTERVAL_MICROS,
+ TEST_MIN_DATA_RATE_KBPS, delayBoundUs)
+ .setMsduLifetimeMillis(msduLifetimeMs)
+ .build());
+
+ // MSDU delivery ratio should be a valid enum
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder()
+ .setMsduDeliveryInfo(DELIVERY_RATIO_95 - 1, TEST_COUNT_EXPONENT)
+ .build());
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder()
+ .setMsduDeliveryInfo(DELIVERY_RATIO_99_9999 + 1, TEST_COUNT_EXPONENT)
+ .build());
+
+ // MSDU count exponent should be between 0 and 15 (inclusive)
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder()
+ .setMsduDeliveryInfo(TEST_DELIVERY_RATIO, -1)
+ .build());
+ assertThrows(IllegalArgumentException.class, () ->
+ getDefaultBuilder()
+ .setMsduDeliveryInfo(TEST_DELIVERY_RATIO, 16)
+ .build());
+ }
+
+ /**
+ * Test that an exception is thrown if the caller attempts to get an optional field
+ * that was not assigned a value.
+ */
+ @Test
+ public void testOptionalFields_unsetException() {
+ assertThrows(IllegalStateException.class, () ->
+ getDefaultBuilder().build().getMaxMsduSizeOctets());
+ assertThrows(IllegalStateException.class, () ->
+ getDefaultBuilder().build().getServiceStartTimeMicros());
+ assertThrows(IllegalStateException.class, () ->
+ getDefaultBuilder().build().getServiceStartTimeLinkId());
+ assertThrows(IllegalStateException.class, () ->
+ getDefaultBuilder().build().getMeanDataRateKbps());
+ assertThrows(IllegalStateException.class, () ->
+ getDefaultBuilder().build().getBurstSizeOctets());
+ assertThrows(IllegalStateException.class, () ->
+ getDefaultBuilder().build().getMsduLifetimeMillis());
+ assertThrows(IllegalStateException.class, () ->
+ getDefaultBuilder().build().getDeliveryRatio());
+ assertThrows(IllegalStateException.class, () ->
+ getDefaultBuilder().build().getCountExponent());
+ }
+
+ /**
+ * Tests that the parceling logic can properly read and write from a Parcel.
+ */
+ @Test
+ public void testParcelReadWrite() {
+ QosCharacteristics qosCharacteristics = getDefaultQosCharacteristics();
+ Parcel parcel = Parcel.obtain();
+ qosCharacteristics.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
+ QosCharacteristics unparceledQosCharacteristics =
+ QosCharacteristics.CREATOR.createFromParcel(parcel);
+ validateDefaultFields(unparceledQosCharacteristics);
+ }
+
+ /**
+ * Tests that the overridden equality and hashCode operators properly compare the same object.
+ */
+ @Test
+ public void testSameObjectComparison() {
+ QosCharacteristics qosCharacteristics1 = getDefaultQosCharacteristics();
+ QosCharacteristics qosCharacteristics2 = getDefaultQosCharacteristics();
+ assertTrue(qosCharacteristics1.equals(qosCharacteristics2));
+ assertEquals(qosCharacteristics1.hashCode(), qosCharacteristics2.hashCode());
+ }
+
+ /**
+ * Tests that the overridden equality and hashCode operators properly compare different objects.
+ */
+ @Test
+ public void testDifferentObjectComparison() {
+ QosCharacteristics qosCharacteristics1 = getDefaultQosCharacteristics();
+ QosCharacteristics qosCharacteristics2 = getDefaultBuilder().build();
+ assertFalse(qosCharacteristics1.equals(qosCharacteristics2));
+ assertNotEquals(qosCharacteristics1.hashCode(), qosCharacteristics2.hashCode());
+ }
+}
diff --git a/framework/tests/src/android/net/wifi/QosPolicyParamsTest.java b/framework/tests/src/android/net/wifi/QosPolicyParamsTest.java
index cb50bac307..fe40e2158c 100644
--- a/framework/tests/src/android/net/wifi/QosPolicyParamsTest.java
+++ b/framework/tests/src/android/net/wifi/QosPolicyParamsTest.java
@@ -62,19 +62,36 @@ public class QosPolicyParamsTest {
}
/**
- * Creates a QosPolicyParams object will all fields assigned to a default test value.
+ * Creates a QosCharacteristics object with all fields assigned to a default value.
+ */
+ private static QosCharacteristics createTestQosCharacteristics() {
+ int minServiceIntervalMicros = 2000;
+ int maxServiceIntervalMicros = 5000;
+ int minDataRateKbps = 500;
+ int delayBoundMicros = 200;
+ return new QosCharacteristics.Builder(
+ minServiceIntervalMicros, maxServiceIntervalMicros,
+ minDataRateKbps, delayBoundMicros).build();
+ }
+
+ /**
+ * Creates a QosPolicyParams object with all fields assigned to a default test value.
*/
private QosPolicyParams createTestQosPolicyParams() {
- return new QosPolicyParams.Builder(TEST_POLICY_ID, TEST_DIRECTION)
- .setUserPriority(TEST_USER_PRIORITY)
- .setIpVersion(TEST_IP_VERSION)
- .setDscp(TEST_DSCP)
- .setSourcePort(TEST_SOURCE_PORT)
- .setProtocol(TEST_PROTOCOL)
- .setDestinationPort(TEST_DESTINATION_PORT)
- .setSourceAddress(getInetAddress(TEST_SOURCE_ADDRESS))
- .setDestinationAddress(getInetAddress(TEST_DESTINATION_ADDRESS))
- .build();
+ QosPolicyParams.Builder builder =
+ new QosPolicyParams.Builder(TEST_POLICY_ID, TEST_DIRECTION)
+ .setUserPriority(TEST_USER_PRIORITY)
+ .setIpVersion(TEST_IP_VERSION)
+ .setDscp(TEST_DSCP)
+ .setSourcePort(TEST_SOURCE_PORT)
+ .setProtocol(TEST_PROTOCOL)
+ .setDestinationPort(TEST_DESTINATION_PORT)
+ .setSourceAddress(getInetAddress(TEST_SOURCE_ADDRESS))
+ .setDestinationAddress(getInetAddress(TEST_DESTINATION_ADDRESS));
+ if (SdkLevel.isAtLeastV()) {
+ builder.setQosCharacteristics(createTestQosCharacteristics());
+ }
+ return builder.build();
}
/**
@@ -91,6 +108,10 @@ public class QosPolicyParamsTest {
assertEquals(TEST_DESTINATION_PORT, params.getDestinationPort());
assertTrue(getInetAddress(TEST_SOURCE_ADDRESS).equals(params.getSourceAddress()));
assertTrue(getInetAddress(TEST_DESTINATION_ADDRESS).equals(params.getDestinationAddress()));
+ if (SdkLevel.isAtLeastV()) {
+ QosCharacteristics testQosCharacteristics = createTestQosCharacteristics();
+ assertEquals(testQosCharacteristics, params.getQosCharacteristics());
+ }
}
/**
@@ -139,6 +160,10 @@ public class QosPolicyParamsTest {
// Policies for downlink are required to have a User Priority and IP Version.
new QosPolicyParams.Builder(TEST_POLICY_ID, QosPolicyParams.DIRECTION_DOWNLINK)
.build());
+ assertThrows(IllegalArgumentException.class, () ->
+ // Policies for uplink are required to have QoS characteristics.
+ new QosPolicyParams.Builder(TEST_POLICY_ID, QosPolicyParams.DIRECTION_UPLINK)
+ .build());
}
/**
diff --git a/framework/tests/src/android/net/wifi/ScanResultTest.java b/framework/tests/src/android/net/wifi/ScanResultTest.java
index 14a9aef830..32265c3279 100644
--- a/framework/tests/src/android/net/wifi/ScanResultTest.java
+++ b/framework/tests/src/android/net/wifi/ScanResultTest.java
@@ -262,6 +262,8 @@ public class ScanResultTest {
+ "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
+ "standard: 11ac, "
+ "80211mcResponder: is not supported, "
+ + "80211azNtbResponder: is not supported, "
+ + "TWT Responder: no, "
+ "Radio Chain Infos: null, interface name: test_ifname", scanResult.toString());
}
@@ -284,6 +286,8 @@ public class ScanResultTest {
+ "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
+ "standard: 11ac, "
+ "80211mcResponder: is not supported, "
+ + "80211azNtbResponder: is not supported, "
+ + "TWT Responder: no, "
+ "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, "
+ "RadioChainInfo: id=1, level=-54], interface name: test_ifname",
scanResult.toString());
@@ -302,6 +306,8 @@ public class ScanResultTest {
+ "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
+ "standard: 11ac, "
+ "80211mcResponder: is not supported, "
+ + "80211azNtbResponder: is not supported, "
+ + "TWT Responder: no, "
+ "Radio Chain Infos: null, interface name: test_ifname", scanResult.toString());
}
diff --git a/framework/tests/src/android/net/wifi/SoftApInfoTest.java b/framework/tests/src/android/net/wifi/SoftApInfoTest.java
index f415447b6a..b2f9e35844 100644
--- a/framework/tests/src/android/net/wifi/SoftApInfoTest.java
+++ b/framework/tests/src/android/net/wifi/SoftApInfoTest.java
@@ -17,6 +17,8 @@
package android.net.wifi;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import android.net.MacAddress;
import android.os.Parcel;
@@ -27,6 +29,8 @@ import com.android.modules.utils.build.SdkLevel;
import org.junit.Test;
+import java.util.List;
+
/**
* Unit tests for {@link android.net.wifi.SoftApInfo}.
*/
@@ -38,6 +42,9 @@ public class SoftApInfoTest {
private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_LEGACY;
private static final MacAddress TEST_AP_MAC = MacAddress.fromString("aa:bb:cc:dd:ee:ff");
private static final long TEST_SHUTDOWN_TIMEOUT_MILLIS = 100_000;
+ private static final List<OuiKeyedData> TEST_VENDOR_DATA =
+ OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
+
/**
* Verifies copy constructor.
*/
@@ -49,7 +56,9 @@ public class SoftApInfoTest {
info.setBssid(TEST_AP_MAC);
info.setWifiStandard(TEST_WIFI_STANDARD);
info.setApInstanceIdentifier(TEST_AP_INSTANCE);
-
+ if (SdkLevel.isAtLeastV()) {
+ info.setVendorData(TEST_VENDOR_DATA);
+ }
SoftApInfo copiedInfo = new SoftApInfo(info);
@@ -68,6 +77,9 @@ public class SoftApInfoTest {
info.setBssid(TEST_AP_MAC);
info.setWifiStandard(TEST_WIFI_STANDARD);
info.setApInstanceIdentifier(TEST_AP_INSTANCE);
+ if (SdkLevel.isAtLeastV()) {
+ info.setVendorData(TEST_VENDOR_DATA);
+ }
Parcel parcelW = Parcel.obtain();
info.writeToParcel(parcelW, 0);
@@ -97,6 +109,9 @@ public class SoftApInfoTest {
assertEquals(info.getWifiStandard(), ScanResult.WIFI_STANDARD_UNKNOWN);
assertEquals(info.getApInstanceIdentifier(), null);
}
+ if (SdkLevel.isAtLeastV()) {
+ assertNotNull(info.getVendorData());
+ }
}
/**
@@ -119,6 +134,10 @@ public class SoftApInfoTest {
assertEquals(info.getApInstanceIdentifier(), TEST_AP_INSTANCE);
}
assertEquals(info.getAutoShutdownTimeoutMillis(), TEST_SHUTDOWN_TIMEOUT_MILLIS);
+ if (SdkLevel.isAtLeastV()) {
+ info.setVendorData(TEST_VENDOR_DATA);
+ assertTrue(TEST_VENDOR_DATA.equals(info.getVendorData()));
+ }
}
}
diff --git a/framework/tests/src/android/net/wifi/UriParserResultsTest.java b/framework/tests/src/android/net/wifi/UriParserResultsTest.java
new file mode 100644
index 0000000000..a5f4b2238c
--- /dev/null
+++ b/framework/tests/src/android/net/wifi/UriParserResultsTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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 android.net.wifi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.net.module.util.MacAddressUtils;
+
+import org.junit.Test;
+
+/** Unit tests for {@link android.net.wifi.UriParserResults}. */
+@SmallTest
+public class UriParserResultsTest {
+ private static final String TEST_PUBLIC_KEY = "testPublicKey";
+ private static final String TEST_INFORMATION = "testInformation";
+
+ WifiConfiguration generateTestWifiConfig() {
+ WifiConfiguration config = new WifiConfiguration();
+ final String mSsid = "\"TestAP\"";
+ final String bSsid = MacAddressUtils.createRandomUnicastAddress().toString();
+ config.SSID = mSsid;
+ config.BSSID = bSsid;
+ return config;
+ }
+
+ private void testParcelOperation(UriParserResults testResult) throws Exception {
+ Parcel parcelW = Parcel.obtain();
+ testResult.writeToParcel(parcelW, 0);
+ byte[] bytes = parcelW.marshall();
+ parcelW.recycle();
+
+ Parcel parcelR = Parcel.obtain();
+ parcelR.unmarshall(bytes, 0, bytes.length);
+ parcelR.setDataPosition(0);
+ UriParserResults fromParcel = UriParserResults.CREATOR.createFromParcel(parcelR);
+
+ assertEquals(testResult, fromParcel);
+ assertEquals(testResult.hashCode(), fromParcel.hashCode());
+ }
+
+ /** Verifies parcel serialization/deserialization. */
+ @Test
+ public void testParcelOperation() throws Exception {
+ final WifiConfiguration testWifiConfig = generateTestWifiConfig();
+ testParcelOperation(
+ new UriParserResults(
+ UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG,
+ null,
+ null,
+ testWifiConfig));
+ testParcelOperation(
+ new UriParserResults(
+ UriParserResults.URI_SCHEME_DPP,
+ TEST_PUBLIC_KEY,
+ TEST_INFORMATION,
+ null));
+ }
+
+ @Test
+ public void testGetXXXMethods() throws Exception {
+ final WifiConfiguration testWifiConfig = generateTestWifiConfig();
+ UriParserResults testResultZxing =
+ new UriParserResults(
+ UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG,
+ null,
+ null,
+ testWifiConfig);
+ assertEquals(
+ testResultZxing.getUriScheme(),
+ UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG);
+ assertNull(testResultZxing.getPublicKey());
+ assertNull(testResultZxing.getInformation());
+ assertEquals(testWifiConfig.toString(), testResultZxing.getWifiConfiguration().toString());
+
+ UriParserResults testResultDpp =
+ new UriParserResults(
+ UriParserResults.URI_SCHEME_DPP,
+ TEST_PUBLIC_KEY,
+ TEST_INFORMATION,
+ null);
+ assertEquals(testResultDpp.getUriScheme(), UriParserResults.URI_SCHEME_DPP);
+ assertEquals(testResultDpp.getPublicKey(), TEST_PUBLIC_KEY);
+ assertEquals(testResultDpp.getInformation(), TEST_INFORMATION);
+ assertNull(testResultDpp.getWifiConfiguration());
+ }
+}
diff --git a/framework/tests/src/android/net/wifi/WifiConfigurationTest.java b/framework/tests/src/android/net/wifi/WifiConfigurationTest.java
index defcc5248c..240f2d1373 100644
--- a/framework/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ b/framework/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -41,6 +41,7 @@ import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
+import static org.mockito.Mockito.mock;
import android.net.MacAddress;
import android.net.ProxyInfo;
@@ -62,6 +63,7 @@ import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
@@ -122,6 +124,9 @@ public class WifiConfigurationTest {
config.setSubscriptionGroup(ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB"));
config.getNetworkSelectionStatus().setDisableTime(12333);
config.getNetworkSelectionStatus().setDisableEndTime(45666);
+ if (SdkLevel.isAtLeastV()) {
+ config.setVendorData(OuiKeyedDataUtil.createTestOuiKeyedDataList(5));
+ }
assertEquals(12333, config.getNetworkSelectionStatus().getDisableTime());
assertEquals(45666, config.getNetworkSelectionStatus().getDisableEndTime());
Parcel parcelW = Parcel.obtain();
@@ -160,6 +165,9 @@ public class WifiConfigurationTest {
reconfig.getNetworkSelectionStatus().getDisableTime());
assertEquals(config.getNetworkSelectionStatus().getDisableEndTime(),
reconfig.getNetworkSelectionStatus().getDisableEndTime());
+ if (SdkLevel.isAtLeastV()) {
+ assertTrue(config.getVendorData().equals(reconfig.getVendorData()));
+ }
Parcel parcelWW = Parcel.obtain();
reconfig.writeToParcel(parcelWW, 0);
@@ -186,6 +194,9 @@ public class WifiConfigurationTest {
config.restricted = true;
config.isCurrentlyConnected = true;
config.setIsUserSelected(true);
+ if (SdkLevel.isAtLeastV()) {
+ config.setVendorData(OuiKeyedDataUtil.createTestOuiKeyedDataList(5));
+ }
WifiConfiguration reconfig = new WifiConfiguration(config);
@@ -203,6 +214,9 @@ public class WifiConfigurationTest {
assertTrue(reconfig.restricted);
assertTrue(reconfig.isCurrentlyConnected);
assertTrue(reconfig.isUserSelected());
+ if (SdkLevel.isAtLeastV()) {
+ assertTrue(config.getVendorData().equals(reconfig.getVendorData()));
+ }
}
@Test
@@ -1406,4 +1420,18 @@ public class WifiConfigurationTest {
assertTrue(config.getAllNetworkKeys().contains(
config.getNetworkKeyFromSecurityType(SECURITY_TYPE_PASSPOINT_R1_R2)));
}
+
+ /**
+ * Verifies that vendor data can be set and retrieved successfully.
+ */
+ @Test
+ public void testSetAndGetVendorData() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ WifiConfiguration config = new WifiConfiguration();
+ assertNotNull(config.getVendorData()); // non-null default value
+
+ List<OuiKeyedData> vendorData = Arrays.asList(mock(OuiKeyedData.class));
+ config.setVendorData(vendorData);
+ assertTrue(vendorData.equals(config.getVendorData()));
+ }
}
diff --git a/framework/tests/src/android/net/wifi/WifiInfoTest.java b/framework/tests/src/android/net/wifi/WifiInfoTest.java
index d860b7b713..b751b4fba1 100644
--- a/framework/tests/src/android/net/wifi/WifiInfoTest.java
+++ b/framework/tests/src/android/net/wifi/WifiInfoTest.java
@@ -73,6 +73,8 @@ public class WifiInfoTest {
private static final int TEST_MLO_LINK_ID = 3;
private static final int TEST_CHANNEL = 36;
private static final int TEST_LINK_SPEED = 300;
+ private static final List<OuiKeyedData> TEST_VENDOR_DATA =
+ OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
private void addMloInfo(WifiInfo info) {
info.setApMldMacAddress(MacAddress.fromString(AP_MLD_MAC_ADDRESS));
@@ -164,6 +166,9 @@ public class WifiInfoTest {
if (SdkLevel.isAtLeastT()) {
addMloInfo(info);
}
+ if (SdkLevel.isAtLeastV()) {
+ info.setVendorData(TEST_VENDOR_DATA);
+ }
return info;
}
@@ -211,6 +216,9 @@ public class WifiInfoTest {
if (SdkLevel.isAtLeastT()) {
assertMloNoRedaction(info);
}
+ if (SdkLevel.isAtLeastV()) {
+ assertTrue(TEST_VENDOR_DATA.equals(info.getVendorData()));
+ }
}
/**
@@ -521,6 +529,9 @@ public class WifiInfoTest {
writeWifiInfo.setIsPrimary(true);
writeWifiInfo.setRestricted(true);
writeWifiInfo.enableApTidToLinkMappingNegotiationSupport(true);
+ if (SdkLevel.isAtLeastV()) {
+ writeWifiInfo.setVendorData(TEST_VENDOR_DATA);
+ }
WifiInfo readWifiInfo = new WifiInfo(writeWifiInfo);
@@ -548,6 +559,9 @@ public class WifiInfoTest {
assertTrue(readWifiInfo.isPrimary());
}
assertTrue(readWifiInfo.isApTidToLinkMappingNegotiationSupported());
+ if (SdkLevel.isAtLeastV()) {
+ assertTrue(TEST_VENDOR_DATA.equals(readWifiInfo.getVendorData()));
+ }
}
/**
@@ -577,6 +591,10 @@ public class WifiInfoTest {
assertNull(wifiInfo.getApMldMacAddress());
assertEquals(0, wifiInfo.getAffiliatedMloLinks().size());
assertFalse(wifiInfo.isApTidToLinkMappingNegotiationSupported());
+ if (SdkLevel.isAtLeastV()) {
+ assertNotNull(wifiInfo.getVendorData());
+ assertTrue(wifiInfo.getVendorData().isEmpty());
+ }
}
/**
diff --git a/framework/tests/src/android/net/wifi/WifiManagerTest.java b/framework/tests/src/android/net/wifi/WifiManagerTest.java
index 9f2c44a40c..c9355bda6d 100644
--- a/framework/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/framework/tests/src/android/net/wifi/WifiManagerTest.java
@@ -45,6 +45,7 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MBB;
import static android.net.wifi.WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET;
import static android.net.wifi.WifiManager.WIFI_FEATURE_ADDITIONAL_STA_RESTRICTED;
import static android.net.wifi.WifiManager.WIFI_FEATURE_AP_STA;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED;
import static android.net.wifi.WifiManager.WIFI_FEATURE_DECORATED_IDENTITY;
import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP;
import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP_AKM;
@@ -58,9 +59,9 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_SCANNER;
import static android.net.wifi.WifiManager.WIFI_FEATURE_T2LM_NEGOTIATION;
import static android.net.wifi.WifiManager.WIFI_FEATURE_TRUST_ON_FIRST_USE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WEP;
-import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA_PERSONAL;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA_PERSONAL;
import static android.net.wifi.WifiManager.WpsCallback;
import static org.junit.Assert.assertArrayEquals;
@@ -100,6 +101,7 @@ import android.content.pm.ApplicationInfo;
import android.net.DhcpInfo;
import android.net.DhcpOption;
import android.net.MacAddress;
+import android.net.TetheringManager;
import android.net.wifi.WifiManager.ActiveCountryCodeChangedCallback;
import android.net.wifi.WifiManager.CoexCallback;
import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
@@ -120,6 +122,8 @@ import android.net.wifi.WifiUsabilityStatsEntry.ContentionTimeStats;
import android.net.wifi.WifiUsabilityStatsEntry.LinkStats;
import android.net.wifi.WifiUsabilityStatsEntry.RadioStats;
import android.net.wifi.WifiUsabilityStatsEntry.RateStats;
+import android.net.wifi.twt.TwtRequest;
+import android.net.wifi.twt.TwtSessionCallback;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -185,6 +189,10 @@ public class WifiManagerTest {
private static final byte[] TEST_OUI = new byte[]{0x01, 0x02, 0x03};
private static final int TEST_LINK_LAYER_STATS_POLLING_INTERVAL_MS = 1000;
+ private static final TetheringManager.TetheringRequest TEST_TETHERING_REQUEST =
+ new TetheringManager.TetheringRequest.Builder(TetheringManager.TETHERING_WIFI).build();
+ private static final String TEST_INTERFACE_NAME = "test-wlan0";
+
@Mock Context mContext;
@Mock android.net.wifi.IWifiManager mWifiService;
@Mock ApplicationInfo mApplicationInfo;
@@ -1288,9 +1296,14 @@ public class WifiManagerTest {
mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
verify(mWifiService).registerSoftApCallback(callbackCaptor.capture());
- callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ SoftApState state = new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME);
+ callbackCaptor.getValue().onStateChanged(state);
mLooper.dispatchAll();
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ ArgumentCaptor<SoftApState> softApStateCaptor = ArgumentCaptor.forClass(SoftApState.class);
+ verify(mSoftApCallback).onStateChanged(softApStateCaptor.capture());
+ assertEquals(state, softApStateCaptor.getValue());
}
/*
@@ -1810,9 +1823,12 @@ public class WifiManagerTest {
mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback);
verify(mWifiService).registerSoftApCallback(callbackCaptor.capture());
- final List<WifiClient> testClients = new ArrayList();
- callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0);
- callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
+ SoftApState state0 = new SoftApState(WIFI_AP_STATE_ENABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME);
+ callbackCaptor.getValue().onStateChanged(state0);
+ SoftApState state1 = new SoftApState(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME);
+ callbackCaptor.getValue().onStateChanged(state1);
callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability);
@@ -1820,6 +1836,11 @@ public class WifiManagerTest {
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0);
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability);
+ ArgumentCaptor<SoftApState> softApStateCaptor =
+ ArgumentCaptor.forClass(SoftApState.class);
+ verify(mSoftApCallback, times(2)).onStateChanged(softApStateCaptor.capture());
+ assertEquals(state0, softApStateCaptor.getAllValues().get(0));
+ assertEquals(state1, softApStateCaptor.getAllValues().get(1));
}
/*
@@ -1834,9 +1855,24 @@ public class WifiManagerTest {
mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback);
verify(mWifiService).registerSoftApCallback(callbackCaptor.capture());
- callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ SoftApState state = new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME);
+ callbackCaptor.getValue().onStateChanged(state);
altLooper.dispatchAll();
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ ArgumentCaptor<SoftApState> softApStateCaptor =
+ ArgumentCaptor.forClass(SoftApState.class);
+ verify(mSoftApCallback).onStateChanged(softApStateCaptor.capture());
+ SoftApState softApState = softApStateCaptor.getValue();
+ assertEquals(WIFI_AP_STATE_ENABLED, softApState.getState());
+ try {
+ softApState.getFailureReason();
+ fail("getFailureReason should throw if not in failure state");
+ } catch (IllegalStateException e) {
+ // Pass.
+ }
+ assertEquals(TEST_INTERFACE_NAME, softApState.getIface());
+ assertEquals(TEST_TETHERING_REQUEST, softApState.getTetheringRequest());
}
/**
@@ -2976,7 +3012,7 @@ public class WifiManagerTest {
ArgumentCaptor<IActionListener> binderListenerCaptor =
ArgumentCaptor.forClass(IActionListener.class);
verify(mWifiService).connect(eq(null), eq(TEST_NETWORK_ID), binderListenerCaptor.capture(),
- anyString());
+ anyString(), any());
assertNotNull(binderListenerCaptor.getValue());
// Trigger on success.
@@ -2996,7 +3032,7 @@ public class WifiManagerTest {
@Test
public void testConnectWithListenerHandleSecurityException() throws Exception {
doThrow(new SecurityException()).when(mWifiService)
- .connect(eq(null), anyInt(), any(IActionListener.class), anyString());
+ .connect(eq(null), anyInt(), any(IActionListener.class), anyString(), any());
ActionListener externalListener = mock(ActionListener.class);
mWifiManager.connect(TEST_NETWORK_ID, externalListener);
@@ -3010,7 +3046,7 @@ public class WifiManagerTest {
@Test
public void testConnectWithListenerHandleRemoteException() throws Exception {
doThrow(new RemoteException()).when(mWifiService)
- .connect(eq(null), anyInt(), any(IActionListener.class), anyString());
+ .connect(eq(null), anyInt(), any(IActionListener.class), anyString(), any());
ActionListener externalListener = mock(ActionListener.class);
mWifiManager.connect(TEST_NETWORK_ID, externalListener);
@@ -3027,7 +3063,7 @@ public class WifiManagerTest {
mWifiManager.connect(configuration, null);
verify(mWifiService).connect(eq(configuration), eq(WifiConfiguration.INVALID_NETWORK_ID),
- eq(null), anyString());
+ eq(null), anyString(), any());
}
/**
@@ -3861,7 +3897,9 @@ public class WifiManagerTest {
verify(mWifiService).registerLocalOnlyHotspotSoftApCallback(callbackCaptor.capture(),
any(Bundle.class));
- callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ SoftApState state = new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME);
+ callbackCaptor.getValue().onStateChanged(state);
callbackCaptor.getValue().onConnectedClientsOrInfoChanged(
(Map<String, SoftApInfo>) mTestSoftApInfoMap.clone(),
(Map<String, List<WifiClient>>) mTestWifiClientsMap.clone(), false, true);
@@ -3871,6 +3909,10 @@ public class WifiManagerTest {
mLooper.dispatchAll();
verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ ArgumentCaptor<SoftApState> softApStateCaptor =
+ ArgumentCaptor.forClass(SoftApState.class);
+ verify(mSoftApCallback).onStateChanged(softApStateCaptor.capture());
+ assertEquals(state, softApStateCaptor.getValue());
verify(mSoftApCallback).onConnectedClientsChanged(clientList);
verify(mSoftApCallback).onConnectedClientsChanged(mTestApInfo1, clientList);
@@ -4158,4 +4200,193 @@ public class WifiManagerTest {
verify(mWifiService).queryWepAllowed(
any(IBooleanListener.Stub.class));
}
+
+ /**
+ * Verify {@link WifiManager#setPerSsidRoamingMode(WifiSsid, int)}.
+ */
+ @Test
+ public void testSetPerSsidRoamingMode() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ // Invalid input throws exception.
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiManager.setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID), -1));
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiManager.setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID), 3));
+ assertThrows(NullPointerException.class,
+ () -> mWifiManager.setPerSsidRoamingMode(null, WifiManager.ROAMING_MODE_NORMAL));
+ // Set and verify.
+ mWifiManager.setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID),
+ WifiManager.ROAMING_MODE_NORMAL);
+ verify(mWifiService).setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID),
+ WifiManager.ROAMING_MODE_NORMAL, TEST_PACKAGE_NAME);
+ }
+
+ /**
+ * Verify {@link WifiManager#removePerSsidRoamingMode(WifiSsid)}.
+ */
+ @Test
+ public void testRemovePerSsidRoamingMode() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ // Invalid input throws exception.
+ assertThrows(NullPointerException.class,
+ () -> mWifiManager.removePerSsidRoamingMode(null));
+ // Remove and verify.
+ mWifiManager.removePerSsidRoamingMode(WifiSsid.fromString(TEST_SSID));
+ verify(mWifiService).removePerSsidRoamingMode(WifiSsid.fromString(TEST_SSID),
+ TEST_PACKAGE_NAME);
+ }
+
+ /**
+ * Verify {@link WifiManager#getPerSsidRoamingModes()}.
+ */
+ @Test
+ public void testGetPerSsidRoamingModes() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ Consumer<Map<String, Integer>> resultsSetCallback = mock(Consumer.class);
+ SynchronousExecutor executor = mock(SynchronousExecutor.class);
+ // Null executor/callback exception.
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.getPerSsidRoamingModes(null,
+ resultsSetCallback));
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.getPerSsidRoamingModes(executor,
+ null));
+ // Get and verify.
+ mWifiManager.getPerSsidRoamingModes(executor, resultsSetCallback);
+ verify(mWifiService).getPerSsidRoamingModes(eq(TEST_PACKAGE_NAME),
+ any(IMapListener.Stub.class));
+ }
+
+ @Test
+ public void testGetTwtCapabilities() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ Consumer<Bundle> resultCallback = mock(Consumer.class);
+ SynchronousExecutor executor = mock(SynchronousExecutor.class);
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ // Null check
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.getTwtCapabilities(executor, null));
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.getTwtCapabilities(null, resultCallback));
+ // Get and verify
+ mWifiManager.getTwtCapabilities(executor, resultCallback);
+ verify(mWifiService).getTwtCapabilities(any(ITwtCapabilitiesListener.Stub.class),
+ bundleCaptor.capture());
+ verify(mContext.getAttributionSource()).equals(
+ bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE));
+ }
+
+ @Test
+ public void testSetupTwtSession() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ TwtSessionCallback resultCallback = mock(TwtSessionCallback.class);
+ SynchronousExecutor executor = mock(SynchronousExecutor.class);
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ TwtRequest twtRequest = mock(TwtRequest.class);
+ // Null check
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.setupTwtSession(null, executor, resultCallback));
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.setupTwtSession(twtRequest, null, resultCallback));
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.setupTwtSession(twtRequest, executor, null));
+ // Call twtSessionSetup and verify
+ mWifiManager.setupTwtSession(twtRequest, executor, resultCallback);
+ verify(mWifiService).setupTwtSession(any(TwtRequest.class), any(ITwtCallback.class),
+ bundleCaptor.capture());
+ verify(mContext.getAttributionSource()).equals(
+ bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE));
+ }
+
+ @Test
+ public void testGetStatsTwtSession() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ Consumer<Bundle> resultCallback = mock(Consumer.class);
+ SynchronousExecutor executor = mock(SynchronousExecutor.class);
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ // Null check
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.getStatsTwtSession(0, null, resultCallback));
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.getStatsTwtSession(0, executor, null));
+ // Call twtSessionGetStats and verify
+ mWifiManager.getStatsTwtSession(2, executor, resultCallback);
+ verify(mWifiService).getStatsTwtSession(eq(2), any(ITwtStatsListener.class),
+ bundleCaptor.capture());
+ verify(mContext.getAttributionSource()).equals(
+ bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE));
+ }
+
+ @Test
+ public void testTeardownTwtSession() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ // Call twtSessionTeardown and verify
+ mWifiManager.teardownTwtSession(10);
+ verify(mWifiService).teardownTwtSession(eq(10), bundleCaptor.capture());
+ verify(mContext.getAttributionSource()).equals(
+ bundleCaptor.getValue().getParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE));
+ }
+
+ /**
+ * Test behavior of isD2dSupportedWhenInfraStaDisabled.
+ */
+ @Test
+ public void testIsD2dSupportedWhenInfraStaDisabled() throws Exception {
+ when(mWifiService.getSupportedFeatures())
+ .thenReturn(new Long(WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED));
+ assertTrue(mWifiManager.isD2dSupportedWhenInfraStaDisabled());
+ when(mWifiService.getSupportedFeatures())
+ .thenReturn(new Long(~WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED));
+ assertFalse(mWifiManager.isD2dSupportedWhenInfraStaDisabled());
+ }
+
+ @Test
+ public void testSetD2dAllowedInfraStaDisabled() throws Exception {
+ mWifiManager.setD2dAllowedWhenInfraStaDisabled(true);
+ verify(mWifiService).setD2dAllowedWhenInfraStaDisabled(true);
+ mWifiManager.setD2dAllowedWhenInfraStaDisabled(false);
+ verify(mWifiService).setD2dAllowedWhenInfraStaDisabled(false);
+ }
+
+ @Test
+ public void testQueryD2dAllowedInfraStaDisabled() throws Exception {
+ Consumer<Boolean> resultsSetCallback = mock(Consumer.class);
+ SynchronousExecutor executor = mock(SynchronousExecutor.class);
+ // Null executor/callback exception.
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.queryD2dAllowedWhenInfraStaDisabled(null, resultsSetCallback));
+ assertThrows("null listener should trigger exception", NullPointerException.class,
+ () -> mWifiManager.queryD2dAllowedWhenInfraStaDisabled(executor, null));
+ // Set and verify.
+ mWifiManager.queryD2dAllowedWhenInfraStaDisabled(executor, resultsSetCallback);
+ verify(mWifiService).queryD2dAllowedWhenInfraStaDisabled(
+ any(IBooleanListener.Stub.class));
+ }
+
+ @Test
+ public void testRetrieveRestoreWifiBackupData() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ Consumer<byte[]> resultsSetCallback = mock(Consumer.class);
+ SynchronousExecutor executor = mock(SynchronousExecutor.class);
+ byte[] testByteArray = new byte[0];
+ // Null executor/callback exception.
+ assertThrows("null executor should trigger exception", NullPointerException.class,
+ () -> mWifiManager.retrieveWifiBackupData(null, resultsSetCallback));
+ assertThrows("null listener should trigger exception", NullPointerException.class,
+ () -> mWifiManager.retrieveWifiBackupData(executor, null));
+ // Call and verify.
+ mWifiManager.retrieveWifiBackupData(executor, resultsSetCallback);
+ verify(mWifiService).retrieveWifiBackupData(
+ any(IByteArrayListener.Stub.class));
+ mWifiManager.restoreWifiBackupData(testByteArray);
+ verify(mWifiService).restoreWifiBackupData(eq(testByteArray));
+ }
+
+
+ @Test
+ public void testIsPreferredNetworkOffloadSupported() throws Exception {
+ mWifiManager.isPreferredNetworkOffloadSupported();
+ verify(mWifiService).isPnoSupported();
+ }
}
diff --git a/framework/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/framework/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index 397ede4166..5d61ca7f0d 100644
--- a/framework/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/framework/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -1735,4 +1735,22 @@ public class WifiNetworkSuggestionTest {
.setWifiSsid(ssid)
.build();
}
+
+ /**
+ * Test set a network suggestion with Wi-Fi 7
+ */
+ @Test
+ public void testNetworkSuggestionForWifi7() {
+ // Validate default behavior
+ WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder().setSsid(
+ TEST_SSID).setWpa2Passphrase(TEST_PRESHARED_KEY).build();
+ assertTrue(suggestion.isWifi7Enabled());
+ assertTrue(suggestion.wifiConfiguration.isWifi7Enabled());
+
+ // Validate disable Wi-Fi 7
+ suggestion = new WifiNetworkSuggestion.Builder().setSsid(TEST_SSID).setWpa2Passphrase(
+ TEST_PRESHARED_KEY).setWifi7Enabled(false).build();
+ assertFalse(suggestion.isWifi7Enabled());
+ assertFalse(suggestion.wifiConfiguration.isWifi7Enabled());
+ }
}
diff --git a/framework/tests/src/android/net/wifi/WifiUriParserTest.java b/framework/tests/src/android/net/wifi/WifiUriParserTest.java
new file mode 100644
index 0000000000..c38974bb59
--- /dev/null
+++ b/framework/tests/src/android/net/wifi/WifiUriParserTest.java
@@ -0,0 +1,185 @@
+/*
+ * 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 android.net.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+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 androidx.test.filters.SmallTest;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Test;
+
+import java.util.List;
+
+/** Unit tests for {@link com.android.server.wifi.WifiUriParser}. */
+@SmallTest
+public class WifiUriParserTest {
+
+ private static final String TEST_DPP_INFORMATION = "Easy_Connect_Demo";
+ private static final String TEST_DPP_PUBLIC_KEY = "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIg"
+ + "ACDmtXD1Sz6/5B4YRdmTkbkkFLDwk8f0yRnfm1Gokpx/0=";
+ private static final String TEST_DPP_URI = "DPP:C:81/1;I:" + TEST_DPP_INFORMATION
+ + ";K:" + TEST_DPP_PUBLIC_KEY + ";;";
+
+ private void verifyZxParsing(
+ UriParserResults uri,
+ String expectedSSID,
+ int expectedAuthType,
+ List<SecurityParams> expectedSecurityParamsList,
+ String expectedPreShareKey,
+ boolean isWep) {
+ assertNotNull(uri);
+ WifiConfiguration config = uri.getWifiConfiguration();
+ assertNotNull(config);
+ assertThat(config.SSID).isEqualTo(expectedSSID);
+ assertThat(config.getAuthType()).isEqualTo(expectedAuthType);
+ if (isWep) {
+ assertThat(config.wepKeys[0]).isEqualTo(expectedPreShareKey);
+ } else {
+ assertThat(config.preSharedKey).isEqualTo(expectedPreShareKey);
+ }
+ List<SecurityParams> configSecurityParamsList = config.getSecurityParamsList();
+ assertEquals(expectedSecurityParamsList, configSecurityParamsList);
+ assertNull(uri.getPublicKey());
+ assertNull(uri.getInformation());
+ assertEquals(UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG, uri.getUriScheme());
+ }
+
+ @Test
+ public void testZxParsing() {
+ // Test no password
+ List<SecurityParams> expectedSecurityParamsList =
+ ImmutableList.of(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_OPEN),
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_OWE));
+ UriParserResults uri = WifiUriParser.parseUri("WIFI:S:testAbC;T:nopass");
+ verifyZxParsing(
+ uri,
+ "\"testAbC\"",
+ WifiConfiguration.KeyMgmt.NONE,
+ expectedSecurityParamsList,
+ null,
+ false);
+ // invalid code but it should work.
+ uri = WifiUriParser.parseUri("WIFI:S:testAbC; T:nopass");
+ verifyZxParsing(
+ uri,
+ "\"testAbC\"",
+ WifiConfiguration.KeyMgmt.NONE,
+ expectedSecurityParamsList,
+ null,
+ false);
+
+ // Test WEP
+ expectedSecurityParamsList =
+ ImmutableList.of(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_WEP));
+ uri = WifiUriParser.parseUri("WIFI:S:reallyLONGone;T:WEP;P:somepasswo#%^**123rd");
+ verifyZxParsing(
+ uri,
+ "\"reallyLONGone\"",
+ WifiConfiguration.KeyMgmt.NONE,
+ expectedSecurityParamsList,
+ "\"somepasswo#%^**123rd\"",
+ true);
+ // invalid code but it should work.
+ uri = WifiUriParser.parseUri("WIFI:S:reallyLONGone;T:WEP; P:somepassword");
+ verifyZxParsing(
+ uri,
+ "\"reallyLONGone\"",
+ WifiConfiguration.KeyMgmt.NONE,
+ expectedSecurityParamsList,
+ "\"somepassword\"",
+ true);
+
+ // Test WPA
+ expectedSecurityParamsList =
+ ImmutableList.of(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_PSK));
+ uri = WifiUriParser.parseUri("WIFI:S:anotherone;T:WPA;P:3#=3j9asicla");
+ verifyZxParsing(
+ uri,
+ "\"anotherone\"",
+ WifiConfiguration.KeyMgmt.WPA_PSK,
+ expectedSecurityParamsList,
+ "\"3#=3j9asicla\"",
+ false);
+ // invalid code but it should work.
+ uri = WifiUriParser.parseUri("WIFI: S:anotherone;T:WPA;P:abcdefghihklmn");
+ verifyZxParsing(
+ uri,
+ "\"anotherone\"",
+ WifiConfiguration.KeyMgmt.WPA_PSK,
+ expectedSecurityParamsList,
+ "\"abcdefghihklmn\"",
+ false);
+
+ // Test SAE
+ expectedSecurityParamsList =
+ ImmutableList.of(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_SAE));
+ uri = WifiUriParser.parseUri("WIFI:S:xx;T:SAE;P:a");
+ verifyZxParsing(
+ uri,
+ "\"xx\"",
+ WifiConfiguration.KeyMgmt.SAE,
+ expectedSecurityParamsList,
+ "\"a\"",
+ false);
+ // invalid code but it should work.
+ uri = WifiUriParser.parseUri("WIFI: S:xx; T:SAE; P:a");
+ verifyZxParsing(
+ uri,
+ "\"xx\"",
+ WifiConfiguration.KeyMgmt.SAE,
+ expectedSecurityParamsList,
+ "\"a\"",
+ false);
+ }
+
+ @Test
+ public void testDppParsing() {
+ UriParserResults uri = WifiUriParser.parseUri(TEST_DPP_URI);
+ assertEquals(UriParserResults.URI_SCHEME_DPP, uri.getUriScheme());
+ assertEquals(TEST_DPP_INFORMATION, uri.getInformation());
+ assertEquals(TEST_DPP_PUBLIC_KEY, uri.getPublicKey());
+ assertNull(uri.getWifiConfiguration());
+ }
+
+ @Test
+ public void testInvalidUriParsing() {
+ assertThrows(IllegalArgumentException.class,
+ () -> WifiUriParser.parseUri("Invalid Uri"));
+ // Empty SSID
+ assertThrows(IllegalArgumentException.class,
+ () -> WifiUriParser.parseUri("WIFI:S:;T:nopass"));
+ // Empty passphrase
+ assertThrows(IllegalArgumentException.class,
+ () -> WifiUriParser.parseUri("WIFI: S:xx; T:SAE; P:"));
+ }
+}
diff --git a/framework/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/framework/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 0bb0e21239..e24fa354ad 100644
--- a/framework/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/framework/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -41,6 +41,8 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.MacAddress;
import android.net.wifi.IBooleanListener;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.OuiKeyedDataUtil;
import android.net.wifi.RttManager;
import android.net.wifi.SynchronousExecutor;
import android.net.wifi.util.HexEncoding;
@@ -66,6 +68,7 @@ import org.mockito.MockitoAnnotations;
import java.net.Inet6Address;
import java.net.UnknownHostException;
+import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
@@ -340,6 +343,8 @@ public class WifiAwareManagerTest {
final PeerHandle peerHandle = new PeerHandle(873);
final String string1 = "hey from here...";
final byte[] matchFilter = { 1, 12, 2, 31, 32 };
+ final OuiKeyedData[] vendorData = new OuiKeyedData[5];
+ OuiKeyedDataUtil.createTestOuiKeyedDataList(5).toArray(vendorData);
final int messageId = 2123;
final int reason = AWARE_STATUS_ERROR;
@@ -379,7 +384,7 @@ public class WifiAwareManagerTest {
// (3) ...
publishSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter,
- 0, new byte[0], null, null);
+ 0, new byte[0], null, null, vendorData);
sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
@@ -499,6 +504,8 @@ public class WifiAwareManagerTest {
final PeerHandle peerHandle = new PeerHandle(873);
final String string1 = "hey from here...";
final byte[] matchFilter = { 1, 12, 3, 31, 32 }; // bad data!
+ final OuiKeyedData[] vendorData = new OuiKeyedData[5];
+ OuiKeyedDataUtil.createTestOuiKeyedDataList(5).toArray(vendorData);
final int messageId = 2123;
final int reason = AWARE_STATUS_ERROR;
final int distanceMm = 100;
@@ -537,9 +544,9 @@ public class WifiAwareManagerTest {
// (3) ...
subscribeSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter,
- 0, new byte[0], null, null);
+ 0, new byte[0], null, null, vendorData);
sessionProxyCallback.getValue().onMatchWithDistance(peerHandle.peerId, string1.getBytes(),
- matchFilter, distanceMm, 0, new byte[0], null, null);
+ matchFilter, distanceMm, 0, new byte[0], null, null, vendorData);
sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
@@ -672,14 +679,18 @@ public class WifiAwareManagerTest {
final boolean supportBand6g = true;
final int dwWindow5GHz = 3;
final int dwWindow6GHz = 4;
+ final List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
- ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
+ ConfigRequest.Builder builder = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
.setClusterLow(clusterLow).setMasterPreference(masterPreference)
.setSupport5gBand(supportBand5g)
.setSupport6gBand(supportBand6g)
.setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
- .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz)
- .build();
+ .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz);
+ if (SdkLevel.isAtLeastV()) {
+ builder.setVendorData(vendorData);
+ }
+ ConfigRequest configRequest = builder.build();
collector.checkThat("mClusterHigh", clusterHigh, equalTo(configRequest.mClusterHigh));
collector.checkThat("mClusterLow", clusterLow, equalTo(configRequest.mClusterLow));
@@ -695,6 +706,9 @@ public class WifiAwareManagerTest {
equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]));
collector.checkThat("mDiscoveryWindowInterval[6GHz]", dwWindow6GHz,
equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ]));
+ if (SdkLevel.isAtLeastV()) {
+ collector.checkThat("mVendorData", vendorData, equalTo(configRequest.getVendorData()));
+ }
}
@Test(expected = IllegalArgumentException.class)
@@ -777,15 +791,19 @@ public class WifiAwareManagerTest {
final int dwWindow24GHz = 1;
final int dwWindow5GHz = 5;
final int dwWindow6GHz = 4;
+ final List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
- ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
+ ConfigRequest.Builder builder = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
.setClusterLow(clusterLow).setMasterPreference(masterPreference)
.setSupport5gBand(supportBand5g)
.setSupport6gBand(supportBand6g)
.setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwWindow24GHz)
.setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
- .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz)
- .build();
+ .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz);
+ if (SdkLevel.isAtLeastV()) {
+ builder.setVendorData(vendorData);
+ }
+ ConfigRequest configRequest = builder.build();
Parcel parcelW = Parcel.obtain();
configRequest.writeToParcel(parcelW, 0);
@@ -822,6 +840,10 @@ public class WifiAwareManagerTest {
collector.checkThat("mMinDistanceMm", subscribeConfig.mMinDistanceMm, equalTo(0));
collector.checkThat("mMaxDistanceMmSet", subscribeConfig.mMaxDistanceMmSet, equalTo(false));
collector.checkThat("mMaxDistanceMm", subscribeConfig.mMaxDistanceMm, equalTo(0));
+ if (SdkLevel.isAtLeastV()) {
+ collector.checkThat("mVendorData", subscribeConfig.getVendorData(),
+ equalTo(Collections.emptyList()));
+ }
}
@Test
@@ -834,15 +856,21 @@ public class WifiAwareManagerTest {
final boolean enableTerminateNotification = false;
final int minDistance = 10;
final int maxDistance = 50;
-
- SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
- new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
- .setSubscribeType(subscribeType)
- .setTtlSec(subscribeTtl)
- .setTerminateNotificationEnabled(enableTerminateNotification)
- .setMinDistanceMm(minDistance)
- .setMaxDistanceMm(maxDistance).build();
+ final List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
+
+ SubscribeConfig.Builder subscribeConfigBuilder =
+ new SubscribeConfig.Builder().setServiceName(serviceName)
+ .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
+ new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
+ .setSubscribeType(subscribeType)
+ .setTtlSec(subscribeTtl)
+ .setTerminateNotificationEnabled(enableTerminateNotification)
+ .setMinDistanceMm(minDistance)
+ .setMaxDistanceMm(maxDistance);
+ if (SdkLevel.isAtLeastV()) {
+ subscribeConfigBuilder.setVendorData(vendorData);
+ }
+ SubscribeConfig subscribeConfig = subscribeConfigBuilder.build();
collector.checkThat("mServiceName", serviceName.getBytes(),
equalTo(subscribeConfig.mServiceName));
@@ -858,6 +886,10 @@ public class WifiAwareManagerTest {
collector.checkThat("mMinDistanceMm", minDistance, equalTo(subscribeConfig.mMinDistanceMm));
collector.checkThat("mMaxDistanceMmSet", true, equalTo(subscribeConfig.mMaxDistanceMmSet));
collector.checkThat("mMaxDistanceMm", maxDistance, equalTo(subscribeConfig.mMaxDistanceMm));
+ if (SdkLevel.isAtLeastV()) {
+ collector.checkThat("mVendorData", vendorData,
+ equalTo(subscribeConfig.getVendorData()));
+ }
}
@Test
@@ -870,15 +902,21 @@ public class WifiAwareManagerTest {
final boolean enableTerminateNotification = true;
final int minDistance = 10;
final int maxDistance = 50;
-
- SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
- new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
- .setSubscribeType(subscribeType)
- .setTtlSec(subscribeTtl)
- .setTerminateNotificationEnabled(enableTerminateNotification)
- .setMinDistanceMm(minDistance)
- .setMaxDistanceMm(maxDistance).build();
+ final List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
+
+ SubscribeConfig.Builder subscribeConfigBuilder =
+ new SubscribeConfig.Builder().setServiceName(serviceName)
+ .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
+ new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
+ .setSubscribeType(subscribeType)
+ .setTtlSec(subscribeTtl)
+ .setTerminateNotificationEnabled(enableTerminateNotification)
+ .setMinDistanceMm(minDistance)
+ .setMaxDistanceMm(maxDistance);
+ if (SdkLevel.isAtLeastV()) {
+ subscribeConfigBuilder.setVendorData(vendorData);
+ }
+ SubscribeConfig subscribeConfig = subscribeConfigBuilder.build();
Parcel parcelW = Parcel.obtain();
subscribeConfig.writeToParcel(parcelW, 0);
@@ -922,6 +960,10 @@ public class WifiAwareManagerTest {
collector.checkThat("mEnableTerminateNotification",
publishConfig.mEnableTerminateNotification, equalTo(true));
collector.checkThat("mEnableRanging", publishConfig.mEnableRanging, equalTo(false));
+ if (SdkLevel.isAtLeastV()) {
+ collector.checkThat("mVendorData", publishConfig.getVendorData(),
+ equalTo(Collections.emptyList()));
+ }
}
@Test
@@ -933,14 +975,20 @@ public class WifiAwareManagerTest {
final int publishTtl = 15;
final boolean enableTerminateNotification = false;
final boolean enableRanging = true;
-
- PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
- new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
- .setPublishType(publishType)
- .setTtlSec(publishTtl)
- .setTerminateNotificationEnabled(enableTerminateNotification)
- .setRangingEnabled(enableRanging).build();
+ final List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
+
+ PublishConfig.Builder publishConfigBuilder =
+ new PublishConfig.Builder().setServiceName(serviceName)
+ .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
+ new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
+ .setPublishType(publishType)
+ .setTtlSec(publishTtl)
+ .setTerminateNotificationEnabled(enableTerminateNotification)
+ .setRangingEnabled(enableRanging);
+ if (SdkLevel.isAtLeastV()) {
+ publishConfigBuilder.setVendorData(vendorData);
+ }
+ PublishConfig publishConfig = publishConfigBuilder.build();
collector.checkThat("mServiceName", serviceName.getBytes(),
equalTo(publishConfig.mServiceName));
@@ -952,6 +1000,10 @@ public class WifiAwareManagerTest {
collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
equalTo(publishConfig.mEnableTerminateNotification));
collector.checkThat("mEnableRanging", enableRanging, equalTo(publishConfig.mEnableRanging));
+ if (SdkLevel.isAtLeastV()) {
+ collector.checkThat("mVendorData", vendorData, equalTo(
+ publishConfig.getVendorData()));
+ }
}
@Test
@@ -963,14 +1015,21 @@ public class WifiAwareManagerTest {
final int publishTtl = 15;
final boolean enableTerminateNotification = false;
final boolean enableRanging = true;
-
- PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
- new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
- .setPublishType(publishType)
- .setTtlSec(publishTtl)
- .setTerminateNotificationEnabled(enableTerminateNotification)
- .setRangingEnabled(enableRanging).build();
+ final List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
+
+ PublishConfig.Builder publishConfigBuilder =
+ new PublishConfig.Builder().setServiceName(serviceName)
+ .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
+ new TlvBufferUtils.TlvIterable(0, 1, matchFilter)
+ .toList())
+ .setPublishType(publishType)
+ .setTtlSec(publishTtl)
+ .setTerminateNotificationEnabled(enableTerminateNotification)
+ .setRangingEnabled(enableRanging);
+ if (SdkLevel.isAtLeastV()) {
+ publishConfigBuilder.setVendorData(vendorData);
+ }
+ PublishConfig publishConfig = publishConfigBuilder.build();
Parcel parcelW = Parcel.obtain();
publishConfig.writeToParcel(parcelW, 0);
diff --git a/framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java b/framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
index 568d59963f..15eba6fd8c 100644
--- a/framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
+++ b/framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import android.net.MacAddress;
+import android.net.wifi.OuiKeyedDataUtil;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
@@ -264,6 +265,9 @@ public class WifiP2pConfigTest {
public void testWifiP2pConfig() throws Exception {
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = DEVICE_ADDRESS;
+ if (SdkLevel.isAtLeastV()) {
+ config.setVendorData(OuiKeyedDataUtil.createTestOuiKeyedDataList(5));
+ }
WifiP2pConfig copiedConfig = new WifiP2pConfig(config);
// no equals operator, use toString for comparison.
@@ -279,6 +283,9 @@ public class WifiP2pConfigTest {
parcelR.setDataPosition(0);
WifiP2pConfig configFromParcel = WifiP2pConfig.CREATOR.createFromParcel(parcelR);
+ if (SdkLevel.isAtLeastV()) {
+ assertTrue(config.getVendorData().equals(configFromParcel.getVendorData()));
+ }
// no equals operator, use toString for comparison.
assertEquals(config.toString(), configFromParcel.toString());
}
diff --git a/framework/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java b/framework/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java
index 7af86b9d2c..611792d7d7 100644
--- a/framework/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java
+++ b/framework/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java
@@ -20,7 +20,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
+import android.net.MacAddress;
+import android.net.wifi.OuiKeyedDataUtil;
import android.net.wifi.ScanResult;
+import android.os.Parcel;
import androidx.test.filters.SmallTest;
@@ -28,6 +31,8 @@ import com.android.modules.utils.build.SdkLevel;
import org.junit.Test;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -37,6 +42,8 @@ import java.util.List;
*/
@SmallTest
public class WifiP2pDeviceTest {
+ private static final MacAddress INTERFACE_MAC_ADDRESS =
+ MacAddress.fromString("aa:bb:cc:dd:ee:10");
/**
* Compare two p2p devices.
@@ -138,4 +145,66 @@ public class WifiP2pDeviceTest {
device.setVendorElements(ies);
assertEquals(ies, device.getVendorElements());
}
+
+ /** Tests that this class can be properly parceled and unparceled. */
+ @Test
+ public void testParcelReadWrite() {
+ WifiP2pDevice device = new WifiP2pDevice();
+ device.deviceName = "deviceName";
+ device.deviceAddress = "11:22:33:44:55:66";
+ device.primaryDeviceType = "primaryDeviceType";
+ device.secondaryDeviceType = "secondaryDeviceType";
+ device.wpsConfigMethodsSupported = 0x0008;
+ device.deviceCapability = 1;
+ device.groupCapability = 1;
+ device.status = WifiP2pDevice.CONNECTED;
+ if (SdkLevel.isAtLeastV()) {
+ device.setVendorData(OuiKeyedDataUtil.createTestOuiKeyedDataList(5));
+ }
+
+ Parcel parcel = Parcel.obtain();
+ device.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
+ WifiP2pDevice unparceledDevice = WifiP2pDevice.CREATOR.createFromParcel(parcel);
+
+ assertEquals(device.deviceName, unparceledDevice.deviceName);
+ assertEquals(device.deviceAddress, unparceledDevice.deviceAddress);
+ assertEquals(device.primaryDeviceType, unparceledDevice.primaryDeviceType);
+ assertEquals(device.secondaryDeviceType, unparceledDevice.secondaryDeviceType);
+ assertEquals(device.wpsConfigMethodsSupported, unparceledDevice.wpsConfigMethodsSupported);
+ assertEquals(device.deviceCapability, unparceledDevice.deviceCapability);
+ assertEquals(device.groupCapability, unparceledDevice.groupCapability);
+ assertEquals(device.status, unparceledDevice.status);
+ if (SdkLevel.isAtLeastV()) {
+ assertEquals(device.getVendorData(), unparceledDevice.getVendorData());
+ }
+ }
+
+ /**
+ * Test the setter/getter for device interface MAC address.
+ */
+ @Test
+ public void testInterfaceMacAddressSetterGetter() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ WifiP2pDevice device = new WifiP2pDevice();
+ device.setInterfaceMacAddress(INTERFACE_MAC_ADDRESS);
+ assertEquals(INTERFACE_MAC_ADDRESS, device.getInterfaceMacAddress());
+ }
+
+ /**
+ * Test the setter/getter for device IP address.
+ */
+ @Test
+ public void testIpAddressSetterGetter() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ WifiP2pDevice device = new WifiP2pDevice();
+ InetAddress ipAddress;
+ try {
+ ipAddress = InetAddress.getByName("192.168.49.1");
+ } catch (UnknownHostException e) {
+ return;
+ }
+ device.setIpAddress(ipAddress);
+ assertEquals("192.168.49.1", device.getIpAddress().getHostAddress());
+ }
}
diff --git a/framework/tests/src/android/net/wifi/p2p/WifiP2pDiscoveryConfigTest.java b/framework/tests/src/android/net/wifi/p2p/WifiP2pDiscoveryConfigTest.java
new file mode 100644
index 0000000000..9133ab724a
--- /dev/null
+++ b/framework/tests/src/android/net/wifi/p2p/WifiP2pDiscoveryConfigTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2023 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 android.net.wifi.p2p;
+
+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.wifi.OuiKeyedData;
+import android.net.wifi.OuiKeyedDataUtil;
+import android.os.Parcel;
+
+import com.android.modules.utils.build.SdkLevel;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+public class WifiP2pDiscoveryConfigTest {
+ private static final int TEST_SCAN_TYPE = WifiP2pManager.WIFI_P2P_SCAN_SINGLE_FREQ;
+ private static final int TEST_FREQUENCY_MHZ = 900;
+
+ @Before
+ public void setUp() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ }
+
+ /** Tests that the builder throws an exception if given an invalid integer argument. */
+ @Test
+ public void testBuilderInvalidIntegerArgument() {
+ assertThrows(IllegalArgumentException.class, () ->
+ new WifiP2pDiscoveryConfig.Builder(-1 /* scan type */).build());
+
+ WifiP2pDiscoveryConfig.Builder singleFreqBuilder =
+ new WifiP2pDiscoveryConfig.Builder(WifiP2pManager.WIFI_P2P_SCAN_SINGLE_FREQ);
+ assertThrows(IllegalArgumentException.class, () -> singleFreqBuilder.setFrequencyMhz(-1));
+ // Expect exception on build, since a valid frequency was not set.
+ assertThrows(IllegalArgumentException.class, () -> singleFreqBuilder.build());
+ }
+
+ /** Tests that the builder throws an exception if given a null vendor data value. */
+ @Test
+ public void testBuilderNullVendorData() {
+ WifiP2pDiscoveryConfig.Builder builder =
+ new WifiP2pDiscoveryConfig.Builder(TEST_SCAN_TYPE);
+ assertThrows(IllegalArgumentException.class, () -> builder.setVendorData(null));
+ }
+
+ /** Tests that this class can be properly parceled and unparceled. */
+ @Test
+ public void testParcelReadWrite() throws Exception {
+ List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
+ WifiP2pDiscoveryConfig config =
+ new WifiP2pDiscoveryConfig.Builder(TEST_SCAN_TYPE)
+ .setFrequencyMhz(TEST_FREQUENCY_MHZ)
+ .setVendorData(vendorData)
+ .build();
+ Parcel parcel = Parcel.obtain();
+ config.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
+ WifiP2pDiscoveryConfig unparceledConfig =
+ WifiP2pDiscoveryConfig.CREATOR.createFromParcel(parcel);
+
+ assertEquals(TEST_SCAN_TYPE, unparceledConfig.getScanType());
+ assertEquals(TEST_FREQUENCY_MHZ, unparceledConfig.getFrequencyMhz());
+ assertTrue(vendorData.equals(unparceledConfig.getVendorData()));
+ }
+}
diff --git a/framework/tests/src/android/net/wifi/p2p/WifiP2pExtListenParamsTest.java b/framework/tests/src/android/net/wifi/p2p/WifiP2pExtListenParamsTest.java
new file mode 100644
index 0000000000..7ac837c35b
--- /dev/null
+++ b/framework/tests/src/android/net/wifi/p2p/WifiP2pExtListenParamsTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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 android.net.wifi.p2p;
+
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.OuiKeyedDataUtil;
+import android.os.Parcel;
+
+import com.android.modules.utils.build.SdkLevel;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+public class WifiP2pExtListenParamsTest {
+ @Before
+ public void setUp() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ }
+
+ /** Tests that the builder throws an exception if given a null vendor data value. */
+ @Test
+ public void testBuilderNullVendorData() {
+ WifiP2pExtListenParams.Builder builder = new WifiP2pExtListenParams.Builder();
+ assertThrows(IllegalArgumentException.class, () -> builder.setVendorData(null));
+ }
+
+ /** Tests that this class can be properly parceled and unparceled. */
+ @Test
+ public void testParcelReadWrite() throws Exception {
+ List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
+ WifiP2pExtListenParams params =
+ new WifiP2pExtListenParams.Builder()
+ .setVendorData(vendorData)
+ .build();
+ Parcel parcel = Parcel.obtain();
+ params.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
+ WifiP2pExtListenParams unparceledParams =
+ WifiP2pExtListenParams.CREATOR.createFromParcel(parcel);
+ assertTrue(vendorData.equals(unparceledParams.getVendorData()));
+ }
+}
diff --git a/framework/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java b/framework/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java
index 9473e42184..e84a76bc28 100644
--- a/framework/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java
+++ b/framework/tests/src/android/net/wifi/p2p/WifiP2pGroupTest.java
@@ -18,14 +18,24 @@ package android.net.wifi.p2p;
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.InetAddresses;
+import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.OuiKeyedDataUtil;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
+import com.android.modules.utils.build.SdkLevel;
+
import org.junit.Test;
+import java.util.Collection;
+import java.util.List;
+
/**
* Unit test harness for {@link android.net.wifi.p2p.WifiP2pGroup}
*/
@@ -38,8 +48,15 @@ public class WifiP2pGroupTest {
private static final String PASSPHRASE = "HelloWorld";
private static final WifiP2pDevice GROUP_OWNER = new WifiP2pDevice("de:ad:be:ef:00:01");
private static final int FREQUENCY = 5300;
- private static final WifiP2pDevice CLIENT_1 = new WifiP2pDevice("aa:bb:cc:dd:ee:01");
- private static final WifiP2pDevice CLIENT_2 = new WifiP2pDevice("aa:bb:cc:dd:ee:02");
+ private static final String CLIENT_1_DEV_ADDRESS = "aa:bb:cc:dd:ee:01";
+ private static final String CLIENT_2_DEV_ADDRESS = "aa:bb:cc:dd:ee:02";
+ private static final WifiP2pDevice CLIENT_1 = new WifiP2pDevice(CLIENT_1_DEV_ADDRESS);
+ private static final WifiP2pDevice CLIENT_2 = new WifiP2pDevice(CLIENT_2_DEV_ADDRESS);
+ private static final MacAddress CLIENT_1_INTERFACE_MAC_ADDRESS =
+ MacAddress.fromString("aa:bb:cc:dd:ee:10");
+ private static final String CLIENT_1_IP_ADDRESS = "192.168.49.10";
+ private static final List<OuiKeyedData> VENDOR_DATA =
+ OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
/**
* Verify setter/getter functions.
@@ -56,7 +73,16 @@ public class WifiP2pGroupTest {
group.setOwner(GROUP_OWNER);
group.setFrequency(FREQUENCY);
group.addClient(CLIENT_1.deviceAddress);
+ group.setClientInterfaceMacAddress(CLIENT_1.deviceAddress,
+ CLIENT_1_INTERFACE_MAC_ADDRESS);
+ if (SdkLevel.isAtLeastV()) {
+ group.setClientIpAddress(CLIENT_1_INTERFACE_MAC_ADDRESS,
+ InetAddresses.parseNumericAddress(CLIENT_1_IP_ADDRESS));
+ }
group.addClient(CLIENT_2);
+ if (SdkLevel.isAtLeastV()) {
+ group.setVendorData(VENDOR_DATA);
+ }
assertEquals(INTERFACE, group.getInterface());
assertEquals(NETWORK_ID, group.getNetworkId());
@@ -65,11 +91,28 @@ public class WifiP2pGroupTest {
assertFalse(group.isGroupOwner());
assertEquals(GROUP_OWNER, group.getOwner());
assertEquals(FREQUENCY, group.getFrequency());
+ if (SdkLevel.isAtLeastV()) {
+ assertTrue(VENDOR_DATA.equals(group.getVendorData()));
+ }
assertFalse(group.isClientListEmpty());
assertTrue(group.contains(CLIENT_1));
assertEquals(2, group.getClientList().size());
+ Collection<WifiP2pDevice> clientsList = group.getClientList();
+ for (WifiP2pDevice client : clientsList) {
+ if (client.deviceAddress.equals(CLIENT_1_DEV_ADDRESS)) {
+ assertEquals(CLIENT_1_INTERFACE_MAC_ADDRESS, client.getInterfaceMacAddress());
+ if (SdkLevel.isAtLeastV()) {
+ assertEquals(CLIENT_1_IP_ADDRESS, client.getIpAddress().getHostAddress());
+ }
+ } else if (client.deviceAddress.equals(CLIENT_2_DEV_ADDRESS)) {
+ assertNull(client.getInterfaceMacAddress());
+ if (SdkLevel.isAtLeastV()) {
+ assertNull(client.getIpAddress());
+ }
+ }
+ }
group.removeClient(CLIENT_1);
group.removeClient(CLIENT_2.deviceAddress);
@@ -86,6 +129,9 @@ public class WifiP2pGroupTest {
parcelR.setDataPosition(0);
WifiP2pGroup fromParcel = WifiP2pGroup.CREATOR.createFromParcel(parcelR);
+ if (SdkLevel.isAtLeastV()) {
+ assertTrue(VENDOR_DATA.equals(fromParcel.getVendorData()));
+ }
assertEquals(group.toString(), fromParcel.toString());
}
diff --git a/framework/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java b/framework/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java
index 15116ebb47..21c42d8760 100644
--- a/framework/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java
+++ b/framework/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java
@@ -34,6 +34,7 @@ import static org.mockito.Mockito.when;
import android.content.AttributionSource;
import android.content.Context;
import android.net.wifi.ScanResult;
+import android.net.wifi.SynchronousExecutor;
import android.os.Bundle;
import android.os.test.TestLooper;
import android.view.Display;
@@ -267,4 +268,17 @@ public class WifiP2pManagerTest {
WifiP2pManager.FEATURE_GROUP_OWNER_IPV6_LINK_LOCAL_ADDRESS_PROVIDED);
assertTrue(mDut.isGroupOwnerIPv6LinkLocalAddressProvided());
}
+
+ @Test
+ public void testWifiP2pListener() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ SynchronousExecutor executor = mock(SynchronousExecutor.class);
+ WifiP2pManager.WifiP2pListener listener = mock(WifiP2pManager.WifiP2pListener.class);
+ mDut.initialize(mContextMock, mTestLooper.getLooper(), null);
+ mDut.registerWifiP2pListener(executor, listener);
+ verify(mP2pServiceMock).registerWifiP2pListener(any(IWifiP2pListener.Stub.class),
+ eq(PACKAGE_NAME), any(Bundle.class));
+ mDut.unregisterWifiP2pListener(listener);
+ verify(mP2pServiceMock).unregisterWifiP2pListener(any(IWifiP2pListener.Stub.class));
+ }
}
diff --git a/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
index 4f4e37e4b3..5514224ce6 100644
--- a/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
+++ b/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
@@ -29,6 +29,8 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
+import android.net.wifi.OuiKeyedDataUtil;
import android.net.wifi.ScanResult;
import android.net.wifi.aware.PeerHandle;
import android.os.Bundle;
@@ -38,6 +40,8 @@ import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
+import com.android.modules.utils.build.SdkLevel;
+
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -85,9 +89,17 @@ public class WifiRttManagerTest {
public void testRangeSuccess() throws Exception {
RangingRequest request = new RangingRequest.Builder().build();
List<RangingResult> results = new ArrayList<>();
- results.add(
- new RangingResult(RangingResult.STATUS_SUCCESS, MacAddress.BROADCAST_ADDRESS, 15, 5,
- 10, 8, 5, null, null, null, 666, true));
+ results.add(new RangingResult.Builder()
+ .setStatus(RangingResult.STATUS_SUCCESS)
+ .setMacAddress(MacAddress.BROADCAST_ADDRESS)
+ .setDistanceMm(15)
+ .setDistanceStdDevMm(5)
+ .setRssi(10)
+ .setNumAttemptedMeasurements(8)
+ .setNumSuccessfulMeasurements(5)
+ .setRangingTimestampMillis(666)
+ .set80211mcMeasurement(true)
+ .build());
RangingResultCallback callbackMock = mock(RangingResultCallback.class);
ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
@@ -155,6 +167,9 @@ public class WifiRttManagerTest {
builder.addWifiAwarePeer(mac1);
builder.addWifiAwarePeer(peerHandle1);
builder.setRttBurstSize(4);
+ if (SdkLevel.isAtLeastV()) {
+ builder.setVendorData(OuiKeyedDataUtil.createTestOuiKeyedDataList(5));
+ }
RangingRequest request = builder.build();
Parcel parcelW = Parcel.obtain();
@@ -444,11 +459,25 @@ public class WifiRttManagerTest {
long timestamp = System.currentTimeMillis();
byte[] lci = { 0x5, 0x6, 0x7 };
byte[] lcr = { 0x1, 0x2, 0x3, 0xA, 0xB, 0xC };
+ List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
// RangingResults constructed with a MAC address
- RangingResult result = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
- numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr, null, timestamp,
- true);
+ RangingResult.Builder resultBuilder = new RangingResult.Builder()
+ .setStatus(status)
+ .setMacAddress(mac)
+ .setDistanceMm(distanceCm)
+ .setDistanceStdDevMm(distanceStdDevCm)
+ .setRssi(rssi)
+ .setNumAttemptedMeasurements(numAttemptedMeasurements)
+ .setNumSuccessfulMeasurements(numSuccessfulMeasurements)
+ .setLci(lci)
+ .setLcr(lcr)
+ .setRangingTimestampMillis(timestamp)
+ .set80211mcMeasurement(true);
+ if (SdkLevel.isAtLeastV()) {
+ resultBuilder.setVendorData(vendorData);
+ }
+ RangingResult result = resultBuilder.build();
Parcel parcelW = Parcel.obtain();
result.writeToParcel(parcelW, 0);
@@ -463,21 +492,19 @@ public class WifiRttManagerTest {
assertEquals(result, rereadResult);
// RangingResults constructed with a PeerHandle
- result =
- new RangingResult(
- status,
- peerHandle,
- distanceCm,
- distanceStdDevCm,
- rssi,
- numAttemptedMeasurements,
- numSuccessfulMeasurements,
- null,
- null,
- null,
- timestamp,
- RangingResult.UNSPECIFIED,
- RangingResult.UNSPECIFIED);
+ resultBuilder = new RangingResult.Builder()
+ .setStatus(status)
+ .setPeerHandle(peerHandle)
+ .setDistanceMm(distanceCm)
+ .setDistanceStdDevMm(distanceStdDevCm)
+ .setRssi(rssi)
+ .setNumAttemptedMeasurements(numAttemptedMeasurements)
+ .setNumSuccessfulMeasurements(numSuccessfulMeasurements)
+ .setRangingTimestampMillis(timestamp);
+ if (SdkLevel.isAtLeastV()) {
+ resultBuilder.setVendorData(vendorData);
+ }
+ result = resultBuilder.build();
parcelW = Parcel.obtain();
result.writeToParcel(parcelW, 0);
@@ -509,13 +536,30 @@ public class WifiRttManagerTest {
byte[] lci = { };
byte[] lcr = { };
- RangingResult rr1 = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
- numAttemptedMeasurements, numSuccessfulMeasurements, lci, lcr, null, timestamp,
- true);
- RangingResult rr2 = new RangingResult(status, mac, distanceCm, distanceStdDevCm, rssi,
- numAttemptedMeasurements, numSuccessfulMeasurements, null, null, null, timestamp,
- true);
-
+ RangingResult rr1 = new RangingResult.Builder()
+ .setStatus(status)
+ .setMacAddress(mac)
+ .setDistanceMm(distanceCm)
+ .setDistanceStdDevMm(distanceStdDevCm)
+ .setRssi(rssi)
+ .setNumAttemptedMeasurements(numAttemptedMeasurements)
+ .setNumSuccessfulMeasurements(numSuccessfulMeasurements)
+ .setLci(lci)
+ .setLcr(lcr)
+ .setRangingTimestampMillis(timestamp)
+ .set80211mcMeasurement(true)
+ .build();
+ RangingResult rr2 = new RangingResult.Builder()
+ .setStatus(status)
+ .setMacAddress(mac)
+ .setDistanceMm(distanceCm)
+ .setDistanceStdDevMm(distanceStdDevCm)
+ .setRssi(rssi)
+ .setNumAttemptedMeasurements(numAttemptedMeasurements)
+ .setNumSuccessfulMeasurements(numSuccessfulMeasurements)
+ .setRangingTimestampMillis(timestamp)
+ .set80211mcMeasurement(true)
+ .build();
assertEquals(rr1, rr2);
}
@@ -525,9 +569,15 @@ public class WifiRttManagerTest {
@Test
public void testResponderConfigParcel() {
// ResponderConfig constructed with a MAC address
- ResponderConfig config = new ResponderConfig(MacAddress.fromString("00:01:02:03:04:05"),
- ResponderConfig.RESPONDER_AP, true, ResponderConfig.CHANNEL_WIDTH_80MHZ, 2134, 2345,
- 2555, ResponderConfig.PREAMBLE_LEGACY);
+ ResponderConfig config = new ResponderConfig.Builder()
+ .setMacAddress(MacAddress.fromString("00:01:02:03:04:05"))
+ .set80211mcSupported(true)
+ .setChannelWidth(ScanResult.CHANNEL_WIDTH_80MHZ)
+ .setFrequencyMhz(2134)
+ .setCenterFreq0Mhz(2345)
+ .setCenterFreq1Mhz(2555)
+ .setPreamble(ScanResult.PREAMBLE_LEGACY)
+ .build();
Parcel parcelW = Parcel.obtain();
config.writeToParcel(parcelW, 0);
@@ -542,9 +592,16 @@ public class WifiRttManagerTest {
assertEquals(config, rereadConfig);
// ResponderConfig constructed with a PeerHandle
- config = new ResponderConfig(new PeerHandle(10), ResponderConfig.RESPONDER_AWARE, false,
- ResponderConfig.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, 5555, 6666, 7777,
- ResponderConfig.PREAMBLE_VHT);
+ config = new ResponderConfig.Builder()
+ .setPeerHandle(new PeerHandle(10))
+ .setResponderType(ResponderConfig.RESPONDER_AWARE)
+ .set80211mcSupported(false)
+ .setChannelWidth(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ)
+ .setFrequencyMhz(5555)
+ .setCenterFreq0Mhz(6666)
+ .setCenterFreq1Mhz(7777)
+ .setPreamble(ScanResult.PREAMBLE_VHT)
+ .build();
parcelW = Parcel.obtain();
config.writeToParcel(parcelW, 0);
diff --git a/framework/tests/src/android/net/wifi/twt/TwtRequestTest.java b/framework/tests/src/android/net/wifi/twt/TwtRequestTest.java
new file mode 100644
index 0000000000..81f5a61b33
--- /dev/null
+++ b/framework/tests/src/android/net/wifi/twt/TwtRequestTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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 android.net.wifi.twt;
+
+import static android.net.wifi.MloLink.MAX_MLO_LINK_ID;
+import static android.net.wifi.MloLink.MIN_MLO_LINK_ID;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link TwtRequest}
+ */
+@SmallTest
+public class TwtRequestTest {
+ @Test
+ public void testTwtRequest() {
+
+ final int testMinWakeDuration = 100;
+ final int testMaxWakeDuration = 1000;
+ final int testMinWakeInterval = 9999;
+ final int testMaxWakeInterval = 999999;
+ final int testMloLinkId = 2;
+
+ TwtRequest.Builder builder = new TwtRequest.Builder(testMinWakeDuration,
+ testMaxWakeDuration, testMinWakeInterval, testMaxWakeInterval);
+
+ assertThrows(IllegalArgumentException.class, () -> builder.setLinkId(MIN_MLO_LINK_ID - 1));
+ assertThrows(IllegalArgumentException.class, () -> builder.setLinkId(MAX_MLO_LINK_ID + 1));
+
+ builder.setLinkId(testMloLinkId);
+ TwtRequest twtRequest = builder.build();
+ assertEquals(testMinWakeDuration, twtRequest.getMinWakeDurationMicros());
+ assertEquals(testMaxWakeDuration, twtRequest.getMaxWakeDurationMicros());
+ assertEquals(testMinWakeInterval, twtRequest.getMinWakeIntervalMicros());
+ assertEquals(testMaxWakeInterval, twtRequest.getMaxWakeIntervalMicros());
+ assertEquals(testMloLinkId, twtRequest.getLinkId());
+ }
+}
diff --git a/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java b/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java
index b1116332de..4a485c06ab 100644
--- a/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java
+++ b/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java
@@ -44,8 +44,16 @@ public class ScanResultUtilTest {
@Test
public void testNetworkCreationFromScanResult() {
final String ssid = "Another SSid";
- ScanResult scanResult = new ScanResult(ssid, "ab:cd:01:ef:45:89", 1245, 0, "",
- -78, 2450, 1025, 22, 33, 20, 0, 0, true);
+ ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(ssid),
+ "ab:cd:01:ef:45:89")
+ .setHessid(1245)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
scanResult.informationElements = new InformationElement[] {
createIE(InformationElement.EID_SSID, ssid.getBytes(StandardCharsets.UTF_8))
};
@@ -137,22 +145,16 @@ public class ScanResultUtilTest {
@Test
public void testGenerateSecurityParamsListFromScanResult() {
final String ssid = "Another SSid";
- ScanResult scanResult =
- new ScanResult(
- ssid,
- "ab:cd:01:ef:45:89",
- 1245,
- 0,
- "",
- -78,
- 2450,
- 1025,
- 22,
- 33,
- 20,
- 0,
- 0,
- true);
+ ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(ssid),
+ "ab:cd:01:ef:45:89")
+ .setHessid(1245)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
scanResult.informationElements =
new InformationElement[] {
createIE(InformationElement.EID_SSID, ssid.getBytes(StandardCharsets.UTF_8))
@@ -314,9 +316,17 @@ public class ScanResultUtilTest {
final String ssid = "WPA3-Transition";
String caps = "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -333,9 +343,17 @@ public class ScanResultUtilTest {
final String ssid = "WPA3-Transition";
String caps = "[WPA2-FT/PSK+PSK+SAE+FT/SAE-CCMP][ESS][WPS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -352,9 +370,17 @@ public class ScanResultUtilTest {
final String ssid = "WPA2-Network";
String caps = "[WPA2-FT/PSK+PSK][ESS][WPS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -371,9 +397,17 @@ public class ScanResultUtilTest {
final String ssid = "WPA3-Network";
String caps = "[WPA2-FT/SAE+SAE][ESS][WPS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -390,9 +424,17 @@ public class ScanResultUtilTest {
final String ssid = "WPA3-AP";
String caps = "[RSN-SAE_EXT_KEY-CCMP][ESS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -409,9 +451,17 @@ public class ScanResultUtilTest {
final String ssid = "FT-EAP-AP";
String caps = " [WPA2-FT/EAP-CCMP][RSN-FT/EAP-CCMP][ESS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -429,9 +479,17 @@ public class ScanResultUtilTest {
String caps = "[WPA2-EAP-FILS-SHA256-CCMP]"
+ "[RSN-EAP-FILS-SHA256-CCMP][ESS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -450,9 +508,17 @@ public class ScanResultUtilTest {
String caps = "[WPA2-EAP-FILS-SHA384-CCMP]"
+ "[RSN-EAP-FILS-SHA384-CCMP][ESS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -470,9 +536,17 @@ public class ScanResultUtilTest {
final String ssid = "EAP-NETWORK";
String caps = "[EAP/SHA1][ESS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -488,9 +562,18 @@ public class ScanResultUtilTest {
boolean isR1R2Network, boolean isR3Network) {
final String ssid = "PASSPOINT-NETWORK";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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();
+
if (isPasspoint) {
input.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK);
}
@@ -545,9 +628,17 @@ public class ScanResultUtilTest {
final String ssid = "UnknownAkm-Network";
String caps = "[RSN-?-TKIP+CCMP][ESS][WPS]";
- ScanResult input = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ 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))
@@ -558,9 +649,19 @@ public class ScanResultUtilTest {
private ScanResult makeScanResult(String caps) {
final String ssid = "TestSsid";
- ScanResult r = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+
+ ScanResult r = 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();
+
return r;
}
@@ -645,8 +746,17 @@ public class ScanResultUtilTest {
@Test
public void testUnknownAkmForSecurityParamsGeneration() {
final String ssid = "Another SSid";
- ScanResult scanResult = new ScanResult(ssid, "ab:cd:01:ef:45:89", 1245, 0, "",
- -78, 2450, 1025, 22, 33, 20, 0, 0, true);
+ ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(ssid),
+ "ab:cd:01:ef:45:89")
+ .setHessid(1245)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
+
scanResult.informationElements = new InformationElement[] {
createIE(InformationElement.EID_SSID, ssid.getBytes(StandardCharsets.UTF_8))
};
diff --git a/service/Android.bp b/service/Android.bp
index 10bcdbadf9..220d9fb74a 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -121,7 +121,7 @@ java_library {
"service-entitlement",
"wifi-lite-protos",
"wifi-nano-protos",
- "wifi_aconfig_flags_lib",
+ "android.net.wifi.flags-aconfig-java",
],
apex_available: ["com.android.wifi"],
}
diff --git a/service/ServiceWifiResources/res/values-af/strings.xml b/service/ServiceWifiResources/res/values-af/strings.xml
index 5e429c91d8..3473553ae0 100644
--- a/service/ServiceWifiResources/res/values-af/strings.xml
+++ b/service/ServiceWifiResources/res/values-af/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Aan:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Voer die vereiste PIN in:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Die tablet sal tydelik van Wi-Fi ontkoppel terwyl dit aan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gekoppel is"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Jou Android TV-toestel sal tydelik van Wi-Fi ontkoppel terwyl dit aan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gekoppel is"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Die foon sal tydelik van Wi-Fi ontkoppel terwyl dit aan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gekoppel is"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Jou toestel sal tydelik van wi-fi af ontkoppel word terwyl dit aan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gekoppel is"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Kan nie aan <xliff:g id="SSID">%1$s</xliff:g> koppel nie"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tik om privaatheidinstellings te verander en herprobeer"</string>
diff --git a/service/ServiceWifiResources/res/values-am/strings.xml b/service/ServiceWifiResources/res/values-am/strings.xml
index 24af7e8ad8..4adbe8c0fb 100644
--- a/service/ServiceWifiResources/res/values-am/strings.xml
+++ b/service/ServiceWifiResources/res/values-am/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"ለ፦"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"የሚፈለገውን ፒን ተይብ፦"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"ፒን፦"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"ጡባዊው ከ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ጋር ተገናኝቶ ባለበት ጊዜ በጊዜያዊነት ከWi-Fi ጋር ይላቀቃል"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"ወደ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ተገናኝቶ ሳለ የእርስዎ Android TV መሣሪያ ለጊዜው ከ Wi-Fi ግንኙነቱ ይቋረጣል"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ስልኩ ከ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ጋር ተገናኝቶ ባለበት ጊዜ በጊዜያዊነት ከWi-Fi ጋር ያለው ግንኙነት ይቋረጣል"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"መሣሪያዎ ከ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ጋር በሚገናኝበት ጊዜ ለጊዜው ከWi-Fi ጋር ግንኙነቱ ይቋረጣል"</string>
<string name="dlg_ok" msgid="254496739491689405">"እሺ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"ከ<xliff:g id="SSID">%1$s</xliff:g> ጋር መገናኘት አልተቻለም"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"የግላዊነት ቅንብሮችን ለመቀየር መታ ያድርጉ እና ዳግም ይሞክሩ"</string>
diff --git a/service/ServiceWifiResources/res/values-ar/strings.xml b/service/ServiceWifiResources/res/values-ar/strings.xml
index 9b015a264f..619d94501f 100644
--- a/service/ServiceWifiResources/res/values-ar/strings.xml
+++ b/service/ServiceWifiResources/res/values-ar/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"إلى:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"‏اكتب رمز PIN المطلوب:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"رقم التعريف الشخصي:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"‏سيتم قطع اتصال الجهاز اللوحي مؤقتًا بشبكة Wi-Fi في الوقت الذي يكون فيه متصلاً بـ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"‏سيتم قطع اتصال جهاز Android TV بشبكة Wi-Fi مؤقتًا أثناء اتصاله بجهاز<xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"‏سيتم قطع اتصال الهاتف مؤقتًا بشبكة Wi-Fi في الوقت الذي يكون فيه متصلاً بـ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"‏سيتم قطع اتصال الجهاز بشبكة Wi-Fi مؤقتًا أثناء اتصاله بـ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"حسنًا"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"يتعذّر الاتصال بـ <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"انقر لتغيير إعدادات الخصوصية وإعادة المحاولة."</string>
diff --git a/service/ServiceWifiResources/res/values-as/strings.xml b/service/ServiceWifiResources/res/values-as/strings.xml
index 7f47460530..4b2f966940 100644
--- a/service/ServiceWifiResources/res/values-as/strings.xml
+++ b/service/ServiceWifiResources/res/values-as/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"প্ৰতি:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"প্ৰয়োজনীয় পিন নম্বৰটো লিখক:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"পিন:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"টি.ভি.টো <xliff:g id="DEVICE_NAME">%1$s</xliff:g> লৈ সংযোগ হৈ থকাৰ অৱস্থাত অস্থায়ীভাৱে ৱাই-ফাইৰ পৰা সংযোগ বিচ্ছিন্ন হ\'ব"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"আপোনাৰ Android TV ডিভাইচটো <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ লগত সংযোগ হ’লে অস্থায়ীভাৱে ৱাই-ফাইৰ পৰা সংযোগ বিচ্ছিন্ন হ’ব"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ফ\'নটো <xliff:g id="DEVICE_NAME">%1$s</xliff:g> লৈ সংযোগ হ\'লে ৱাই-ফাইৰ পৰা কিছু সময়ৰ বাবে সংযোগ স্বীকাৰ বিচ্ছিন্ন হ\'ব"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"আপোনাৰ ডিভাইচটো <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ লগত সংযুক্ত হৈ থকাৰ অৱস্থাত অস্থায়ীভাৱে ৱাই-ফাইৰ পৰা সংযোগ বিচ্ছিন্ন হ’ব"</string>
<string name="dlg_ok" msgid="254496739491689405">"ঠিক আছে"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g>ৰ সৈতে সংযোগ কৰিব নোৱাৰি"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"গোপনীয়তাৰ ছেটিং সলনি কৰিবলৈ আৰু পুনৰ চেষ্টা কৰিবলৈ টিপক"</string>
diff --git a/service/ServiceWifiResources/res/values-az/strings.xml b/service/ServiceWifiResources/res/values-az/strings.xml
index b9f844492e..b39b9715cc 100644
--- a/service/ServiceWifiResources/res/values-az/strings.xml
+++ b/service/ServiceWifiResources/res/values-az/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kimə:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Tələb olunan PİN kodu daxil edin:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PİN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Bu planşet <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazına qoşulan zaman Wi-Fi şəbəkəsindən müvəqqəti ayrılmış olacaq"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazına qoşularkən Wi-Fi bağlantısı müvəqqəti olaraq kəsiləcək."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Bu telefon <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazına qoşulan zaman Wi-Fi şəbəkəsindən müvəqqəti ayrılmış olacaq"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazına qoşulanda cihaz Wi-Fi-dan müvəqqəti ayrılacaq"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> şəbəkəsinə qoşulmaq mümkün deyil"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Toxunaraq məxfilik ayarını dəyişin və yenidən cəhd edin"</string>
diff --git a/service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml b/service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml
index 97bd1970cd..6799970ff6 100644
--- a/service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml
+++ b/service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kome:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Unesite potrebni PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tablet će privremeno prekinuti vezu sa WiFi-em dok je povezan sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV uređaj će privremeno prekinuti vezu sa WiFi mrežom dok je povezan sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefon će privremeno prekinuti vezu sa WiFi-em dok je povezan sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Uređaj će privremeno prekinuti vezu sa WiFi mrežom dok je povezan sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Potvrdi"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Povezivanje na mrežu <xliff:g id="SSID">%1$s</xliff:g> nije uspelo"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Dodirnite da biste promenili podešavanja privatnosti i probali ponovo"</string>
diff --git a/service/ServiceWifiResources/res/values-be/strings.xml b/service/ServiceWifiResources/res/values-be/strings.xml
index 9212251cc3..ae333d9730 100644
--- a/service/ServiceWifiResources/res/values-be/strings.xml
+++ b/service/ServiceWifiResources/res/values-be/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Каму:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Увядзіце патрэбны PIN-код:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-код"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Тэлефон будзе часова адключаны ад сеткі Wi-Fi, пакуль ён падлучаны да прылады <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Прылада Android TV будзе часова адключана ад сеткі Wi-Fi, пакуль яна падключана да прылады \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\""</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Тэлефон будзе часова адключаны ад Wi-Fi, пакуль ён падлучаны да прылады <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Прылада будзе часова заставацца адключанай ад сеткі Wi-Fi, пакуль падключана да прылады \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\""</string>
<string name="dlg_ok" msgid="254496739491689405">"ОК"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Не ўдалося падключыцца да сеткі \"<xliff:g id="SSID">%1$s</xliff:g>\""</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Націсніце, каб змяніць налады прыватнасці, і паўтарыце спробу"</string>
diff --git a/service/ServiceWifiResources/res/values-bg/strings.xml b/service/ServiceWifiResources/res/values-bg/strings.xml
index 16cf7424df..eb2f5f49da 100644
--- a/service/ServiceWifiResources/res/values-bg/strings.xml
+++ b/service/ServiceWifiResources/res/values-bg/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"До:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Въведете задължителния ПИН:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"ПИН:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Таблетът временно ще прекъсне връзката с Wi-Fi, докато е свързан с/ъс <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Wi-Fi връзката на устройството ви с Android TV временно ще бъде прекратена, докато то е свързано към <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Телефонът временно ще прекрати връзката с Wi-Fi, докато е свързан с/ъс <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Връзката с Wi-Fi на устройството ви временно ще бъде прекратена, докато то е свързано с(ъс) <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Не може да се установи връзка с(ъс) <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Докоснете, за да промените настройките за поверителност, и опитайте отново"</string>
diff --git a/service/ServiceWifiResources/res/values-bn/strings.xml b/service/ServiceWifiResources/res/values-bn/strings.xml
index f43872581d..f981dc2988 100644
--- a/service/ServiceWifiResources/res/values-bn/strings.xml
+++ b/service/ServiceWifiResources/res/values-bn/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"প্রাপক:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"প্রয়োজনীয় পিনটি লিখুন:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"পিন:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"ট্যাবলেটটি যখন <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এ সংযুক্ত হবে তখন এটি ওয়াই-ফাই থেকে সাময়িকভাবে সংযোগ বিচ্ছিন্ন হবে"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>-এ কানেক্ট থাকা অবস্থায় আপনার Android TV ডিভাইস সাময়িকভাবে ওয়াই-ফাই থেকে ডিসকানেক্ট হয়ে যাবে"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ফোনটি যখন <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এ সংযুক্ত হবে তখন এটি ওয়াই-ফাই থেকে সাময়িকভাবে সংযোগ বিচ্ছিন্ন হবে"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>-এ কানেক্ট থাকা অবস্থায় আপনার ডিভাইস সাময়িকভাবে ওয়াই-ফাই থেকে ডিসকানেক্ট হয়ে যাবে"</string>
<string name="dlg_ok" msgid="254496739491689405">"ঠিক আছে"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g>-এর সাথে কানেক্ট করা যাচ্ছে না"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"গোপনীয়তা সেটিংস পরিবর্তন করতে এবং আবার চেষ্টা করতে ট্যাপ করুন"</string>
diff --git a/service/ServiceWifiResources/res/values-bs/strings.xml b/service/ServiceWifiResources/res/values-bs/strings.xml
index 73414bdde2..ca0ea80d7a 100644
--- a/service/ServiceWifiResources/res/values-bs/strings.xml
+++ b/service/ServiceWifiResources/res/values-bs/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Prima:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Unesite potrebni PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tablet će privremeno prekinuti WiFi vezu dok bude povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Povezanost Android TV uređaja i WiFi mreže će se privremeno prekinuti dok je povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefon će privremeno prekinuti WiFi vezu dok bude povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Povezanost uređaja s WiFi mrežom će se privremeno prekinuti dok je povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Uredu"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Nije se moguće povezati s mrežom <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Dodirnite da promijenite postavke privatnosti i pokušajte ponovo"</string>
diff --git a/service/ServiceWifiResources/res/values-ca/strings.xml b/service/ServiceWifiResources/res/values-ca/strings.xml
index 86c4fe2d7c..97483600ba 100644
--- a/service/ServiceWifiResources/res/values-ca/strings.xml
+++ b/service/ServiceWifiResources/res/values-ca/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Per a:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Introdueix el PIN sol·licitat:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"La tauleta es desconnectarà temporalment de la Wi-Fi mentre estigui connectada a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"El dispositiu Android TV es desconnectarà temporalment de la Wi‑Fi mentre estigui connectat a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"El telèfon es desconnectarà temporalment de la Wi-Fi mentre estigui connectat a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"El dispositiu es desconnectarà temporalment de la Wi‑Fi mentre estigui connectat a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"D\'acord"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"No es pot connectar a <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Toca per canviar la configuració de privadesa i torna-ho a provar"</string>
diff --git a/service/ServiceWifiResources/res/values-cs/strings.xml b/service/ServiceWifiResources/res/values-cs/strings.xml
index 99640357a9..e26e53cedb 100644
--- a/service/ServiceWifiResources/res/values-cs/strings.xml
+++ b/service/ServiceWifiResources/res/values-cs/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Komu:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Zadejte požadovaný kód PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tablet se při připojení k zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g> dočasně odpojí od sítě Wi-Fi"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Zatímco bude zařízení Android TV připojeno k zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, dočasně se odpojí od sítě Wi-Fi."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefon se při připojení k zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g> dočasně odpojí od sítě Wi-Fi"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Zatímco bude zařízení připojeno k zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, dočasně se odpojí od Wi-Fi"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"K síti <xliff:g id="SSID">%1$s</xliff:g> se nelze připojit"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Klepnutím změníte nastavení ochrany soukromí a budete opakovat pokus"</string>
diff --git a/service/ServiceWifiResources/res/values-da/strings.xml b/service/ServiceWifiResources/res/values-da/strings.xml
index 5d08fa5298..6a27388ae7 100644
--- a/service/ServiceWifiResources/res/values-da/strings.xml
+++ b/service/ServiceWifiResources/res/values-da/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Til:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Skriv den påkrævede pinkode:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"Pinkode:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Wi-Fi-forbindelse til tabletten vil midlertidigt blive afbrudt, når den er tilsluttet <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Wi-Fi-forbindelsen til din Android TV-enhed bliver midlertidigt afbrudt, når den er tilsluttet <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefonens Wi-Fi-forbindelse vil midlertidigt blive afbrudt, når den er tilsluttet <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Enhedens Wi-Fi-forbindelse afbrydes midlertidigt, når den er tilknyttet <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Der kan ikke oprettes forbindelse til <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tryk for at ændre privatlivsindstillingerne, og prøv igen"</string>
diff --git a/service/ServiceWifiResources/res/values-de/strings.xml b/service/ServiceWifiResources/res/values-de/strings.xml
index 1f5c2bdf9c..4032ff10e2 100644
--- a/service/ServiceWifiResources/res/values-de/strings.xml
+++ b/service/ServiceWifiResources/res/values-de/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"An:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Gib die PIN ein:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Das Tablet wird vorübergehend vom WLAN getrennt, während eine Verbindung mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> besteht."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Das Android TV-Gerät wird vorübergehend vom WLAN getrennt, während es mit \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" verbunden ist."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Das Telefon wird vorübergehend vom WLAN getrennt, während eine Verbindung mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> hergestellt wird."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Dein Gerät wird vorübergehend vom WLAN getrennt, während es mit „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“ verbunden ist"</string>
<string name="dlg_ok" msgid="254496739491689405">"Ok"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Verbindung zu <xliff:g id="SSID">%1$s</xliff:g> nicht möglich"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tippe, um die Datenschutzeinstellung zu ändern und es noch einmal zu versuchen"</string>
diff --git a/service/ServiceWifiResources/res/values-el/strings.xml b/service/ServiceWifiResources/res/values-el/strings.xml
index 09ae52a997..1e3a8e0b0e 100644
--- a/service/ServiceWifiResources/res/values-el/strings.xml
+++ b/service/ServiceWifiResources/res/values-el/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Προς:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Πληκτρολογήστε τον απαιτούμενο κωδικό PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Το tablet θα αποσυνδεθεί προσωρινά από το δίκτυο Wi-Fi ενώ συνδέεται στη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Η συσκευή σας Android TV θα αποσυνδεθεί προσωρινά από το δίκτυο Wi-Fi, ενόσω είναι συνδεδεμένη στη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Το τηλέφωνο θα αποσυνδεθεί προσωρινά από το δίκτυο Wi-Fi ενώ συνδέεται στη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Η συσκευή σας θα αποσυνδεθεί προσωρινά από το δίκτυο Wi-Fi ενώ είναι συνδεδεμένη στη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"ΟΚ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Δεν είναι δυνατή η σύνδεση με <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Πατήστε για αλλαγή των ρυθμίσεων απορρήτου και δοκιμάστε ξανά"</string>
diff --git a/service/ServiceWifiResources/res/values-en-rAU/strings.xml b/service/ServiceWifiResources/res/values-en-rAU/strings.xml
index c5540fef7e..03afd3affa 100644
--- a/service/ServiceWifiResources/res/values-en-rAU/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rAU/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"To:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Type the required PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Your Android TV device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Your device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Can\'t connect to <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tap to change privacy settings and retry"</string>
diff --git a/service/ServiceWifiResources/res/values-en-rCA/strings.xml b/service/ServiceWifiResources/res/values-en-rCA/strings.xml
index b89fb28d5f..d15645c2c7 100644
--- a/service/ServiceWifiResources/res/values-en-rCA/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rCA/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"To:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Type the required PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Your Android TV device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Your device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Can\'t connect to <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tap to change privacy settings and retry"</string>
diff --git a/service/ServiceWifiResources/res/values-en-rGB/strings.xml b/service/ServiceWifiResources/res/values-en-rGB/strings.xml
index c5540fef7e..03afd3affa 100644
--- a/service/ServiceWifiResources/res/values-en-rGB/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rGB/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"To:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Type the required PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Your Android TV device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Your device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Can\'t connect to <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tap to change privacy settings and retry"</string>
diff --git a/service/ServiceWifiResources/res/values-en-rIN/strings.xml b/service/ServiceWifiResources/res/values-en-rIN/strings.xml
index c5540fef7e..03afd3affa 100644
--- a/service/ServiceWifiResources/res/values-en-rIN/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rIN/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"To:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Type the required PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Your Android TV device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Your device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Can\'t connect to <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tap to change privacy settings and retry"</string>
diff --git a/service/ServiceWifiResources/res/values-en-rXC/strings.xml b/service/ServiceWifiResources/res/values-en-rXC/strings.xml
index d5e5c56c98..6c41c5400c 100644
--- a/service/ServiceWifiResources/res/values-en-rXC/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rXC/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎To:‎‏‎‎‏‎"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎Type the required PIN:‎‏‎‎‏‎"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎PIN:‎‏‎‎‏‎"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‎‎The tablet will temporarily disconnect from Wi-Fi while it\'s connected to ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎Your Android TV device will temporarily disconnect from Wi-Fi while it\'s connected to ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‎The phone will temporarily disconnect from Wi-Fi while it\'s connected to ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎Your device will temporarily disconnect from Wi-Fi while it\'s connected to ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="dlg_ok" msgid="254496739491689405">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎OK‎‏‎‎‏‎"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎Can\'t connect to ‎‏‎‎‏‏‎<xliff:g id="SSID">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‎Tap to change privacy settings and retry‎‏‎‎‏‎"</string>
diff --git a/service/ServiceWifiResources/res/values-es-rUS/strings.xml b/service/ServiceWifiResources/res/values-es-rUS/strings.xml
index 66ddc08d91..200eb24cba 100644
--- a/service/ServiceWifiResources/res/values-es-rUS/strings.xml
+++ b/service/ServiceWifiResources/res/values-es-rUS/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Para:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Escribe el PIN solicitado:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"La tablet se desconectará temporalmente de la red Wi-Fi mientras esté conectada a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Se desconectará temporalmente el dispositivo Android TV de la red Wi-Fi mientras esté conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"El dispositivo se desconectará temporalmente de la red Wi-Fi mientras esté conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Se desconectará temporalmente el dispositivo de la red Wi-Fi mientras esté conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Aceptar"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"No se puede establecer conexión con <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Presiona para cambiar la configuración de privacidad y volver a intentarlo"</string>
diff --git a/service/ServiceWifiResources/res/values-es/strings.xml b/service/ServiceWifiResources/res/values-es/strings.xml
index 6302a34ff4..33f0d5e984 100644
--- a/service/ServiceWifiResources/res/values-es/strings.xml
+++ b/service/ServiceWifiResources/res/values-es/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Para:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Escribe el PIN solicitado:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"El tablet se desconectará temporalmente de la red Wi-Fi mientras esté conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Mientras el dispositivo Android TV esté conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, se desconectará temporalmente de la red Wi‑Fi"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"El teléfono se desconectará temporalmente de la red Wi-Fi mientras está conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Tu dispositivo se desconectará temporalmente de la red Wi-Fi mientras esté conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Aceptar"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"No se puede conectar a <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Toca para cambiar los ajustes de privacidad y vuelve a intentarlo"</string>
diff --git a/service/ServiceWifiResources/res/values-et/strings.xml b/service/ServiceWifiResources/res/values-et/strings.xml
index 6ad483c705..444af98731 100644
--- a/service/ServiceWifiResources/res/values-et/strings.xml
+++ b/service/ServiceWifiResources/res/values-et/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Saaja:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Sisestage nõutav PIN-kood:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-kood:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tahvelarvuti ühendus WiFi-ga katkestatakse ajutiselt, kui see on ühendatud seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ühendamisel katkestatakse ajutiselt Android TV seadme ühendus WiFi-võrguga."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefoni ühendus WiFi-ga katkestatakse ajutiselt, kui see on ühendatud seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ühenduse loomisel katkestatakse ajutiselt teie seadme ühendus WiFi-võrguga."</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Võrguga <xliff:g id="SSID">%1$s</xliff:g> ei õnnestu ühendada"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Puudutage privaatsusseadete muutmiseks ja uuesti proovimiseks"</string>
diff --git a/service/ServiceWifiResources/res/values-eu/strings.xml b/service/ServiceWifiResources/res/values-eu/strings.xml
index c1463a4871..9ec4e91d5c 100644
--- a/service/ServiceWifiResources/res/values-eu/strings.xml
+++ b/service/ServiceWifiResources/res/values-eu/strings.xml
@@ -40,10 +40,10 @@
<string name="wifi_suggestion_imsi_privacy_exemption_confirmation_content" msgid="9211241189147807136">"Konektatzen bazara, baliteke <xliff:g id="CARRIERNAME">%s</xliff:g> operadorearen wifi-sareek zure SIM txartelarekin lotutako identifikatzaile esklusiboa atzitzea edo partekatzea. Horrela, baliteke zure gailuaren kokapenaren jarraipena egiteko aukera izatea."</string>
<string name="wifi_suggestion_action_allow_imsi_privacy_exemption_confirmation" msgid="2168947026413431603">"Konektatu"</string>
<string name="wifi_suggestion_action_disallow_imsi_privacy_exemption_confirmation" msgid="5156881939985876066">"Ez konektatu"</string>
- <string name="wifi_wakeup_onboarding_title" msgid="3868826648004934540">"Wi‑Fi konexioa automatikoki aktibatuko da"</string>
+ <string name="wifi_wakeup_onboarding_title" msgid="3868826648004934540">"Wifi-konexioa automatikoki aktibatuko da"</string>
<string name="wifi_wakeup_onboarding_subtext" msgid="5705886295837387430">"Gordeta daukazun kalitate handiko sare batetik gertu zaudenean"</string>
<string name="wifi_wakeup_onboarding_action_disable" msgid="6209706680391785825">"Ez aktibatu berriro"</string>
- <string name="wifi_wakeup_enabled_title" msgid="5043486751612595850">"Automatikoki aktibatu da Wi‑Fi konexioa"</string>
+ <string name="wifi_wakeup_enabled_title" msgid="5043486751612595850">"Automatikoki aktibatu da wifi-konexioa"</string>
<string name="wifi_wakeup_enabled_content" msgid="3911262526267025882">"Gordetako sare honetatik gertu zaude: <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
<string name="wifi_watchdog_network_disabled" msgid="5769226742956006362">"Ezin izan da wifi-sarera konektatu"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="1725243835135539125">" SSIDak Interneteko konexio txarra du."</string>
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Hartzaileak:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Idatzi beharrezko PINa:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PINa:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tableta wifi-saretik deskonektatuko da <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailura konektatuta dagoen bitartean"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV gailua wifi-saretik deskonektatuko da aldi batez <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailura konektatuta dagoen bitartean"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefonoa wifi-saretik deskonektatuko da <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailura konektatuta dagoen bitartean"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Gailua wifi-saretik deskonektatuko da aldi batez <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailura konektatuta dagoen bitartean"</string>
<string name="dlg_ok" msgid="254496739491689405">"Ados"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Ezin da konektatu <xliff:g id="SSID">%1$s</xliff:g> sarera"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Sakatu hau pribatutasun-ezarpenak aldatzeko, eta saiatu berriro"</string>
diff --git a/service/ServiceWifiResources/res/values-fa/strings.xml b/service/ServiceWifiResources/res/values-fa/strings.xml
index f4c842608c..c1012ffb3f 100644
--- a/service/ServiceWifiResources/res/values-fa/strings.xml
+++ b/service/ServiceWifiResources/res/values-fa/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"به:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"پین لازم را تایپ کنید:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"پین:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"‏در حین اتصال به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ارتباط این رایانه لوحی با Wi-Fi موقتاً قطع خواهد شد."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"‏وقتی دستگاه Android TV به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> متصل است، اتصال آن به Wi-Fi موقتاً قطع می‌شود"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"‏این گوشی به‌طور موقت از Wi-Fi قطع خواهد شد، در حالی که به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> وصل است"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"‏وقتی دستگاهتان به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> متصل است، اتصال آن به Wi-Fi موقتاً قطع می‌شود"</string>
<string name="dlg_ok" msgid="254496739491689405">"تأیید"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"اتصال به <xliff:g id="SSID">%1$s</xliff:g> امکان‌پذیر نیست"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"برای تغییر تنظیم حریم خصوصی ضربه بزنید و دوباره امتحان کنید"</string>
diff --git a/service/ServiceWifiResources/res/values-fi/strings.xml b/service/ServiceWifiResources/res/values-fi/strings.xml
index 4c1dbf467d..dcda428a8f 100644
--- a/service/ServiceWifiResources/res/values-fi/strings.xml
+++ b/service/ServiceWifiResources/res/values-fi/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kohde:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Kirjoita pyydetty PIN-koodi:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-koodi:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tablet-laitteen yhteys Wi-Fi-verkkoon katkaistaan väliaikaisesti tabletin ollessa yhdistettynä laitteeseen <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV ‑laitteen Wi-Fi-yhteys katkeaa tilapäisesti, kun siihen on yhdistetty <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Puhelimen yhteys Wi-Fi-verkkoon katkaistaan väliaikaisesti puhelimen ollessa yhdistettynä laitteeseen <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Laitteen Wi-Fi-yhteys katkeaa tilapäisesti, kun siihen on yhdistetty <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Verkkoon <xliff:g id="SSID">%1$s</xliff:g> ei saada yhteyttä"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Napauta muuttaaksesi yksityisyysasetusta ja yritä uudelleen"</string>
diff --git a/service/ServiceWifiResources/res/values-fr-feminine/strings.xml b/service/ServiceWifiResources/res/values-fr-feminine/strings.xml
new file mode 100644
index 0000000000..bc890db014
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-fr-feminine/strings.xml
@@ -0,0 +1,22 @@
+<?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>
+</resources>
diff --git a/service/ServiceWifiResources/res/values-fr-masculine/strings.xml b/service/ServiceWifiResources/res/values-fr-masculine/strings.xml
new file mode 100644
index 0000000000..9ed7470594
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-fr-masculine/strings.xml
@@ -0,0 +1,22 @@
+<?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>
+</resources>
diff --git a/service/ServiceWifiResources/res/values-fr-neuter/strings.xml b/service/ServiceWifiResources/res/values-fr-neuter/strings.xml
new file mode 100644
index 0000000000..025a654e2d
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-fr-neuter/strings.xml
@@ -0,0 +1,22 @@
+<?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>
+</resources>
diff --git a/service/ServiceWifiResources/res/values-fr-rCA/strings.xml b/service/ServiceWifiResources/res/values-fr-rCA/strings.xml
index a0a7495fcd..ff9cceaf2b 100644
--- a/service/ServiceWifiResources/res/values-fr-rCA/strings.xml
+++ b/service/ServiceWifiResources/res/values-fr-rCA/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"À :"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Saisissez le NIP requis :"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"NIP :"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"La tablette sera déconnectée du réseau Wi-Fi tant qu\'elle sera connectée à l\'appareil \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Votre appareil Android TV se déconnectera temporairement du Wi-Fi lors de sa connexion à l\'appareil <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Le téléphone sera déconnecté du réseau Wi-Fi tant qu\'il sera connecté à l\'appareil <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Votre appareil sera déconnecté temporairement de la connexion Wi-Fi lorsqu\'il sera connecté à <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Impossible de se connecter à <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Touchez pour modifier les paramètres de confidentialité et réessayer"</string>
diff --git a/service/ServiceWifiResources/res/values-fr/strings.xml b/service/ServiceWifiResources/res/values-fr/strings.xml
index 181f2a6c1e..cbc4374ae2 100644
--- a/service/ServiceWifiResources/res/values-fr/strings.xml
+++ b/service/ServiceWifiResources/res/values-fr/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"À :"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Saisissez le code PIN requis :"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"Code :"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"La tablette sera déconnectée du réseau Wi-Fi tant qu\'elle sera connectée à l\'appareil \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Votre appareil Android TV se déconnectera temporairement du Wi-Fi lors de sa connexion à l\'appareil <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Le téléphone sera déconnecté du réseau Wi-Fi tant qu\'il sera connecté à l\'appareil <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Tant que votre appareil sera connecté à <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, il sera temporairement déconnecté du Wi-Fi"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Impossible de se connecter à <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Appuyez pour modifier les paramètres de confidentialité, puis réessayez"</string>
diff --git a/service/ServiceWifiResources/res/values-gl/strings.xml b/service/ServiceWifiResources/res/values-gl/strings.xml
index bdadda5351..5123f9a754 100644
--- a/service/ServiceWifiResources/res/values-gl/strings.xml
+++ b/service/ServiceWifiResources/res/values-gl/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Para:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Escribe o PIN obrigatorio:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"A tableta desconectarase temporalmente da wifi mentres está conectada a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"O dispositivo Android TV desconectarase temporalmente da wifi mentres estea conectado a: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"O teléfono desconectarase temporalmente da wifi mentres está conectado con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"O dispositivo desconectarase temporalmente da wifi mentres estea conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Aceptar"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Non se puido establecer conexión co <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Toca para cambiar a configuración de privacidade e tentalo de novo"</string>
diff --git a/service/ServiceWifiResources/res/values-gu/strings.xml b/service/ServiceWifiResources/res/values-gu/strings.xml
index 4a5a38dac9..3ef9523ea7 100644
--- a/service/ServiceWifiResources/res/values-gu/strings.xml
+++ b/service/ServiceWifiResources/res/values-gu/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"પ્રતિ:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"આવશ્યક પિન લખો:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"પિન:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"ટેબ્લેટ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે વાઇ-ફાઇ થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"તમારું Android TV ડિવાઇસ, <xliff:g id="DEVICE_NAME">%1$s</xliff:g>થી કનેક્ટ હોય તે વખતે વાઇ-ફાઇથી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ફોન <xliff:g id="DEVICE_NAME">%1$s</xliff:g> થી કનેક્ટ હોય તે વખતે વાઇ-ફાઇ થી અસ્થાયી રૂપે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"જ્યારે તમારું ડિવાઇસ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> સાથે કનેક્ટેડ હોય, ત્યારે તેને વાઇ-ફાઇથી હંગામી રીતે ડિસ્કનેક્ટ કરવામાં આવશે"</string>
<string name="dlg_ok" msgid="254496739491689405">"ઓકે"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> સાથે કનેક્ટ કરી શકાતું નથી"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"પ્રાઇવસી સેટિંગ બદલવા અને ફરી પ્રયાસ કરવા ટૅપ કરો"</string>
diff --git a/service/ServiceWifiResources/res/values-hi/strings.xml b/service/ServiceWifiResources/res/values-hi/strings.xml
index f9ad27a479..0b6ba44e9a 100644
--- a/service/ServiceWifiResources/res/values-hi/strings.xml
+++ b/service/ServiceWifiResources/res/values-hi/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"प्रति:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"आवश्‍यक पिन लिखें:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"पिन:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> से कनेक्ट रहने पर टैबलेट वाई-फ़ाई से अस्थायी रूप से डिसकनेक्ट हो जाएगा"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>से कनेक्ट रहने के दौरान आपका Android TV डिवाइस, Wi-Fi से अस्थायी रूप से डिसकनेक्ट हो जाएगा."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"फ़ोन <xliff:g id="DEVICE_NAME">%1$s</xliff:g> से कनेक्ट रहते समय वाई-फ़ाई से अस्थायी रूप से डिसकनेक्ट हो जाएगा"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> से कनेक्ट रहने के दौरान आपका डिवाइस, वाई-फ़ाई से अस्थायी रूप से डिसकनेक्ट हो जाएगा"</string>
<string name="dlg_ok" msgid="254496739491689405">"ठीक है"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> से कनेक्ट नहीं किया जा सकता"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"निजता सेटिंग बदलने के लिए टैप करें और फिर से कोशिश करें"</string>
diff --git a/service/ServiceWifiResources/res/values-hr/strings.xml b/service/ServiceWifiResources/res/values-hr/strings.xml
index 92e6d14cad..dd3bfba71e 100644
--- a/service/ServiceWifiResources/res/values-hr/strings.xml
+++ b/service/ServiceWifiResources/res/values-hr/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Prima:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Upišite potreban PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tablet će se privremeno isključiti s Wi-Fija dok je povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV uređaj privremeno će prekinuti vezu s Wi-Fijem dok je povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefon će se privremeno isključiti s Wi-Fija dok je povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Vaš će uređaj privremeno prekinuti vezu s Wi-Fijem dok je povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"U redu"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Povezivanje s mrežom <xliff:g id="SSID">%1$s</xliff:g> nije uspjelo"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Dodirnite da biste promijenili postavke privatnosti i pokušajte ponovo"</string>
diff --git a/service/ServiceWifiResources/res/values-hu/strings.xml b/service/ServiceWifiResources/res/values-hu/strings.xml
index 983ef1311c..bd7e938bef 100644
--- a/service/ServiceWifiResources/res/values-hu/strings.xml
+++ b/service/ServiceWifiResources/res/values-hu/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Címzett:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Adja meg a szükséges PIN kódot:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-kód:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"A táblagép ideiglenesen lecsatlakozik a Wi-Fi hálózatról, míg a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközhöz csatlakozik"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Az Android TV eszköz ideiglenesen bontja a Wi-Fi-kapcsolatot arra az időre, amíg a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközhöz csatlakozik"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"A telefon ideiglenesen kilép a Wi-Fi hálózatról, míg a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközhöz csatlakozik."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Az eszköze ideiglenesen bontja a Wi-Fi-kapcsolatot arra az időre, amíg a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközhöz csatlakozik"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Nem lehet csatlakozni a következőhöz: <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Koppintson az adatvédelmi beállítások módosításához, majd próbálja újra"</string>
diff --git a/service/ServiceWifiResources/res/values-hy/strings.xml b/service/ServiceWifiResources/res/values-hy/strings.xml
index 2a771d82ab..84738c1722 100644
--- a/service/ServiceWifiResources/res/values-hy/strings.xml
+++ b/service/ServiceWifiResources/res/values-hy/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Ում`"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Մուտքագրեք պահանջվող PIN-ը:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-ը՝"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Գրասալիկը ժամանակավորապես կանջատվի Wi-Fi-ից, քանի դեռ այն կապակցված է <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ին"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Ձեր Android TV սարքը ժամանակավորապես կանջատվի Wi-Fi-ից, քանի դեռ այն միացված է <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ին"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Հեռախոսը ժամանակավորապես կանջատվի Wi-Fi-ից, քանի դեռ այն միացված է <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ին"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Ձեր սարքը ժամանակավորապես կանջատվի Wi-Fi-ից, քանի դեռ միացված է <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ին"</string>
<string name="dlg_ok" msgid="254496739491689405">"Եղավ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Չհաջողվեց միանալ <xliff:g id="SSID">%1$s</xliff:g> սարքին"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Հպեք՝ գաղտնիության կարգավորումները փոփոխելու և նորից փորձելու համար։"</string>
diff --git a/service/ServiceWifiResources/res/values-in/strings.xml b/service/ServiceWifiResources/res/values-in/strings.xml
index 514dfca230..5e818035dd 100644
--- a/service/ServiceWifiResources/res/values-in/strings.xml
+++ b/service/ServiceWifiResources/res/values-in/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kepada:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Ketik PIN yang diminta:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Sambungan tablet akan diputuskan dari Wi-Fi untuk sementara saat terhubung dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Perangkat Android TV akan memutuskan hubungan sementara dari Wi-Fi saat terhubung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Ponsel akan terputus sementara dari Wi-Fi saat terhubung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Koneksi perangkat akan terputus sementara dari Wi-Fi saat terhubung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Oke"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Tidak dapat terhubung ke <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Ketuk untuk mengubah setelan privasi dan coba lagi"</string>
diff --git a/service/ServiceWifiResources/res/values-is/strings.xml b/service/ServiceWifiResources/res/values-is/strings.xml
index 15818b8312..ebb850acea 100644
--- a/service/ServiceWifiResources/res/values-is/strings.xml
+++ b/service/ServiceWifiResources/res/values-is/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Til:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Sláðu inn PIN-númerið sem er krafist:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-númer:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Wi-Fi tengingu spjaldtölvunnar verður tímabundið slitið á meðan hún er tengd við <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV mun tímabundið aftengjast Wi-Fi á meðan það er tengt við <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Síminn mun tímabundið aftengjast Wi-Fi á meðan hann er tengdur við <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Tækið þitt mun tímabundið aftengjast Wi-Fi á meðan það er tengt við <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Í lagi"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Ekki hægt að tengjast <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Ýttu til að breyta persónuverndarstillingum og reyna aftur"</string>
diff --git a/service/ServiceWifiResources/res/values-it/strings.xml b/service/ServiceWifiResources/res/values-it/strings.xml
index 1143108a18..d029f4e01c 100644
--- a/service/ServiceWifiResources/res/values-it/strings.xml
+++ b/service/ServiceWifiResources/res/values-it/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"A:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Inserisci il PIN richiesto:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Il tablet verrà momentaneamente scollegato dalla rete Wi-Fi durante il collegamento a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Il dispositivo Android TV verrà scollegato temporaneamente dalla rete Wi-Fi mentre è connesso a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Il telefono verrà momentaneamente scollegato dalla rete Wi-Fi durante il collegamento a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Il dispositivo verrà scollegato temporaneamente dalla rete Wi-Fi mentre è connesso a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Impossibile connettersi alla rete <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tocca per cambiare le impostazioni sulla privacy e riprova"</string>
diff --git a/service/ServiceWifiResources/res/values-iw/strings.xml b/service/ServiceWifiResources/res/values-iw/strings.xml
index e1291128a9..3bd7d33c0f 100644
--- a/service/ServiceWifiResources/res/values-iw/strings.xml
+++ b/service/ServiceWifiResources/res/values-iw/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"אל:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"יש להקליד את קוד האימות הנדרש:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"קוד אימות:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"‏הטאבלט יתנתק מרשת ה-Wi-Fi באופן זמני כשהוא מחובר אל <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"‏מכשיר ה-Android TV יתנתק מרשת ה-Wi-Fi באופן זמני כשהוא מחובר אל <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"‏הטלפון יתנתק מרשת ה-Wi-Fi באופן זמני כשהוא מחובר אל <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"‏המכשיר יתנתק מרשת ה-Wi-Fi באופן זמני כשהוא מחובר אל <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"אישור"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"לא ניתן להתחבר אל <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"יש להקיש כדי לשנות את הגדרות הפרטיות ולנסות שוב"</string>
diff --git a/service/ServiceWifiResources/res/values-ja/strings.xml b/service/ServiceWifiResources/res/values-ja/strings.xml
index ccc60f380e..6c31f68c3d 100644
--- a/service/ServiceWifiResources/res/values-ja/strings.xml
+++ b/service/ServiceWifiResources/res/values-ja/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"受信側:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"必要なPINを入力してください:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"タブレットが<xliff:g id="DEVICE_NAME">%1$s</xliff:g>に接続されている間は一時的にWi-Fi接続が切断されます"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV デバイスが <xliff:g id="DEVICE_NAME">%1$s</xliff:g> に接続されている間は一時的に Wi-Fi 接続が解除されます"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"モバイル デバイスが<xliff:g id="DEVICE_NAME">%1$s</xliff:g>に接続されている間は一時的にWi-Fi接続が解除されます。"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"デバイスが <xliff:g id="DEVICE_NAME">%1$s</xliff:g> に接続されている間は一時的に Wi-Fi 接続が解除されます"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> に接続できません"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"タップしてプライバシー設定を変更し、もう一度お試しください"</string>
diff --git a/service/ServiceWifiResources/res/values-ka/strings.xml b/service/ServiceWifiResources/res/values-ka/strings.xml
index 4528330297..0ae523bc61 100644
--- a/service/ServiceWifiResources/res/values-ka/strings.xml
+++ b/service/ServiceWifiResources/res/values-ka/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"მიმღები:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"შეიყვანეთ საჭირო PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"პინ-კოდი:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"ტაბლეტი დროებით გაითიშება Wi-Fi-დან, სანამ მიერთებულია <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ზე"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"თქვენი Android TV მოწყობილობა დროებით გაითიშება Wi-Fi-დან, სანამ ის <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-თან იქნება დაკავშირებული"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ტელეფონი დროებით გაითიშება Wi-Fi-დან, სანამ მიერთებულია <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ზე"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"თქვენი მოწყობილობა დროებით გაითიშება Wi-Fi-დან, სანამ ის <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-თან იქნება დაკავშირებული"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g>-თან დაკავშირება ვერ ხერხდება"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"შეეხეთ კონფიდენციალურობის პარამეტრების შესაცვლელად და ცადეთ ხელახლა"</string>
diff --git a/service/ServiceWifiResources/res/values-kk/strings.xml b/service/ServiceWifiResources/res/values-kk/strings.xml
index 003869d405..33fcbeb648 100644
--- a/service/ServiceWifiResources/res/values-kk/strings.xml
+++ b/service/ServiceWifiResources/res/values-kk/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Кімге:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Өтінілген PIN кодты теру:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Планшет <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысына қосылғанша Wi-Fi байланысынан уақытша ажыратылады"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысына қосулы тұрғанда, Android TV құрылғысы Wi-Fi желісінен уақытша ажырайды."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысына жалғанып тұрғанда телефон уақытша Wi-Fi байланысынан ажыратылады"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысына қосулы тұрғанда, құрылғыңыз Wi-Fi желісінен уақытша ажырайды."</string>
<string name="dlg_ok" msgid="254496739491689405">"Жарайды"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> құрылғысына қосылмайды."</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Құпиялық параметрін өзгерту үшін түртіп, әрекетті қайталаңыз."</string>
diff --git a/service/ServiceWifiResources/res/values-km/strings.xml b/service/ServiceWifiResources/res/values-km/strings.xml
index 318c11bf5c..6a63936625 100644
--- a/service/ServiceWifiResources/res/values-km/strings.xml
+++ b/service/ServiceWifiResources/res/values-km/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"ទៅ៖"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"បញ្ចូល​កូដ PIN ដែល​ទាមទារ៖"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"កូដ PIN ៖"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"កុំព្យូទ័រ​បន្ទះ​នឹង​ផ្ដាច់​ជា​បណ្ដោះអាសន្ន​ពី​វ៉ាយហ្វាយ ខណៈ​ដែល​វា​ភ្ជាប់​ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"ឧបករណ៍ Android TV របស់អ្នកនឹង​ផ្ដាច់ពី Wi-Fi ជាបណ្តោះអាសន្ន នៅពេល​ឧបករណ៍នេះភ្ជាប់ជាមួយ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ទូរស័ព្ទ​នឹង​​ផ្ដាច់​ពី​វ៉ាយហ្វាយ​ខណៈ​ដែល​វា​ត្រូវ​បាន​តភ្ជាប់​ទៅ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"ឧបករណ៍របស់អ្នកនឹងផ្ដាច់ពី Wi-Fi ជាបណ្ដោះអាសន្ន នៅពេលឧបករណ៍នេះភ្ជាប់ជាមួយ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"យល់ព្រម"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"មិនអាចភ្ជាប់ជាមួយ <xliff:g id="SSID">%1$s</xliff:g> បានទេ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"ចុច ដើម្បី​ប្ដូរ​ការកំណត់​ឯកជនភាព រួច​ព្យាយាម​ម្ដងទៀត"</string>
diff --git a/service/ServiceWifiResources/res/values-kn/strings.xml b/service/ServiceWifiResources/res/values-kn/strings.xml
index fba1a5d9bd..5bc762e2e2 100644
--- a/service/ServiceWifiResources/res/values-kn/strings.xml
+++ b/service/ServiceWifiResources/res/values-kn/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"ಗೆ:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"ಅಗತ್ಯವಿರುವ ಪಿನ್‌ ಟೈಪ್ ಮಾಡಿ:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"ಪಿನ್‌:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"ಟ್ಯಾಬ್ಲೆಟ್ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಾಗ ಅದನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ವೈ-ಫೈ ನಿಂದ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗುತ್ತದೆ"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"ನಿಮ್ಮ Android TV ಸಾಧನವು <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಾಗ, ವೈ-ಫೈ ನಿಂದ ತಾತ್ಕಾಲಿಕವಾಗಿ ಸಂಪರ್ಕ ಕಡಿದುಕೊಳ್ಳುತ್ತದೆ"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ಫೋನ್ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಾಗ ವೈ-ಫೈ ನಿಂದ ಅದು ತಾತ್ಕಾಲಿಕವಾಗಿ ಸಂಪರ್ಕ ಕಡಿತಗೊಳ್ಳುತ್ತದೆ"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"ನಿಮ್ಮ ಸಾಧನವು <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಆಗಿರುವಾಗ, ವೈ-ಫೈನಿಂದ ಅದು ತಾತ್ಕಾಲಿಕವಾಗಿ ಡಿಸ್‌ಕನೆಕ್ಟ್ ಆಗುತ್ತದೆ"</string>
<string name="dlg_ok" msgid="254496739491689405">"ಸರಿ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"ಗೌಪ್ಯತೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಮರುಪ್ರಯತ್ನಿಸಿ"</string>
diff --git a/service/ServiceWifiResources/res/values-ko/strings.xml b/service/ServiceWifiResources/res/values-ko/strings.xml
index 747167ee0a..e77fb11b13 100644
--- a/service/ServiceWifiResources/res/values-ko/strings.xml
+++ b/service/ServiceWifiResources/res/values-ko/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"수신:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"필수 PIN 입력:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>에 연결되어 있는 동안 일시적으로 태블릿의 Wi-Fi 연결이 해제됩니다."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>에 연결되어 있는 동안 Android TV 기기의 Wi-Fi 연결이 일시적으로 해제됩니다."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>에 연결되어 있는 동안 일시적으로 휴대전화의 Wi-Fi 연결이 해제됩니다."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>에 연결되어 있는 동안 기기의 Wi-Fi 연결이 일시적으로 해제됩니다"</string>
<string name="dlg_ok" msgid="254496739491689405">"확인"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g>에 연결할 수 없습니다."</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"탭하여 개인정보 보호 설정을 변경하고 다시 시도하세요."</string>
diff --git a/service/ServiceWifiResources/res/values-ky/strings.xml b/service/ServiceWifiResources/res/values-ky/strings.xml
index f574c1ab46..1dac1db9f7 100644
--- a/service/ServiceWifiResources/res/values-ky/strings.xml
+++ b/service/ServiceWifiResources/res/values-ky/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Алуучу:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Талап кылынган PIN\'ди териңиз:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Планшет <xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен байланышып турганда, Wi-Fi\'дан убактылуу ажыратылат"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүнө туташып турганда убактылуу Wi-Fi\'дан ажыратылат"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Телефон <xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен байланышып турганда, Wi-Fi\'дан убактылуу ажыратылат"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Түзмөгүңүз <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүнө туташып турганда убактылуу Wi-Fi\'дан ажыратылат"</string>
<string name="dlg_ok" msgid="254496739491689405">"Жарайт"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> менен туташпай жатат"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Купуялык параметрлерин өзгөртүү үчүн таптап, кайталап көрүңүз"</string>
diff --git a/service/ServiceWifiResources/res/values-lo/strings.xml b/service/ServiceWifiResources/res/values-lo/strings.xml
index f362fa7e91..4d99e108cd 100644
--- a/service/ServiceWifiResources/res/values-lo/strings.xml
+++ b/service/ServiceWifiResources/res/values-lo/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"ຈາກ:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"ພິມລະຫັດ PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"ແທັບເລັດຈະຖືກຕັດການເຊື່ອມຕໍ່ຈາກ Wi-Fi ເປັນການຊົ່ວຄາວ ໃນຂະນະທີ່ມັນເຊື່ອມຕໍ່ກັບ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຢູ່."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"ອຸປະກອນ Android TV ຂອງທ່ານຈະຕັດການເຊື່ອມຕໍ່ຈາກ Wi-Fi ເປັນການຊົ່ວຄາວໃນລະຫວ່າງທີ່ມັນເຊື່ອມຕໍ່ຫາ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ໂທລະສັບຈະຖືກຢຸດການເຊື່ອມຕໍ່ຊົ່ວຄາວຈາກ Wi-Fi ໃນຂະນະທີ່ມັນເຊື່ອມຕໍ່ກັບ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"ອຸປະກອນຂອງທ່ານຈະຕັດການເຊື່ອມຕໍ່ຈາກ Wi-Fi ເປັນການຊົ່ວຄາວໃນລະຫວ່າງທີ່ມັນເຊື່ອມຕໍ່ຫາ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"ຕົກລົງ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"ບໍ່ສາມາດເຊື່ອມຕໍ່ຫາ <xliff:g id="SSID">%1$s</xliff:g> ໄດ້"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"ແຕະເພື່ອປ່ຽນການຕັ້ງຄ່າຄວາມເປັນສ່ວນຕົວແລ້ວລອງໃໝ່"</string>
diff --git a/service/ServiceWifiResources/res/values-lt/strings.xml b/service/ServiceWifiResources/res/values-lt/strings.xml
index 8580219070..e496179c51 100644
--- a/service/ServiceWifiResources/res/values-lt/strings.xml
+++ b/service/ServiceWifiResources/res/values-lt/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Skirta:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Įveskite reikiamą PIN kodą:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN kodas:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Planšetinis kompiuteris bus laikinai atjungtas nuo „Wi-Fi“, kol jis prijungtas prie „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"„Android TV“ įrenginys bus laikinai atjungtas nuo „Wi-Fi“, kol bus prijungtas prie „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefonas bus laikinai atjungtas nuo „Wi-Fi“, kol bus prijungtas prie „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Įrenginys bus laikinai atjungtas nuo „Wi-Fi“, kol bus prijungtas prie „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“"</string>
<string name="dlg_ok" msgid="254496739491689405">"Gerai"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Nepavyksta prisijungti prie „<xliff:g id="SSID">%1$s</xliff:g>“"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Palieskite, kad pakeistumėte privatumo nustatymus, ir bandykite dar kartą"</string>
diff --git a/service/ServiceWifiResources/res/values-lv/strings.xml b/service/ServiceWifiResources/res/values-lv/strings.xml
index 68da3783ed..6523fd3bdc 100644
--- a/service/ServiceWifiResources/res/values-lv/strings.xml
+++ b/service/ServiceWifiResources/res/values-lv/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kam:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Ierakstiet pieprasīto PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Planšetdators tiks īslaicīgi atvienots no Wi-Fi tīkla, kamēr būs izveidots savienojums ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV ierīce tiks īslaicīgi atvienota no Wi-Fi tīkla, kamēr ir izveidots savienojums ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Tālrunis tiks īslaicīgi atvienots no Wi-Fi tīkla, kamēr būs izveidots savienojums ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Jūsu ierīce tiks īslaicīgi atvienota no Wi-Fi tīkla, kamēr ir izveidots savienojums ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="dlg_ok" msgid="254496739491689405">"Labi"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Nevar izveidot savienojumu ar: <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Pieskarieties, lai mainītu konfidencialitātes iestatījumus un mēģinātu vēlreiz"</string>
diff --git a/service/ServiceWifiResources/res/values-mk/strings.xml b/service/ServiceWifiResources/res/values-mk/strings.xml
index 513b33d6a4..f8db829ddb 100644
--- a/service/ServiceWifiResources/res/values-mk/strings.xml
+++ b/service/ServiceWifiResources/res/values-mk/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"До:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Внеси го бараниот PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Таблетот привремено ќе се исклучи од Wi-Fi, додека да се приклучи на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Привремено ќе се прекине врската на вашиот уред Android TV со Wi-Fi додека е поврзан со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Телефонот привремено ќе се исклучи од Wi-Fi додека е приклучен на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Ќе се прекине врската на вашиот уред со Wi-Fi привремено додека е поврзан со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Во ред"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Не може да се поврзе на „<xliff:g id="SSID">%1$s</xliff:g>“"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Допрете за да ги промените поставките за приватност и обидете се повторно"</string>
diff --git a/service/ServiceWifiResources/res/values-ml/strings.xml b/service/ServiceWifiResources/res/values-ml/strings.xml
index ca56e784b0..18f1ada5b2 100644
--- a/service/ServiceWifiResources/res/values-ml/strings.xml
+++ b/service/ServiceWifiResources/res/values-ml/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"ടു:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"ആവശ്യമായ പിൻ ടൈപ്പുചെയ്യുക:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"പിൻ:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"ടാബ്‌ലെറ്റ് <xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതിൽ കണക്റ്റുചെയ്‌തിരിക്കുമ്പോൾ അത് താൽക്കാലികമായി Wi-Fi-യിൽ നിന്നും വിച്ഛേദിക്കപ്പെടും."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"നിങ്ങളുടെ Android TV <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ഉപകരണവുമായി കണക്‌റ്റ് ചെയ്‌തിരിക്കുമ്പോൾ അത് താൽക്കാലികമായി വൈഫൈയിൽ നിന്ന് വിച്‌ഛേദിക്കും"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതിലേക്ക് കണക്റ്റുചെയ്‌തിരിക്കുമ്പോൾ ഫോൺ Wi-Fi-യിൽ നിന്ന് താൽക്കാലികമായി വിച്ഛേദിക്കും"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"നിങ്ങളുടെ ഉപകരണം <xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതുമായി കണക്റ്റ് ചെയ്തിരിക്കുമ്പോൾ, അത് വൈഫൈയിൽ നിന്ന് താൽക്കാലികമായി വിച്ഛേദിക്കും"</string>
<string name="dlg_ok" msgid="254496739491689405">"ശരി"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g>-ലേക്ക് കണക്‌റ്റ് ചെയ്യാനാവുന്നില്ല"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"സ്വകാര്യതാ ക്രമീകരണം മാറ്റാൻ ടാപ്പ് ചെയ്യുക, വീണ്ടും ശ്രമിക്കുക"</string>
diff --git a/service/ServiceWifiResources/res/values-mn/strings.xml b/service/ServiceWifiResources/res/values-mn/strings.xml
index 69b1376e34..9ab92aca8f 100644
--- a/service/ServiceWifiResources/res/values-mn/strings.xml
+++ b/service/ServiceWifiResources/res/values-mn/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Хэнд:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Шаардлагатай ПИН-г бичнэ үү:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"ПИН:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Таблет <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-тэй холбогдох үедээ түр зуур Wi-Fi-с салах болно."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Таны Android TV төхөөрөмж <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-д холбогдсон үед Wi-Fi-с түр хугацаанд сална"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Утас <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-тай холбогдох үедээ түр зуур Wi-Fi-с салах болно."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Таны төхөөрөмж <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-д холбогдсон үедээ Wi-Fi-с түр сална"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g>-д холбогдож чадсангүй"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Нууцлалын тохиргоог өөрчлөхийн тулд товшоод, дахин оролдоно уу"</string>
diff --git a/service/ServiceWifiResources/res/values-mr/strings.xml b/service/ServiceWifiResources/res/values-mr/strings.xml
index 57fd585057..5cdd82f0d2 100644
--- a/service/ServiceWifiResources/res/values-mr/strings.xml
+++ b/service/ServiceWifiResources/res/values-mr/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"प्रति:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"आवश्यक पिन टाइप करा:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"पिन:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"टॅबलेट <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ला कनेक्‍ट केलेले असताना तात्‍पुरते वाय-फाय वरून डिस्‍कनेक्‍ट होईल"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>शी तुमचे Android TV डिव्हाइस कनेक्ट केलेले असताना ते वाय-फाय वरून तात्पुरते डिस्कनेक्ट केले जाईल"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> वर फोन कनेक्ट केलेला असताना तो वाय-फाय वरून तात्पुरता डिस्कनेक्ट केला जाईल"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"तुमचे डिव्हाइस <xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी कनेक्ट केलेले असताना वाय-फायवरून तात्पुरते डिस्कनेक्ट होईल"</string>
<string name="dlg_ok" msgid="254496739491689405">"ठीक"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> शी कनेक्ट करता आले नाही"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"गोपनीयता सेटिंग्ज बदलण्यासाठी टॅप करा आणि पुन्हा प्रयत्न करा"</string>
diff --git a/service/ServiceWifiResources/res/values-ms/strings.xml b/service/ServiceWifiResources/res/values-ms/strings.xml
index bbb0c84764..66e5b8b5c6 100644
--- a/service/ServiceWifiResources/res/values-ms/strings.xml
+++ b/service/ServiceWifiResources/res/values-ms/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kepada:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Taipkan PIN yang diperlukan:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Sambungan tablet ke Wi-Fi akan diputuskan buat sementara waktu semasa tablet bersambung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Peranti Android TV anda akan diputuskan sambungan daripada Wi-Fi untuk sementara waktu semasa peranti ini disambungkan ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Sambungan telefon ke Wi-Fi akan diputuskan buat sementara waktu semasa telefon bersambung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Peranti anda akan diputuskan sambungan daripada Wi-Fi untuk sementara waktu semasa peranti ini disambungkan kepada <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Tidak dapat menyambung ke <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Ketik untuk menukar tetapan privasi, kemudian cuba semula"</string>
diff --git a/service/ServiceWifiResources/res/values-my/strings.xml b/service/ServiceWifiResources/res/values-my/strings.xml
index 6bba39c317..ea57a2a317 100644
--- a/service/ServiceWifiResources/res/values-my/strings.xml
+++ b/service/ServiceWifiResources/res/values-my/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"သို့:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"လိုအပ်သော ပင် နံပါတ် ရိုက်ရန်:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"ပင် နံပါတ်:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> နှင့် ဆက်သွယ်ထားစဉ် တက်ဘလက်ဟာ Wi-Fi နှင့် ဆက်သွယ်မှု ရပ်ဆိုင်းထားမှာ ဖြစ်ပါတယ်"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"သင်၏ Android TV စက်ပစ္စည်းသည် <xliff:g id="DEVICE_NAME">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားသည့်အခါ Wi-Fi မှနေ၍ ယာယီ ချိတ်ဆက်မှုဖြုတ်သွားပါမည်။"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို ဆက်သွယ်ထားစဉ် ဖုန်းအား ဝိုင်ဖိုင်မှ ဆက်သွယ်မှု ရပ်ဆိုင်းထားပါမည်"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"သင့်စက်သည် <xliff:g id="DEVICE_NAME">%1$s</xliff:g> သို့ ချိတ်ဆက်ထားစဉ် Wi-Fi နှင့် ချိတ်ဆက်မှုကို ယာယီဖြုတ်ထားမည်"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> နှင့် ချိတ်ဆက်၍မရပါ။"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"ကိုယ်ရေးလုံခြုံမှုဆက်တင်ကို ပြောင်းရန် တို့ပြီးနောက် ပြန်စမ်းကြည့်ပါ"</string>
diff --git a/service/ServiceWifiResources/res/values-nb/strings.xml b/service/ServiceWifiResources/res/values-nb/strings.xml
index 48f781463b..f97c308e43 100644
--- a/service/ServiceWifiResources/res/values-nb/strings.xml
+++ b/service/ServiceWifiResources/res/values-nb/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Til:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Skriv inn påkrevd PIN-kode:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Nettbrettet frakobles Wifi midlertidig mens den er tilkoblet <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV-enheten din blir midlertidig koblet fra wifi mens den er koblet til <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefonen frakobles Wifi midlertidig mens den er tilkoblet <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Enheten din blir midlertidig koblet fra wifi mens den er koblet til <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Kan ikke koble til <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Trykk for å endre personverninnstillingene og prøve på nytt"</string>
diff --git a/service/ServiceWifiResources/res/values-ne/strings.xml b/service/ServiceWifiResources/res/values-ne/strings.xml
index 6d4f3b68a8..e4a33a2f0f 100644
--- a/service/ServiceWifiResources/res/values-ne/strings.xml
+++ b/service/ServiceWifiResources/res/values-ne/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"प्रापक:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"आवश्यक PIN टाइप गर्नुहोस्:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"यो <xliff:g id="DEVICE_NAME">%1$s</xliff:g>सँग जोडिएको बेला ट्याब्लेट अस्थायी रूपमा वाइ-फाइबाट विच्छेद गरिने छ।"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"तपाईंको Android टिभी यन्त्र <xliff:g id="DEVICE_NAME">%1$s</xliff:g> मा कनेक्ट भएको बेला यो केही समयका लागि Wi-Fi बाट विच्छेद हुने छ।"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"जब यो <xliff:g id="DEVICE_NAME">%1$s</xliff:g> सँग जडित हुन्छ, फोन अस्थायी रूपमा वाइ-फाइबाट विच्छेद हुने छ"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"तपाईंको डिभाइस <xliff:g id="DEVICE_NAME">%1$s</xliff:g> मा कनेक्ट गरिएको बेलामा यो केही बेर Wi-Fi बाट डिस्कनेक्ट हुने छ"</string>
<string name="dlg_ok" msgid="254496739491689405">"ठिक छ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> मा जडान गर्न सकिएन"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"गोपनीयता सेटिङ परिवर्तन गर्न ट्याप गरेर फेरि प्रयास गर्नुहोस्"</string>
diff --git a/service/ServiceWifiResources/res/values-nl/strings.xml b/service/ServiceWifiResources/res/values-nl/strings.xml
index 97424752f9..4c6e2d7da9 100644
--- a/service/ServiceWifiResources/res/values-nl/strings.xml
+++ b/service/ServiceWifiResources/res/values-nl/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Naar:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Voer de gewenste pincode in:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"Pincode"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"De verbinding met het wifi-netwerk wordt tijdelijk uitgezet terwijl de telefoon is verbonden met <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"De verbinding met het wifi-netwerk wordt tijdelijk uitgezet terwijl het Android TV-apparaat is verbonden met <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"De verbinding met het wifi-netwerk wordt tijdelijk uitgezet terwijl de telefoon verbonden is met <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Je apparaat verbreekt tijdelijk de verbinding met wifi terwijl het verbonden is met <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Kan niet verbinden met <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tik om de privacyinstellingen aan te passen en probeer het opnieuw"</string>
diff --git a/service/ServiceWifiResources/res/values-or/strings.xml b/service/ServiceWifiResources/res/values-or/strings.xml
index 71fb148738..6abb1e6c34 100644
--- a/service/ServiceWifiResources/res/values-or/strings.xml
+++ b/service/ServiceWifiResources/res/values-or/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"ପ୍ରାପ୍ତେଷୁ:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"ଆବଶ୍ୟକ PIN ଟାଇପ୍‍ କରନ୍ତୁ:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ସଂଯୁକ୍ତ ହୋଇଥିବାବେଳେ, ୱାଇ-ଫାଇଠାରୁ ଟାବଲେଟ୍‍ଟି ଅସ୍ଥାୟୀ ଭାବେ ବିଚ୍ଛିନ୍ନ ହେବ"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ସଂଯୋଗ ହେଉଥିବା ସମୟରେ ୱାଇ-ଫାଇରୁ ଅସ୍ଥାୟୀ ଭାବେ ବିଚ୍ଛିନ୍ନ ହେବ"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ସଂଯୋଗ ଥିବାବେଳେ ଫୋନ୍‌ଟି ୱାଇ-ଫାଇରୁ ଅସ୍ଥାୟୀ ଭାବରେ ବିଚ୍ଛିନ୍ନ ହେବ"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"ଆପଣଙ୍କ ଡିଭାଇସ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ କନେକ୍ଟ ଥିବା ସମୟରେ ଏହା ଅସ୍ଥାୟୀ ଭାବେ ୱାଇ-ଫାଇରୁ ଡିସକନେକ୍ଟ ହୋଇଯିବ"</string>
<string name="dlg_ok" msgid="254496739491689405">"ଠିକ ଅଛି"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> ସହିତ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"ଗୋପନୀୟତା ସେଟିଂସ୍ ବଦଳେଇବାକୁ ଟାପ୍ କରନ୍ତୁ ଏବଂ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
diff --git a/service/ServiceWifiResources/res/values-pa/strings.xml b/service/ServiceWifiResources/res/values-pa/strings.xml
index d01fe9c170..2589be4766 100644
--- a/service/ServiceWifiResources/res/values-pa/strings.xml
+++ b/service/ServiceWifiResources/res/values-pa/strings.xml
@@ -25,9 +25,9 @@
<string name="wifi_available_action_connect" msgid="5636634933476946222">"ਕਨੈਕਟ ਕਰੋ"</string>
<string name="wifi_available_action_all_networks" msgid="8491109932336522211">"ਸਾਰੇ ਨੈੱਟਵਰਕ"</string>
<string name="notification_channel_network_status" msgid="1631786866932924838">"ਨੈੱਟਵਰਕ ਅਵਸਥਾ"</string>
- <string name="notification_channel_network_alerts" msgid="1391603215241200880">"ਨੈੱਟਵਰਕ ਸੁਚੇਤਨਾਵਾਂ"</string>
+ <string name="notification_channel_network_alerts" msgid="1391603215241200880">"ਨੈੱਟਵਰਕ ਅਲਰਟ"</string>
<string name="notification_channel_network_available" msgid="8454366142428864948">"ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਹੈ"</string>
- <string name="notification_channel_apm_alerts" msgid="6775293475896473489">"APM ਸੁਚੇਤਨਾਵਾਂ"</string>
+ <string name="notification_channel_apm_alerts" msgid="6775293475896473489">"APM ਅਲਰਟ"</string>
<string name="wifi_suggestion_title" msgid="2564179935989099139">"ਕੀ ਸੁਝਾਏ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਵਰਤਣੇ ਹਨ?"</string>
<string name="wifi_suggestion_content" msgid="6985149577828091835">"<xliff:g id="NAME">%s</xliff:g> ਦੇ ਸੁਝਾਏ ਨੈੱਟਵਰਕ। ਸ਼ਾਇਦ ਡੀਵਾਈਸ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਹੋਵੇ।"</string>
<string name="wifi_suggestion_action_allow_app" msgid="7757859972144671588">"ਵਰਤਣ ਦਿਓ"</string>
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"ਵੱਲ:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"ਲੋੜੀਂਦਾ ਪਿੰਨ ਟਾਈਪ ਕਰੋ:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"ਪਿੰਨ:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"ਟੈਬਲੈੱਟ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ ਵਾਈ-ਫਾਈ ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਵੇਗਾ"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"ਤੁਹਾਡਾ Android TV ਡੀਵਾਈਸ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਾਈ-ਫਾਈ ਤੋਂ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਵੇਗਾ"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ਫ਼ੋਨ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ ਵਾਈ-ਫਾਈ ਤੋਂ ਅਸਥਾਈ ਤੌਰ ਤੇ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਏਗਾ"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋਣ \'ਤੇ, ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਕੁਝ ਸਮੇਂ ਲਈ ਵਾਈ-ਫਾਈ ਤੋਂ ਡਿਸਕਨੈਕਟ ਹੋ ਜਾਵੇਗਾ"</string>
<string name="dlg_ok" msgid="254496739491689405">"ਠੀਕ ਹੈ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"ਪਰਦੇਦਾਰੀ ਸੈਟਿੰਗਾਂ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰਕੇ ਮੁੜ-ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
diff --git a/service/ServiceWifiResources/res/values-pl/strings.xml b/service/ServiceWifiResources/res/values-pl/strings.xml
index 2f2b3b8771..e3afb51815 100644
--- a/service/ServiceWifiResources/res/values-pl/strings.xml
+++ b/service/ServiceWifiResources/res/values-pl/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Do:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Wpisz wymagany kod PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"Kod PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Na czas połączenia z <xliff:g id="DEVICE_NAME">%1$s</xliff:g> tablet zostanie tymczasowo odłączony od Wi-Fi"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Urządzenie z Androidem TV zostanie odłączone od sieci Wi-Fi na czas połączenia z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Na czas połączenia z <xliff:g id="DEVICE_NAME">%1$s</xliff:g> telefon zostanie tymczasowo odłączony od Wi-Fi"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Gdy urządzenie zostanie podłączone do urządzenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, tymczasowo rozłączy się z Wi-Fi"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Nie można połączyć się z siecią <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Kliknij, by zmienić ustawienia prywatności, i spróbuj jeszcze raz"</string>
diff --git a/service/ServiceWifiResources/res/values-pt-rBR/strings.xml b/service/ServiceWifiResources/res/values-pt-rBR/strings.xml
index 71aa053e88..2f2060c0e2 100644
--- a/service/ServiceWifiResources/res/values-pt-rBR/strings.xml
+++ b/service/ServiceWifiResources/res/values-pt-rBR/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Para:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Digite o PIN obrigatório:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"O tablet desconectará temporariamente da rede Wi-Fi enquanto estiver conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"O dispositivo Android TV desconectará o Wi-Fi temporariamente enquanto estiver conectado ao <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"O telefone desconectará temporariamente da rede Wi-Fi enquanto estiver conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"O dispositivo vai desconectar o Wi-Fi temporariamente enquanto estiver conectado ao <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Não foi possível se conectar à rede <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Toque para mudar as configurações de privacidade e tentar novamente"</string>
diff --git a/service/ServiceWifiResources/res/values-pt-rPT/strings.xml b/service/ServiceWifiResources/res/values-pt-rPT/strings.xml
index 3804873187..e3b51b2959 100644
--- a/service/ServiceWifiResources/res/values-pt-rPT/strings.xml
+++ b/service/ServiceWifiResources/res/values-pt-rPT/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Para:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Introduza o PIN solicitado:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"O tablet sera temporariamente desligado da rede Wi-Fi enquanto estiver ligado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"O seu dispositivo Android TV irá desligar-se temporariamente da rede Wi-Fi enquanto está ligado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"O telemóvel irá desligar-se temporariamente da rede Wi-Fi enquanto está ligado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"O seu dispositivo vai desligar-se temporariamente da rede Wi-Fi enquanto está ligado ao dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Não é possível ligar a <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Toque para alterar as definições de privacidade e tente novamente."</string>
diff --git a/service/ServiceWifiResources/res/values-pt/strings.xml b/service/ServiceWifiResources/res/values-pt/strings.xml
index 71aa053e88..2f2060c0e2 100644
--- a/service/ServiceWifiResources/res/values-pt/strings.xml
+++ b/service/ServiceWifiResources/res/values-pt/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Para:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Digite o PIN obrigatório:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"O tablet desconectará temporariamente da rede Wi-Fi enquanto estiver conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"O dispositivo Android TV desconectará o Wi-Fi temporariamente enquanto estiver conectado ao <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"O telefone desconectará temporariamente da rede Wi-Fi enquanto estiver conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"O dispositivo vai desconectar o Wi-Fi temporariamente enquanto estiver conectado ao <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Não foi possível se conectar à rede <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Toque para mudar as configurações de privacidade e tentar novamente"</string>
diff --git a/service/ServiceWifiResources/res/values-ro/strings.xml b/service/ServiceWifiResources/res/values-ro/strings.xml
index c150310f6e..40271f5458 100644
--- a/service/ServiceWifiResources/res/values-ro/strings.xml
+++ b/service/ServiceWifiResources/res/values-ro/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Către:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Introdu codul PIN necesar:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"Cod PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tableta se va deconecta temporar de la rețeaua Wi-Fi cât timp este conectată la <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Dispozitivul Android TV se va deconecta temporar de la rețeaua Wi-Fi cât timp este conectat la <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefonul se va deconecta temporar de la rețeaua Wi-Fi cât timp este conectat la <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Dispozitivul se va deconecta temporar de la Wi-Fi cât timp este conectat la <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Nu se poate conecta la <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Atinge pentru a modifica setările de confidențialitate și a încerca din nou"</string>
diff --git a/service/ServiceWifiResources/res/values-ru/strings.xml b/service/ServiceWifiResources/res/values-ru/strings.xml
index d4629ef513..a47cd0e788 100644
--- a/service/ServiceWifiResources/res/values-ru/strings.xml
+++ b/service/ServiceWifiResources/res/values-ru/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Кому:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Введите PIN-код:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-код:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"При подключении к устройству <xliff:g id="DEVICE_NAME">%1$s</xliff:g> планшетный ПК будет временно отключаться от сети Wi-Fi"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"При подключении к устройству <xliff:g id="DEVICE_NAME">%1$s</xliff:g> устройство Android TV будет временно отключаться от сети Wi-Fi."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"При подключении к устройству <xliff:g id="DEVICE_NAME">%1$s</xliff:g> телефон будет временно отключаться от сети Wi-Fi"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"На время подключения к устройству <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ваше устройство отключится от сети Wi-Fi."</string>
<string name="dlg_ok" msgid="254496739491689405">"ОК"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Не удалось подключиться к устройству \"<xliff:g id="SSID">%1$s</xliff:g>\""</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Нажмите, чтобы изменить настройки конфиденциальности и повторить попытку."</string>
diff --git a/service/ServiceWifiResources/res/values-si/strings.xml b/service/ServiceWifiResources/res/values-si/strings.xml
index 2e65f866bb..d9c7cb4bd2 100644
--- a/service/ServiceWifiResources/res/values-si/strings.xml
+++ b/service/ServiceWifiResources/res/values-si/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"වෙත:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"අවශ්‍ය PIN එක ටයිප් කරන්න:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"ටැබ්ලටය <xliff:g id="DEVICE_NAME">%1$s</xliff:g> වෙත සම්බන්ධ වන අතරතුර එය Wi-Fi වලින් තාවකාලිකව විසන්ධි කෙරේ."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"ඔබගේ Android TV උපාංගය <xliff:g id="DEVICE_NAME">%1$s</xliff:g> වෙත සම්බන්ධ වී පවතින විට Wi-Fi වෙතින් එය තාවකාලිකව විසන්ධි වනු ඇත"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"දුරකථනය <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ට සම්බන්ධ වී පවතින විට Wi-Fi වලින් එය තාවකාලිකව විසන්ධි වෙයි."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> වෙත සම්බන්ධ වී ඇති අතරේ ඔබේ උපාංගය Wi-Fi වෙතින් තාවකාලිකව විසන්ධි වනු ඇත"</string>
<string name="dlg_ok" msgid="254496739491689405">"හරි"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> වෙත සම්බන්ධ විය නොහැකිය"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"රහස්‍යතා සැකසීම් වෙනස් කිරීමට තට්ටු කර යළි උත්සාහ කරන්න"</string>
diff --git a/service/ServiceWifiResources/res/values-sk/strings.xml b/service/ServiceWifiResources/res/values-sk/strings.xml
index a1cea844a3..397dc9f33c 100644
--- a/service/ServiceWifiResources/res/values-sk/strings.xml
+++ b/service/ServiceWifiResources/res/values-sk/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Komu:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Zadajte požadovaný kód PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tablet bude počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> od siete Wi‑Fi dočasne odpojený."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Zariadenie Android TV sa počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> dočasne odpojí od siete Wi‑Fi"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefón bude počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> od siete Wi‑Fi dočasne odpojený."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Počas pripojenia k zariadeniu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> sa vaše zariadenie dočasne odpojí od siete Wi‑Fi"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"K sieti <xliff:g id="SSID">%1$s</xliff:g> sa nedá pripojiť"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Klepnutím zmeňte nastavenia ochrany súkromia a skúste to znova"</string>
diff --git a/service/ServiceWifiResources/res/values-sl/strings.xml b/service/ServiceWifiResources/res/values-sl/strings.xml
index ab99da0faa..e05b77dae6 100644
--- a/service/ServiceWifiResources/res/values-sl/strings.xml
+++ b/service/ServiceWifiResources/res/values-sl/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Za:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Vnesite zahtevano kodo PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tablični računalnik bo začasno prekinil povezavo z Wi-Fi-jem, medtem ko je povezan z napravo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Naprava Android TV bo začasno prekinila povezavo z omrežjem Wi-Fi, medtem ko je povezana z napravo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefon bo začasno prekinil povezavo z Wi-Fi-jem, ko je povezan z napravo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Naprava bo začasno prekinila povezavo z omrežjem Wi-Fi, medtem ko je povezana z napravo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"V redu"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Povezava z omrežjem <xliff:g id="SSID">%1$s</xliff:g> ni mogoča"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Dotaknite se za spremembo nastavitev zasebnosti in poskusite znova"</string>
diff --git a/service/ServiceWifiResources/res/values-sq/strings.xml b/service/ServiceWifiResources/res/values-sq/strings.xml
index 92fe6fa9bc..a71a892754 100644
--- a/service/ServiceWifiResources/res/values-sq/strings.xml
+++ b/service/ServiceWifiResources/res/values-sq/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Për:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Shkruaj PIN-in e kërkuar:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-i:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tableti do të shkëputet përkohësisht nga Wi-Fi gjatë kohës së lidhjes me <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Pajisja jote Android TV do të shkëputet përkohësisht nga Wi-Fi ndërkohë që është e lidhur me <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefoni do të shkëputet përkohësisht nga Wi-Fi gjatë kohës së lidhjes me <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Pajisja jote do të shkëputet përkohësisht nga Wi-Fi ndërkohë që është e lidhur me <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Në rregull"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Nuk mund të lidhet me <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Trokit për të ndryshuar cilësimet e privatësisë dhe provo përsëri"</string>
diff --git a/service/ServiceWifiResources/res/values-sr/strings.xml b/service/ServiceWifiResources/res/values-sr/strings.xml
index 4b4491e596..ae3eff432e 100644
--- a/service/ServiceWifiResources/res/values-sr/strings.xml
+++ b/service/ServiceWifiResources/res/values-sr/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Коме:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Унесите потребни PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Таблет ће привремено прекинути везу са WiFi-ем док је повезан са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV уређај ће привремено прекинути везу са WiFi мрежом док је повезан са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Телефон ће привремено прекинути везу са WiFi-ем док је повезан са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Уређај ће привремено прекинути везу са WiFi мрежом док је повезан са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Потврди"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Повезивање на мрежу <xliff:g id="SSID">%1$s</xliff:g> није успело"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Додирните да бисте променили подешавања приватности и пробали поново"</string>
diff --git a/service/ServiceWifiResources/res/values-sv/strings.xml b/service/ServiceWifiResources/res/values-sv/strings.xml
index 07f76a1d3e..d02a82d58b 100644
--- a/service/ServiceWifiResources/res/values-sv/strings.xml
+++ b/service/ServiceWifiResources/res/values-sv/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Till:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Ange den obligatoriska PIN-koden:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-kod:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Surfplattans wifi-anslutning kommer tillfälligt att avbrytas när den är ansluten till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV-enheten kopplas tillfälligt från wifi medan den är ansluten till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Mobilen kommer tillfälligt att kopplas från wifi när den är ansluten till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Enheten kopplas tillfälligt från wifi när den är ansluten till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Det gick inte att ansluta till <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Tryck för att ändra integritetsinställningar och försök igen"</string>
diff --git a/service/ServiceWifiResources/res/values-sw/strings.xml b/service/ServiceWifiResources/res/values-sw/strings.xml
index 30af5eab02..b63f476ffa 100644
--- a/service/ServiceWifiResources/res/values-sw/strings.xml
+++ b/service/ServiceWifiResources/res/values-sw/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kwa:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Charaza PIN inayohitajika:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Kompyuta ndogo itaukata muunganisho kwa muda kutoka kwenye Wi-Fi inapokuwa imeunganishwa kwenye <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Kifaa chako cha Android TV kitatenganishwa na Wi-Fi kwa muda wakati kimeunganishwa kwenye <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Simu itaukata muunganisho kwa muda kutoka kwenye Wi-Fi inapokuwa imeunganishwa kwenye <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Kifaa chako kitatenganishwa na Wi-Fi kwa muda wakati kimeunganishwa kwenye <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"Sawa"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Imeshindwa kuunganisha kwenye <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Gusa ili ubadilishe mipangilio ya faragha na ujaribu tena"</string>
diff --git a/service/ServiceWifiResources/res/values-ta/strings.xml b/service/ServiceWifiResources/res/values-ta/strings.xml
index d565756e59..005dfe55a5 100644
--- a/service/ServiceWifiResources/res/values-ta/strings.xml
+++ b/service/ServiceWifiResources/res/values-ta/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"பெறுநர்:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"பின்வரும் அவசியமான பின்னை உள்ளிடவும்:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"பின்:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> உடன் டேப்லெட் இணைக்கப்படும்போது, வைஃபையிலிருந்து தற்காலிகமாகத் துண்டிக்கப்படும்."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"உங்கள் Android TV <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்துடன் இணைக்கப்பட்டிருக்கும் போது வைஃபையிலிருந்து தற்காலிகமாகத் துண்டிக்கப்படும்"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> உடன் மொபைல் இணைக்கப்படும்போது, வைஃபையிலிருந்து தற்காலிகமாகத் துண்டிக்கப்படும்."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> உடன் இணைக்கப்பட்டிருக்கும்போது உங்கள் சாதனம் வைஃபை இணைப்பில் இருந்து தற்காலிகமாகத் துண்டிக்கப்படும்"</string>
<string name="dlg_ok" msgid="254496739491689405">"சரி"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> உடன் இணைக்க முடியவில்லை"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"தனியுரிமை அமைப்புகளை மாற்ற தட்டி மீண்டும் முயலவும்"</string>
diff --git a/service/ServiceWifiResources/res/values-te/strings.xml b/service/ServiceWifiResources/res/values-te/strings.xml
index 0de30c809a..ec40546f41 100644
--- a/service/ServiceWifiResources/res/values-te/strings.xml
+++ b/service/ServiceWifiResources/res/values-te/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"వీరికి:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"అవసరమైన పిన్‌ను టైప్ చేయండి:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"పిన్‌:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"టాబ్లెట్ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>కు కనెక్ట్ చేయబడినప్పుడు Wi-Fi నుండి తాత్కాలికంగా డిస్‌కనెక్ట్ చేయబడుతుంది"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"మీ Android TV పరికరం <xliff:g id="DEVICE_NAME">%1$s</xliff:g>కి కనెక్ట్ అయి ఉన్నప్పుడు తాత్కాలికంగా Wi-Fi నుండి డిస్‌కనెక్ట్ అవుతుంది"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"ఫోన్ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>కి కనెక్ట్ అయినప్పుడు అది Wi-Fi నుండి తాత్కాలికంగా డిస్‌కనెక్ట్ చేయబడుతుంది"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"మీ పరికరం <xliff:g id="DEVICE_NAME">%1$s</xliff:g>‌కి కనెక్ట్ అయి ఉన్నప్పుడు తాత్కాలికంగా Wi-Fi నుండి డిస్‌కనెక్ట్ అవుతుంది"</string>
<string name="dlg_ok" msgid="254496739491689405">"సరే"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g>కు కనెక్ట్ చేయడం సాధ్యపడదు"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"మీ గోప్యతా సెట్టింగ్‌లను మార్చడానికి నొక్కి, మళ్లీ ట్రై చేయండి"</string>
diff --git a/service/ServiceWifiResources/res/values-th/strings.xml b/service/ServiceWifiResources/res/values-th/strings.xml
index 8d2ed19641..0958cc3ceb 100644
--- a/service/ServiceWifiResources/res/values-th/strings.xml
+++ b/service/ServiceWifiResources/res/values-th/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"ถึง:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"พิมพ์ PIN ที่ต้องการ:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"แท็บเล็ตนี้จะยกเลิกการเชื่อมต่อกับ WiFi ชั่วคราวในขณะที่เชื่อมต่อกับ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"อุปกรณ์ Android TV จะยกเลิกการเชื่อมต่อ Wi-Fi ชั่วคราวระหว่างที่เชื่อมต่อกับ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"โทรศัพท์จะยกเลิกการเชื่อมต่อกับ WiFi ชั่วคราวในขณะที่เชื่อมต่อกับ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"อุปกรณ์ของคุณจะยกเลิกการเชื่อมต่อ Wi-Fi ชั่วคราวระหว่างที่เชื่อมต่อกับ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"ตกลง"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"เชื่อมต่อกับ <xliff:g id="SSID">%1$s</xliff:g> ไม่ได้"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"แตะเพื่อเปลี่ยนการตั้งค่าความเป็นส่วนตัวแล้วลองใหม่"</string>
diff --git a/service/ServiceWifiResources/res/values-tl/strings.xml b/service/ServiceWifiResources/res/values-tl/strings.xml
index 9966aec343..7b16618e41 100644
--- a/service/ServiceWifiResources/res/values-tl/strings.xml
+++ b/service/ServiceWifiResources/res/values-tl/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kay:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"I-type ang kinakailangang PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Pansamantalang madidiskoneta ang tablet sa Wi-Fi habang nakakonekta ito sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Pansamantalang madidiskonekta sa Wi-Fi ang iyong Android TV device habang nakakonekta ito sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Pansamantalang madidiskoneta ang telepono sa Wi-Fi habang nakakonekta ito sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Pansamantalang madidiskonekta sa Wi-Fi ang iyong device habang nakakonekta ito sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Hindi makakonekta sa <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"I-tap para baguhin ang mga setting ng privacy at subukan ulit"</string>
diff --git a/service/ServiceWifiResources/res/values-tr/strings.xml b/service/ServiceWifiResources/res/values-tr/strings.xml
index 15504803de..efc4d1b7ad 100644
--- a/service/ServiceWifiResources/res/values-tr/strings.xml
+++ b/service/ServiceWifiResources/res/values-tr/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Alıcı:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Gerekli PIN\'i yazın:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Tablet <xliff:g id="DEVICE_NAME">%1$s</xliff:g> adlı cihaza bağlıyken Kablosuz ağ bağlantısı geçici olarak kesilecektir"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV cihazınız <xliff:g id="DEVICE_NAME">%1$s</xliff:g> adlı cihaza bağlıyken kablosuz ağ bağlantısı geçici olarak kesilecek"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefon <xliff:g id="DEVICE_NAME">%1$s</xliff:g> adlı cihaza bağlıyken Kablosuz ağ bağlantısı geçici olarak kesilecektir"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Cihazınız <xliff:g id="DEVICE_NAME">%1$s</xliff:g> adlı cihaza bağlıyken kablosuz bağlantısı geçici olarak kesilecek"</string>
<string name="dlg_ok" msgid="254496739491689405">"Tamam"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> ağına bağlanılamıyor"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Gizlilik ayarını değiştirip tekrar denemek için dokunun"</string>
diff --git a/service/ServiceWifiResources/res/values-uk/strings.xml b/service/ServiceWifiResources/res/values-uk/strings.xml
index 2afa400fe3..456be30cbc 100644
--- a/service/ServiceWifiResources/res/values-uk/strings.xml
+++ b/service/ServiceWifiResources/res/values-uk/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Кому:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Введіть потрібний PIN-код:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN-код:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Під час з’єднання з пристроєм <xliff:g id="DEVICE_NAME">%1$s</xliff:g> планшетний ПК тимчасово від’єднається від мережі Wi-Fi"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"На час підключення до пристрою <xliff:g id="DEVICE_NAME">%1$s</xliff:g> Android TV тимчасово відключиться від мережі Wi-Fi"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Під час з’єднання з пристроєм <xliff:g id="DEVICE_NAME">%1$s</xliff:g> телефон тимчасово від’єднається від мережі Wi-Fi"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"На час підключення до пристрою \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" ваш пристрій буде від’єднано від мережі Wi-Fi"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Не вдалося підключитися до мережі \"<xliff:g id="SSID">%1$s</xliff:g>\""</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Натисніть, щоб змінити налаштування конфіденційності й повторити спробу"</string>
diff --git a/service/ServiceWifiResources/res/values-ur/strings.xml b/service/ServiceWifiResources/res/values-ur/strings.xml
index 9305ac6f01..d96adbadbc 100644
--- a/service/ServiceWifiResources/res/values-ur/strings.xml
+++ b/service/ServiceWifiResources/res/values-ur/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"بنام:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"‏مطلوبہ PIN ٹائپ کریں:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"‏ٹیبلیٹ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> سے مربوط ہونے پر عارضی طور پر Wi-Fi سے منقطع ہو جائے گا"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"‏آپ کا Android TV آلہ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> سے منسلک ہونے پر عارضی طور پر Wi-Fi سے غیر منسلک ہو جائے گا"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"‏فون <xliff:g id="DEVICE_NAME">%1$s</xliff:g> سے مربوط رہنے کے وقت عارضی طور پر Wi-Fi سے منقطع ہوجائے گا"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"‏آپ کا آلہ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> سے منسلک ہونے پر، عارضی طور پر Wi-Fi سے غیر منسلک ہو جائے گا"</string>
<string name="dlg_ok" msgid="254496739491689405">"ٹھیک ہے"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> سے منسلک نہیں کر سکتے"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"رازداری کی ترتیبات تبدیل کرنے اور دوبارہ کوشش کرنے کے لیے تھپتھپائیں"</string>
diff --git a/service/ServiceWifiResources/res/values-uz/strings.xml b/service/ServiceWifiResources/res/values-uz/strings.xml
index fa24256ffd..ebd27bd65a 100644
--- a/service/ServiceWifiResources/res/values-uz/strings.xml
+++ b/service/ServiceWifiResources/res/values-uz/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Kimga:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"So‘ralgan PIN kodni kiriting:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN kod:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Planshet <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ga ulanganligi tufayli vaqtincha Wi-Fi tarmog‘idan uzildi."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV qurilmangiz <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasiga ulangani uchun u vaqtincha Wi-Fi tarmoqdan uzildi."</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Telefon <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ga ulanganligi tufayli vaqtincha Wi-Fi tarmog‘idan uzildi."</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Qurilmangiz <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasiga ulangani uchun u vaqtincha Wi-Fi tarmoqdan uzildi."</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"<xliff:g id="SSID">%1$s</xliff:g> bilan aloqa oʻrnatilmadi"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Maxfiylik sozlamalarini oʻzgartirish uchun bosing va qayta urining"</string>
diff --git a/service/ServiceWifiResources/res/values-vi/strings.xml b/service/ServiceWifiResources/res/values-vi/strings.xml
index fe43095eae..bd2e416ca5 100644
--- a/service/ServiceWifiResources/res/values-vi/strings.xml
+++ b/service/ServiceWifiResources/res/values-vi/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Người nhận:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Nhập PIN bắt buộc:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"Mã PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Máy tính bảng sẽ tạm thời ngắt kết nối khỏi Wi-Fi trong khi máy tính bảng được kết nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Thiết bị Android TV sẽ tạm thời ngắt kết nối khỏi Wi-Fi trong khi kết nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Điện thoại sẽ tạm thời ngắt kết nối khỏi Wi-Fi trong khi điện thoại được kết nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Thiết bị của bạn sẽ tạm thời ngắt kết nối với Wi-Fi trong khi kết nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"OK"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Không thể kết nối với <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Nhấn để thay đổi các tùy chọn cài đặt quyền riêng tư rồi thử lại"</string>
diff --git a/service/ServiceWifiResources/res/values-zh-rCN/strings.xml b/service/ServiceWifiResources/res/values-zh-rCN/strings.xml
index 737a627623..5a0871e7af 100644
--- a/service/ServiceWifiResources/res/values-zh-rCN/strings.xml
+++ b/service/ServiceWifiResources/res/values-zh-rCN/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"收件人:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"输入所需的PIN码:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN 码:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"平板电脑连接到“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”时会暂时断开与WLAN的连接"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"当 Android TV 设备连接到 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 时,它会暂时断开 WLAN 连接"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"手机连接到<xliff:g id="DEVICE_NAME">%1$s</xliff:g>时会暂时断开与WLAN的连接。"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"当设备连接到<xliff:g id="DEVICE_NAME">%1$s</xliff:g>时,它会暂时断开 WLAN 连接"</string>
<string name="dlg_ok" msgid="254496739491689405">"确定"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"无法连接到“<xliff:g id="SSID">%1$s</xliff:g>”"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"点按以更改隐私设置并重试"</string>
diff --git a/service/ServiceWifiResources/res/values-zh-rHK/strings.xml b/service/ServiceWifiResources/res/values-zh-rHK/strings.xml
index 00009b2f08..635311749b 100644
--- a/service/ServiceWifiResources/res/values-zh-rHK/strings.xml
+++ b/service/ServiceWifiResources/res/values-zh-rHK/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"收件者:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"請輸入必要的 PIN 碼:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN 碼:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"平板電腦與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 連線期間將暫時中斷 Wi-Fi 連線"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV 裝置與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 連線期間,系統將暫時中斷 Wi-Fi 連線"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"手機與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 連線期間將暫時中斷 Wi-Fi 連線"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"裝置與「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」連線期間將暫時中斷 Wi-Fi 連線"</string>
<string name="dlg_ok" msgid="254496739491689405">"確定"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"無法連接「<xliff:g id="SSID">%1$s</xliff:g>」"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"輕按以更改私隱設定,然後重試"</string>
diff --git a/service/ServiceWifiResources/res/values-zh-rTW/strings.xml b/service/ServiceWifiResources/res/values-zh-rTW/strings.xml
index 90a9b2deb9..6aed027f4c 100644
--- a/service/ServiceWifiResources/res/values-zh-rTW/strings.xml
+++ b/service/ServiceWifiResources/res/values-zh-rTW/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"收件者:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"請輸入必要的 PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN 碼:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"平板電腦與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 連線期間將暫時中斷 Wi-Fi 連線"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Android TV 裝置與「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」連線期間將暫時中斷 Wi-Fi 連線"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"手機與 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 連線期間將暫時中斷 Wi-Fi 連線"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"裝置與「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」連線期間將暫時中斷 Wi-Fi 連線"</string>
<string name="dlg_ok" msgid="254496739491689405">"確定"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"無法連線至「<xliff:g id="SSID">%1$s</xliff:g>」"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"輕觸即可變更隱私權設定並重試"</string>
diff --git a/service/ServiceWifiResources/res/values-zu/strings.xml b/service/ServiceWifiResources/res/values-zu/strings.xml
index 23c754f1b3..d8e04f070e 100644
--- a/service/ServiceWifiResources/res/values-zu/strings.xml
+++ b/service/ServiceWifiResources/res/values-zu/strings.xml
@@ -60,9 +60,7 @@
<string name="wifi_p2p_to_message" msgid="3809923305696994787">"Ku:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5200220251738047620">"Faka i-PIN edingekayo:"</string>
<string name="wifi_p2p_show_pin_message" msgid="1000091690967930798">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="2875937871590955304">"Ithebulethi izonqamuka okwesikhashana ku-Wi-Fi ngenkathi ixhumeke ku-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="9133053225387001827">"Idivayisi yakho ye-Android TV izonqamula okwesikhashana kusuka ku-Wi-Fi ngenkathi ixhumeke ku-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="2226863827636191980">"Ifoni izonqamuka okwesikhashana ku-Wi-Fi ngenkathi ixhumeke ku-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+ <string name="wifi_p2p_frequency_conflict_message" msgid="8535404941723941766">"Idivayisi yakho izonqamuka okwesikhashana ku-Wi-Fi ngenkathi uxhume ku-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="dlg_ok" msgid="254496739491689405">"KULUNGILE"</string>
<string name="wifi_cannot_connect_with_randomized_mac_title" msgid="2344570489693915253">"Ayikwazi ukuxhumeka ku-<xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_cannot_connect_with_randomized_mac_message" msgid="4834133226521813352">"Thepha ukuze ushintshe izilungiselelo zobumfihlo uphinde uzame futhi"</string>
diff --git a/service/ServiceWifiResources/res/values/config.xml b/service/ServiceWifiResources/res/values/config.xml
index 14b83ebc94..eb1845c0e8 100644
--- a/service/ServiceWifiResources/res/values/config.xml
+++ b/service/ServiceWifiResources/res/values/config.xml
@@ -611,6 +611,12 @@
<integer translatable="false" name="config_wifiDisableReasonAuthenticationNoSubscriptionDurationMs"> -1 </integer>
<integer translatable="false" name="config_wifiDisableReasonConsecutiveFailuresDurationMs"> 300000 </integer>
+ <!-- Configuration for disabling a network due to repeated NUD failures -->
+ <!-- The number of NUD failures that need to happen to trigger blocking -->
+ <integer translatable="false" name="config_wifiDisableReasonRepeatedNudFailuresThreshold"> 5 </integer>
+ <!-- The NUD failures need to happen within this time window or else the counter will be reset -->
+ <integer translatable="false" name="config_wifiDisableReasonRepeatedNudFailuresWindowMs"> 60000 </integer>
+
<!-- List of constants that indicate the number of consecutive failures per type needed to block a BSSID.
A blocked BSSID will not be considered in network selection and firmware roaming.-->
<integer translatable="false" name="config_wifiBssidBlocklistMonitorApUnableToHandleNewStaThreshold"> 1 </integer>
@@ -660,9 +666,6 @@
<!-- Indicates that hidden networks are to be scanned during scan only mode -->
<bool translatable="false" name="config_wifiScanHiddenNetworksScanOnlyMode">false</bool>
- <!-- Enable logging WifiIsUnusableEvent in metrics which gets triggered when wifi becomes unusable. -->
- <bool translatable="false" name="config_wifiIsUnusableEventMetricsEnabled">true</bool>
-
<!-- The minimum number of txBad the framework has to observe to trigger a wifi data stall. -->
<integer translatable="false" name="config_wifiDataStallMinTxBad">1</integer>
@@ -1273,4 +1276,54 @@
regulatory domain.
false: disconnect on NUD failures (normal/default action). -->
<bool translatable="false" name ="config_wifiDisableNudDisconnectsForWapiInSpecificCc">false</bool>
+ <!-- A list of AKM suite selector mapping to configure the unknown AKM suite specifier to
+ known AKM suite specifier (Refer IEEE-80211-2020 section 9.4.2.24.3 AKM suites).
+ An AKM suite selector is defined as a combination of OUI (Organizationally unique
+ identifier) and AKMP (Authentication and key management protocol) suite type in IEEE80211
+ spec. For example 00-0F-AC:1 represents Authentication negotiated over IEEE Std 802.1X,
+ where the OUI is 00-0F-AC and AKMP is 1.
+ The Values specified here is for OEMs to allow setting the security type for APs which
+ advertise the AKMs not defined in Wi-Fi framework(unknown to framework). If a mapping is
+ available, framework sets the AP's key management type to the mapped known AKM and the
+ security type will be derived based on the known AKM. Then it is up to the HAL
+ implementation to derive the actual AKM to use in connection.
+ The mapping specified here is in integer decimal format separated by a comma:
+ (Unknown AKM, Known AKM).
+ When defining the integer AKM value here, follow this rule, the most significant byte
+ should carry the AKMP suite type. Use the below method to compute the integer decimal
+ AKM suite selector value - AKM_VALUE(0x00, 0x0f, 0xac, 0x1)
+ AKM_VALUE(a, b, c, d) -> ((((u32) (a)) << 24) | (((u32) (b)) << 16) | (((u32) (c)) << 8)
+ | (u32) (d)) = 28053248 (Hex value - 0x01ac0f00) -->
+ <string-array translatable="false" name="config_wifiUnknownAkmToKnownAkmMapping">
+ <!-- Below is a sample configuration for this list:
+ <item>unknownAkm1,knownAkm</item>
+ <item>unknownAkm2,knownAkm</item>
+ -->
+ </string-array>
+ <!-- Integer for minimum time between IEEE 802.11az non-trigger based ranging measurements in
+ microseconds. Note that ranging request converts this to units of 100 microseconds. So the
+ value should be a multiple of 100 microseconds. Non-zero values in this setting take
+ precedence over individual responder settings, effectively enforcing a system-wide minimum
+ measurement interval for non-trigger based ranging operations.. -->
+ <integer translatable="false" name="config_wifi80211azMinTimeBetweenNtbMeasurementsMicros">250000</integer>
+ <!-- Integer for maximum time between IEEE 802.11az non-trigger based ranging measurements in
+ microseconds. Note that ranging request converts this to units of 10 milliseconds. So the
+ value should be a multiple of 10000 microseconds. Non-zero values in this setting take
+ precedence over individual responder settings, effectively enforcing a system-wide maximum
+ measurement interval for non-trigger based ranging operations. -->
+ <integer translatable="false" name="config_wifi80211azMaxTimeBetweenNtbMeasurementsMicros">15000000</integer>
+
+ <!-- Boolean indicating whether the device supports d2d allowed control when infra STA is disabled -->
+ <bool translatable="false" name ="config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled">false</bool>
+ <!-- Array describing MAC OUI list to block TWT session setup request. If the primary station is
+ connected to an AP with a MAC address OUI (https://standards-oui.ieee.org/oui/oui.txt)
+ matching with any of entries in this blocked list, WifiManager#setupTwtSession() will fail
+ with TwtSessionCallback#onFailure(errorCode = TWT_ERROR_CODE_AP_OUI_BLOCKLISTED).
+ -->
+ <integer-array translatable="false" name="config_wifiTwtBlockedOuiList">
+ <!-- Below is a sample configuration for this list:
+ <item>0x001122</item>
+ <item>0x334455</item>
+ -->
+ </integer-array>
</resources>
diff --git a/service/ServiceWifiResources/res/values/overlayable.xml b/service/ServiceWifiResources/res/values/overlayable.xml
index 0504a5e74d..5764f263d6 100644
--- a/service/ServiceWifiResources/res/values/overlayable.xml
+++ b/service/ServiceWifiResources/res/values/overlayable.xml
@@ -179,6 +179,8 @@
<item type="integer" name="config_wifiDisableReasonByWrongPasswordDurationMs" />
<item type="integer" name="config_wifiDisableReasonAuthenticationNoSubscriptionDurationMs" />
<item type="integer" name="config_wifiDisableReasonConsecutiveFailuresDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonRepeatedNudFailuresThreshold" />
+ <item type="integer" name="config_wifiDisableReasonRepeatedNudFailuresWindowMs" />
<item type="integer" name="config_wifiBssidBlocklistMonitorApUnableToHandleNewStaThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorNetworkValidationFailureThreshold" />
@@ -199,7 +201,6 @@
<item type="integer" name="config_wifiBssidBlocklistMonitorValidationFailureBaseBlockDurationMs" />
<item type="bool" name="config_wifiScanHiddenNetworksScanOnlyMode" />
<item type="integer" name="config_wifiHardwareSoftapMaxClientCount" />
- <item type="bool" name="config_wifiIsUnusableEventMetricsEnabled" />
<item type="integer" name="config_wifiDataStallMinTxBad" />
<item type="integer" name="config_wifiDataStallMinTxSuccessWithoutRx" />
<item type="bool" name="config_wifiLinkSpeedMetricsEnabled" />
@@ -336,6 +337,11 @@
<item type="bool" name="config_wifiSofapHalMapWpa3TransitionModeToWpa3OnlyIn6GHzBand" />
<item type="bool" name ="config_wifiRemainConnectedAfterIpProvisionTimeout" />
<item type="bool" name ="config_wifiDisableNudDisconnectsForWapiInSpecificCc" />
+ <item type="array" name="config_wifiUnknownAkmToKnownAkmMapping" />
+ <item type="integer" name="config_wifi80211azMinTimeBetweenNtbMeasurementsMicros"/>
+ <item type="integer" name="config_wifi80211azMaxTimeBetweenNtbMeasurementsMicros"/>
+ <item type="bool" name="config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled" />
+ <item type="array" name="config_wifiTwtBlockedOuiList" />
<!-- Params from config.xml that can be overlayed -->
diff --git a/service/ServiceWifiResources/res/values/strings.xml b/service/ServiceWifiResources/res/values/strings.xml
index 8b7f383ad8..26624b023e 100644
--- a/service/ServiceWifiResources/res/values/strings.xml
+++ b/service/ServiceWifiResources/res/values/strings.xml
@@ -112,9 +112,7 @@
<string name="wifi_p2p_enter_pin_message">Type the required PIN: </string>
<string name="wifi_p2p_show_pin_message">PIN: </string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet">The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv">Your Android TV device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
- <string name="wifi_p2p_frequency_conflict_message" product="default">The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
+ <string name="wifi_p2p_frequency_conflict_message">Your device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
<!-- Dialog ok button-->
<string name="dlg_ok">OK</string>
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index 9b776bd53c..ccd85abf37 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -18,6 +18,8 @@ package com.android.server.wifi;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
+import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
+import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
@@ -47,6 +49,7 @@ import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.IWifiNetworkStateChangedListener;
import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
+import android.net.wifi.SoftApState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -214,9 +217,9 @@ public class ActiveModeWarden {
}
/**
- * Get the request WorkSource for secondary CMM
+ * Get the request WorkSource for secondary LOCAL-ONLY CMM
*
- * @return the WorkSources of the current secondary CMMs
+ * @return the WorkSources of the current secondary LOCAL-ONLY CMMs
*/
public Set<WorkSource> getSecondaryRequestWs() {
synchronized (mServiceApiLock) {
@@ -716,6 +719,7 @@ public class ActiveModeWarden {
}
}, new IntentFilter(TelephonyManager.ACTION_EMERGENCY_CALL_STATE_CHANGED));
}
+ mWifiGlobals.setD2dStaConcurrencySupported(mWifiNative.isP2pStaConcurrencySupported());
// Initialize the supported feature set.
setSupportedFeatureSet(mWifiNative.getSupportedFeatureSet(null),
mWifiNative.isStaApConcurrencySupported(),
@@ -1414,7 +1418,7 @@ public class ActiveModeWarden {
ConcreteClientModeManager manager = mWifiInjector.makeClientModeManager(
listener, requestorWs, role, mVerboseLoggingEnabled);
mClientModeManagers.add(manager);
- if (ROLE_CLIENT_SECONDARY_LONG_LIVED.equals(role) || ROLE_CLIENT_LOCAL_ONLY.equals(role)) {
+ if (ROLE_CLIENT_LOCAL_ONLY.equals(role)) {
synchronized (mServiceApiLock) {
mRequestWs.add(new WorkSource(requestorWs));
}
@@ -1435,7 +1439,7 @@ public class ActiveModeWarden {
synchronized (mServiceApiLock) {
mRequestWs.remove(manager.getRequestorWs());
}
- if (ROLE_CLIENT_SECONDARY_LONG_LIVED.equals(role) || ROLE_CLIENT_LOCAL_ONLY.equals(role)) {
+ if (ROLE_CLIENT_LOCAL_ONLY.equals(role)) {
synchronized (mServiceApiLock) {
mRequestWs.add(new WorkSource(requestorWs));
}
@@ -1690,8 +1694,7 @@ public class ActiveModeWarden {
private void onStoppedOrStartFailure(ConcreteClientModeManager clientModeManager) {
mClientModeManagers.remove(clientModeManager);
- if (ROLE_CLIENT_SECONDARY_LONG_LIVED.equals(clientModeManager.getPreviousRole())
- || ROLE_CLIENT_LOCAL_ONLY.equals(clientModeManager.getPreviousRole())) {
+ if (ROLE_CLIENT_LOCAL_ONLY.equals(clientModeManager.getPreviousRole())) {
synchronized (mServiceApiLock) {
mRequestWs.remove(clientModeManager.getRequestorWs());
}
@@ -2048,8 +2051,9 @@ public class ActiveModeWarden {
softApConfig.getTargetMode() == IFACE_IP_MODE_LOCAL_ONLY
? mLohsCallback : mSoftApCallback;
// need to notify SoftApCallback that start/stop AP failed
- callback.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ callback.onStateChanged(new SoftApState(
+ WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL,
+ softApConfig.getTetheringRequest(), null /* iface */));
}
break;
default:
@@ -2107,7 +2111,7 @@ public class ActiveModeWarden {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ActiveModeWarden.class.getSimpleName() + "."
+ DefaultState.class.getSimpleName() + "." + getWhatToString(what);
}
@@ -2140,17 +2144,17 @@ public class ActiveModeWarden {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ActiveModeWarden.class.getSimpleName() + "."
+ DefaultState.class.getSimpleName() + "." + getWhatToString(what);
}
@Override
- void enterImpl() {
+ public void enterImpl() {
}
@Override
- void exitImpl() {
+ public void exitImpl() {
}
private void checkAndHandleAirplaneModeState() {
@@ -2238,7 +2242,8 @@ public class ActiveModeWarden {
}
private boolean shouldEnableSta() {
- return mSettingsStore.isWifiToggleEnabled() || shouldEnableScanOnlyMode();
+ return (mSettingsStore.isWifiToggleEnabled() || shouldEnableScanOnlyMode())
+ && !mSettingsStore.isSatelliteModeOn();
}
private void handleStaToggleChangeInDisabledState(WorkSource requestorWs) {
@@ -2422,7 +2427,8 @@ public class ActiveModeWarden {
if (mAllowRootToGetLocalOnlyCmm && curUid == 0) { // 0 is root UID.
continue;
}
- if (mWifiPermissionsUtil.checkEnterCarModePrioritized(curUid)) {
+ if (curUid != Process.SYSTEM_UID
+ && mWifiPermissionsUtil.checkEnterCarModePrioritized(curUid)) {
requestInfo.listener.onAnswer(primaryManager);
if (mVerboseLoggingEnabled) {
Log.w(TAG, "Uid " + curUid
@@ -2510,8 +2516,7 @@ public class ActiveModeWarden {
// fallback decision
if (requestInfo.clientRole == ROLE_CLIENT_LOCAL_ONLY
- && mContext.getResources().getBoolean(
- R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)
+ && isStaStaConcurrencySupportedForLocalOnlyConnections()
&& !mWifiPermissionsUtil.isTargetSdkLessThan(
requestInfo.requestorWs.getPackageName(0), Build.VERSION_CODES.S,
requestInfo.requestorWs.getUid(0))) {
@@ -2768,6 +2773,9 @@ public class ActiveModeWarden {
// The WPA didn't be deprecated, set it.
additionalFeatureSet |= WifiManager.WIFI_FEATURE_WPA_PERSONAL;
}
+ if (mWifiGlobals.isD2dSupportedWhenInfraStaDisabled()) {
+ additionalFeatureSet |= WifiManager.WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED;
+ }
mSupportedFeatureSet.set(
(supportedFeatureSet | concurrencyFeatureSet | additionalFeatureSet)
& ~excludedFeatureSet);
diff --git a/service/java/com/android/server/wifi/ApplicationQosPolicyRequestHandler.java b/service/java/com/android/server/wifi/ApplicationQosPolicyRequestHandler.java
index 088ad63652..f5893d5817 100644
--- a/service/java/com/android/server/wifi/ApplicationQosPolicyRequestHandler.java
+++ b/service/java/com/android/server/wifi/ApplicationQosPolicyRequestHandler.java
@@ -30,6 +30,7 @@ import android.os.RemoteException;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
import com.android.wifi.resources.R;
import java.io.PrintWriter;
@@ -353,16 +354,33 @@ public class ApplicationQosPolicyRequestHandler {
* Request to send all tracked policies to the specified interface.
*
* @param ifaceName Interface name to send the policies to.
+ * @param apSupportsQosChars Whether the AP connected on this interface
+ * supports QosCharacteristics.
*/
- public void queueAllPoliciesOnIface(String ifaceName) {
- List<QosPolicyParams> policyList = mPolicyTrackingTable.getAllPolicies();
+ public void queueAllPoliciesOnIface(String ifaceName, boolean apSupportsQosChars) {
+ List<QosPolicyParams> policiesWithoutQosChars =
+ mPolicyTrackingTable.getAllPolicies(false);
+ List<QosPolicyParams> policiesWithQosChars = SdkLevel.isAtLeastV() && apSupportsQosChars
+ ? mPolicyTrackingTable.getAllPolicies(true) : Collections.emptyList();
+ int totalNumPolicies = policiesWithoutQosChars.size() + policiesWithQosChars.size();
+
Log.i(TAG, "Queueing all policies on iface=" + ifaceName + ". numPolicies="
- + policyList.size());
- if (policyList.isEmpty()) return;
+ + totalNumPolicies);
+ Log.i(TAG, policiesWithQosChars.size() + " policies contain QosCharacteristics");
+ if (totalNumPolicies == 0) return;
+
+ // Divide policies into batches of size MAX_POLICIES_PER_TRANSACTION. Separate batches
+ // should be created for policies that contain QosCharacteristics, and those that do
+ // not contain them.
+ List<List<QosPolicyParams>> batches = new ArrayList<>();
+ if (!policiesWithoutQosChars.isEmpty()) {
+ batches.addAll(divideRequestIntoBatches(policiesWithoutQosChars));
+ }
+ if (!policiesWithQosChars.isEmpty()) {
+ batches.addAll(divideRequestIntoBatches(policiesWithQosChars));
+ }
- // Divide policyList into batches of size MAX_POLICIES_PER_TRANSACTION,
- // and queue each batch on the specified interface.
- List<List<QosPolicyParams>> batches = divideRequestIntoBatches(policyList);
+ // Queue all batches on the specified interface.
for (List<QosPolicyParams> batch : batches) {
QueuedRequest request = new QueuedRequest(
REQUEST_TYPE_ADD, batch, null, null, null, DEFAULT_UID);
diff --git a/service/java/com/android/server/wifi/ApplicationQosPolicyTrackingTable.java b/service/java/com/android/server/wifi/ApplicationQosPolicyTrackingTable.java
index 014fe7b1c0..d8509d4b3d 100644
--- a/service/java/com/android/server/wifi/ApplicationQosPolicyTrackingTable.java
+++ b/service/java/com/android/server/wifi/ApplicationQosPolicyTrackingTable.java
@@ -19,6 +19,8 @@ package com.android.server.wifi;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.WifiManager;
+import com.android.modules.utils.build.SdkLevel;
+
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -26,6 +28,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
+import java.util.stream.Stream;
/**
* Table containing application-added QoS policies that are being tracked by the framework.
@@ -214,13 +217,20 @@ public class ApplicationQosPolicyTrackingTable {
/**
* Get all policies that are tracked by this table.
*
+ * @param shouldContainQosChars Whether the returned policies should contain QosCharacteristics.
+ * Only applicable if SDK >= V.
* @return List of policies, or empty list if there are no policies in the table.
*/
- public List<QosPolicyParams> getAllPolicies() {
+ public List<QosPolicyParams> getAllPolicies(boolean shouldContainQosChars) {
if (mPolicyHashToPolicyMap.isEmpty()) {
return new ArrayList<>();
}
- return mPolicyHashToPolicyMap.values().stream().toList();
+ Stream<QosPolicyParams> policyStream = mPolicyHashToPolicyMap.values().stream();
+ if (SdkLevel.isAtLeastV()) {
+ policyStream = policyStream.filter(p ->
+ shouldContainQosChars == (p.getQosCharacteristics() != null));
+ }
+ return policyStream.toList();
}
/**
diff --git a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
index c4d43c578b..03d6cf567c 100644
--- a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
+++ b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
@@ -467,7 +467,7 @@ public class AvailableNetworkNotifier {
// only keep netId, discard other fields
new NetworkUpdateResult(result.getNetworkId()),
new ActionListenerWrapper(listener),
- Process.SYSTEM_UID, mContext.getOpPackageName()));
+ Process.SYSTEM_UID, mContext.getOpPackageName(), null));
addNetworkToBlocklist(mRecommendedNetwork.SSID);
}
diff --git a/service/java/com/android/server/wifi/BackupRestoreController.java b/service/java/com/android/server/wifi/BackupRestoreController.java
new file mode 100644
index 0000000000..374743b8cb
--- /dev/null
+++ b/service/java/com/android/server/wifi/BackupRestoreController.java
@@ -0,0 +1,196 @@
+/*
+ * 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;
+
+import android.util.Log;
+import android.util.Xml;
+
+import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.XmlUtil;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Class used to backup/restore data.
+ */
+public class BackupRestoreController {
+ private static final String TAG = "BackupRestoreController";
+
+ private final WifiSettingsBackupRestore mWifiSettingsBackupRestore;
+ private final Clock mClock;
+
+ private static final String XML_TAG_DOCUMENT_HEADER = "WifiSettingsBackupData";
+ private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+
+ /**
+ * Verbose logging flag.
+ */
+ private boolean mVerboseLoggingEnabled = false;
+ /**
+ * Store the dump of the backup/restore data for debugging. This is only stored when verbose
+ * logging is enabled.
+ */
+ private byte[] mDebugLastBackupDataRetrieved;
+ private long mLastBackupDataRetrievedTimestamp = 0;
+ private byte[] mDebugLastBackupDataRestored;
+ private long mLastBackupDataRestoredTimestamp = 0;
+
+ public BackupRestoreController(WifiSettingsBackupRestore wifiSettingsBackupRestore,
+ Clock clock) {
+ mWifiSettingsBackupRestore = wifiSettingsBackupRestore;
+ mClock = clock;
+ }
+
+ /**
+ * Retrieve an XML byte stream representing the data that needs to be backed up.
+ *
+ * @return Raw byte stream of XML that needs to be backed up.
+ */
+ public byte[] retrieveBackupData() {
+ try {
+ final XmlSerializer out = new FastXmlSerializer();
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+ XmlUtil.writeDocumentStart(out, XML_TAG_DOCUMENT_HEADER);
+
+ mWifiSettingsBackupRestore.retrieveBackupDataFromSettingsConfigStore(out, outputStream);
+
+ XmlUtil.writeDocumentEnd(out, XML_TAG_DOCUMENT_HEADER);
+ byte[] backupData = outputStream.toByteArray();
+ if (mVerboseLoggingEnabled) {
+ mDebugLastBackupDataRetrieved = backupData;
+ }
+ mLastBackupDataRetrievedTimestamp = mClock.getWallClockMillis();
+ return backupData;
+ } catch (IOException e) {
+ Log.e(TAG, "Error retrieving the backup data: " + e);
+ }
+ return new byte[0];
+ }
+
+ private void distpatchBackupData(String sectionName, XmlPullParser in, int depth)
+ throws XmlPullParserException, IOException {
+ switch (sectionName) {
+ case WifiSettingsBackupRestore.XML_TAG_SECTION_HEADER_WIFI_SETTINGS_DATA:
+ mWifiSettingsBackupRestore.restoreSettingsFromBackupData(in, depth);
+ break;
+ default:
+ Log.i(TAG, "unknown tag: (backed up from newer version?)" + sectionName);
+ }
+ }
+
+ /**
+ * Split the back up data to retrieve each back up session.
+ *
+ * @param data raw byte stream representing the XML data.
+ */
+ public void parserBackupDataAndDispatch(byte[] data) {
+ if (data == null || data.length == 0) {
+ Log.e(TAG, "Invalid backup data received");
+ return;
+ }
+ if (mVerboseLoggingEnabled) {
+ mDebugLastBackupDataRestored = data;
+ }
+ try {
+ final XmlPullParser in = Xml.newPullParser();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
+ in.setInput(inputStream, StandardCharsets.UTF_8.name());
+ // Start parsing the XML stream.
+ XmlUtil.gotoDocumentStart(in, XML_TAG_DOCUMENT_HEADER);
+ int sectionDepth = in.getDepth();
+ String[] sectionName = new String[1];
+ while (XmlUtil.gotoNextSectionOrEnd(in, sectionName, sectionDepth)) {
+ try {
+ if (sectionName[0] == null) {
+ throw new XmlPullParserException("Missing value name");
+ }
+ distpatchBackupData(sectionName[0], in, sectionDepth);
+ } catch (XmlPullParserException | IOException ex) {
+ Log.e(TAG, "Error to parser tag: " + sectionName[0]);
+ }
+ }
+ mLastBackupDataRestoredTimestamp = mClock.getWallClockMillis();
+ } catch (XmlPullParserException | IOException ex) {
+ Log.e(TAG, "Error :" + ex);
+ }
+
+ }
+
+ /**
+ * Enable verbose logging.
+ *
+ * @param verboseEnabled whether or not verbosity log level is enabled.
+ */
+ public void enableVerboseLogging(boolean verboseEnabled) {
+ mVerboseLoggingEnabled = verboseEnabled;
+ }
+
+ /**
+ * Dump out the last backup/restore data if verbose logging is enabled.
+ *
+ * @param fd unused
+ * @param pw PrintWriter for writing dump to
+ * @param args unused
+ */
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("Dump of " + TAG);
+ if (mDebugLastBackupDataRetrieved != null) {
+ pw.println("Last backup data retrieved: "
+ + createLogFromBackupData(mDebugLastBackupDataRetrieved));
+
+ }
+ pw.println("mLastBackupDataRetrievedTimestamp: "
+ + (mLastBackupDataRetrievedTimestamp != 0
+ ? FORMATTER.format(new Date(mLastBackupDataRetrievedTimestamp)) : "N/A"));
+ if (mDebugLastBackupDataRestored != null) {
+ pw.println("Last backup data restored: "
+ + createLogFromBackupData(mDebugLastBackupDataRestored));
+ }
+ pw.println("mLastBackupDataRestoredTimestamp: "
+ + (mLastBackupDataRestoredTimestamp != 0
+ ? FORMATTER.format(new Date(mLastBackupDataRestoredTimestamp)) : "N/A"));
+ }
+
+ private String createLogFromBackupData(byte[] data) {
+ if (data != null) {
+ StringBuilder sb = new StringBuilder();
+ try {
+ String xmlString = new String(data, StandardCharsets.UTF_8.name());
+ for (String line : xmlString.split("\n")) {
+ sb.append(line).append("\n");
+ }
+ return sb.toString();
+ } catch (UnsupportedEncodingException e) {
+ Log.e(TAG, "fail to create log from backup data. " + e);
+ }
+ }
+ return "";
+ }
+}
diff --git a/service/java/com/android/server/wifi/ClientMode.java b/service/java/com/android/server/wifi/ClientMode.java
index 1427a8dba4..7292de3338 100644
--- a/service/java/com/android/server/wifi/ClientMode.java
+++ b/service/java/com/android/server/wifi/ClientMode.java
@@ -66,7 +66,7 @@ public interface ClientMode {
void enableVerboseLogging(boolean verbose);
void connectNetwork(NetworkUpdateResult result, ActionListenerWrapper wrapper, int callingUid,
- @NonNull String packageName);
+ @NonNull String packageName, @Nullable String attributionTag);
void saveNetwork(NetworkUpdateResult result, ActionListenerWrapper wrapper, int callingUid,
@NonNull String packageName);
diff --git a/service/java/com/android/server/wifi/ClientModeDefaults.java b/service/java/com/android/server/wifi/ClientModeDefaults.java
index 115dfaf533..f526f2dc6a 100644
--- a/service/java/com/android/server/wifi/ClientModeDefaults.java
+++ b/service/java/com/android/server/wifi/ClientModeDefaults.java
@@ -17,6 +17,7 @@
package com.android.server.wifi;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.net.DhcpResultsParcelable;
import android.net.MacAddress;
import android.net.Network;
@@ -47,7 +48,7 @@ public interface ClientModeDefaults extends ClientMode {
default void dump(FileDescriptor fd, PrintWriter pw, String[] args) { }
default void connectNetwork(NetworkUpdateResult result, ActionListenerWrapper wrapper,
- int callingUid, @NonNull String packageName) {
+ int callingUid, @NonNull String packageName, @Nullable String attributionTag) {
// wifi off, can't connect.
wrapper.sendFailure(WifiManager.ActionListener.FAILURE_BUSY);
}
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index c5a891f708..4b3cf17404 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -93,6 +93,7 @@ import android.net.wifi.WifiManager.DeviceMobilityState;
import android.net.wifi.WifiNetworkAgentSpecifier;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiSsid;
+import android.net.wifi.flags.Flags;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.nl80211.DeviceWiphyCapabilities;
@@ -194,6 +195,11 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
@VisibleForTesting public static final short NUM_LOG_RECS_VERBOSE = 3000;
private static final String TAG = "WifiClientModeImpl";
+ // Hardcoded constant used for caller to avoid triggering connect choice that force framework
+ // to stick to the selected network. Do not change this value to maintain backward
+ // compatibility.
+ public static final String ATTRIBUTION_TAG_DISALLOW_CONNECT_CHOICE =
+ "ATTRIBUTION_TAG_DISALLOW_CONNECT_CHOICE";
private static final int IPCLIENT_STARTUP_TIMEOUT_MS = 2_000;
private static final int IPCLIENT_SHUTDOWN_TIMEOUT_MS = 60_000; // 60 seconds
@@ -214,15 +220,15 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
*/
@Override
protected void loge(String s) {
- Log.e(getTag(), s);
+ Log.e(getTag(), s, null);
}
@Override
protected void logd(String s) {
- Log.d(getTag(), s);
+ Log.d(getTag(), s, null);
}
@Override
protected void log(String s) {
- Log.d(getTag(), s);
+ Log.d(getTag(), s, null);
}
private final WifiContext mContext;
private final WifiMetrics mWifiMetrics;
@@ -358,6 +364,9 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// This is is used to track the number of TDLS peers enabled in driver via enableTdls()
private Set<String> mEnabledTdlsPeers = new ArraySet<>();
+ // Tracks the last NUD failure timestamp, and number of failures.
+ private Pair<Long, Integer> mNudFailureCounter = new Pair<>(0L, 0);
+
/**
* Method to clear {@link #mTargetBssid} and reset the current connected network's
* bssid in wpa_supplicant after a roam/connect attempt.
@@ -1240,6 +1249,16 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// nothing to do.
return;
}
+
+ if (newConfig.isWifi7Enabled() != oldConfig.isWifi7Enabled()) {
+ Log.w(getTag(), "Wi-Fi " + (newConfig.isWifi7Enabled() ? "enabled" : "disabled")
+ + " triggering disconnect");
+ mFrameworkDisconnectReasonOverride =
+ WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__DISCONNECT_NETWORK_WIFI7_TOGGLED;
+ sendMessage(CMD_DISCONNECT, StaEvent.DISCONNECT_NETWORK_WIFI7_TOGGLED);
+ return;
+ }
+
boolean isMetered = WifiConfiguration.isMetered(newConfig, mWifiInfo);
boolean wasMetered = WifiConfiguration.isMetered(oldConfig, mWifiInfo);
// Check if user/app change meteredOverride or trusted for connected network.
@@ -1443,14 +1462,14 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
* @param packageName package name of the app requesting the connection.
*/
private void connectToUserSelectNetwork(int netId, int uid, boolean forceReconnect,
- @NonNull String packageName) {
+ @NonNull String packageName, @Nullable String attributionTag) {
if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
|| mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)) {
mIsUserSelected = true;
}
logd("connectToUserSelectNetwork netId " + netId + ", uid " + uid + ", package "
+ packageName + ", forceReconnect = " + forceReconnect + ", isUserSelected = "
- + mIsUserSelected);
+ + mIsUserSelected + ", attributionTag = " + attributionTag);
updateSaeAutoUpgradeFlagForUserSelectNetwork(netId);
if (!forceReconnect && (mLastNetworkId == netId || mTargetNetworkId == netId)) {
// We're already connecting/connected to the user specified network, don't trigger a
@@ -1487,6 +1506,10 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
}, mWifiThreadRunner).launchDialog();
} else {
+ if (mIsUserSelected && ATTRIBUTION_TAG_DISALLOW_CONNECT_CHOICE.equals(attributionTag)) {
+ mIsUserSelected = false;
+ logd("connectToUserSelectNetwork attributionTag override to disable user selected");
+ }
mWifiConnectivityManager.prepareForForcedConnection(netId);
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
mWifiMetrics.setNominatorForNetwork(netId,
@@ -1632,6 +1655,11 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
if (mContext.getResources().getBoolean(R.bool.config_wifi11axSupportOverride)) {
cap.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, true);
}
+ // Enable WPA3 SAE auto-upgrade offload
+ if (Flags.getDeviceCrossAkmRoamingSupport() && SdkLevel.isAtLeastV()
+ && cap.getMaxNumberAkms() >= 2) {
+ mWifiGlobals.setWpa3SaeUpgradeOffloadEnabled();
+ }
mWifiNative.setDeviceWiphyCapabilities(mInterfaceName, cap);
}
@@ -1652,6 +1680,15 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
return mWifiNative.isWifiStandardSupported(mInterfaceName, standard);
}
+ /**
+ * Check whether 11ax is supported by the most recent connection.
+ */
+ public boolean mostRecentConnectionSupports11ax() {
+ return mLastConnectionCapabilities != null
+ && (mLastConnectionCapabilities.wifiStandard == ScanResult.WIFI_STANDARD_11AX
+ || mLastConnectionCapabilities.wifiStandard == ScanResult.WIFI_STANDARD_11BE);
+ }
+
private byte[] getDstMacForKeepalive(KeepalivePacketData packetData)
throws InvalidPacketException {
try {
@@ -2672,6 +2709,40 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
if (mVerboseLoggingEnabled) log("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
}
+ private void updateMloLinkFromPollResults(MloLink link, WifiSignalPollResults pollResults) {
+ if (link == null) return;
+ int linkId = link.getLinkId();
+ link.setRssi(pollResults.getRssi(linkId));
+ link.setTxLinkSpeedMbps(pollResults.getTxLinkSpeed(linkId));
+ link.setRxLinkSpeedMbps(pollResults.getRxLinkSpeed(linkId));
+ link.setChannel(ScanResult.convertFrequencyMhzToChannelIfSupported(
+ pollResults.getFrequency(linkId)));
+ link.setBand(ScanResult.toBand(pollResults.getFrequency(linkId)));
+ if (mVerboseLoggingEnabled) {
+ logd("updateMloLinkFromPollResults: linkId=" + linkId + " rssi=" + link.getRssi()
+ + " channel=" + link.getChannel()
+ + " band=" + link.getBand()
+ + " TxLinkspeed=" + link.getTxLinkSpeedMbps()
+ + " RxLinkSpeed=" + link.getRxLinkSpeedMbps());
+
+ }
+ }
+
+ private void updateMloLinkFromScanResult(MloLink link) {
+ if (link == null || link.getApMacAddress() == null) return;
+ ScanDetailCache scanDetailCache = mWifiConfigManager.getScanDetailCacheForNetwork(
+ mWifiInfo.getNetworkId());
+ if (scanDetailCache == null) return;
+ ScanResult matchingScanResult = scanDetailCache.getScanResult(
+ link.getApMacAddress().toString());
+ if (matchingScanResult == null) return;
+ link.setRssi(matchingScanResult.level);
+ if (mVerboseLoggingEnabled) {
+ logd("updateMloLinkFromScanResult: linkId=" + link.getLinkId() + " rssi="
+ + link.getRssi());
+ }
+ }
+
/*
* Fetch link layer stats, RSSI, linkspeed, and frequency on current connection
* and update Network capabilities
@@ -2696,21 +2767,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
+ " RxLinkSpeed=" + newRxLinkSpeed);
}
- /* Set link specific signal poll results for associated links */
- for (MloLink link : mWifiInfo.getAssociatedMloLinks()) {
- int linkId = link.getLinkId();
- link.setRssi(pollResults.getRssi(linkId));
- link.setTxLinkSpeedMbps(pollResults.getTxLinkSpeed(linkId));
- link.setRxLinkSpeedMbps(pollResults.getRxLinkSpeed(linkId));
- link.setChannel(ScanResult.convertFrequencyMhzToChannelIfSupported(
- pollResults.getFrequency(linkId)));
- link.setBand(ScanResult.toBand(pollResults.getFrequency(linkId)));
- if (mVerboseLoggingEnabled) {
- logd("linkId=" + linkId + " rssi=" + link.getRssi()
- + " channel=" + link.getChannel()
- + " band=" + link.getBand()
- + " TxLinkspeed=" + link.getTxLinkSpeedMbps()
- + " RxLinkSpeed=" + link.getRxLinkSpeedMbps());
+ for (MloLink link : mWifiInfo.getAffiliatedMloLinks()) {
+ if (pollResults.isAvailable(link.getLinkId())
+ && (link.getState() == MloLink.MLO_LINK_STATE_IDLE
+ || link.getState() == MloLink.MLO_LINK_STATE_ACTIVE)) {
+ updateMloLinkFromPollResults(link, pollResults);
+ } else {
+ updateMloLinkFromScanResult(link);
}
}
@@ -3369,10 +3432,15 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mLastConnectionCapabilities.apTidToLinkMapNegotiationSupported);
mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(mInterfaceName,
maxTxLinkSpeedMbps, maxRxLinkSpeedMbps);
+ mWifiMetrics.setConnectionChannelWidth(mInterfaceName,
+ mLastConnectionCapabilities.channelBandwidth);
if (mLastConnectionCapabilities.wifiStandard == ScanResult.WIFI_STANDARD_11BE) {
updateMloLinkAddrAndStates(mWifiNative.getConnectionMloLinksInfo(mInterfaceName));
updateBlockListAffiliatedBssids();
}
+ if (SdkLevel.isAtLeastV() && mLastConnectionCapabilities.vendorData != null) {
+ mWifiInfo.setVendorData(mLastConnectionCapabilities.vendorData);
+ }
if (mVerboseLoggingEnabled) {
StringBuilder sb = new StringBuilder();
logd(sb.append("WifiStandard: ").append(ScanResult.wifiStandardToString(
@@ -3502,6 +3570,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mCurrentConnectionDetectedCaptivePortal = false;
mLastSimBasedConnectionCarrierName = null;
+ mNudFailureCounter = new Pair<>(0L, 0);
checkAbnormalDisconnectionAndTakeBugReport();
mWifiScoreCard.resetConnectionState(mInterfaceName);
updateLayer2Information();
@@ -3676,7 +3745,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
* Inform other components that a new connection attempt is starting.
*/
private void reportConnectionAttemptStart(
- WifiConfiguration config, String targetBSSID, int roamType) {
+ WifiConfiguration config, String targetBSSID, int roamType, int uid) {
boolean isOobPseudonymEnabled = false;
if (config.enterpriseConfig != null && config.enterpriseConfig.isAuthenticationSimBased()
&& mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(config.carrierId)) {
@@ -3685,7 +3754,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
int overlapWithLastConnectionMs =
mWifiMetrics.startConnectionEvent(
mInterfaceName, config, targetBSSID, roamType, isOobPseudonymEnabled,
- getClientRoleForMetrics(config));
+ getClientRoleForMetrics(config), uid);
if (mDeviceConfigFacade.isOverlappingConnectionBugreportEnabled()
&& overlapWithLastConnectionMs
> mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs()) {
@@ -4005,16 +4074,28 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// roaming. The linked network roaming reset the mLastNetworkId which results in
// the connected configuration to be null.
config = getConnectingWifiConfigurationInternal();
+ if (config == null) {
+ // config could be null if it had been removed from WifiConfigManager. In this case
+ // we should simply disconnect.
+ handleIpReachabilityLost(lossReason);
+ return;
+ }
+ }
+ final long curTime = mClock.getElapsedSinceBootMillis();
+ if (curTime - mNudFailureCounter.first <= mWifiGlobals.getRepeatedNudFailuresWindowMs()) {
+ mNudFailureCounter = new Pair<>(curTime, mNudFailureCounter.second + 1);
+ } else {
+ mNudFailureCounter = new Pair<>(curTime, 1);
}
- if (config == null || (config.getIpAssignment() == IpConfiguration.IpAssignment.STATIC)) {
- // config could be null if it had been removed from WifiConfigManager. In this case
- // we should simply disconnect. And if IP reachability failures come from static IP
- // case(e.g. a misconfigured default gateway IP address), refreshing L3 provisioning
- // doesn't help improve the situation and also introduces a loop, it's better to
- // disconnect and disable the auto-rejoin on that network.
+ if (mNudFailureCounter.second >= mWifiGlobals.getRepeatedNudFailuresThreshold()) {
+ // Disable and disconnect due to repeated NUD failures within limited time window.
+ mWifiConfigManager.updateNetworkSelectionStatus(config.networkId,
+ WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES);
handleIpReachabilityLost(lossReason);
+ mNudFailureCounter = new Pair<>(0L, 0);
return;
}
+
final NetworkAgentConfig naConfig = getNetworkAgentConfigInternal(config);
final NetworkCapabilities nc = getCapabilities(
getConnectedWifiConfigurationInternal(), getConnectedBssidInternal());
@@ -4367,10 +4448,10 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
WifiConfiguration config = getConnectedWifiConfigurationInternal();
boolean shouldSetUserConnectChoice = config != null
+ && mIsUserSelected
&& isRecentlySelectedByTheUser(config)
&& (config.getNetworkSelectionStatus().hasEverConnected()
- || config.isEphemeral())
- && mWifiPermissionsUtil.checkNetworkSettingsPermission(config.lastConnectUid);
+ || config.isEphemeral());
mWifiConfigManager.updateNetworkAfterConnect(mLastNetworkId,
mIsUserSelected, shouldSetUserConnectChoice, mWifiInfo.getRssi());
// Notify PasspointManager of Passpoint network connected event.
@@ -4612,7 +4693,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ClientModeImpl.class.getSimpleName() + "."
+ ConnectableState.class.getSimpleName() + "." + getWhatToString(what);
}
@@ -4718,7 +4799,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
updateWifiConfigOnStartConnection(config, bssid);
reportConnectionAttemptStart(config, mTargetBssid,
- WifiMetricsProto.ConnectionEvent.ROAM_UNRELATED);
+ WifiMetricsProto.ConnectionEvent.ROAM_UNRELATED, uid);
String currentMacAddress = mWifiNative.getMacAddress(mInterfaceName);
mWifiInfo.setMacAddress(currentMacAddress);
@@ -4778,7 +4859,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
int netId = result.getNetworkId();
connectToUserSelectNetwork(
netId, message.sendingUid, result.hasCredentialChanged(),
- cnm.packageName);
+ cnm.packageName, cnm.attributionTag);
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_CONNECT_NETWORK,
mWifiConfigManager.getConfiguredNetwork(netId));
cnm.listener.sendSuccess();
@@ -5287,7 +5368,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
public boolean isAffiliatedLinkBssid(@NonNull MacAddress bssid) {
List<MloLink> links = mWifiInfo.getAffiliatedMloLinks();
for (MloLink link: links) {
- if (link.getApMacAddress().equals(bssid)) {
+ if (bssid.equals(link.getApMacAddress())) {
return true;
}
}
@@ -5556,7 +5637,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ClientModeImpl.class.getSimpleName() + "."
+ ConnectingOrConnectedState.class.getSimpleName() + "." + getWhatToString(
what);
@@ -5749,8 +5830,10 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiInfo.setNetworkKey(config.getNetworkKeyFromSecurityType(
mWifiInfo.getCurrentSecurityType()));
if (mApplicationQosPolicyRequestHandler.isFeatureEnabled()) {
- mApplicationQosPolicyRequestHandler.queueAllPoliciesOnIface(mInterfaceName);
+ mApplicationQosPolicyRequestHandler.queueAllPoliciesOnIface(
+ mInterfaceName, mostRecentConnectionSupports11ax());
}
+ mWifiNative.resendMscs(mInterfaceName);
updateLayer2Information();
updateCurrentConnectionInfo();
transitionTo(mL3ProvisioningState);
@@ -5979,7 +6062,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ClientModeImpl.class.getSimpleName() + "."
+ L2ConnectingState.class.getSimpleName() + "." + getWhatToString(what);
}
@@ -6406,7 +6489,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ClientModeImpl.class.getSimpleName() + "."
+ L2ConnectedState.class.getSimpleName() + "." + getWhatToString(what);
}
@@ -6544,7 +6627,8 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
checkIfNeedDisconnectSecondaryWifi();
if (mApplicationQosPolicyRequestHandler.isFeatureEnabled()) {
- mApplicationQosPolicyRequestHandler.queueAllPoliciesOnIface(mInterfaceName);
+ mApplicationQosPolicyRequestHandler.queueAllPoliciesOnIface(
+ mInterfaceName, mostRecentConnectionSupports11ax());
}
break;
}
@@ -6623,6 +6707,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
else {
mRssiMonitor.setShortPollRssiInterval();
+ removeMessages(CMD_RSSI_POLL);
}
break;
}
@@ -6905,7 +6990,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
Log.e(getTag(), "Fail to create an IpClient instance within "
+ IPCLIENT_STARTUP_TIMEOUT_MS + "ms");
handleNetworkDisconnect(false,
- WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__TIMEOUT);
+ WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__DISCONNECT_CREATE_IP_CLIENT_TIMEOUT);
transitionTo(mDisconnectedState);
break;
}
@@ -6925,7 +7010,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ClientModeImpl.class.getSimpleName() + "."
+ WaitBeforeL3ProvisioningState.class.getSimpleName() + "."
+ getWhatToString(what);
@@ -6966,7 +7051,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ClientModeImpl.class.getSimpleName() + "."
+ L3ProvisioningState.class.getSimpleName() + "." + getWhatToString(what);
}
@@ -7060,7 +7145,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ClientModeImpl.class.getSimpleName() + "." + RoamingState.class.getSimpleName()
+ "." + getWhatToString(what);
}
@@ -7251,10 +7336,16 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiMetrics.noteFirstL3ConnectionAfterBoot(true);
updateCurrentConnectionInfo();
sendConnectedState();
+ // Set the roaming policy for the currently connected network
+ if (isPrimary() && getClientRoleForMetrics(config)
+ != WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_LOCAL_ONLY) {
+ mWifiInjector.getWifiRoamingModeManager().applyWifiRoamingMode(
+ mInterfaceName, mWifiInfo.getSSID());
+ }
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ClientModeImpl.class.getSimpleName() + "."
+ L3ConnectedState.class.getSimpleName() + "." + getWhatToString(what);
}
@@ -7291,6 +7382,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
config.networkId,
DISABLED_UNWANTED_LOW_RSSI);
}
+ mFrameworkDisconnectReasonOverride = WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__DISCONNECT_UNWANTED_BY_CONNECTIVITY;
mWifiNative.disconnect(mInterfaceName);
} else if (message.arg1 == NETWORK_STATUS_UNWANTED_DISABLE_AUTOJOIN
|| message.arg1 == NETWORK_STATUS_UNWANTED_VALIDATION_FAILED) {
@@ -7462,7 +7554,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
+ " targetRoamBSSID " + mTargetBssid);
reportConnectionAttemptStart(config, mTargetBssid,
- WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
+ WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, Process.WIFI_UID);
if (mWifiNative.roamToNetwork(mInterfaceName, config)) {
mTargetWifiConfiguration = config;
mIsAutoRoaming = true;
@@ -7550,7 +7642,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ClientModeImpl.class.getSimpleName() + "."
+ DisconnectedState.class.getSimpleName() + "." + getWhatToString(what);
}
@@ -7826,21 +7918,23 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
public final NetworkUpdateResult result;
public final ActionListenerWrapper listener;
public final String packageName;
+ public final String attributionTag;
ConnectNetworkMessage(NetworkUpdateResult result, ActionListenerWrapper listener,
- String packageName) {
+ String packageName, @Nullable String attributionTag) {
this.result = result;
this.listener = listener;
this.packageName = packageName;
+ this.attributionTag = attributionTag;
}
}
/** Trigger network connection and provide status via the provided callback. */
public void connectNetwork(NetworkUpdateResult result, ActionListenerWrapper wrapper,
- int callingUid, @NonNull String packageName) {
+ int callingUid, @NonNull String packageName, @Nullable String attributionTag) {
Message message =
obtainMessage(CMD_CONNECT_NETWORK,
- new ConnectNetworkMessage(result, wrapper, packageName));
+ new ConnectNetworkMessage(result, wrapper, packageName, attributionTag));
message.sendingUid = callingUid;
sendMessage(message);
}
@@ -7850,7 +7944,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
int callingUid, @NonNull String packageName) {
Message message =
obtainMessage(CMD_SAVE_NETWORK,
- new ConnectNetworkMessage(result, wrapper, packageName));
+ new ConnectNetworkMessage(result, wrapper, packageName, null));
message.sendingUid = callingUid;
sendMessage(message);
}
@@ -8120,9 +8214,43 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
? mLastL2KeyAndGroupHint.second : null;
final Layer2Information layer2Info = new Layer2Information(l2Key, groupHint,
currentBssid);
- final boolean mRemainConnectedAfterIpProvisionTimeout = mContext.getResources().getBoolean(
- R.bool.config_wifiRemainConnectedAfterIpProvisionTimeout);
+ final ProvisioningConfiguration.Builder prov =
+ new ProvisioningConfiguration.Builder()
+ .withDisplayName(config.SSID)
+ .withCreatorUid(config.creatorUid)
+ .withLayer2Information(layer2Info)
+ .withDhcpOptions(convertToInternalDhcpOptions(options));
+ if (isUsingMacRandomization) {
+ // Use EUI64 address generation for link-local IPv6 addresses.
+ prov.withRandomMacAddress();
+ }
+ if (mContext.getResources().getBoolean(R.bool.config_wifiEnableApfOnNonPrimarySta)
+ || isPrimary()) {
+ // unclear if the native layer will return the correct non-capabilities if APF is
+ // not supported on secondary interfaces.
+ prov.withApfCapabilities(mWifiNative.getApfCapabilities(mInterfaceName));
+ }
+ if (SdkLevel.isAtLeastV()) {
+ // Set the user dhcp hostname setting.
+ int hostnameSetting = config.isSendDhcpHostnameEnabled()
+ ? IIpClient.HOSTNAME_SETTING_SEND
+ : IIpClient.HOSTNAME_SETTING_DO_NOT_SEND;
+ int restrictions = mWifiGlobals.getSendDhcpHostnameRestriction();
+ // Override the user setting the dhcp hostname restrictions.
+ if (config.isOpenNetwork()) {
+ if ((restrictions
+ & WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN) != 0) {
+ hostnameSetting = IIpClient.HOSTNAME_SETTING_DO_NOT_SEND;
+ }
+ } else {
+ if ((restrictions
+ & WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_SECURE) != 0) {
+ hostnameSetting = IIpClient.HOSTNAME_SETTING_DO_NOT_SEND;
+ }
+ }
+ prov.withHostnameSetting(hostnameSetting);
+ }
if (isFilsConnection) {
stopIpClient();
if (isUsingStaticIp) {
@@ -8130,27 +8258,9 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
return false;
}
setConfigurationsPriorToIpClientProvisioning(config);
- final ProvisioningConfiguration.Builder prov =
- new ProvisioningConfiguration.Builder()
- .withPreDhcpAction()
- .withPreconnection()
- .withDisplayName(config.SSID)
- .withCreatorUid(config.creatorUid)
- .withLayer2Information(layer2Info)
- .withProvisioningTimeoutMs(mRemainConnectedAfterIpProvisionTimeout ? 0 :
- PROVISIONING_TIMEOUT_FILS_CONNECTION_MS);
- if (mContext.getResources().getBoolean(R.bool.config_wifiEnableApfOnNonPrimarySta)
- || isPrimary()) {
- // unclear if the native layer will return the correct non-capabilities if APF is
- // not supported on secondary interfaces.
- prov.withApfCapabilities(mWifiNative.getApfCapabilities(mInterfaceName));
- }
- if (isUsingMacRandomization) {
- // Use EUI64 address generation for link-local IPv6 addresses.
- prov.withRandomMacAddress();
- }
- prov.withDhcpOptions(convertToInternalDhcpOptions(options));
- mIpClient.startProvisioning(prov.build());
+ prov.withPreconnection()
+ .withPreDhcpAction()
+ .withProvisioningTimeoutMs(PROVISIONING_TIMEOUT_FILS_CONNECTION_MS);
} else {
sendNetworkChangeBroadcast(DetailedState.OBTAINING_IPADDR);
// We must clear the config BSSID, as the wifi chipset may decide to roam
@@ -8168,56 +8278,36 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// CONNECTED.
stopDhcpSetup();
setConfigurationsPriorToIpClientProvisioning(config);
- ScanResult scanResult = getScanResultInternal(config);
- final ProvisioningConfiguration.Builder prov;
- ProvisioningConfiguration.ScanResultInfo scanResultInfo = null;
- if (scanResult != null) {
- final List<ScanResultInfo.InformationElement> ies =
- new ArrayList<ScanResultInfo.InformationElement>();
- for (ScanResult.InformationElement ie : scanResult.getInformationElements()) {
- ScanResultInfo.InformationElement scanResultInfoIe =
- new ScanResultInfo.InformationElement(ie.getId(), ie.getBytes());
- ies.add(scanResultInfoIe);
- }
- scanResultInfo = new ProvisioningConfiguration.ScanResultInfo(scanResult.SSID,
- scanResult.BSSID, ies);
- }
final Network network = (mNetworkAgent != null) ? mNetworkAgent.getNetwork() : null;
+ prov.withNetwork(network);
if (!isUsingStaticIp) {
- prov = new ProvisioningConfiguration.Builder()
- .withPreDhcpAction()
- .withNetwork(network)
- .withDisplayName(config.SSID)
- .withScanResultInfo(scanResultInfo)
- .withCreatorUid(config.creatorUid)
- .withLayer2Information(layer2Info);
+ ProvisioningConfiguration.ScanResultInfo scanResultInfo = null;
+ ScanResult scanResult = getScanResultInternal(config);
+ if (scanResult != null) {
+ final List<ScanResultInfo.InformationElement> ies =
+ new ArrayList<ScanResultInfo.InformationElement>();
+ for (ScanResult.InformationElement ie : scanResult.getInformationElements()) {
+ ScanResultInfo.InformationElement scanResultInfoIe =
+ new ScanResultInfo.InformationElement(ie.getId(), ie.getBytes());
+ ies.add(scanResultInfoIe);
+ }
+ scanResultInfo = new ProvisioningConfiguration.ScanResultInfo(scanResult.SSID,
+ scanResult.BSSID, ies);
+ }
+ prov.withScanResultInfo(scanResultInfo)
+ .withPreDhcpAction();
} else {
StaticIpConfiguration staticIpConfig = config.getStaticIpConfiguration();
- prov = new ProvisioningConfiguration.Builder()
- .withStaticConfiguration(staticIpConfig)
- .withNetwork(network)
- .withDisplayName(config.SSID)
- .withCreatorUid(config.creatorUid)
- .withLayer2Information(layer2Info);
- }
- if (mContext.getResources().getBoolean(R.bool.config_wifiEnableApfOnNonPrimarySta)
- || isPrimary()) {
- // unclear if the native layer will return the correct non-capabilities if APF is
- // not supported on secondary interfaces.
- prov.withApfCapabilities(mWifiNative.getApfCapabilities(mInterfaceName));
- }
- if (isUsingMacRandomization) {
- // Use EUI64 address generation for link-local IPv6 addresses.
- prov.withRandomMacAddress();
+ prov.withStaticConfiguration(staticIpConfig)
+ .withoutIpReachabilityMonitor();
}
- prov.withDhcpOptions(convertToInternalDhcpOptions(options));
- if (mRemainConnectedAfterIpProvisionTimeout) {
- prov.withProvisioningTimeoutMs(0);
- }
- mIpClient.startProvisioning(prov.build());
}
-
+ if (mContext.getResources().getBoolean(
+ R.bool.config_wifiRemainConnectedAfterIpProvisionTimeout)) {
+ prov.withProvisioningTimeoutMs(0);
+ }
+ mIpClient.startProvisioning(prov.build());
return true;
}
@@ -8372,7 +8462,8 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
Log.v(TAG, "Idle mode changed: iface " + mInterfaceName
+ " enabling roaming");
}
- enableRoaming(true);
+ mWifiInjector.getWifiRoamingModeManager().applyWifiRoamingMode(
+ mInterfaceName, mWifiInfo.getSSID());
}
@Override
diff --git a/service/java/com/android/server/wifi/ConcreteClientModeManager.java b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
index 79ea6e825a..3864262b56 100644
--- a/service/java/com/android/server/wifi/ConcreteClientModeManager.java
+++ b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
@@ -475,6 +475,10 @@ public class ConcreteClientModeManager implements ClientModeManager {
* Get deferring time before turning off WiFi.
*/
private int getWifiOffDeferringTimeMs() {
+ if (mRole != ROLE_CLIENT_PRIMARY && !isSecondaryInternet()) {
+ Log.d(getTag(), "Do not defer stop for non-internet providing CMMs");
+ return 0;
+ }
SubscriptionManager subscriptionManager =
mContext.getSystemService(SubscriptionManager.class);
if (subscriptionManager == null) {
@@ -965,7 +969,7 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ConcreteClientModeManager.class.getSimpleName() + "."
+ IdleState.class.getSimpleName() + "."
+ getWhatToString(what);
@@ -1044,7 +1048,7 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ConcreteClientModeManager.class.getSimpleName() + "."
+ StartedState.class.getSimpleName() + "."
+ getWhatToString(what);
@@ -1170,7 +1174,7 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ConcreteClientModeManager.class.getSimpleName() + "."
+ ScanOnlyModeState.class.getSimpleName() + "."
+ getWhatToString(what);
@@ -1242,7 +1246,7 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return ConcreteClientModeManager.class.getSimpleName() + "."
+ ConnectModeState.class.getSimpleName() + "."
+ getWhatToString(what);
@@ -1376,8 +1380,8 @@ public class ConcreteClientModeManager implements ClientModeManager {
@Override
public void connectNetwork(NetworkUpdateResult result, ActionListenerWrapper wrapper,
- int callingUid, @NonNull String packageName) {
- getClientMode().connectNetwork(result, wrapper, callingUid, packageName);
+ int callingUid, @NonNull String packageName, @Nullable String attributionTag) {
+ getClientMode().connectNetwork(result, wrapper, callingUid, packageName, attributionTag);
}
@Override
diff --git a/service/java/com/android/server/wifi/ConnectHelper.java b/service/java/com/android/server/wifi/ConnectHelper.java
index 50110a93bf..f9a2e09421 100644
--- a/service/java/com/android/server/wifi/ConnectHelper.java
+++ b/service/java/com/android/server/wifi/ConnectHelper.java
@@ -17,6 +17,7 @@
package com.android.server.wifi;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.net.wifi.WifiManager;
import android.util.Log;
@@ -46,10 +47,10 @@ public class ConnectHelper {
public void connectToNetwork(
@NonNull NetworkUpdateResult result,
@NonNull ActionListenerWrapper wrapper,
- int callingUid, @NonNull String packageName) {
+ int callingUid, @NonNull String packageName, @Nullable String attributionTag) {
connectToNetwork(
mActiveModeWarden.getPrimaryClientModeManager(), result, wrapper, callingUid,
- packageName);
+ packageName, attributionTag);
}
/**
@@ -60,14 +61,15 @@ public class ConnectHelper {
@NonNull ClientModeManager clientModeManager,
@NonNull NetworkUpdateResult result,
@NonNull ActionListenerWrapper wrapper,
- int callingUid, @NonNull String packageName) {
+ int callingUid, @NonNull String packageName, @Nullable String attributionTag) {
int netId = result.getNetworkId();
if (mWifiConfigManager.getConfiguredNetwork(netId) == null) {
Log.e(TAG, "connectToNetwork Invalid network Id=" + netId);
wrapper.sendFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
return;
}
- mWifiConfigManager.updateBeforeConnect(netId, callingUid, packageName);
- clientModeManager.connectNetwork(result, wrapper, callingUid, packageName);
+ mWifiConfigManager.updateBeforeConnect(netId, callingUid, packageName,
+ !ClientModeImpl.ATTRIBUTION_TAG_DISALLOW_CONNECT_CHOICE.equals(attributionTag));
+ clientModeManager.connectNetwork(result, wrapper, callingUid, packageName, attributionTag);
}
}
diff --git a/service/java/com/android/server/wifi/DppManager.java b/service/java/com/android/server/wifi/DppManager.java
index 8ef3ce19ef..76a8f63e54 100644
--- a/service/java/com/android/server/wifi/DppManager.java
+++ b/service/java/com/android/server/wifi/DppManager.java
@@ -1078,7 +1078,7 @@ public class DppManager {
private void logd(String message) {
if (mVerboseLoggingEnabled) {
- Log.d(TAG, message);
+ Log.d(TAG, message, null);
}
}
diff --git a/service/java/com/android/server/wifi/ExternalScoreUpdateObserverProxy.java b/service/java/com/android/server/wifi/ExternalScoreUpdateObserverProxy.java
index 5aa44e48b2..9936bd0531 100644
--- a/service/java/com/android/server/wifi/ExternalScoreUpdateObserverProxy.java
+++ b/service/java/com/android/server/wifi/ExternalScoreUpdateObserverProxy.java
@@ -74,7 +74,7 @@ public class ExternalScoreUpdateObserverProxy extends IScoreUpdateObserver.Stub
private void incrementAndMaybeLogWtf(String message) {
mCountNullCallback++;
if (mCountNullCallback >= MAX_NULL_CALLBACK_TRIGGER_WTF) {
- Log.wtf(TAG, message);
+ Log.wtf(TAG, message, null);
}
}
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index 3e950d9fea..b1b77813a8 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -181,6 +181,13 @@ public class HalDeviceManager {
}
/**
+ * Returns whether or not the concurrency combo is loaded from the driver.
+ */
+ public boolean isConcurrencyComboLoadedFromDriver() {
+ return mIsConcurrencyComboLoadedFromDriver;
+ }
+
+ /**
* Enables verbose logging.
*/
public void enableVerboseLogging(boolean verboseEnabled) {
diff --git a/service/java/com/android/server/wifi/HostapdHalAidlImp.java b/service/java/com/android/server/wifi/HostapdHalAidlImp.java
index b4a95d5cea..ffca0c3526 100644
--- a/service/java/com/android/server/wifi/HostapdHalAidlImp.java
+++ b/service/java/com/android/server/wifi/HostapdHalAidlImp.java
@@ -33,6 +33,7 @@ import android.hardware.wifi.hostapd.Ieee80211ReasonCode;
import android.hardware.wifi.hostapd.IfaceParams;
import android.hardware.wifi.hostapd.NetworkParams;
import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.BandType;
@@ -397,10 +398,13 @@ public class HostapdHalAidlImp implements IHostapdHal {
try {
SoftApHalCallback callback = mSoftApHalCallbacks.get(info.ifaceName);
if (callback != null) {
+ List<OuiKeyedData> vendorData = isServiceVersionAtLeast(2)
+ ? HalAidlUtil.halToFrameworkOuiKeyedDataList(info.vendorData)
+ : Collections.emptyList();
callback.onInfoChanged(info.apIfaceInstance, info.freqMhz,
mapHalChannelBandwidthToSoftApInfo(info.channelBandwidth),
mapHalGenerationToWifiStandard(info.generation),
- MacAddress.fromBytes(info.apIfaceInstanceMacAddress));
+ MacAddress.fromBytes(info.apIfaceInstanceMacAddress), vendorData);
}
mActiveInstances.add(info.apIfaceInstance);
} catch (IllegalArgumentException iae) {
diff --git a/service/java/com/android/server/wifi/HostapdHalHidlImp.java b/service/java/com/android/server/wifi/HostapdHalHidlImp.java
index 48b513134c..1dc63f03dd 100644
--- a/service/java/com/android/server/wifi/HostapdHalHidlImp.java
+++ b/service/java/com/android/server/wifi/HostapdHalHidlImp.java
@@ -1278,7 +1278,8 @@ public class HostapdHalHidlImp implements IHostapdHal {
callback.onInfoChanged(apIfaceInstance, frequency,
mapHalBandwidthToSoftApInfo(bandwidth),
mapHalGenerationToWifiStandard(generation),
- MacAddress.fromBytes(apIfaceInstanceMacAddress));
+ MacAddress.fromBytes(apIfaceInstanceMacAddress),
+ Collections.emptyList());
}
} catch (IllegalArgumentException iae) {
Log.e(TAG, " Invalid apIfaceInstanceMacAddress, " + iae);
diff --git a/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java
index f4dc94a2b5..6796b2e904 100644
--- a/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java
@@ -19,6 +19,7 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.net.MacAddress;
+import android.net.wifi.MscsParams;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.SecurityParams;
import android.net.wifi.WifiConfiguration;
@@ -729,7 +730,10 @@ interface ISupplicantStaIfaceHal {
* @param isEnabled true if the feature is enabled, false otherwise.
* @return true if operation is successful, false otherwise.
*/
- boolean setNetworkCentricQosPolicyFeatureEnabled(@NonNull String ifaceName, boolean isEnabled);
+ default boolean setNetworkCentricQosPolicyFeatureEnabled(
+ @NonNull String ifaceName, boolean isEnabled) {
+ return false;
+ }
/**
* Sends a QoS policy response.
@@ -740,15 +744,20 @@ interface ISupplicantStaIfaceHal {
* @param qosPolicyStatusList List of framework QosPolicyStatus objects.
* @return true if response is sent successfully, false otherwise.
*/
- boolean sendQosPolicyResponse(String ifaceName, int qosPolicyRequestId, boolean morePolicies,
- @NonNull List<SupplicantStaIfaceHal.QosPolicyStatus> qosPolicyStatusList);
+ default boolean sendQosPolicyResponse(String ifaceName, int qosPolicyRequestId,
+ boolean morePolicies,
+ @NonNull List<SupplicantStaIfaceHal.QosPolicyStatus> qosPolicyStatusList) {
+ return false;
+ }
/**
* Indicates the removal of all active QoS policies configured by the AP.
*
* @param ifaceName Name of the interface.
*/
- boolean removeAllQosPolicies(String ifaceName);
+ default boolean removeAllQosPolicies(String ifaceName) {
+ return false;
+ }
/**
* Send a set of QoS SCS policy add requests to the AP.
@@ -763,8 +772,10 @@ interface ISupplicantStaIfaceHal {
* Status code will be one of
* {@link SupplicantStaIfaceHal.QosPolicyScsRequestStatusCode}.
*/
- List<SupplicantStaIfaceHal.QosPolicyStatus> addQosPolicyRequestForScs(
- @NonNull String ifaceName, @NonNull List<QosPolicyParams> policies);
+ default List<SupplicantStaIfaceHal.QosPolicyStatus> addQosPolicyRequestForScs(
+ @NonNull String ifaceName, @NonNull List<QosPolicyParams> policies) {
+ return null;
+ }
/**
* Request the removal of specific QoS policies for SCS.
@@ -779,8 +790,10 @@ interface ISupplicantStaIfaceHal {
* Status code will be one of
* {@link SupplicantStaIfaceHal.QosPolicyScsRequestStatusCode}.
*/
- List<SupplicantStaIfaceHal.QosPolicyStatus> removeQosPolicyForScs(
- @NonNull String ifaceName, @NonNull List<Byte> policyIds);
+ default List<SupplicantStaIfaceHal.QosPolicyStatus> removeQosPolicyForScs(
+ @NonNull String ifaceName, @NonNull List<Byte> policyIds) {
+ return null;
+ }
/**
* Register a callback to receive notifications for QoS SCS transactions.
@@ -788,7 +801,8 @@ interface ISupplicantStaIfaceHal {
*
* @param callback {@link SupplicantStaIfaceHal.QosScsResponseCallback} to register.
*/
- void registerQosScsResponseCallback(SupplicantStaIfaceHal.QosScsResponseCallback callback);
+ default void registerQosScsResponseCallback(
+ SupplicantStaIfaceHal.QosScsResponseCallback callback) {}
/**
* Generate DPP credential for network access
@@ -798,8 +812,10 @@ interface ISupplicantStaIfaceHal {
* @param privEcKey Private EC Key for DPP Configurator
* Returns true when operation is successful. On error, false is returned.
*/
- boolean generateSelfDppConfiguration(@NonNull String ifaceName, @NonNull String ssid,
- byte[] privEcKey);
+ default boolean generateSelfDppConfiguration(@NonNull String ifaceName, @NonNull String ssid,
+ byte[] privEcKey) {
+ return false;
+ }
/**
* Set the currently configured network's anonymous identity.
@@ -809,6 +825,31 @@ interface ISupplicantStaIfaceHal {
* @param updateToNativeService write the data to the native service.
* @return true if succeeds, false otherwise.
*/
- boolean setEapAnonymousIdentity(@NonNull String ifaceName, String anonymousIdentity,
- boolean updateToNativeService);
+ default boolean setEapAnonymousIdentity(@NonNull String ifaceName, String anonymousIdentity,
+ boolean updateToNativeService) {
+ return false;
+ }
+
+ /**
+ * Enable Mirrored Stream Classification Service (MSCS) and configure using
+ * the provided configuration values.
+ *
+ * @param mscsParams {@link MscsParams} object containing the configuration parameters.
+ * @param ifaceName Name of the interface.
+ */
+ default void enableMscs(@NonNull MscsParams mscsParams, String ifaceName) {}
+
+ /**
+ * Resend the previously configured MSCS parameters on this interface, if any exist.
+ *
+ * @param ifaceName Name of the interface.
+ */
+ default void resendMscs(String ifaceName) {};
+
+ /**
+ * Disable Mirrored Stream Classification Service (MSCS).
+ *
+ * @param ifaceName Name of the interface.
+ */
+ default void disableMscs(String ifaceName) {}
}
diff --git a/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java b/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java
index 38e5d34e7f..f80f0ae186 100644
--- a/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java
+++ b/service/java/com/android/server/wifi/InsecureEapNetworkHandler.java
@@ -383,6 +383,18 @@ public class InsecureEapNetworkHandler {
Log.d(TAG, cert.getSubjectX500Principal().getName());
}
+ if (null == mPendingServerCertSubjectInfo) {
+ handleError(mCurrentTofuConfig.SSID);
+ Log.d(TAG, "No valid subject info in Server cert for TLS-based connection.");
+ return false;
+ }
+
+ if (null == mPendingServerCertIssuerInfo) {
+ handleError(mCurrentTofuConfig.SSID);
+ Log.d(TAG, "No valid issuer info in Server cert for TLS-based connection.");
+ return false;
+ }
+
if (!configureServerValidationMethod()) {
Log.e(TAG, "Server cert chain is invalid.");
String ssid = mCurrentTofuConfig.SSID;
@@ -987,7 +999,7 @@ public class InsecureEapNetworkHandler {
}
} catch (Exception e) {
// Fall through
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
// The certificate is not in the trust store.
return false;
diff --git a/service/java/com/android/server/wifi/InterfaceConflictManager.java b/service/java/com/android/server/wifi/InterfaceConflictManager.java
index dd23ac9569..21c0463d02 100644
--- a/service/java/com/android/server/wifi/InterfaceConflictManager.java
+++ b/service/java/com/android/server/wifi/InterfaceConflictManager.java
@@ -523,7 +523,7 @@ public class InterfaceConflictManager {
private void localLog(String log) {
mLocalLog.log(log);
if (mVerboseLoggingEnabled) {
- Log.d(TAG, log);
+ Log.d(TAG, log, null);
}
}
diff --git a/service/java/com/android/server/wifi/LogcatLog.java b/service/java/com/android/server/wifi/LogcatLog.java
index 32341ac854..a813ad65f4 100644
--- a/service/java/com/android/server/wifi/LogcatLog.java
+++ b/service/java/com/android/server/wifi/LogcatLog.java
@@ -92,48 +92,48 @@ class LogcatLog implements WifiLog {
@Override
public void eC(String msg) {
- Log.e(mTag, msg);
+ Log.e(mTag, msg, null);
}
@Override
public void wC(String msg) {
- Log.w(mTag, msg);
+ Log.w(mTag, msg, null);
}
@Override
public void iC(String msg) {
- Log.i(mTag, msg);
+ Log.i(mTag, msg, null);
}
@Override
public void tC(String msg) {
- Log.d(mTag, msg);
+ Log.d(mTag, msg, null);
}
/* Legacy methods */
@Override
public void e(String msg) {
- Log.e(mTag, msg);
+ Log.e(mTag, msg, null);
}
@Override
public void w(String msg) {
- Log.w(mTag, msg);
+ Log.w(mTag, msg, null);
}
@Override
public void i(String msg) {
- Log.i(mTag, msg);
+ Log.i(mTag, msg, null);
}
@Override
public void d(String msg) {
- Log.d(mTag, msg);
+ Log.d(mTag, msg, null);
}
@Override
public void v(String msg) {
- Log.v(mTag, msg);
+ Log.v(mTag, msg, null);
}
/* Internal details */
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionNominator.java b/service/java/com/android/server/wifi/NetworkSuggestionNominator.java
index 6a02b17476..bcee442fb9 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionNominator.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionNominator.java
@@ -20,6 +20,7 @@ import static com.android.server.wifi.WifiNetworkSelector.toNetworkString;
import android.annotation.NonNull;
import android.net.wifi.WifiConfiguration;
+import android.os.Process;
import android.telephony.TelephonyManager;
import android.util.LocalLog;
import android.util.Log;
@@ -161,7 +162,8 @@ public class NetworkSuggestionNominator implements WifiNetworkSelector.NetworkNo
if (!untrustedNetworkAllowed && !config.trusted) {
return true;
}
- if (!restrictedNetworkAllowedUids.contains(config.creatorUid) && config.restricted) {
+ if (!(restrictedNetworkAllowedUids.contains(config.creatorUid)
+ || config.creatorUid == Process.SYSTEM_UID) && config.restricted) {
return true;
}
// For suggestions with both oem paid & oem private set, ignore them If both oem paid
diff --git a/service/java/com/android/server/wifi/PmkCacheManager.java b/service/java/com/android/server/wifi/PmkCacheManager.java
index a952870604..adcd54948d 100644
--- a/service/java/com/android/server/wifi/PmkCacheManager.java
+++ b/service/java/com/android/server/wifi/PmkCacheManager.java
@@ -22,6 +22,7 @@ import android.os.Handler;
import android.util.Log;
import android.util.SparseArray;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
@@ -39,6 +40,10 @@ public class PmkCacheManager {
private final Handler mEventHandler;
private boolean mVerboseLoggingEnabled = false;
+
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
private SparseArray<List<PmkCacheStoreData>> mPmkCacheEntries = new SparseArray<>();
public PmkCacheManager(Clock clock, Handler eventHandler) {
@@ -58,63 +63,71 @@ public class PmkCacheManager {
*/
public boolean add(MacAddress macAddress, int networkId, MacAddress bssid,
long expirationTimeInSec, ArrayList<Byte> serializedEntry) {
- if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
- if (macAddress == null) {
- Log.w(TAG, "Omit PMK cache due to no valid MAC address");
- return false;
- }
- if (null == serializedEntry) {
- Log.w(TAG, "Omit PMK cache due to null entry.");
- return false;
- }
- final long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
- if (elapseTimeInSecond >= expirationTimeInSec) {
- Log.w(TAG, "Omit expired PMK cache.");
- return false;
- }
+ synchronized (mLock) {
+ if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
+ if (macAddress == null) {
+ Log.w(TAG, "Omit PMK cache due to no valid MAC address");
+ return false;
+ }
+ if (null == serializedEntry) {
+ Log.w(TAG, "Omit PMK cache due to null entry.");
+ return false;
+ }
+ final long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
+ if (elapseTimeInSecond >= expirationTimeInSec) {
+ Log.w(TAG, "Omit expired PMK cache.");
+ return false;
+ }
- PmkCacheStoreData newStoreData =
- new PmkCacheStoreData(macAddress, bssid, serializedEntry, expirationTimeInSec);
- List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
- if (pmkDataList == null) {
- pmkDataList = new ArrayList<>();
- mPmkCacheEntries.put(networkId, pmkDataList);
- } else {
- if (bssid != null) {
- // Remove the stored PMK cache if the PMK cache is changed for an existing BSSID.
- PmkCacheStoreData existStoreData = pmkDataList.stream()
- .filter(storeData -> Objects.equals(storeData.bssid, bssid))
- .findAny()
- .orElse(null);
- if (null != existStoreData) {
- if (Objects.equals(existStoreData, newStoreData)) {
+ PmkCacheStoreData newStoreData =
+ new PmkCacheStoreData(macAddress, bssid, serializedEntry, expirationTimeInSec);
+ List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
+ if (pmkDataList == null) {
+ pmkDataList = new ArrayList<>();
+ mPmkCacheEntries.put(networkId, pmkDataList);
+ } else {
+ PmkCacheStoreData existStoreData = null;
+ if (bssid != null) {
+ // Remove the stored PMK cache if the PMK cache is changed for an existing
+ // BSSID.
+ for (PmkCacheStoreData storeData : pmkDataList) {
+ if (Objects.equals(storeData.bssid, bssid)) {
+ existStoreData = storeData;
+ break;
+ }
+ }
+ if (null != existStoreData) {
+ if (Objects.equals(existStoreData, newStoreData)) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "PMK entry exists for the BSSID, skip it.");
+ }
+ return true;
+ }
+ pmkDataList.remove(existStoreData);
+ }
+ } else {
+ for (PmkCacheStoreData storeData : pmkDataList) {
+ if (Objects.equals(storeData, newStoreData)) {
+ existStoreData = storeData;
+ break;
+ }
+ }
+ if (null != existStoreData) {
if (mVerboseLoggingEnabled) {
- Log.d(TAG, "PMK entry exists for the BSSID, skip it.");
+ Log.d(TAG, "PMK entry exists, skip it.");
}
return true;
}
- pmkDataList.remove(existStoreData);
- }
- } else {
- PmkCacheStoreData existStoreData = pmkDataList.stream()
- .filter(storeData -> Objects.equals(storeData, newStoreData))
- .findAny()
- .orElse(null);
- if (null != existStoreData) {
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "PMK entry exists, skip it.");
- }
- return true;
}
}
- }
- pmkDataList.add(newStoreData);
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "Network " + networkId + " PmkCache Count: " + pmkDataList.size());
+ pmkDataList.add(newStoreData);
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "Network " + networkId + " PmkCache Count: " + pmkDataList.size());
+ }
+ updatePmkCacheExpiration();
+ return true;
}
- updatePmkCacheExpiration();
- return true;
}
/**
@@ -124,12 +137,14 @@ public class PmkCacheManager {
* @return true when PMK caches are removed; otherwise, false.
*/
public boolean remove(int networkId) {
- if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
- if (!mPmkCacheEntries.contains(networkId)) return false;
+ synchronized (mLock) {
+ if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
+ if (!mPmkCacheEntries.contains(networkId)) return false;
- mPmkCacheEntries.remove(networkId);
- updatePmkCacheExpiration();
- return true;
+ mPmkCacheEntries.remove(networkId);
+ updatePmkCacheExpiration();
+ return true;
+ }
}
/**
@@ -142,16 +157,18 @@ public class PmkCacheManager {
*/
public boolean remove(int networkId, MacAddress curMacAddress) {
- if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
- List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
- if (null == pmkDataList) return false;
+ synchronized (mLock) {
+ if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
+ List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
+ if (null == pmkDataList) return false;
- pmkDataList.removeIf(pmkData -> !Objects.equals(curMacAddress, pmkData.macAddress));
+ pmkDataList.removeIf(pmkData -> !Objects.equals(curMacAddress, pmkData.macAddress));
- if (pmkDataList.size() == 0) {
- remove(networkId);
+ if (pmkDataList.size() == 0) {
+ remove(networkId);
+ }
+ return true;
}
- return true;
}
/**
@@ -162,18 +179,20 @@ public class PmkCacheManager {
* If none of PMK cache is associated with the network ID, return null.
*/
public List<ArrayList<Byte>> get(int networkId) {
- List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
- if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return null;
- if (null == pmkDataList) return null;
-
- final long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
- List<ArrayList<Byte>> dataList = new ArrayList<>();
- for (PmkCacheStoreData pmkData: pmkDataList) {
- if (pmkData.isValid(elapseTimeInSecond)) {
- dataList.add(pmkData.data);
+ synchronized (mLock) {
+ List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
+ if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return null;
+ if (null == pmkDataList) return null;
+
+ final long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
+ List<ArrayList<Byte>> dataList = new ArrayList<>();
+ for (PmkCacheStoreData pmkData : pmkDataList) {
+ if (pmkData.isValid(elapseTimeInSecond)) {
+ dataList.add(pmkData.data);
+ }
}
+ return dataList;
}
- return dataList;
}
/**
@@ -185,46 +204,48 @@ public class PmkCacheManager {
@VisibleForTesting
void updatePmkCacheExpiration() {
- mEventHandler.removeCallbacksAndMessages(PMK_CACHE_EXPIRATION_ALARM_TAG);
-
- long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
- long nextUpdateTimeInSecond = Long.MAX_VALUE;
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "Update PMK cache expiration at " + elapseTimeInSecond);
- }
+ synchronized (mLock) {
+ mEventHandler.removeCallbacksAndMessages(PMK_CACHE_EXPIRATION_ALARM_TAG);
- List<Integer> emptyStoreDataList = new ArrayList<>();
- for (int i = 0; i < mPmkCacheEntries.size(); i++) {
- int networkId = mPmkCacheEntries.keyAt(i);
- List<PmkCacheStoreData> list = mPmkCacheEntries.get(networkId);
- list.removeIf(pmkData -> !pmkData.isValid(elapseTimeInSecond));
- if (list.size() == 0) {
- emptyStoreDataList.add(networkId);
- continue;
+ long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
+ long nextUpdateTimeInSecond = Long.MAX_VALUE;
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "Update PMK cache expiration at " + elapseTimeInSecond);
}
- for (PmkCacheStoreData pmkData: list) {
- if (nextUpdateTimeInSecond > pmkData.expirationTimeInSec) {
- nextUpdateTimeInSecond = pmkData.expirationTimeInSec;
+
+ List<Integer> emptyStoreDataList = new ArrayList<>();
+ for (int i = 0; i < mPmkCacheEntries.size(); i++) {
+ int networkId = mPmkCacheEntries.keyAt(i);
+ List<PmkCacheStoreData> list = mPmkCacheEntries.get(networkId);
+ list.removeIf(pmkData -> !pmkData.isValid(elapseTimeInSecond));
+ if (list.size() == 0) {
+ emptyStoreDataList.add(networkId);
+ continue;
+ }
+ for (PmkCacheStoreData pmkData : list) {
+ if (nextUpdateTimeInSecond > pmkData.expirationTimeInSec) {
+ nextUpdateTimeInSecond = pmkData.expirationTimeInSec;
+ }
}
}
- }
- emptyStoreDataList.forEach(networkId -> mPmkCacheEntries.remove(networkId));
+ emptyStoreDataList.forEach(networkId -> mPmkCacheEntries.remove(networkId));
- // No need to arrange next update since there is no valid PMK in the cache.
- if (nextUpdateTimeInSecond == Long.MAX_VALUE) {
- return;
- }
+ // No need to arrange next update since there is no valid PMK in the cache.
+ if (nextUpdateTimeInSecond == Long.MAX_VALUE) {
+ return;
+ }
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "PMK cache next expiration time: " + nextUpdateTimeInSecond);
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "PMK cache next expiration time: " + nextUpdateTimeInSecond);
+ }
+ long delayedTimeInMs = (nextUpdateTimeInSecond - elapseTimeInSecond) * 1000;
+ mEventHandler.postDelayed(
+ () -> {
+ updatePmkCacheExpiration();
+ },
+ PMK_CACHE_EXPIRATION_ALARM_TAG,
+ (delayedTimeInMs > 0) ? delayedTimeInMs : 0);
}
- long delayedTimeInMs = (nextUpdateTimeInSecond - elapseTimeInSecond) * 1000;
- mEventHandler.postDelayed(
- () -> {
- updatePmkCacheExpiration();
- },
- PMK_CACHE_EXPIRATION_ALARM_TAG,
- (delayedTimeInMs > 0) ? delayedTimeInMs : 0);
}
private static class PmkCacheStoreData {
diff --git a/service/java/com/android/server/wifi/RestrictedWifiNetworkFactory.java b/service/java/com/android/server/wifi/RestrictedWifiNetworkFactory.java
index 8ef248e03c..2dda1471a6 100644
--- a/service/java/com/android/server/wifi/RestrictedWifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/RestrictedWifiNetworkFactory.java
@@ -16,14 +16,18 @@
package com.android.server.wifi;
+import android.annotation.TargetApi;
import android.content.Context;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkRequest;
+import android.os.Build;
import android.os.Looper;
import android.util.ArraySet;
import android.util.Log;
+import com.android.modules.utils.build.SdkLevel;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Set;
@@ -38,15 +42,27 @@ public class RestrictedWifiNetworkFactory extends NetworkFactory {
private final WifiConnectivityManager mWifiConnectivityManager;
private Set<Integer> mRequestUids = new ArraySet<>();
+ private final NetworkCapabilities mCapabilitiesFilter;
public RestrictedWifiNetworkFactory(Looper l, Context c, NetworkCapabilities f,
WifiConnectivityManager connectivityManager) {
super(l, c, TAG, f);
mWifiConnectivityManager = connectivityManager;
-
+ mCapabilitiesFilter = f;
setScoreFilter(SCORE_FILTER);
}
+ // package-private
+ @TargetApi(Build.VERSION_CODES.S)
+ void updateSubIdsInCapabilitiesFilter(Set<Integer> subIds) {
+ if (SdkLevel.isAtLeastS()) {
+ NetworkCapabilities newFilter =
+ new NetworkCapabilities.Builder(mCapabilitiesFilter)
+ .setSubscriptionIds(subIds).build();
+ setCapabilityFilter(newFilter);
+ }
+ }
+
@Override
protected void needNetworkFor(NetworkRequest networkRequest) {
if (!networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
diff --git a/service/java/com/android/server/wifi/RunnerHandler.java b/service/java/com/android/server/wifi/RunnerHandler.java
index 2456cf1986..78b7b12a4f 100644
--- a/service/java/com/android/server/wifi/RunnerHandler.java
+++ b/service/java/com/android/server/wifi/RunnerHandler.java
@@ -42,7 +42,7 @@ import java.util.Set;
public class RunnerHandler extends Handler {
private static final String TAG = "WifiThreadRunner";
- private static final String KEY_SIGNATURE = "KEY_RUNNER_HANDLER_SIGNATURE";
+ public static final String KEY_SIGNATURE = "KEY_RUNNER_HANDLER_SIGNATURE";
private static final String KEY_WHEN = "KEY_RUNNER_HANDLER_WHEN";
private static final int METRICS_THRESHOLD_MILLIS = 100;
@@ -101,10 +101,12 @@ public class RunnerHandler extends Handler {
@Override
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
- String signature = getSignature(new Throwable("RunnerHandler:").getStackTrace(),
- msg.getCallback());
Bundle bundle = msg.getData();
- bundle.putString(KEY_SIGNATURE, signature);
+ if (bundle.getString(KEY_SIGNATURE) == null) {
+ String signature = getSignature(new Throwable("RunnerHandler:").getStackTrace(),
+ msg.getCallback());
+ bundle.putString(KEY_SIGNATURE, signature);
+ }
return super.sendMessageAtTime(msg, uptimeMillis);
}
diff --git a/service/java/com/android/server/wifi/RunnerState.java b/service/java/com/android/server/wifi/RunnerState.java
index 39f842428b..5dbe65c493 100644
--- a/service/java/com/android/server/wifi/RunnerState.java
+++ b/service/java/com/android/server/wifi/RunnerState.java
@@ -53,7 +53,7 @@ public abstract class RunnerState extends State {
* The Runner state Constructor
* @param threshold the running time threshold in milliseconds
*/
- RunnerState(int threshold, @NonNull LocalLog localLog) {
+ public RunnerState(int threshold, @NonNull LocalLog localLog) {
mRunningTimeThresholdInMilliseconds = threshold;
mLocalLog = localLog;
}
@@ -111,22 +111,22 @@ public abstract class RunnerState extends State {
/**
* Implement this method for State enter process, instead of enter()
*/
- abstract void enterImpl();
+ public abstract void enterImpl();
/**
* Implement this method for State exit process, instead of exit()
*/
- abstract void exitImpl();
+ public abstract void exitImpl();
/**
- * Implement this method for State message processing, instead of processMessage()
+ * Implement this method for process message, instead of processMessage()
*/
- abstract boolean processMessageImpl(Message message);
+ public abstract boolean processMessageImpl(Message msg);
/**
* Implement this to translate a message `what` into a readable String
* @param what message 'what' field
* @return Readable string
*/
- abstract String getMessageLogRec(int what);
+ public abstract String getMessageLogRec(int what);
}
diff --git a/service/java/com/android/server/wifi/ScanDetail.java b/service/java/com/android/server/wifi/ScanDetail.java
index fec34ed136..59eb16af85 100644
--- a/service/java/com/android/server/wifi/ScanDetail.java
+++ b/service/java/com/android/server/wifi/ScanDetail.java
@@ -42,6 +42,7 @@ public class ScanDetail {
private volatile NetworkDetail mNetworkDetail;
private long mSeen = 0;
private byte[] mInformationElementRawData;
+ private static final ScanResult.Builder sBuilder = new ScanResult.Builder();
/**
* Main constructor used when converting from NativeScanResult
@@ -59,6 +60,8 @@ public class ScanDetail {
int centerFreq1 = ScanResult.UNSPECIFIED;
boolean isPasspoint = false;
boolean is80211McResponder = false;
+ boolean isTwtResponder = false;
+ boolean is11azNtbResponder = false;
if (networkDetail != null) {
hessid = networkDetail.getHESSID();
anqpDomainId = networkDetail.getAnqpDomainID();
@@ -72,9 +75,23 @@ public class ScanDetail {
&& networkDetail.isInterworking()
&& networkDetail.getHSRelease() != null;
is80211McResponder = networkDetail.is80211McResponderSupport();
+ isTwtResponder = networkDetail.isIndividualTwtSupported();
+ is11azNtbResponder = networkDetail.is80211azNtbResponder();
}
- mScanResult = new ScanResult(wifiSsid, bssid, hessid, anqpDomainId, osuProviders, caps,
- level, frequency, tsf);
+ sBuilder.clear();
+ mScanResult = sBuilder
+ .setWifiSsid(wifiSsid)
+ .setBssid(bssid)
+ .setHessid(hessid)
+ .setAnqpDomainId(anqpDomainId)
+ .setOsuProviders(osuProviders)
+ .setCaps(caps)
+ .setRssi(level)
+ .setFrequency(frequency)
+ .setTsf(tsf)
+ .setIsTwtResponder(isTwtResponder)
+ .setIs80211azNtbRTTResponder(is11azNtbResponder)
+ .build();
mSeen = System.currentTimeMillis();
mScanResult.seen = mSeen;
mScanResult.channelWidth = channelWidth;
diff --git a/service/java/com/android/server/wifi/ScanRequestProxy.java b/service/java/com/android/server/wifi/ScanRequestProxy.java
index 651f487273..c5af30effe 100644
--- a/service/java/com/android/server/wifi/ScanRequestProxy.java
+++ b/service/java/com/android/server/wifi/ScanRequestProxy.java
@@ -579,7 +579,8 @@ public class ScanRequestProxy {
* @param bssid BSSID as string {@link ScanResult#BSSID}.
* @return ScanResult for the corresponding bssid if found, null otherwise.
*/
- public @Nullable ScanResult getScanResult(@NonNull String bssid) {
+ public @Nullable ScanResult getScanResult(@Nullable String bssid) {
+ if (bssid == null) return null;
ScanResult scanResult = mFullScanCache.get(bssid);
if (scanResult == null) {
scanResult = mPartialScanCache.get(bssid);
diff --git a/service/java/com/android/server/wifi/SelfRecovery.java b/service/java/com/android/server/wifi/SelfRecovery.java
index c50ff43240..e7a182e49d 100644
--- a/service/java/com/android/server/wifi/SelfRecovery.java
+++ b/service/java/com/android/server/wifi/SelfRecovery.java
@@ -138,21 +138,30 @@ public class SelfRecovery {
private class SubsystemRestartListenerInternal
implements HalDeviceManager.SubsystemRestartListener{
- public void onSubsystemRestart(@RecoveryReason int reason) {
+ private void onSubsystemRestart(@RecoveryReason int reason, long timeElapsedFromLastTrigger,
+ int resultForLogging) {
Log.e(TAG, "Restarting wifi for reason: " + getRecoveryReasonAsString(reason));
+ WifiStatsLog.write(WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED,
+ convertSelfRecoveryReason(reason),
+ resultForLogging,
+ timeElapsedFromLastTrigger);
mActiveModeWarden.recoveryRestartWifi(reason,
reason != REASON_LAST_RESORT_WATCHDOG && reason != REASON_API_CALL);
}
@Override
public void onSubsystemRestart() {
+ long timeElapsedFromLastTrigger = getTimeElapsedFromLastTrigger();
+ mLastSelfRecoveryTimeStampMillis = mClock.getWallClockMillis();
if (mRecoveryState == STATE_RESTART_WIFI) {
// If the wifi restart recovery is triggered then proceed
- onSubsystemRestart(mSelfRecoveryReason);
+ onSubsystemRestart(mSelfRecoveryReason, timeElapsedFromLastTrigger,
+ WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__RESULT__RES_RESTART_STARTED_INTERNAL_RECOVERY_BY_NATIVE_CALLBACK);
} else {
// We did not trigger recovery, but looks like the firmware crashed?
mRecoveryState = STATE_RESTART_WIFI;
- onSubsystemRestart(REASON_SUBSYSTEM_RESTART);
+ onSubsystemRestart(REASON_SUBSYSTEM_RESTART, timeElapsedFromLastTrigger,
+ WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__RESULT__RES_RESTART_STARTED_INTERNAL_RECOVERY_BY_NATIVE_CALLBACK);
}
}
}
@@ -248,11 +257,8 @@ public class SelfRecovery {
mRecoveryState = STATE_RESTART_WIFI;
if (!mWifiNative.startSubsystemRestart()) {
// HAL call failed, fallback to internal flow.
- mSubsystemRestartListener.onSubsystemRestart(reason);
- WifiStatsLog.write(WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED,
- convertSelfRecoveryReason(reason),
- WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__RESULT__RES_RESTART_FAILURE,
- timeElapsedFromLastTrigger);
+ mSubsystemRestartListener.onSubsystemRestart(reason, timeElapsedFromLastTrigger,
+ WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__RESULT__RES_RESTART_STARTED_INTERNAL_RECOVERY);
return;
}
WifiStatsLog.write(WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED,
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index c2e89688e5..1d8ab5117a 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -31,6 +31,7 @@ import android.net.wifi.ScanResult;
import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApInfo;
+import android.net.wifi.SoftApState;
import android.net.wifi.WifiAnnotations;
import android.net.wifi.WifiClient;
import android.net.wifi.WifiContext;
@@ -38,6 +39,7 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
+import android.net.wifi.nl80211.DeviceWiphyCapabilities;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Looper;
@@ -314,7 +316,8 @@ public class SoftApManager implements ActiveModeManager {
public void onInfoChanged(String apIfaceInstance, int frequency,
@WifiAnnotations.Bandwidth int bandwidth,
@WifiAnnotations.WifiStandard int generation,
- MacAddress apIfaceInstanceMacAddress) {
+ MacAddress apIfaceInstanceMacAddress,
+ @NonNull List<OuiKeyedData> vendorData) {
SoftApInfo apInfo = new SoftApInfo();
apInfo.setFrequency(frequency);
apInfo.setBandwidth(bandwidth);
@@ -324,6 +327,9 @@ public class SoftApManager implements ActiveModeManager {
}
apInfo.setApInstanceIdentifier(apIfaceInstance != null
? apIfaceInstance : mApInterfaceName);
+ if (SdkLevel.isAtLeastV() && vendorData != null && !vendorData.isEmpty()) {
+ apInfo.setVendorData(vendorData);
+ }
mStateMachine.sendMessage(
SoftApStateMachine.CMD_AP_INFO_CHANGED, 0, 0, apInfo);
}
@@ -473,7 +479,8 @@ public class SoftApManager implements ActiveModeManager {
apConfig.getTargetMode(),
mCurrentSoftApConfiguration,
mCurrentSoftApCapability,
- mCountryCode);
+ mCountryCode,
+ apConfig.getTetheringRequest());
if (mCurrentSoftApConfiguration != null) {
mIsUnsetBssid = mCurrentSoftApConfiguration.getBssid() == null;
if (mCurrentSoftApCapability.areFeaturesSupported(
@@ -632,7 +639,8 @@ public class SoftApManager implements ActiveModeManager {
mSpecifiedModeConfiguration.getTargetMode(),
mSpecifiedModeConfiguration.getSoftApConfiguration(),
mCurrentSoftApCapability,
- mCountryCode);
+ mCountryCode,
+ mSpecifiedModeConfiguration.getTetheringRequest());
}
/**
@@ -701,7 +709,7 @@ public class SoftApManager implements ActiveModeManager {
private void onL2Connected(@NonNull ConcreteClientModeManager clientModeManager) {
Log.d(getTag(), "onL2Connected called");
mStateMachine.sendMessage(SoftApStateMachine.CMD_HANDLE_WIFI_CONNECTED,
- clientModeManager.getConnectionInfo());
+ clientModeManager);
}
@@ -724,7 +732,11 @@ public class SoftApManager implements ActiveModeManager {
*/
private void updateApState(int newState, int currentState, int reason) {
mCurrentApState = newState;
- mSoftApCallback.onStateChanged(newState, reason);
+ mSoftApCallback.onStateChanged(new SoftApState(
+ newState,
+ reason,
+ mSpecifiedModeConfiguration.getTetheringRequest(),
+ mApInterfaceName));
//send the AP state change broadcast
final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
@@ -739,6 +751,7 @@ public class SoftApManager implements ActiveModeManager {
intent.putExtra(WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME, mApInterfaceName);
intent.putExtra(
WifiManager.EXTRA_WIFI_AP_MODE, mSpecifiedModeConfiguration.getTargetMode());
+
if (SdkLevel.isAtLeastSv2()) {
mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
android.Manifest.permission.ACCESS_WIFI_STATE);
@@ -1144,7 +1157,7 @@ public class SoftApManager implements ActiveModeManager {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return SoftApManager.class.getSimpleName() + "." + IdleState.class.getSimpleName()
+ "." + getWhatToString(what);
}
@@ -1292,31 +1305,35 @@ public class SoftApManager implements ActiveModeManager {
break;
}
- // Only check if it's possible to create single AP, since a DBS request
- // already falls back to single AP if we can't create DBS.
- if (!mWifiNative.isItPossibleToCreateApIface(mRequestorWs)) {
- handleStartSoftApFailure(START_RESULT_FAILURE_INTERFACE_CONFLICT);
- break;
- }
- if (SdkLevel.isAtLeastT()
- && mCurrentSoftApConfiguration.isIeee80211beEnabled()
- && !mCurrentSoftApCapability.areFeaturesSupported(
- SoftApCapability.SOFTAP_FEATURE_IEEE80211_BE)) {
- Log.d(getTag(), "11BE is not supported, removing from configuration");
- mCurrentSoftApConfiguration = new SoftApConfiguration
- .Builder(mCurrentSoftApConfiguration)
- .setIeee80211beEnabled(false)
- .build();
- }
mApInterfaceName = mWifiNative.setupInterfaceForSoftApMode(
mWifiNativeInterfaceCallback, mRequestorWs,
mCurrentSoftApConfiguration.getBand(), isBridgeRequired(),
SoftApManager.this, getVendorData());
if (TextUtils.isEmpty(mApInterfaceName)) {
Log.e(getTag(), "setup failure when creating ap interface.");
- handleStartSoftApFailure(START_RESULT_FAILURE_CREATE_INTERFACE);
+ // Only check if it's possible to create single AP, since a DBS request
+ // already falls back to single AP if we can't create DBS.
+ if (!mWifiNative.isItPossibleToCreateApIface(mRequestorWs)) {
+ handleStartSoftApFailure(START_RESULT_FAILURE_INTERFACE_CONFLICT);
+ } else {
+ handleStartSoftApFailure(START_RESULT_FAILURE_CREATE_INTERFACE);
+ }
break;
}
+
+ DeviceWiphyCapabilities capa =
+ mWifiNative.getDeviceWiphyCapabilities(
+ mApInterfaceName, isBridgeRequired());
+ if (SdkLevel.isAtLeastT()
+ && mCurrentSoftApConfiguration.isIeee80211beEnabled()
+ && (capa == null || !capa.isWifiStandardSupported(
+ ScanResult.WIFI_STANDARD_11BE))) {
+ Log.d(getTag(), "11BE is not supported, removing from configuration");
+ mCurrentSoftApConfiguration = new SoftApConfiguration.Builder(
+ mCurrentSoftApConfiguration).setIeee80211beEnabled(
+ false).build();
+ }
+
mSoftApNotifier.dismissSoftApShutdownTimeoutExpiredNotification();
updateApState(WifiManager.WIFI_AP_STATE_ENABLING,
WifiManager.WIFI_AP_STATE_DISABLED, 0);
@@ -1350,7 +1367,8 @@ public class SoftApManager implements ActiveModeManager {
mSpecifiedModeConfiguration.getTargetMode(),
newConfig,
mCurrentSoftApCapability,
- mCountryCode);
+ mCountryCode,
+ mSpecifiedModeConfiguration.getTetheringRequest());
Log.d(getTag(), "Configuration changed to " + newConfig);
// Idle mode, update all configurations.
mCurrentSoftApConfiguration = newConfig;
@@ -1383,19 +1401,19 @@ public class SoftApManager implements ActiveModeManager {
}
@Override
- void enterImpl() {
+ public void enterImpl() {
mWifiInjector.getWifiCountryCode().registerListener(mCountryCodeChangeListener);
sendMessageDelayed(CMD_DRIVER_COUNTRY_CODE_CHANGE_TIMED_OUT, TIMEOUT_MS);
}
@Override
- void exitImpl() {
+ public void exitImpl() {
mWifiInjector.getWifiCountryCode().unregisterListener(mCountryCodeChangeListener);
removeMessages(CMD_DRIVER_COUNTRY_CODE_CHANGE_TIMED_OUT);
}
@Override
- boolean processMessageImpl(Message message) {
+ public boolean processMessageImpl(Message message) {
if (message.what == CMD_DRIVER_COUNTRY_CODE_CHANGED) {
if (!TextUtils.equals(mCountryCode, (String) message.obj)) {
Log.i(getTag(), "Ignore country code changed: " + message.obj);
@@ -1406,7 +1424,7 @@ public class SoftApManager implements ActiveModeManager {
mCurrentSoftApCapability.setCountryCode(mCountryCode);
mCurrentSoftApCapability =
ApConfigUtil.updateSoftApCapabilityWithAvailableChannelList(
- mCurrentSoftApCapability, mContext, mWifiNative);
+ mCurrentSoftApCapability, mContext, mWifiNative, null);
updateSafeChannelFrequencyList();
if (isBridgedMode()) {
SoftApConfiguration tempConfig =
@@ -1455,7 +1473,7 @@ public class SoftApManager implements ActiveModeManager {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return SoftApManager.class.getSimpleName() + "." + RunnerState.class.getSimpleName()
+ "." + getWhatToString(what);
}
@@ -1915,7 +1933,7 @@ public class SoftApManager implements ActiveModeManager {
}
@Override
- String getMessageLogRec(int what) {
+ public String getMessageLogRec(int what) {
return SoftApManager.class.getSimpleName() + "." + RunnerState.class.getSimpleName()
+ "." + getWhatToString(what);
}
@@ -2070,7 +2088,8 @@ public class SoftApManager implements ActiveModeManager {
mSpecifiedModeConfiguration.getTargetMode(),
newConfig,
mCurrentSoftApCapability,
- mCountryCode);
+ mCountryCode,
+ mSpecifiedModeConfiguration.getTetheringRequest());
Log.d(getTag(), "Configuration changed to " + newConfig);
if (mCurrentSoftApConfiguration.getMaxNumberOfClients()
!= newConfig.getMaxNumberOfClients()) {
@@ -2157,30 +2176,44 @@ public class SoftApManager implements ActiveModeManager {
Log.d(getTag(), "Ignore wifi connected in single AP state");
break;
}
- WifiInfo wifiInfo = (WifiInfo) message.obj;
+ ConcreteClientModeManager cmm = (ConcreteClientModeManager) message.obj;
+ String wifiInterface = cmm.getInterfaceName();
+ WifiInfo wifiInfo = cmm.getConnectionInfo();
int wifiFreq = wifiInfo.getFrequency();
+ int wifiBand = ApConfigUtil.convertFrequencyToBand(wifiFreq);
+ List<Integer> bands = new ArrayList<Integer>();
+ bands.add(wifiBand);
String targetShutDownInstance = "";
if (wifiFreq > 0 && !mSafeChannelFrequencyList.contains(wifiFreq)) {
Log.i(getTag(), "Wifi connected to freq:" + wifiFreq
+ " which is unavailable for SAP");
for (SoftApInfo sapInfo : mCurrentSoftApInfoMap.values()) {
- if (ApConfigUtil.convertFrequencyToBand(sapInfo.getFrequency())
- == ApConfigUtil.convertFrequencyToBand(wifiFreq)) {
+ int sapBand =
+ ApConfigUtil.convertFrequencyToBand(sapInfo.getFrequency());
+ if (sapBand == wifiBand) {
targetShutDownInstance = sapInfo.getApInstanceIdentifier();
Log.d(getTag(), "Remove the " + targetShutDownInstance
+ " instance which is running on the same band as "
+ "the wifi connection on an unsafe channel");
- break;
+ } else {
+ bands.add(sapBand);
}
}
// Wifi may connect to different band as the SAP. For instances:
// Wifi connect to 6Ghz but bridged AP is running on 2.4Ghz + 5Ghz.
- // In this case, targetShutDownInstance will be empty, shutdown the
- // highest frequency instance.
- removeIfaceInstanceFromBridgedApIface(
- TextUtils.isEmpty(targetShutDownInstance)
- ? getHighestFrequencyInstance(mCurrentSoftApInfoMap.keySet())
- : targetShutDownInstance);
+ // In this case, targetShutDownInstance will be empty, check whether
+ // the chip supports this combination. If not, shutdown the highest
+ // frequency instance.
+ if (TextUtils.isEmpty(targetShutDownInstance)) {
+ // We have to use STA ifacename to query band combinations.
+ if (!mWifiNative.isBandCombinationSupported(wifiInterface, bands)) {
+ removeIfaceInstanceFromBridgedApIface(
+ getHighestFrequencyInstance(
+ mCurrentSoftApInfoMap.keySet()));
+ }
+ } else {
+ removeIfaceInstanceFromBridgedApIface(targetShutDownInstance);
+ }
}
break;
case CMD_PLUGGED_STATE_CHANGED:
diff --git a/service/java/com/android/server/wifi/SoftApModeConfiguration.java b/service/java/com/android/server/wifi/SoftApModeConfiguration.java
index 8cef93eac6..ad279a7ea6 100644
--- a/service/java/com/android/server/wifi/SoftApModeConfiguration.java
+++ b/service/java/com/android/server/wifi/SoftApModeConfiguration.java
@@ -16,6 +16,7 @@
package com.android.server.wifi;
+import android.net.TetheringManager;
import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiManager;
@@ -41,8 +42,14 @@ class SoftApModeConfiguration {
*/
private final @Nullable SoftApConfiguration mSoftApConfig;
+ /**
+ * TetheringRequest for internal use, or null if none was passed in.
+ */
+ private final @Nullable TetheringManager.TetheringRequest mTetheringRequest;
+
SoftApModeConfiguration(int targetMode, @Nullable SoftApConfiguration config,
- SoftApCapability capability, @Nullable String countryCode) {
+ SoftApCapability capability, @Nullable String countryCode,
+ @Nullable TetheringManager.TetheringRequest request) {
Preconditions.checkArgument(
targetMode == WifiManager.IFACE_IP_MODE_TETHERED
|| targetMode == WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
@@ -51,6 +58,7 @@ class SoftApModeConfiguration {
mSoftApConfig = config;
mCapability = capability;
mCountryCode = countryCode;
+ mTetheringRequest = request;
}
public int getTargetMode() {
@@ -68,4 +76,8 @@ class SoftApModeConfiguration {
public String getCountryCode() {
return mCountryCode;
}
+
+ public TetheringManager.TetheringRequest getTetheringRequest() {
+ return mTetheringRequest;
+ }
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
index af82aa0ba6..5f377894cb 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
@@ -329,11 +329,17 @@ class SupplicantStaIfaceCallbackAidlImpl extends ISupplicantStaIfaceCallback.Stu
WifiConfiguration curConfiguration =
mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
if (curConfiguration != null) {
+ // In case of PSK networks the disconnection event in the middle of key exchange
+ // happens due to PSK mismatch. But filter out the de-authentication/disassociation
+ // frame from AP with known reason codes which are not related to PSK mismatch from
+ // reporting wrong password error.
if (mStateBeforeDisconnect == StaIfaceCallbackState.FOURWAY_HANDSHAKE
&& (WifiConfigurationUtil.isConfigForPskNetwork(curConfiguration)
- || WifiConfigurationUtil.isConfigForWapiPskNetwork(curConfiguration))
- && (!locallyGenerated || reasonCode
- != StaIfaceReasonCode.IE_IN_4WAY_DIFFERS)) {
+ || WifiConfigurationUtil.isConfigForWapiPskNetwork(
+ curConfiguration))
+ && (!locallyGenerated
+ || (reasonCode != StaIfaceReasonCode.IE_IN_4WAY_DIFFERS
+ && reasonCode != StaIfaceReasonCode.DISASSOC_AP_BUSY))) {
mWifiMonitor.broadcastAuthenticationFailureEvent(
mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1,
mCurrentSsid, MacAddress.fromBytes(bssid));
@@ -353,35 +359,39 @@ class SupplicantStaIfaceCallbackAidlImpl extends ISupplicantStaIfaceCallback.Stu
private void handleAssocRejectEvent(AssocRejectEventInfo assocRejectInfo) {
boolean isWrongPwd = false;
WifiConfiguration curConfiguration = mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
- if (curConfiguration != null) {
- if (!assocRejectInfo.timedOut) {
- Log.d(TAG, "flush PMK cache due to association rejection for config id "
- + curConfiguration.networkId + ".");
- mStaIfaceHal.removePmkCacheEntry(curConfiguration.networkId);
- }
- if (assocRejectInfo.statusCode
- == SupplicantStaIfaceHal.StaIfaceStatusCode.CHALLENGE_FAIL
- && WifiConfigurationUtil.isConfigForWepNetwork(curConfiguration)) {
- mStaIfaceHal.logCallback("WEP incorrect password");
- isWrongPwd = true;
- } else if (assocRejectInfo.statusCode
- == SupplicantStaIfaceHal.StaIfaceStatusCode.UNSPECIFIED_FAILURE
- || assocRejectInfo.statusCode
- == SupplicantStaIfaceHal.StaIfaceStatusCode.CHALLENGE_FAIL) {
- // Special handling for WPA3-Personal networks. If the password is
- // incorrect, the AP will send association rejection, with status code 1
- // (unspecified failure) or 15 (challenge fail). In SAE networks, the password
- // authentication is not related to the 4-way handshake. In this case, we will
- // send an authentication failure event up.
- // Network Selection status is guaranteed to be initialized
- SecurityParams params = curConfiguration.getNetworkSelectionStatus()
- .getCandidateSecurityParams();
- if (params != null
- && params.getSecurityType() == WifiConfiguration.SECURITY_TYPE_SAE) {
- // If this is ever connected, the password should be correct.
- isWrongPwd = !curConfiguration.getNetworkSelectionStatus().hasEverConnected();
- if (isWrongPwd) {
+ if (curConfiguration != null && !assocRejectInfo.timedOut) {
+ int statusCode = assocRejectInfo.statusCode;
+ Log.d(TAG, "flush PMK cache due to association rejection for config id "
+ + curConfiguration.networkId + ".");
+ mStaIfaceHal.removePmkCacheEntry(curConfiguration.networkId);
+ // Network Selection status is guaranteed to be initialized.
+ SecurityParams params = curConfiguration.getNetworkSelectionStatus()
+ .getCandidateSecurityParams();
+ if (params != null) {
+ if (params.getSecurityType() == WifiConfiguration.SECURITY_TYPE_WEP
+ && statusCode == SupplicantStaIfaceHal.StaIfaceStatusCode.CHALLENGE_FAIL) {
+ mStaIfaceHal.logCallback("WEP incorrect password");
+ isWrongPwd = true;
+ } else if (params.getSecurityType() == WifiConfiguration.SECURITY_TYPE_SAE) {
+ // Special handling for WPA3-Personal networks. In SAE networks, the password
+ // authentication is not related to the 4-way handshake. If the password is
+ // incorrect, the HAL will send association rejection, with status code 1
+ // (unspecified failure) or 15 (challenge fail).
+ // As per IEEE80211-2020 specification section - 12.4.7.6, an SAE message that
+ // was not successfully verified is indicated with a status code of 15. This
+ // typically happens when the entered password is wrong. So treat status code
+ // of 15 as incorrect password.
+ // Some implementations also send status code of 1 for incorrect password. But
+ // this is a generic status code and can't be treated as incorrect password all
+ // the time. So treat status code of 1 as incorrect password only if the STA
+ // was not connected to this network before. In this case, we will
+ // send an authentication failure event up.
+ if (statusCode == SupplicantStaIfaceHal.StaIfaceStatusCode.CHALLENGE_FAIL
+ || (statusCode
+ == SupplicantStaIfaceHal.StaIfaceStatusCode.UNSPECIFIED_FAILURE
+ && !curConfiguration.getNetworkSelectionStatus().hasEverConnected())) {
mStaIfaceHal.logCallback("SAE incorrect password");
+ isWrongPwd = true;
} else {
mStaIfaceHal.logCallback("SAE association rejection");
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java
index 3673d7bdcf..da8a38b9e3 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java
@@ -287,10 +287,17 @@ abstract class SupplicantStaIfaceCallbackHidlImpl extends ISupplicantStaIfaceCal
WifiConfiguration curConfiguration =
mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
if (curConfiguration != null) {
+ // In case of PSK networks the disconnection event in the middle of key exchange
+ // happens due to PSK mismatch. But filter out the de-authentication/disassociation
+ // frame from AP with known reason codes which are not related to PSK mismatch from
+ // reporting wrong password error.
if (mStateBeforeDisconnect == State.FOURWAY_HANDSHAKE
&& (WifiConfigurationUtil.isConfigForPskNetwork(curConfiguration)
- || WifiConfigurationUtil.isConfigForWapiPskNetwork(curConfiguration))
- && (!locallyGenerated || reasonCode != ReasonCode.IE_IN_4WAY_DIFFERS)) {
+ || WifiConfigurationUtil.isConfigForWapiPskNetwork(
+ curConfiguration))
+ && (!locallyGenerated
+ || (reasonCode != ReasonCode.IE_IN_4WAY_DIFFERS
+ && reasonCode != ReasonCode.DISASSOC_AP_BUSY))) {
mWifiMonitor.broadcastAuthenticationFailureEvent(
mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1,
mCurrentSsid, MacAddress.fromBytes(bssid));
@@ -311,35 +318,39 @@ abstract class SupplicantStaIfaceCallbackHidlImpl extends ISupplicantStaIfaceCal
boolean isWrongPwd = false;
WifiConfiguration curConfiguration =
mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
- if (curConfiguration != null) {
- if (!assocRejectInfo.timedOut) {
- Log.d(TAG, "flush PMK cache due to association rejection for config id "
- + curConfiguration.networkId + ".");
- mStaIfaceHal.removePmkCacheEntry(curConfiguration.networkId);
- }
- if (assocRejectInfo.statusCode
- == SupplicantStaIfaceHal.StaIfaceStatusCode.CHALLENGE_FAIL
- && WifiConfigurationUtil.isConfigForWepNetwork(curConfiguration)) {
- mStaIfaceHal.logCallback("WEP incorrect password");
- isWrongPwd = true;
- } else if (assocRejectInfo.statusCode
- == SupplicantStaIfaceHal.StaIfaceStatusCode.UNSPECIFIED_FAILURE
- || assocRejectInfo.statusCode
- == SupplicantStaIfaceHal.StaIfaceStatusCode.CHALLENGE_FAIL) {
- // Special handling for WPA3-Personal networks. If the password is
- // incorrect, the AP will send association rejection, with status code 1
- // (unspecified failure) or 15 (challenge fail). In SAE networks, the password
- // authentication is not related to the 4-way handshake. In this case, we will
- // send an authentication failure event up.
- // Network Selection status is guaranteed to be initialized
- SecurityParams params = curConfiguration.getNetworkSelectionStatus()
- .getCandidateSecurityParams();
- if (params != null
- && params.getSecurityType() == WifiConfiguration.SECURITY_TYPE_SAE) {
- // If this is ever connected, the password should be correct.
- isWrongPwd = !curConfiguration.getNetworkSelectionStatus().hasEverConnected();
- if (isWrongPwd) {
+ if (curConfiguration != null && !assocRejectInfo.timedOut) {
+ int statusCode = assocRejectInfo.statusCode;
+ Log.d(TAG, "flush PMK cache due to association rejection for config id "
+ + curConfiguration.networkId + ".");
+ mStaIfaceHal.removePmkCacheEntry(curConfiguration.networkId);
+ // Network Selection status is guaranteed to be initialized.
+ SecurityParams params = curConfiguration.getNetworkSelectionStatus()
+ .getCandidateSecurityParams();
+ if (params != null) {
+ if (params.getSecurityType() == WifiConfiguration.SECURITY_TYPE_WEP
+ && statusCode == SupplicantStaIfaceHal.StaIfaceStatusCode.CHALLENGE_FAIL) {
+ mStaIfaceHal.logCallback("WEP incorrect password");
+ isWrongPwd = true;
+ } else if (params.getSecurityType() == WifiConfiguration.SECURITY_TYPE_SAE) {
+ // Special handling for WPA3-Personal networks. In SAE networks, the password
+ // authentication is not related to the 4-way handshake. If the password is
+ // incorrect, the HAL will send association rejection, with status code 1
+ // (unspecified failure) or 15 (challenge fail).
+ // As per IEEE80211-2020 specification section - 12.4.7.6, an SAE message that
+ // was not successfully verified is indicated with a status code of 15. This
+ // typically happens when the entered password is wrong. So treat status code
+ // of 15 as incorrect password.
+ // Some implementations also send status code of 1 for incorrect password. But
+ // this is a generic status code and can't be treated as incorrect password all
+ // the time. So treat status code of 1 as incorrect password only if the STA
+ // was not connected to this network before. In this case, we will
+ // send an authentication failure event up.
+ if (statusCode == SupplicantStaIfaceHal.StaIfaceStatusCode.CHALLENGE_FAIL
+ || (statusCode
+ == SupplicantStaIfaceHal.StaIfaceStatusCode.UNSPECIFIED_FAILURE
+ && !curConfiguration.getNetworkSelectionStatus().hasEverConnected())) {
mStaIfaceHal.logCallback("SAE incorrect password");
+ isWrongPwd = true;
} else {
mStaIfaceHal.logCallback("SAE association rejection");
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
index 8671ecbce5..eb6f4609df 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
@@ -19,6 +19,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.net.MacAddress;
+import android.net.wifi.MscsParams;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.SecurityParams;
import android.net.wifi.WifiConfiguration;
@@ -842,16 +843,22 @@ public class SupplicantStaIfaceHal {
}
/**
+ * Check whether the HAL service is using AIDL.
+ *
+ * @return true if the AIDL service is being used, false otherwise.
+ */
+ public boolean isAidlService() {
+ return mStaIfaceHal != null && mStaIfaceHal instanceof SupplicantStaIfaceHalAidlImpl;
+ }
+
+ /**
* Check whether the AIDL service is running at least the expected version.
*
* @param expectedVersion Version number to check.
* @return true if the AIDL service is available and >= the expected version, false otherwise.
*/
public boolean isAidlServiceVersionAtLeast(int expectedVersion) {
- if (mStaIfaceHal == null || mStaIfaceHal instanceof SupplicantStaIfaceHalHidlImpl) {
- return false;
- }
- return ((SupplicantStaIfaceHalAidlImpl) mStaIfaceHal)
+ return isAidlService() && ((SupplicantStaIfaceHalAidlImpl) mStaIfaceHal)
.isServiceVersionAtLeast(expectedVersion);
}
@@ -2363,6 +2370,42 @@ public class SupplicantStaIfaceHal {
updateToNativeService);
}
+ /**
+ * See comments for {@link ISupplicantStaIfaceHal#enableMscs(MscsParams, String)}
+ */
+ public void enableMscs(@NonNull MscsParams mscsParams, String ifaceName) {
+ String methodStr = "enableMscs";
+ if (mStaIfaceHal == null) {
+ handleNullHal(methodStr);
+ return;
+ }
+ mStaIfaceHal.enableMscs(mscsParams, ifaceName);
+ }
+
+ /**
+ * See comments for {@link ISupplicantStaIfaceHal#resendMscs(String)}
+ */
+ public void resendMscs(String ifaceName) {
+ String methodStr = "resendMscs";
+ if (mStaIfaceHal == null) {
+ handleNullHal(methodStr);
+ return;
+ }
+ mStaIfaceHal.resendMscs(ifaceName);
+ }
+
+ /**
+ * See comments for {@link ISupplicantStaIfaceHal#disableMscs(String)}
+ */
+ public void disableMscs(String ifaceName) {
+ String methodStr = "disableMscs";
+ if (mStaIfaceHal == null) {
+ handleNullHal(methodStr);
+ return;
+ }
+ mStaIfaceHal.disableMscs(ifaceName);
+ }
+
private boolean handleNullHal(String methodStr) {
Log.e(TAG, "Cannot call " + methodStr + " because HAL object is null.");
return false;
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
index b7050efc2f..ec9a942bda 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
@@ -36,7 +36,7 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
import android.annotation.NonNull;
import android.content.Context;
-import android.hardware.wifi.V1_6.WifiChannelWidthInMhz;
+import android.hardware.wifi.WifiChannelWidthInMhz;
import android.hardware.wifi.supplicant.BtCoexistenceMode;
import android.hardware.wifi.supplicant.ConnectionCapabilities;
import android.hardware.wifi.supplicant.DebugLevel;
@@ -55,12 +55,18 @@ import android.hardware.wifi.supplicant.IpVersion;
import android.hardware.wifi.supplicant.KeyMgmtMask;
import android.hardware.wifi.supplicant.LegacyMode;
import android.hardware.wifi.supplicant.MloLinksInfo;
+import android.hardware.wifi.supplicant.MscsParams.FrameClassifierFields;
+import android.hardware.wifi.supplicant.MsduDeliveryInfo;
+import android.hardware.wifi.supplicant.MsduDeliveryInfo.DeliveryRatio;
import android.hardware.wifi.supplicant.PortRange;
+import android.hardware.wifi.supplicant.QosCharacteristics;
+import android.hardware.wifi.supplicant.QosCharacteristics.QosCharacteristicsMask;
import android.hardware.wifi.supplicant.QosPolicyClassifierParams;
import android.hardware.wifi.supplicant.QosPolicyClassifierParamsMask;
import android.hardware.wifi.supplicant.QosPolicyData;
import android.hardware.wifi.supplicant.QosPolicyRequestType;
import android.hardware.wifi.supplicant.QosPolicyScsData;
+import android.hardware.wifi.supplicant.QosPolicyScsData.LinkDirection;
import android.hardware.wifi.supplicant.QosPolicyScsRequestStatus;
import android.hardware.wifi.supplicant.QosPolicyScsRequestStatusCode;
import android.hardware.wifi.supplicant.QosPolicyStatus;
@@ -74,6 +80,7 @@ import android.hardware.wifi.supplicant.WpsConfigMethods;
import android.net.DscpPolicy;
import android.net.MacAddress;
import android.net.NetworkAgent;
+import android.net.wifi.MscsParams;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.ScanResult;
import android.net.wifi.SecurityParams;
@@ -94,6 +101,7 @@ import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.mockwifi.MockWifiServiceUtil;
+import com.android.server.wifi.util.HalAidlUtil;
import com.android.server.wifi.util.NativeUtil;
import java.nio.ByteBuffer;
@@ -163,6 +171,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
private CountDownLatch mWaitForDeathLatch;
private INonStandardCertCallback mNonStandardCertCallback;
private SupplicantStaIfaceHal.QosScsResponseCallback mQosScsResponseCallback;
+ private MscsParams mLastMscsParams;
private class SupplicantDeathRecipient implements DeathRecipient {
@Override
@@ -2892,11 +2901,107 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
hasSrcIp, srcIp, hasDstIp, dstIp, srcPort, dstPortRange, protocol));
}
+ @VisibleForTesting
+ protected static byte frameworkToHalDeliveryRatio(
+ @android.net.wifi.QosCharacteristics.DeliveryRatio int frameworkRatio) {
+ switch (frameworkRatio) {
+ case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_95:
+ return DeliveryRatio.RATIO_95;
+ case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_96:
+ return DeliveryRatio.RATIO_96;
+ case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_97:
+ return DeliveryRatio.RATIO_97;
+ case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_98:
+ return DeliveryRatio.RATIO_98;
+ case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99:
+ return DeliveryRatio.RATIO_99;
+ case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_9:
+ return DeliveryRatio.RATIO_99_9;
+ case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_99:
+ return DeliveryRatio.RATIO_99_99;
+ case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_999:
+ return DeliveryRatio.RATIO_99_999;
+ case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_9999:
+ return DeliveryRatio.RATIO_99_9999;
+ default:
+ Log.e(TAG, "Invalid delivery ratio received: " + frameworkRatio);
+ return DeliveryRatio.RATIO_95;
+ }
+ }
+
+ @VisibleForTesting
+ protected static byte frameworkToHalPolicyDirection(
+ @QosPolicyParams.Direction int frameworkDirection) {
+ switch (frameworkDirection) {
+ case QosPolicyParams.DIRECTION_UPLINK:
+ return LinkDirection.UPLINK;
+ case QosPolicyParams.DIRECTION_DOWNLINK:
+ return LinkDirection.DOWNLINK;
+ default:
+ Log.e(TAG, "Invalid direction received: " + frameworkDirection);
+ return LinkDirection.DOWNLINK;
+ }
+ }
+
+ /**
+ * Convert from a framework QosCharacteristics to its HAL equivalent.
+ */
+ @VisibleForTesting
+ protected static QosCharacteristics frameworkToHalQosCharacteristics(
+ android.net.wifi.QosCharacteristics frameworkChars) {
+ QosCharacteristics halChars = new QosCharacteristics();
+ halChars.minServiceIntervalUs = frameworkChars.getMinServiceIntervalMicros();
+ halChars.maxServiceIntervalUs = frameworkChars.getMaxServiceIntervalMicros();
+ halChars.minDataRateKbps = frameworkChars.getMinDataRateKbps();
+ halChars.delayBoundUs = frameworkChars.getDelayBoundMicros();
+
+ int optionalFieldMask = 0;
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.MAX_MSDU_SIZE)) {
+ optionalFieldMask |= QosCharacteristicsMask.MAX_MSDU_SIZE;
+ halChars.maxMsduSizeOctets = (char) frameworkChars.getMaxMsduSizeOctets();
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.SERVICE_START_TIME)) {
+ optionalFieldMask |= QosCharacteristicsMask.SERVICE_START_TIME;
+ optionalFieldMask |= QosCharacteristicsMask.SERVICE_START_TIME_LINK_ID;
+ halChars.serviceStartTimeUs = frameworkChars.getServiceStartTimeMicros();
+ halChars.serviceStartTimeLinkId = (byte) frameworkChars.getServiceStartTimeLinkId();
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.MEAN_DATA_RATE)) {
+ optionalFieldMask |= QosCharacteristicsMask.MEAN_DATA_RATE;
+ halChars.meanDataRateKbps = frameworkChars.getMeanDataRateKbps();
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.BURST_SIZE)) {
+ optionalFieldMask |= QosCharacteristicsMask.BURST_SIZE;
+ halChars.burstSizeOctets = frameworkChars.getBurstSizeOctets();
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.MSDU_LIFETIME)) {
+ optionalFieldMask |= QosCharacteristicsMask.MSDU_LIFETIME;
+ halChars.msduLifetimeMs = (char) frameworkChars.getMsduLifetimeMillis();
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.MSDU_DELIVERY_INFO)) {
+ optionalFieldMask |= QosCharacteristicsMask.MSDU_DELIVERY_INFO;
+ MsduDeliveryInfo deliveryInfo = new MsduDeliveryInfo();
+ deliveryInfo.deliveryRatio =
+ frameworkToHalDeliveryRatio(frameworkChars.getDeliveryRatio());
+ deliveryInfo.countExponent = (byte) frameworkChars.getCountExponent();
+ halChars.msduDeliveryInfo = deliveryInfo;
+ }
+
+ halChars.optionalFieldMask = optionalFieldMask;
+ return halChars;
+ }
+
/**
* Convert from a framework {@link QosPolicyParams} to a HAL QosPolicyScsData object.
*/
@VisibleForTesting
- protected static QosPolicyScsData frameworkToHalQosPolicyScsData(QosPolicyParams params) {
+ protected QosPolicyScsData frameworkToHalQosPolicyScsData(QosPolicyParams params) {
QosPolicyScsData halData = new QosPolicyScsData();
halData.policyId = (byte) params.getTranslatedPolicyId();
halData.userPriority = (byte) params.getUserPriority();
@@ -2940,13 +3045,20 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
paramsMask |= QosPolicyClassifierParamsMask.FLOW_LABEL;
classifierParams.flowLabelIpv6 = params.getFlowLabel();
}
+ if (SdkLevel.isAtLeastV() && isServiceVersionAtLeast(3)) {
+ halData.direction = frameworkToHalPolicyDirection(params.getDirection());
+ if (params.getQosCharacteristics() != null) {
+ halData.QosCharacteristics =
+ frameworkToHalQosCharacteristics(params.getQosCharacteristics());
+ }
+ }
classifierParams.classifierParamMask = paramsMask;
halData.classifierParams = classifierParams;
return halData;
}
- private static QosPolicyScsData[] frameworkToHalQosPolicyScsDataList(
+ private QosPolicyScsData[] frameworkToHalQosPolicyScsDataList(
List<QosPolicyParams> frameworkPolicies) {
QosPolicyScsData[] halDataList = new QosPolicyScsData[frameworkPolicies.size()];
int index = 0;
@@ -3008,6 +3120,9 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
capOut.maxNumberTxSpatialStreams = cap.maxNumberTxSpatialStreams;
capOut.maxNumberRxSpatialStreams = cap.maxNumberRxSpatialStreams;
capOut.apTidToLinkMapNegotiationSupported = cap.apTidToLinkMapNegotiationSupported;
+ if (isServiceVersionAtLeast(3) && cap.vendorData != null) {
+ capOut.vendorData = HalAidlUtil.halToFrameworkOuiKeyedDataList(cap.vendorData);
+ }
return capOut;
} catch (RemoteException e) {
handleRemoteException(e, methodStr);
@@ -3755,6 +3870,121 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
}
+ private static byte frameworkToHalFrameClassifierMask(int frameworkBitmap) {
+ byte halBitmap = 0;
+ if ((frameworkBitmap & MscsParams.FRAME_CLASSIFIER_IP_VERSION) != 0) {
+ halBitmap |= FrameClassifierFields.IP_VERSION;
+ }
+ if ((frameworkBitmap & MscsParams.FRAME_CLASSIFIER_SRC_IP_ADDR) != 0) {
+ halBitmap |= FrameClassifierFields.SRC_IP_ADDR;
+ }
+ if ((frameworkBitmap & MscsParams.FRAME_CLASSIFIER_DST_IP_ADDR) != 0) {
+ halBitmap |= FrameClassifierFields.DST_IP_ADDR;
+ }
+ if ((frameworkBitmap & MscsParams.FRAME_CLASSIFIER_SRC_PORT) != 0) {
+ halBitmap |= FrameClassifierFields.SRC_PORT;
+ }
+ if ((frameworkBitmap & MscsParams.FRAME_CLASSIFIER_DST_PORT) != 0) {
+ halBitmap |= FrameClassifierFields.DST_PORT;
+ }
+ if ((frameworkBitmap & MscsParams.FRAME_CLASSIFIER_DSCP) != 0) {
+ halBitmap |= FrameClassifierFields.DSCP;
+ }
+ if ((frameworkBitmap & MscsParams.FRAME_CLASSIFIER_PROTOCOL_NEXT_HDR) != 0) {
+ halBitmap |= FrameClassifierFields.PROTOCOL_NEXT_HDR;
+ }
+ if ((frameworkBitmap & MscsParams.FRAME_CLASSIFIER_FLOW_LABEL) != 0) {
+ halBitmap |= FrameClassifierFields.FLOW_LABEL;
+ }
+ return halBitmap;
+ }
+
+ private static android.hardware.wifi.supplicant.MscsParams frameworkToHalMscsParams(
+ MscsParams frameworkParams) {
+ android.hardware.wifi.supplicant.MscsParams halParams =
+ new android.hardware.wifi.supplicant.MscsParams();
+ halParams.upBitmap = (byte) frameworkParams.getUserPriorityBitmap();
+ halParams.upLimit = (byte) frameworkParams.getUserPriorityLimit();
+ halParams.streamTimeoutUs = frameworkParams.getStreamTimeoutUs();
+ halParams.frameClassifierMask =
+ frameworkToHalFrameClassifierMask(frameworkParams.getFrameClassifierFields());
+ return halParams;
+ }
+
+ /**
+ * See comments for {@link ISupplicantStaIfaceHal#enableMscs(MscsParams, String)}
+ */
+ @Override
+ public void enableMscs(@NonNull MscsParams mscsParams, String ifaceName) {
+ synchronized (mLock) {
+ if (!isServiceVersionAtLeast(3)) {
+ return;
+ }
+ configureMscsInternal(mscsParams, ifaceName);
+ mLastMscsParams = mscsParams;
+ }
+ }
+
+ /**
+ * See comments for {@link ISupplicantStaIfaceHal#resendMscs(String)}
+ */
+ public void resendMscs(String ifaceName) {
+ synchronized (mLock) {
+ if (!isServiceVersionAtLeast(3)) {
+ return;
+ }
+ if (mLastMscsParams == null) {
+ return;
+ }
+ configureMscsInternal(mLastMscsParams, ifaceName);
+ }
+ }
+
+ private void configureMscsInternal(@NonNull MscsParams mscsParams, String ifaceName) {
+ synchronized (mLock) {
+ if (!isServiceVersionAtLeast(3)) {
+ return;
+ }
+ String methodStr = "configureMscsInternal";
+ ISupplicantStaIface iface = checkStaIfaceAndLogFailure(ifaceName, methodStr);
+ if (iface == null) {
+ return;
+ }
+ try {
+ android.hardware.wifi.supplicant.MscsParams halParams =
+ frameworkToHalMscsParams(mscsParams);
+ iface.configureMscs(halParams);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ }
+ }
+
+ /**
+ * See comments for {@link ISupplicantStaIface#disableMscs()}
+ */
+ @Override
+ public void disableMscs(String ifaceName) {
+ if (!isServiceVersionAtLeast(3)) {
+ return;
+ }
+ String methodStr = "disableMscs";
+ mLastMscsParams = null;
+ ISupplicantStaIface iface = checkStaIfaceAndLogFailure(ifaceName, methodStr);
+ if (iface == null) {
+ return;
+ }
+ try {
+ iface.disableMscs();
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ }
+
private class NonStandardCertCallback extends INonStandardCertCallback.Stub {
@Override
public byte[] getBlob(String alias) {
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
index 0bf1b1dd20..5a431b7e38 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
@@ -53,7 +53,6 @@ import android.hardware.wifi.supplicant.V1_4.LegacyMode;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
import android.net.MacAddress;
-import android.net.wifi.QosPolicyParams;
import android.net.wifi.ScanResult;
import android.net.wifi.SecurityParams;
import android.net.wifi.WifiAnnotations.WifiStandard;
@@ -3945,98 +3944,4 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
return currentConfig.getNetworkSelectionStatus().getCandidateSecurityParams();
}
-
- /**
- * Set whether the network-centric QoS policy feature is enabled or not for this interface.
- *
- * @param ifaceName name of the interface.
- * @param isEnabled true if feature is enabled, false otherwise.
- * @return true without action since this is not a supported feature.
- */
- public boolean setNetworkCentricQosPolicyFeatureEnabled(@NonNull String ifaceName,
- boolean isEnabled) {
- throw new UnsupportedOperationException(
- "setNetworkCentricQosPolicyFeatureEnabled is not supported by the HIDL HAL");
- }
-
- /**
- * Sends a QoS policy response.
- *
- * @param ifaceName Name of the interface.
- * @param qosPolicyRequestId Dialog token to identify the request.
- * @param morePolicies Flag to indicate more QoS policies can be accommodated.
- * @param qosPolicyStatusList List of framework QosPolicyStatus objects.
- * @return true if response is sent successfully, false otherwise.
- */
- public boolean sendQosPolicyResponse(String ifaceName, int qosPolicyRequestId,
- boolean morePolicies,
- @NonNull List<SupplicantStaIfaceHal.QosPolicyStatus> qosPolicyStatusList) {
- throw new UnsupportedOperationException(
- "sendQosPolicyResponse is not supported by the HIDL HAL");
- }
-
- /**
- * Indicates the removal of all active QoS policies configured by the AP.
- *
- * @param ifaceName Name of the interface.
- */
- public boolean removeAllQosPolicies(String ifaceName) {
- throw new UnsupportedOperationException(
- "removeAllQosPolicies is not supported by the HIDL HAL");
- }
-
- /**
- * See comments for {@link ISupplicantStaIfaceHal#addQosPolicyRequestForScs(String, List)}
- */
- public List<SupplicantStaIfaceHal.QosPolicyStatus> addQosPolicyRequestForScs(
- @NonNull String ifaceName, @NonNull List<QosPolicyParams> policies) {
- Log.e(TAG, "addQosPolicyRequestForScs is not supported by the HIDL HAL");
- return null;
- }
-
- /**
- * See comments for {@link ISupplicantStaIfaceHal#removeQosPolicyForScs(String, List)}
- */
- public List<SupplicantStaIfaceHal.QosPolicyStatus> removeQosPolicyForScs(
- @NonNull String ifaceName, @NonNull List<Byte> policyIds) {
- Log.e(TAG, "removeQosPolicyForScs is not supported by the HIDL HAL");
- return null;
- }
-
- /**
- * See comments for {@link ISupplicantStaIfaceHal#registerQosScsResponseCallback(
- * SupplicantStaIfaceHal.QosScsResponseCallback)}
- */
- public void registerQosScsResponseCallback(
- @NonNull SupplicantStaIfaceHal.QosScsResponseCallback callback) {
- Log.e(TAG, "registerQosScsResponseCallback is not supported by the HIDL HAL");
- }
-
- /**
- * Generate DPP credential for network access
- *
- * @param ifaceName Name of the interface.
- * @param ssid ssid of the network
- * @param privEcKey Private EC Key for DPP Configurator
- * Returns false. Not Supported throuh HIDL
- */
- public boolean generateSelfDppConfiguration(@NonNull String ifaceName, @NonNull String ssid,
- byte[] privEcKey) {
- Log.d(TAG, "generateSelfDppConfiguration is not supported");
- return false;
- }
-
- /**
- * Set the currently configured network's anonymous identity.
- *
- * @param ifaceName Name of the interface.
- * @param anonymousIdentity the anonymouns identity.
- * @param updateToNativeService write the data to the native service.
- * @return true if succeeds, false otherwise.
- */
- public boolean setEapAnonymousIdentity(@NonNull String ifaceName, String anonymousIdentity,
- boolean updateToNativeService) {
- Log.d(TAG, "setEapAnonymousIdentity is ignored for HIDL");
- return false;
- }
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkCallbackAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaNetworkCallbackAidlImpl.java
index 21d3426f56..219c716a22 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkCallbackAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkCallbackAidlImpl.java
@@ -177,7 +177,7 @@ class SupplicantStaNetworkCallbackAidlImpl extends ISupplicantStaNetworkCallback
return;
}
String certHash = byteArrayToString(certHashBytes);
- if (null == subject) {
+ if (null == certHash) {
mNetworkHal.logCallback(
"onServerCertificateAvailable: cannot convert cert hash bytes to string.");
return;
diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
index 634ba3f856..3c1a8b4993 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
@@ -16,6 +16,7 @@
package com.android.server.wifi;
+import android.annotation.NonNull;
import android.content.Context;
import android.hardware.wifi.supplicant.AuthAlgMask;
import android.hardware.wifi.supplicant.DppConnectionKeys;
@@ -33,6 +34,7 @@ import android.hardware.wifi.supplicant.PairwiseCipherMask;
import android.hardware.wifi.supplicant.ProtoMask;
import android.hardware.wifi.supplicant.SaeH2eMode;
import android.hardware.wifi.supplicant.TlsVersion;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.SecurityParams;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
@@ -44,6 +46,7 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.util.ArrayUtils;
import com.android.server.wifi.util.HalAidlUtil;
import com.android.server.wifi.util.NativeUtil;
@@ -59,6 +62,7 @@ import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -309,7 +313,14 @@ public class SupplicantStaNetworkHalAidlImpl {
if (config == null) {
return false;
}
- /** SSID */
+ // ieee80211be
+ if (!config.isWifi7Enabled() && isServiceVersionIsAtLeast(3)) {
+ if (!disableEht()) {
+ Log.e(TAG, "failed to disable EHT (Wi-Fi 7)");
+ return false;
+ }
+ }
+ // SSID
if (config.SSID != null) {
WifiSsid wifiSsid = WifiSsid.fromString(config.SSID);
if (!setSsid(wifiSsid.getBytes())) {
@@ -317,7 +328,7 @@ public class SupplicantStaNetworkHalAidlImpl {
return false;
}
}
- /** BSSID */
+ // BSSID
String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
if (bssidStr != null) {
byte[] bssid = NativeUtil.macAddressToByteArray(bssidStr);
@@ -326,7 +337,7 @@ public class SupplicantStaNetworkHalAidlImpl {
return false;
}
}
- /** HiddenSSID */
+ // HiddenSSID
if (!setScanSsid(config.hiddenSSID)) {
Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID);
return false;
@@ -342,12 +353,12 @@ public class SupplicantStaNetworkHalAidlImpl {
boolean isRequirePmf = NativeUtil.getOptimalPmfSettingForConfig(config,
securityParams.isRequirePmf(), mWifiGlobals);
- /** RequirePMF */
+ // RequirePMF
if (!setRequirePmf(isRequirePmf)) {
Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePmf);
return false;
}
- /** Key Management Scheme */
+ // Key Management Scheme
BitSet allowedKeyManagement = securityParams.getAllowedKeyManagement();
if (allowedKeyManagement.cardinality() != 0) {
// Add upgradable type key management flags for PSK/SAE.
@@ -374,7 +385,7 @@ public class SupplicantStaNetworkHalAidlImpl {
return false;
}
}
- /** Security Protocol */
+ // Security Protocol
BitSet allowedProtocols = securityParams.getAllowedProtocols();
if (allowedProtocols.cardinality() != 0 && !setProto(
wifiConfigurationToSupplicantProtoMask(allowedProtocols, mWifiGlobals,
@@ -382,7 +393,7 @@ public class SupplicantStaNetworkHalAidlImpl {
Log.e(TAG, "failed to set Security Protocol");
return false;
}
- /** Auth Algorithm */
+ // Auth Algorithm
BitSet allowedAuthAlgorithms = securityParams.getAllowedAuthAlgorithms();
if (allowedAuthAlgorithms.cardinality() != 0
&& !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask(
@@ -390,7 +401,7 @@ public class SupplicantStaNetworkHalAidlImpl {
Log.e(TAG, "failed to set AuthAlgorithm");
return false;
}
- /** Group Cipher */
+ // Group Cipher
BitSet allowedGroupCiphers = NativeUtil.getOptimalGroupCiphersForConfig(
config, securityParams.getAllowedGroupCiphers(), mWifiGlobals);
if (allowedGroupCiphers.cardinality() != 0
@@ -399,7 +410,7 @@ public class SupplicantStaNetworkHalAidlImpl {
Log.e(TAG, "failed to set Group Cipher");
return false;
}
- /** Pairwise Cipher*/
+ // Pairwise Cipher
BitSet allowedPairwiseCiphers = NativeUtil.getOptimalPairwiseCiphersForConfig(
config, securityParams.getAllowedPairwiseCiphers(), mWifiGlobals);
if (allowedPairwiseCiphers.cardinality() != 0
@@ -408,7 +419,7 @@ public class SupplicantStaNetworkHalAidlImpl {
Log.e(TAG, "failed to set PairwiseCipher");
return false;
}
- /** Pre Shared Key */
+ // Pre Shared Key
// For PSK, this can either be quoted ASCII passphrase or hex string for raw psk.
// For SAE, password must be a quoted ASCII string
if (config.preSharedKey != null) {
@@ -419,7 +430,7 @@ public class SupplicantStaNetworkHalAidlImpl {
}
} else if (config.preSharedKey.startsWith("\"")) {
if (allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
- /* WPA3 case, field is SAE Password */
+ // WPA3 case, field is SAE Password
if (!setSaePassword(
NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
Log.e(TAG, "failed to set sae password");
@@ -444,7 +455,7 @@ public class SupplicantStaNetworkHalAidlImpl {
}
}
}
- /** Wep Keys */
+ // Wep Keys
boolean hasSetKey = false;
if (config.wepKeys != null) {
for (int i = 0; i < config.wepKeys.length; i++) {
@@ -458,18 +469,18 @@ public class SupplicantStaNetworkHalAidlImpl {
}
}
}
- /** Wep Tx Key Idx */
+ // Wep Tx Key Idx
if (hasSetKey) {
if (!setWepTxKeyIdx(config.wepTxKeyIndex)) {
Log.e(TAG, "failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
return false;
}
}
- /** metadata: FQDN + ConfigKey + CreatorUid */
+ // metadata: FQDN + ConfigKey + CreatorUid
final Map<String, String> metadata = new HashMap<String, String>();
if (config.isPasspoint()) {
metadata.put(ID_STRING_KEY_FQDN, config.FQDN);
- /** Selected RCOI */
+ // Selected RCOI
if (!setSelectedRcoi(config.enterpriseConfig.getSelectedRcoi())) {
Log.e(TAG, "failed to set selected RCOI");
return false;
@@ -481,13 +492,13 @@ public class SupplicantStaNetworkHalAidlImpl {
Log.e(TAG, "failed to set id string");
return false;
}
- /** UpdateIdentifier */
+ // UpdateIdentifier
if (config.updateIdentifier != null
&& !setUpdateIdentifier(Integer.parseInt(config.updateIdentifier))) {
Log.e(TAG, "failed to set update identifier");
return false;
}
- /** SAE configuration */
+ // SAE configuration
if (allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
/**
* Hash-to-Element preference.
@@ -512,11 +523,19 @@ public class SupplicantStaNetworkHalAidlImpl {
return false;
}
}
+ // Vendor data
+ if (SdkLevel.isAtLeastV() && isServiceVersionIsAtLeast(3)
+ && config.getVendorData() != null
+ && !config.getVendorData().isEmpty()
+ && !setVendorData(config.getVendorData())) {
+ Log.e(TAG, "Failed to set vendor data.");
+ return false;
+ }
// Finish here if no EAP config to set
if (config.enterpriseConfig != null
&& config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
if (config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.WAPI_CERT) {
- /** WAPI certificate suite name*/
+ // WAPI certificate suite name
String param = config.enterpriseConfig
.getFieldValue(WifiEnterpriseConfig.WAPI_CERT_SUITE_KEY);
if (!TextUtils.isEmpty(param) && !setWapiCertSuite(param)) {
@@ -1304,6 +1323,33 @@ public class SupplicantStaNetworkHalAidlImpl {
}
/**
+ * Disable EHT for this network.
+ *
+ * @return true if successful, false otherwise
+ */
+ private boolean disableEht() {
+ synchronized (mLock) {
+ final String methodStr = "disableEht";
+ if (!checkStaNetworkAndLogFailure(methodStr)) {
+ return false;
+ }
+ try {
+ if (!isServiceVersionIsAtLeast(3)) {
+ return false;
+ }
+ mISupplicantStaNetwork.disableEht();
+ Log.i(TAG, "Successfully disabled EHT");
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
* Set the BSSID for this network.
*
* @param bssidStr MAC address in "XX:XX:XX:XX:XX:XX" form or "any" to reset the mac address.
@@ -3745,4 +3791,29 @@ public class SupplicantStaNetworkHalAidlImpl {
return false;
}
}
+
+ private boolean setVendorData(@NonNull List<OuiKeyedData> vendorData) {
+ synchronized (mLock) {
+ final String methodStr = "setVendorData";
+ if (!checkStaNetworkAndLogFailure(methodStr)) {
+ return false;
+ }
+ try {
+ if (!isServiceVersionIsAtLeast(3)) {
+ return false;
+ }
+ if (vendorData == null || vendorData.isEmpty()) {
+ return false;
+ }
+ mISupplicantStaNetwork.setVendorData(
+ HalAidlUtil.frameworkToHalOuiKeyedDataList(vendorData));
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/TwtManager.java b/service/java/com/android/server/wifi/TwtManager.java
new file mode 100644
index 0000000000..077cd1505a
--- /dev/null
+++ b/service/java/com/android/server/wifi/TwtManager.java
@@ -0,0 +1,651 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.AlarmManager;
+import android.net.MacAddress;
+import android.net.wifi.ITwtCallback;
+import android.net.wifi.ITwtCapabilitiesListener;
+import android.net.wifi.ITwtStatsListener;
+import android.net.wifi.WifiManager;
+import android.net.wifi.twt.TwtRequest;
+import android.net.wifi.twt.TwtSession;
+import android.net.wifi.twt.TwtSessionCallback;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.RemoteException;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.wifi.resources.R;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+
+/**
+ * This class acts as a manager for TWT sessions and callbacks. It establishes a link between unique
+ * callback IDs and their corresponding callbacks, ensuring the correct responses are triggered. To
+ * manage incoming TWT events, the class registers TWT sessions with the appropriate callbacks.
+ * Additionally, it implements a garbage collection task to remove expired callbacks.
+ *
+ * If a registered callback's process goes away, this class will take care of automatically
+ * removing it from the callback list. Twt manager allows simultaneous requests limited by
+ * {@link #MAXIMUM_CALLBACKS}.
+ *
+ * Note: All contexts in TwtManager are in WifiThread. So no locks are used.
+ */
+
+class TwtManager {
+ public static final String TAG = "TwtManager";
+ private static final int TWT_CALLBACK_TIMEOUT_MILLIS = 2000;
+ private static final String TWT_MANAGER_ALARM_TAG = "twtManagerAlarm";
+ private static final int MAXIMUM_CALLBACKS = 8;
+
+ private class Callback implements IBinder.DeathRecipient {
+ public IInterface mCallback;
+ public final int mOwner;
+ public int mSessionId = -1;
+ public final int mId;
+ public final CallbackType mType;
+ public final long mTimestamp;
+
+ Callback(int id, IInterface callback, CallbackType type, int owner) {
+ mId = id;
+ mCallback = callback;
+ mType = type;
+ mOwner = owner;
+ mTimestamp = mClock.getElapsedSinceBootMillis();
+ }
+
+ @Override
+ public void binderDied() {
+ mHandler.post(() -> {
+ unregisterSession(mSessionId);
+ unregisterCallback(mId);
+ });
+ }
+ }
+
+ private enum CallbackType {SETUP, STATS, TEARDOWN}
+ private final SparseArray<Callback> mCommandCallbacks = new SparseArray<>();
+ private final SparseArray<Callback> mTwtSessionCallbacks = new SparseArray<>();
+ private final BitSet mIdBitSet;
+ private final int mStartOffset;
+ private final int mMaxSessions;
+ private String mInterfaceName;
+ private final Clock mClock;
+ private final AlarmManager mAlarmManager;
+ private final Handler mHandler;
+ ArraySet<Integer> mBlockedOuiSet = new ArraySet<>();
+
+ private final WifiNative mWifiNative;
+ private final WifiNativeTwtEvents mWifiNativeTwtEvents;
+ private final AlarmManager.OnAlarmListener mTimeoutListener = () -> {
+ startGarbageCollector();
+ };
+
+ /**
+ * Whenever primary clientModeManager identified by the interface name gets disconnected, reset
+ * the TwtManager.
+ */
+ private class ClientModeImplListenerInternal implements ClientModeImplListener {
+ @Override
+ public void onConnectionEnd(@NonNull ConcreteClientModeManager clientModeManager) {
+ if (clientModeManager.getInterfaceName() != null
+ && clientModeManager.getInterfaceName().equals(mInterfaceName)) {
+ reset();
+ }
+ }
+ }
+
+ TwtManager(@NonNull WifiInjector wifiInjector, @NonNull ClientModeImplMonitor cmiMonitor,
+ @NonNull WifiNative wifiNative, @NonNull Handler handler, @NonNull Clock clock,
+ int maxSessions, int startOffset) {
+ mAlarmManager = wifiInjector.getAlarmManager();
+ mHandler = handler;
+ mClock = clock;
+ mMaxSessions = maxSessions;
+ mIdBitSet = new BitSet(MAXIMUM_CALLBACKS);
+ mStartOffset = startOffset;
+ mWifiNative = wifiNative;
+ mWifiNativeTwtEvents = new WifiNativeTwtEvents();
+ cmiMonitor.registerListener(new ClientModeImplListenerInternal());
+ int[] ouis = wifiInjector.getContext().getResources().getIntArray(
+ R.array.config_wifiTwtBlockedOuiList);
+ if (ouis != null) {
+ for (int oui : ouis) {
+ mBlockedOuiSet.add(oui);
+ }
+ }
+ }
+
+ /**
+ * Notify teardown to the registered caller
+ */
+ private void notifyTeardown(ITwtCallback iTwtCallback,
+ @TwtSessionCallback.TwtReasonCode int reasonCode) {
+ if (iTwtCallback == null) {
+ Log.e(TAG, "notifyTeardown: null interface. Reason code " + reasonCode);
+ return;
+ }
+ try {
+ iTwtCallback.onTeardown(reasonCode);
+ } catch (RemoteException e) {
+ Log.e(TAG, "notifyTeardown: " + e);
+ }
+ }
+
+ private Bundle getDefaultTwtCapabilities() {
+ Bundle twtCapabilities = new Bundle();
+ twtCapabilities.putBoolean(WifiManager.TWT_CAPABILITIES_KEY_BOOLEAN_TWT_REQUESTER, false);
+ twtCapabilities.putInt(WifiManager.TWT_CAPABILITIES_KEY_INT_MIN_WAKE_DURATION_MICROS, -1);
+ twtCapabilities.putInt(WifiManager.TWT_CAPABILITIES_KEY_INT_MAX_WAKE_DURATION_MICROS, -1);
+ twtCapabilities.putLong(WifiManager.TWT_CAPABILITIES_KEY_LONG_MIN_WAKE_INTERVAL_MICROS, -1);
+ twtCapabilities.putLong(WifiManager.TWT_CAPABILITIES_KEY_LONG_MAX_WAKE_INTERVAL_MICROS, -1);
+ return twtCapabilities;
+ }
+
+ private static Bundle getDefaultTwtStats() {
+ Bundle twtStats = new Bundle();
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_COUNT, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_COUNT, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_SIZE, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_SIZE, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_EOSP_COUNT, -1);
+ return twtStats;
+ }
+
+ /**
+ * Notify failure to the registered caller
+ */
+ private void notifyFailure(IInterface iInterface, CallbackType type,
+ @TwtSessionCallback.TwtErrorCode int errorCode) {
+ if (iInterface == null) {
+ Log.e(TAG, "notifyFailure: null interface. Error code " + errorCode);
+ return;
+ }
+ try {
+ if (type == CallbackType.STATS) {
+ ((ITwtStatsListener) iInterface).onResult(getDefaultTwtStats());
+ } else {
+ ((ITwtCallback) iInterface).onFailure(errorCode);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "notifyFailure: " + e);
+ }
+ }
+
+ /**
+ * Expire callbacks and fetch next oldest callback's schedule for timeout
+ *
+ * @param now Current reference time
+ * @return Timeout of the oldest callback with respect to current time. A value 0 means no more
+ * callbacks to expire.
+ */
+ private long handleExpirationsAndGetNextTimeout(long now) {
+ long oldest = Long.MAX_VALUE;
+ List<Integer> expiredIds = new ArrayList<>();
+ for (int i = 0; i < mCommandCallbacks.size(); ++i) {
+ Callback callback = mCommandCallbacks.valueAt(i);
+ if (now - callback.mTimestamp >= TWT_CALLBACK_TIMEOUT_MILLIS) {
+ notifyFailure(callback.mCallback, callback.mType,
+ TwtSessionCallback.TWT_ERROR_CODE_TIMEOUT);
+ // Unregister session now
+ if (callback.mType == CallbackType.TEARDOWN) {
+ unregisterSession(callback.mSessionId);
+ }
+ expiredIds.add(callback.mId);
+ } else {
+ oldest = Math.min(callback.mTimestamp, oldest);
+ }
+ }
+ for (int id : expiredIds) {
+ unregisterCallback(id);
+ }
+
+ if (oldest > now) return 0;
+ // Callbacks which has (age >= TWT_COMMAND_TIMEOUT_MILLIS) is cleaned up already
+ return TWT_CALLBACK_TIMEOUT_MILLIS - (now - oldest);
+ }
+
+ private void startGarbageCollector() {
+ long timeout = handleExpirationsAndGetNextTimeout(mClock.getElapsedSinceBootMillis());
+ if (timeout <= 0) return;
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
+ mClock.getElapsedSinceBootMillis() + timeout, TWT_MANAGER_ALARM_TAG,
+ mTimeoutListener, mHandler);
+ }
+
+ private void stopGarbageCollector() {
+ mAlarmManager.cancel(mTimeoutListener);
+ }
+
+ /**
+ * Register a callback
+ *
+ * @param callback A remote interface performing callback
+ * @param type Type of the callback as {@link CallbackType}
+ * @param owner Owner of the callback
+ * @return Returns an unique id. -1 if registration fails.
+ */
+ private int registerCallback(IInterface callback, CallbackType type, int owner) {
+ if (callback == null) {
+ Log.e(TAG, "registerCallback: Null callback");
+ return -1;
+ }
+ if ((type == CallbackType.SETUP) && (mTwtSessionCallbacks.size() >= mMaxSessions)) {
+ Log.e(TAG, "registerCallback: Maximum sessions reached. Setup not allowed.");
+ notifyFailure(callback, CallbackType.SETUP,
+ TwtSessionCallback.TWT_ERROR_CODE_MAX_SESSIONS_REACHED);
+ return -1;
+ }
+ int id = mIdBitSet.nextClearBit(0);
+ if (id >= MAXIMUM_CALLBACKS) {
+ Log.e(TAG, "registerCallback: No more simultaneous requests possible");
+ notifyFailure(callback, CallbackType.SETUP,
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ return -1;
+ }
+ mIdBitSet.set(id);
+ id += mStartOffset;
+ try {
+ Callback cb = new Callback(id, callback, type, owner);
+ callback.asBinder().linkToDeath(cb, 0);
+ mCommandCallbacks.put(id, cb);
+ } catch (RemoteException e) {
+ Log.e(TAG, "registerCallback: Error on linkToDeath - " + e);
+ notifyFailure(callback, CallbackType.SETUP, TwtSessionCallback.TWT_ERROR_CODE_FAIL);
+ return -1;
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "registerCallback: " + e);
+ notifyFailure(callback, CallbackType.SETUP, TwtSessionCallback.TWT_ERROR_CODE_FAIL);
+ return -1;
+ }
+ // First register triggers GC
+ if (mCommandCallbacks.size() == 1) startGarbageCollector();
+ return id;
+ }
+
+ /**
+ * Unregister a previously registered callback
+ *
+ * @param id Unique callback id returned by
+ * {@link #registerCallback(IInterface, CallbackType, int)}
+ */
+ private void unregisterCallback(int id) {
+ try {
+ if (!mCommandCallbacks.contains(id)) return;
+ // Last unregister stops GC
+ if (mCommandCallbacks.size() == 1) stopGarbageCollector();
+ Callback cb = mCommandCallbacks.get(id);
+ if (!mTwtSessionCallbacks.contains(cb.mSessionId)) {
+ // Note: unregisterSession() will call Binder#unlinktoDeath()
+ cb.mCallback.asBinder().unlinkToDeath(cb, 0);
+ }
+ mCommandCallbacks.delete(id);
+ mIdBitSet.clear(id - mStartOffset);
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "unregisterCallback: invalid id " + id + " " + e);
+ }
+ }
+
+ /**
+ * Register a TWT session
+ *
+ * @param id Unique callback id returned by
+ * {@link #registerCallback(IInterface, CallbackType, int)}
+ * @param sessionId TWT session id
+ * @return true if successful, otherwise false.
+ */
+ private boolean registerSession(int id, int sessionId) {
+ Callback callback = mCommandCallbacks.get(id);
+ if (callback == null) {
+ Log.e(TAG, "registerSession failed. Invalid id " + id);
+ return false;
+ }
+ if (mTwtSessionCallbacks.contains(sessionId)) {
+ Log.e(TAG, "registerSession failed. Session already exists");
+ return false;
+ }
+ callback.mSessionId = sessionId;
+ mTwtSessionCallbacks.put(sessionId, callback);
+ return true;
+ }
+
+ /**
+ * Unregister a TWT session
+ *
+ * @param sessionId TWT session id
+ */
+ private void unregisterSession(int sessionId) {
+ if (!mTwtSessionCallbacks.contains(sessionId)) {
+ Log.e(TAG, "unregisterSession failed. Session does not exist");
+ return;
+ }
+ Callback callback = mTwtSessionCallbacks.get(sessionId);
+ callback.mCallback.asBinder().unlinkToDeath(callback, 0);
+ mTwtSessionCallbacks.delete(sessionId);
+ }
+
+ private boolean isSessionRegistered(int sessionId) {
+ return mTwtSessionCallbacks.get(sessionId) != null;
+ }
+
+ /**
+ * Get callback from TWT session id
+ *
+ * @param sessionId TWT session id
+ * @return Callback registered, otherwise null
+ */
+ private IInterface getCallbackFromSession(int sessionId) {
+ if (mTwtSessionCallbacks.get(sessionId) == null) return null;
+ return mTwtSessionCallbacks.get(sessionId).mCallback;
+ }
+
+ /**
+ * Get owner uid
+ *
+ * @param id unique id returned by {@link #registerCallback(IInterface, CallbackType, int)}
+ * @return Owner UID if registered, otherwise -1
+ */
+ private int getOwnerUid(int id) {
+ try {
+ return mCommandCallbacks.get(id).mOwner;
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "getOwner: invalid id " + id + " " + e);
+ return -1;
+ }
+ }
+
+ /**
+ * Get callback
+ *
+ * @param id unique id returned by {@link #registerCallback(IInterface, CallbackType, int)}
+ * @return Callback if registered, otherwise null
+ */
+ private IInterface getCallback(int id) {
+ try {
+ Callback callback = mCommandCallbacks.get(id);
+ if (callback == null) return null;
+ return callback.mCallback;
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "getCallback: invalid id " + id + " " + e);
+ return null;
+ }
+ }
+
+ /**
+ * Implementation of TWT events from WifiNative. see {@link #registerWifiNativeTwtEvents()}
+ */
+ public class WifiNativeTwtEvents implements WifiNative.WifiTwtEvents {
+ @Override
+ public void onTwtFailure(int cmdId, int twtErrorCode) {
+ ITwtCallback iTwtCallback = (ITwtCallback) getCallback(cmdId);
+ if (iTwtCallback == null) {
+ Log.e(TAG, "onTwtFailure: Command Id is not registered " + cmdId);
+ return;
+ }
+ try {
+ iTwtCallback.onFailure(twtErrorCode);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ }
+ unregisterCallback(cmdId);
+ }
+
+ @Override
+ public void onTwtSessionCreate(int cmdId, int wakeDurationUs, long wakeIntervalUs,
+ int linkId, int sessionId) {
+ ITwtCallback iTwtCallback = (ITwtCallback) getCallback(cmdId);
+ if (iTwtCallback == null) {
+ Log.e(TAG, "onTwtSessionCreate failed. No callback registered for " + cmdId);
+ return;
+ }
+ if (!registerSession(cmdId, sessionId)) {
+ Log.e(TAG, "onTwtSessionCreate failed for session " + sessionId);
+ return;
+ }
+ try {
+ iTwtCallback.onCreate(wakeDurationUs, wakeIntervalUs, linkId, getOwnerUid(cmdId),
+ sessionId);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ }
+ unregisterCallback(cmdId);
+ }
+
+ @Override
+ public void onTwtSessionTeardown(int cmdId, int twtSessionId, int twtReasonCode) {
+ ITwtCallback iTwtCallback = (ITwtCallback) getCallback(cmdId);
+ if (iTwtCallback == null) {
+ // Unsolicited teardown. So get callback from session.
+ iTwtCallback = (ITwtCallback) getCallbackFromSession(twtSessionId);
+ if (iTwtCallback == null) return;
+ }
+ try {
+ iTwtCallback.onTeardown(twtReasonCode);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ }
+ unregisterCallback(cmdId);
+ unregisterSession(twtSessionId);
+ }
+
+ @Override
+ public void onTwtSessionStats(int cmdId, int twtSessionId, Bundle twtStats) {
+ ITwtStatsListener iTwtStatsListener = (ITwtStatsListener) getCallback(cmdId);
+ if (iTwtStatsListener == null) {
+ return;
+ }
+ try {
+ iTwtStatsListener.onResult(twtStats);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ }
+ unregisterCallback(cmdId);
+ }
+ }
+
+ /**
+ * Register for TWT events from WifiNative
+ */
+ public void registerWifiNativeTwtEvents() {
+ mWifiNative.registerTwtCallbacks(mWifiNativeTwtEvents);
+ }
+
+ /**
+ * Get TWT capabilities for the interface
+ *
+ * @param interfaceName Interface name
+ * @param listener listener for TWT capabilities
+ */
+ public void getTwtCapabilities(@Nullable String interfaceName,
+ @NonNull ITwtCapabilitiesListener listener) {
+ try {
+ if (interfaceName == null) {
+ listener.onResult(getDefaultTwtCapabilities());
+ return;
+ }
+ Bundle twtCapabilities = mWifiNative.getTwtCapabilities(interfaceName);
+ if (twtCapabilities == null) twtCapabilities = getDefaultTwtCapabilities();
+ listener.onResult(twtCapabilities);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Sets up a TWT session for the interface
+ *
+ * @param interfaceName Interface name
+ * @param twtRequest TWT request parameters
+ * @param iTwtCallback Callback for the TWT setup command
+ * @param callingUid Caller UID
+ * @param bssid BSSID
+ */
+ public void setupTwtSession(@Nullable String interfaceName, @NonNull TwtRequest twtRequest,
+ @NonNull ITwtCallback iTwtCallback, int callingUid, @NonNull String bssid) {
+ if (isOuiBlockListed(bssid)) {
+ notifyFailure(iTwtCallback, CallbackType.SETUP,
+ TwtSessionCallback.TWT_ERROR_CODE_AP_OUI_BLOCKLISTED);
+ return;
+ }
+ if (!registerInterface(interfaceName)) {
+ notifyFailure(iTwtCallback, CallbackType.SETUP,
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ return;
+ }
+ int id = registerCallback(iTwtCallback, TwtManager.CallbackType.SETUP, callingUid);
+ if (id < 0) {
+ return;
+ }
+ if (!mWifiNative.setupTwtSession(id, interfaceName, twtRequest)) {
+ unregisterCallback(id);
+ notifyFailure(iTwtCallback, CallbackType.SETUP,
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ }
+ }
+
+ private boolean isOuiBlockListed(@NonNull String bssid) {
+ if (mBlockedOuiSet.isEmpty()) return false;
+ byte[] macBytes = MacAddress.fromString(bssid).toByteArray();
+ int oui = (macBytes[0] & 0xFF) << 16 | (macBytes[1] & 0xFF) << 8 | (macBytes[2] & 0xFF);
+ return mBlockedOuiSet.contains(oui);
+ }
+
+ /**
+ * Teardown the TWT session
+ *
+ * @param interfaceName Interface name
+ * @param sessionId TWT session id
+ */
+ public void tearDownTwtSession(@Nullable String interfaceName, int sessionId) {
+ ITwtCallback iTwtCallback = (ITwtCallback) getCallbackFromSession(sessionId);
+ if (iTwtCallback == null) {
+ return;
+ }
+ if (!isRegisteredInterface(interfaceName)) {
+ notifyFailure(iTwtCallback, CallbackType.TEARDOWN,
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ return;
+ }
+ int id = registerCallback(iTwtCallback, TwtManager.CallbackType.TEARDOWN,
+ Binder.getCallingUid());
+ if (id < 0) {
+ return;
+ }
+ if (!mWifiNative.tearDownTwtSession(id, interfaceName, sessionId)) {
+ unregisterCallback(id);
+ notifyFailure(iTwtCallback, CallbackType.TEARDOWN,
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ }
+ }
+
+ /**
+ * Gets stats of the TWT session
+ *
+ * @param interfaceName Interface name
+ * @param iTwtStatsListener Listener for TWT stats
+ * @param sessionId TWT session id
+ */
+ public void getStatsTwtSession(@Nullable String interfaceName,
+ ITwtStatsListener iTwtStatsListener, int sessionId) {
+ if (!isRegisteredInterface(interfaceName)) {
+ notifyFailure(iTwtStatsListener, CallbackType.STATS,
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ return;
+ }
+
+ if (!isSessionRegistered(sessionId)) {
+ notifyFailure(iTwtStatsListener, CallbackType.STATS,
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ return;
+ }
+
+ int id = registerCallback(iTwtStatsListener, TwtManager.CallbackType.STATS,
+ Binder.getCallingUid());
+ if (id < 0) {
+ notifyFailure(iTwtStatsListener, CallbackType.STATS,
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ return;
+ }
+ if (!mWifiNative.getStatsTwtSession(id, interfaceName, sessionId)) {
+ unregisterCallback(id);
+ notifyFailure(iTwtStatsListener, CallbackType.STATS,
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ }
+ }
+
+ private boolean isEmpty() {
+ return (mCommandCallbacks.size() == 0 && mTwtSessionCallbacks.size() == 0);
+ }
+
+ private void reset() {
+ if (isEmpty()) return;
+ stopGarbageCollector();
+ // Notify failure for all pending callbacks
+ for (int i = 0; i < mCommandCallbacks.size(); ++i) {
+ Callback callback = mCommandCallbacks.valueAt(i);
+ if (!mTwtSessionCallbacks.contains(callback.mSessionId)) {
+ // Session cleanup will call Binder#unlinktoDeath()
+ callback.mCallback.asBinder().unlinkToDeath(callback, 0);
+ }
+ notifyFailure(callback.mCallback, callback.mType,
+ TwtSessionCallback.TWT_ERROR_CODE_FAIL);
+ }
+ // Teardown all active sessions
+ for (int i = 0; i < mTwtSessionCallbacks.size(); ++i) {
+ Callback callback = mTwtSessionCallbacks.valueAt(i);
+ callback.mCallback.asBinder().unlinkToDeath(callback, 0);
+ notifyTeardown((ITwtCallback) callback.mCallback,
+ TwtSessionCallback.TWT_REASON_CODE_INTERNALLY_INITIATED);
+ }
+ mCommandCallbacks.clear();
+ mTwtSessionCallbacks.clear();
+ mIdBitSet.clear();
+ unregisterInterface();
+ }
+
+ private void unregisterInterface() {
+ mInterfaceName = null;
+ }
+
+ private boolean registerInterface(String interfaceName) {
+ if (interfaceName == null) return false;
+ if (mInterfaceName == null) {
+ mInterfaceName = interfaceName;
+ return true;
+ }
+ // Check if already registered to the same interface
+ if (interfaceName.equals(mInterfaceName)) {
+ return true;
+ }
+ Log.e(TAG, "Already registered to another interface " + mInterfaceName);
+ return false;
+ }
+
+ private boolean isRegisteredInterface(String interfaceName) {
+ return (interfaceName != null && interfaceName.equals(mInterfaceName));
+ }
+}
diff --git a/service/java/com/android/server/wifi/UntrustedWifiNetworkFactory.java b/service/java/com/android/server/wifi/UntrustedWifiNetworkFactory.java
index d7dda70fd0..85b33aac8f 100644
--- a/service/java/com/android/server/wifi/UntrustedWifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/UntrustedWifiNetworkFactory.java
@@ -16,15 +16,20 @@
package com.android.server.wifi;
+import android.annotation.TargetApi;
import android.content.Context;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkRequest;
+import android.os.Build;
import android.os.Looper;
import android.util.Log;
+import com.android.modules.utils.build.SdkLevel;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Set;
/**
* Network factory to handle untrusted wifi network requests.
@@ -35,15 +40,27 @@ public class UntrustedWifiNetworkFactory extends NetworkFactory {
private final WifiConnectivityManager mWifiConnectivityManager;
private int mConnectionReqCount = 0;
+ private final NetworkCapabilities mCapabilitiesFilter;
public UntrustedWifiNetworkFactory(Looper l, Context c, NetworkCapabilities f,
WifiConnectivityManager connectivityManager) {
super(l, c, TAG, f);
mWifiConnectivityManager = connectivityManager;
-
+ mCapabilitiesFilter = f;
setScoreFilter(SCORE_FILTER);
}
+ // package-private
+ @TargetApi(Build.VERSION_CODES.S)
+ void updateSubIdsInCapabilitiesFilter(Set<Integer> subIds) {
+ if (SdkLevel.isAtLeastS()) {
+ NetworkCapabilities newFilter =
+ new NetworkCapabilities.Builder(mCapabilitiesFilter)
+ .setSubscriptionIds(subIds).build();
+ setCapabilityFilter(newFilter);
+ }
+ }
+
@Override
protected void needNetworkFor(NetworkRequest networkRequest) {
if (!networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)) {
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index b5546a234c..23e8455dbc 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -21,6 +21,8 @@ import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_OWE_TRANSI
import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE;
import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION;
+import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO;
+
import android.annotation.NonNull;
import android.app.compat.CompatChanges;
import android.content.Context;
@@ -85,6 +87,8 @@ public class WifiApConfigStore {
private final WifiConfigManager mWifiConfigManager;
private final ActiveModeWarden mActiveModeWarden;
private final WifiNative mWifiNative;
+ private final HalDeviceManager mHalDeviceManager;
+ private final WifiSettingsConfigStore mWifiSettingsConfigStore;
private boolean mHasNewDataToSerialize = false;
private boolean mForceApChannel = false;
private int mForcedApBand;
@@ -145,6 +149,24 @@ public class WifiApConfigStore {
mMacAddressUtil = wifiInjector.getMacAddressUtil();
mIsAutoAppendLowerBandEnabled = mContext.getResources().getBoolean(
R.bool.config_wifiSoftapAutoAppendLowerBandsToBandConfigurationEnabled);
+ mHalDeviceManager = wifiInjector.getHalDeviceManager();
+ mWifiSettingsConfigStore = wifiInjector.getSettingsConfigStore();
+ mWifiSettingsConfigStore.registerChangeListener(WIFI_STATIC_CHIP_INFO,
+ (key, value) -> {
+ if (mPersistentWifiApConfig != null) {
+ Log.i(TAG, "Chip capability is updated, reset unsupported config");
+ SoftApConfiguration.Builder configBuilder =
+ new SoftApConfiguration.Builder(mPersistentWifiApConfig);
+ if (SdkLevel.isAtLeastS()
+ && mPersistentWifiApConfig.getBands().length > 1) {
+ // Current band setting is dual band, check if device supports it.
+ if (!ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative)) {
+ configBuilder.setBand(generateDefaultBand(mContext));
+ persistConfigAndTriggerBackupManagerProxy(configBuilder.build());
+ }
+ }
+ }
+ }, mHandler);
}
/**
@@ -418,8 +440,11 @@ public class WifiApConfigStore {
// It is new overlay configuration, it should always false in R. Add SdkLevel.isAtLeastS for
// lint check
- if (ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative)) {
- if (SdkLevel.isAtLeastS()) {
+ if (SdkLevel.isAtLeastS()) {
+ boolean isBridgedModeSupported = mHalDeviceManager.isConcurrencyComboLoadedFromDriver()
+ ? ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative)
+ : ApConfigUtil.isBridgedModeSupportedInConfig(mContext);
+ if (isBridgedModeSupported) {
int[] dual_bands = new int[] {
SoftApConfiguration.BAND_2GHZ,
SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ};
diff --git a/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java b/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
index 2d9f91e43d..0eb585fc96 100644
--- a/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
+++ b/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
@@ -93,7 +93,7 @@ class WifiBackupDataV1Parser implements WifiBackupDataParser {
private static final String TAG = "WifiBackupDataV1Parser";
- private static final int HIGHEST_SUPPORTED_MINOR_VERSION = 3;
+ private static final int HIGHEST_SUPPORTED_MINOR_VERSION = 4;
// List of tags supported for <WifiConfiguration> section in minor version 0
private static final Set<String> WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS = Set.of(
@@ -155,8 +155,23 @@ class WifiBackupDataV1Parser implements WifiBackupDataParser {
WifiConfigurationXmlUtil.XML_TAG_NUM_REBOOTS_SINCE_LAST_USE);
}
- // List of tags supported for <IpConfiguration> section in minor version 0 to 3
- private static final Set<String> IP_CONFIGURATION_MINOR_V0_V1_V2_V3_SUPPORTED_TAGS = Set.of(
+ // List of tags supported for <WifiConfiguration> section in minor version 4
+ private static final Set<String> WIFI_CONFIGURATION_MINOR_V4_SUPPORTED_TAGS =
+ new HashSet<String>();
+ static {
+ WIFI_CONFIGURATION_MINOR_V4_SUPPORTED_TAGS.addAll(
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS);
+ WIFI_CONFIGURATION_MINOR_V4_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_ENABLE_WIFI7);
+ WIFI_CONFIGURATION_MINOR_V4_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_IS_REPEATER_ENABLED);
+ WIFI_CONFIGURATION_MINOR_V4_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_SEND_DHCP_HOSTNAME);
+ }
+
+ // List of tags supported for <IpConfiguration> section in last minor version, i.e. version: 4
+ // Note: Update the getSupportedIpConfigurationTags when the minor version is increased.
+ private static final Set<String> IP_CONFIGURATION_LAST_MINOR_SUPPORTED_TAGS = Set.of(
IpConfigurationXmlUtil.XML_TAG_IP_ASSIGNMENT,
IpConfigurationXmlUtil.XML_TAG_LINK_ADDRESS,
IpConfigurationXmlUtil.XML_TAG_LINK_PREFIX_LENGTH,
@@ -315,7 +330,7 @@ class WifiBackupDataV1Parser implements WifiBackupDataParser {
WifiConfiguration configuration = new WifiConfiguration();
String configKeyInData = null;
Set<String> supportedTags = getSupportedWifiConfigurationTags(minorVersion);
-
+ boolean sendDhcpHostnameExists = false;
// Loop through and parse out all the elements from the stream within this section.
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
String tagName = null;
@@ -340,7 +355,6 @@ class WifiBackupDataV1Parser implements WifiBackupDataParser {
+ " section, ignoring.");
continue;
}
-
// note: the below switch case list should contain all tags supported up until the
// highest minor version supported by this parser
switch (tagName) {
@@ -404,12 +418,29 @@ class WifiBackupDataV1Parser implements WifiBackupDataParser {
case WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS_LIST:
parseSecurityParamsListFromXml(in, outerTagDepth + 1, configuration);
break;
+ // V4
+ case WifiConfigurationXmlUtil.XML_TAG_IS_REPEATER_ENABLED:
+ configuration.setRepeaterEnabled((boolean) value);
+ break;
+ case WifiConfigurationXmlUtil.XML_TAG_ENABLE_WIFI7:
+ configuration.setWifi7Enabled((boolean) value);
+ break;
+ case WifiConfigurationXmlUtil.XML_TAG_SEND_DHCP_HOSTNAME:
+ configuration.setSendDhcpHostnameEnabled((boolean) value);
+ sendDhcpHostnameExists = true;
+ break;
default:
// should never happen, since other tags are filtered out earlier
throw new XmlPullParserException(
"Unknown value name found: " + tagName);
}
}
+ if (!sendDhcpHostnameExists) {
+ // Update legacy configs to send the DHCP hostname for secure networks only.
+ configuration.setSendDhcpHostnameEnabled(
+ !configuration.isSecurityType(WifiConfiguration.SECURITY_TYPE_OPEN)
+ && !configuration.isSecurityType(WifiConfiguration.SECURITY_TYPE_OWE));
+ }
clearAnyKnownIssuesInParsedConfiguration(configuration);
return Pair.create(configKeyInData, configuration);
}
@@ -432,6 +463,8 @@ class WifiBackupDataV1Parser implements WifiBackupDataParser {
return WIFI_CONFIGURATION_MINOR_V2_SUPPORTED_TAGS;
case 3:
return WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS;
+ case 4:
+ return WIFI_CONFIGURATION_MINOR_V4_SUPPORTED_TAGS;
default:
Log.e(TAG, "Invalid minorVersion: " + minorVersion);
return Collections.<String>emptySet();
@@ -717,7 +750,8 @@ class WifiBackupDataV1Parser implements WifiBackupDataParser {
case 1:
case 2:
case 3:
- return IP_CONFIGURATION_MINOR_V0_V1_V2_V3_SUPPORTED_TAGS;
+ case 4:
+ return IP_CONFIGURATION_LAST_MINOR_SUPPORTED_TAGS;
default:
Log.e(TAG, "Invalid minorVersion: " + minorVersion);
return Collections.<String>emptySet();
diff --git a/service/java/com/android/server/wifi/WifiBlocklistMonitor.java b/service/java/com/android/server/wifi/WifiBlocklistMonitor.java
index adf313da24..c701caba64 100644
--- a/service/java/com/android/server/wifi/WifiBlocklistMonitor.java
+++ b/service/java/com/android/server/wifi/WifiBlocklistMonitor.java
@@ -279,12 +279,14 @@ public class WifiBlocklistMonitor {
*/
private long getBlocklistDurationWithExponentialBackoff(int failureStreak,
int baseBlocklistDurationMs) {
+ long disableDurationMs = baseBlocklistDurationMs;
failureStreak = Math.min(failureStreak, mContext.getResources().getInteger(
R.integer.config_wifiBssidBlocklistMonitorFailureStreakCap));
- if (failureStreak < 1) {
- return baseBlocklistDurationMs;
+ if (failureStreak >= 1) {
+ disableDurationMs =
+ (long) (Math.pow(2.0, (double) failureStreak) * baseBlocklistDurationMs);
}
- return (long) (Math.pow(2.0, (double) failureStreak) * baseBlocklistDurationMs);
+ return Math.min(disableDurationMs, mWifiGlobals.getWifiConfigMaxDisableDurationMs());
}
/**
@@ -1391,7 +1393,8 @@ public class WifiBlocklistMonitor {
break;
}
}
- return mClock.getElapsedSinceBootMillis() + disableDurationMs;
+ return mClock.getElapsedSinceBootMillis() + Math.min(
+ disableDurationMs, mWifiGlobals.getWifiConfigMaxDisableDurationMs());
}
/**
diff --git a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
index b83896d826..e770ae23a9 100644
--- a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
+++ b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
@@ -55,6 +55,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.Base64;
import android.util.Log;
import android.util.Pair;
@@ -499,11 +500,33 @@ public class WifiCarrierInfoManager {
ACTION_USER_DISALLOWED_CARRIER, mIsLastUserApprovalUiDialog);
}
+ private void updateSubIdsInNetworkFactoryFilters(List<SubscriptionInfo> activeSubInfos) {
+ if (activeSubInfos == null || activeSubInfos.isEmpty()) {
+ return;
+ }
+ Set<Integer> subIds = new ArraySet<>();
+ for (SubscriptionInfo subInfo : activeSubInfos) {
+ if (subInfo.getSubscriptionId() != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ subIds.add(subInfo.getSubscriptionId());
+ }
+ }
+ if (mWifiInjector.getWifiNetworkFactory() != null) {
+ mWifiInjector.getWifiNetworkFactory().updateSubIdsInCapabilitiesFilter(subIds);
+ }
+ if (mWifiInjector.getUntrustedWifiNetworkFactory() != null) {
+ mWifiInjector.getUntrustedWifiNetworkFactory().updateSubIdsInCapabilitiesFilter(subIds);
+ }
+ if (mWifiInjector.getRestrictedWifiNetworkFactory() != null) {
+ mWifiInjector.getRestrictedWifiNetworkFactory()
+ .updateSubIdsInCapabilitiesFilter(subIds);
+ }
+ }
private class SubscriptionChangeListener extends
SubscriptionManager.OnSubscriptionsChangedListener {
@Override
public void onSubscriptionsChanged() {
mActiveSubInfos = mSubscriptionManager.getCompleteActiveSubscriptionInfoList();
+ updateSubIdsInNetworkFactoryFilters(mActiveSubInfos);
mSubIdToSimInfoSparseArray.clear();
mSubscriptionGroupMap.clear();
if (mVerboseLogEnabled) {
@@ -1522,22 +1545,26 @@ public class WifiCarrierInfoManager {
Log.v(TAG, "Raw Response - " + tmResponse);
}
- boolean goodReponse = false;
+ boolean goodResponse = false;
if (tmResponse != null && tmResponse.length() > 4) {
byte[] result = Base64.decode(tmResponse, Base64.DEFAULT);
Log.e(TAG, "Hex Response - " + makeHex(result));
byte tag = result[0];
if (tag == (byte) 0xdb) {
Log.v(TAG, "successful 3G authentication ");
- int resLen = result[1];
- String res = makeHex(result, 2, resLen);
- int ckLen = result[resLen + 2];
- String ck = makeHex(result, resLen + 3, ckLen);
- int ikLen = result[resLen + ckLen + 3];
- String ik = makeHex(result, resLen + ckLen + 4, ikLen);
- sb.append(":" + ik + ":" + ck + ":" + res);
- Log.v(TAG, "ik:" + ik + "ck:" + ck + " res:" + res);
- goodReponse = true;
+ try {
+ int resLen = result[1];
+ String res = makeHex(result, 2, resLen);
+ int ckLen = result[resLen + 2];
+ String ck = makeHex(result, resLen + 3, ckLen);
+ int ikLen = result[resLen + ckLen + 3];
+ String ik = makeHex(result, resLen + ckLen + 4, ikLen);
+ sb.append(":" + ik + ":" + ck + ":" + res);
+ Log.v(TAG, "ik:" + ik + "ck:" + ck + " res:" + res);
+ goodResponse = true;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ Log.e(TAG, "ArrayIndexOutOfBoundsException in get3GAuthResponse: " + e);
+ }
} else if (tag == (byte) 0xdc) {
Log.e(TAG, "synchronisation failure");
int autsLen = result[1];
@@ -1545,7 +1572,7 @@ public class WifiCarrierInfoManager {
resType = WifiNative.SIM_AUTH_RESP_TYPE_UMTS_AUTS;
sb.append(":" + auts);
Log.v(TAG, "auts:" + auts);
- goodReponse = true;
+ goodResponse = true;
} else {
Log.e(TAG, "bad response - unknown tag = " + tag);
}
@@ -1553,7 +1580,7 @@ public class WifiCarrierInfoManager {
Log.e(TAG, "bad response - " + tmResponse);
}
- if (goodReponse) {
+ if (goodResponse) {
String response = sb.toString();
Log.v(TAG, "Supplicant Response -" + response);
return new SimAuthResponseData(resType, response);
@@ -1768,7 +1795,7 @@ public class WifiCarrierInfoManager {
return;
}
- Log.d(TAG, msg);
+ Log.d(TAG, msg, null);
}
/** Dump state. */
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index ec6359f900..d2f26183c3 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -61,6 +61,7 @@ import android.util.Log;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.MacAddressUtils;
import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent;
@@ -810,6 +811,20 @@ public class WifiConfigManager {
}
/**
+ * Check Wi-Fi 7 is enabled for this network.
+ *
+ * @param networkId networkId of the requested network.
+ * @return true if Wi-Fi 7 is enabled for this network, false otherwise.
+ */
+ public boolean isWifi7Enabled(int networkId) {
+ WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+ if (config == null) {
+ return false;
+ }
+ return config.isWifi7Enabled();
+ }
+
+ /**
* Retrieves the configured network corresponding to the provided networkId with password
* masked.
*
@@ -1272,6 +1287,8 @@ public class WifiConfigManager {
externalConfig.getNetworkSelectionStatus().getConnectChoiceRssi());
internalConfig.setBssidAllowlist(externalConfig.getBssidAllowlistInternal());
internalConfig.setRepeaterEnabled(externalConfig.isRepeaterEnabled());
+ internalConfig.setSendDhcpHostnameEnabled(externalConfig.isSendDhcpHostnameEnabled());
+ internalConfig.setWifi7Enabled(externalConfig.isWifi7Enabled());
}
/**
@@ -1514,6 +1531,17 @@ public class WifiConfigManager {
existingInternalConfig);
}
+ if (WifiConfigurationUtil.hasSendDhcpHostnameEnabledChanged(existingInternalConfig,
+ newInternalConfig) && !mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
+ && !mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)) {
+ Log.e(TAG, "UID " + uid + " does not have permission to modify send DHCP hostname "
+ + "setting " + config.getProfileKey() + ". Must have "
+ + "NETWORK_SETTINGS or NETWORK_SETUP_WIZARD.");
+ return new Pair<>(
+ new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID),
+ existingInternalConfig);
+ }
+
if (config.isEnterprise()
&& config.enterpriseConfig.isEapMethodServerCertUsed()
&& !config.enterpriseConfig.isMandatoryParameterSetForServerCertValidation()
@@ -1662,6 +1690,12 @@ public class WifiConfigManager {
Log.e(TAG, "Cannot add/update network with null config");
return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
}
+ if (SdkLevel.isAtLeastV() && config.getVendorData() != null
+ && !config.getVendorData().isEmpty()
+ && !mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(uid)) {
+ Log.e(TAG, "UID " + uid + " does not have permission to include vendor data");
+ return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
+ }
if (mPendingStoreRead) {
Log.e(TAG, "Cannot add/update network before store is read!");
return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
@@ -4083,9 +4117,10 @@ public class WifiConfigManager {
}
/** Update WifiConfigManager before connecting to a network. */
- public void updateBeforeConnect(int networkId, int callingUid, @NonNull String packageName) {
+ public void updateBeforeConnect(int networkId, int callingUid, @NonNull String packageName,
+ boolean disableOthers) {
userEnabledNetwork(networkId);
- if (!enableNetwork(networkId, true, callingUid, null)
+ if (!enableNetwork(networkId, disableOthers, callingUid, null)
|| !updateLastConnectUid(networkId, callingUid)) {
Log.i(TAG, "connect Allowing uid " + callingUid + " packageName " + packageName
+ " with insufficient permissions to connect=" + networkId);
@@ -4397,12 +4432,11 @@ public class WifiConfigManager {
Log.d(TAG, "Set altSubjectMatch to " + altSubjectNames);
}
newConfig.enterpriseConfig.setAltSubjectMatch(altSubjectNames);
- } else {
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "Set domainSuffixMatch to " + serverCertInfo.commonName);
- }
- newConfig.enterpriseConfig.setDomainSuffixMatch(serverCertInfo.commonName);
}
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "Set domainSuffixMatch to " + serverCertInfo.commonName);
+ }
+ newConfig.enterpriseConfig.setDomainSuffixMatch(serverCertInfo.commonName);
newConfig.enterpriseConfig.setUserApproveNoCaCert(false);
// Trigger an update to install CA certificate and the corresponding configuration.
NetworkUpdateResult result = addOrUpdateNetwork(newConfig, internalConfig.creatorUid);
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index a1bfb7a9cb..3d14b8a002 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -259,7 +259,7 @@ public class WifiConfigurationUtil {
* MAC randomization setting has changed or not.
* @param existingConfig Existing WifiConfiguration object corresponding to the network.
* @param newConfig New WifiConfiguration object corresponding to the network.
- * @return true if MAC randomization setting setting changed or the existing confiuration is
+ * @return true if MAC randomization setting changed or the existing configuration is
* null and the newConfig is setting macRandomizationSetting to the default value.
*/
public static boolean hasMacRandomizationSettingsChanged(WifiConfiguration existingConfig,
@@ -271,6 +271,22 @@ public class WifiConfigurationUtil {
}
/**
+ * Compare existing and new WifiConfiguration objects after a network update and return if
+ * DHCP hostname setting has changed or not.
+ * @param existingConfig Existing WifiConfiguration object corresponding to the network.
+ * @param newConfig New WifiConfiguration object corresponding to the network.
+ * @return true if DHCP hostname setting changed or the existing configuration is
+ * null and the newConfig is setting the DHCP hostname setting to the default value.
+ */
+ public static boolean hasSendDhcpHostnameEnabledChanged(WifiConfiguration existingConfig,
+ WifiConfiguration newConfig) {
+ if (existingConfig == null) {
+ return !newConfig.isSendDhcpHostnameEnabled();
+ }
+ return newConfig.isSendDhcpHostnameEnabled() != existingConfig.isSendDhcpHostnameEnabled();
+ }
+
+ /**
* Compare existing and new WifiEnterpriseConfig objects after a network update and return if
* credential parameters have changed or not.
*
@@ -957,6 +973,9 @@ public class WifiConfigurationUtil {
if (WifiConfigurationUtil.hasCredentialChanged(config, config1)) {
return false;
}
+ if (config.isWifi7Enabled() != config1.isWifi7Enabled()) {
+ return false;
+ }
return true;
}
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 574b0b08b6..86483bdfbf 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -268,7 +268,7 @@ public class WifiConnectivityManager {
// be retrieved in bugreport.
private void localLog(String log) {
mLocalLog.log(log);
- if (mVerboseLoggingEnabled) Log.v(TAG, log);
+ if (mVerboseLoggingEnabled) Log.v(TAG, log, null);
}
/**
@@ -402,7 +402,8 @@ public class WifiConnectivityManager {
// a different band with the primary.
return false;
}
- if (WifiInjector.getInstance().getHalDeviceManager()
+ if (mActiveModeWarden.getClientModeManagerInRole(ROLE_CLIENT_SECONDARY_LONG_LIVED)
+ == null && WifiInjector.getInstance().getHalDeviceManager()
.creatingIfaceWillDeletePrivilegedIface(HalDeviceManager.HDM_CREATE_IFACE_STA,
mMultiInternetConnectionRequestorWs)) {
localLog(listenerName + ": No secondary cmm candidate");
@@ -543,6 +544,47 @@ public class WifiConnectivityManager {
return true;
}
+ private boolean shouldSkipSufficiencyCheck(boolean hasExistingSecondaryCmm) {
+ if (hasExistingSecondaryCmm) {
+ // Secondary CMM already exists. NetworkSelector will evaluate if network selection
+ // should proceed
+ return false;
+ }
+
+ // Otherwise check the various secondary use-cases. Network selection should be triggered
+ // if any secondary use-case is available.
+ if (mOemPaidConnectionAllowed || mOemPrivateConnectionAllowed) {
+ // prefer OEM PAID requestor if it exists.
+ WorkSource oemPaidOrOemPrivateRequestorWs =
+ mOemPaidConnectionRequestorWs != null
+ ? mOemPaidConnectionRequestorWs
+ : mOemPrivateConnectionRequestorWs;
+ if (oemPaidOrOemPrivateRequestorWs == null) {
+ Log.e(TAG, "Both mOemPaidConnectionRequestorWs & mOemPrivateConnectionRequestorWs "
+ + "are null!");
+ }
+ if (oemPaidOrOemPrivateRequestorWs != null
+ && mActiveModeWarden.canRequestMoreClientModeManagersInRole(
+ oemPaidOrOemPrivateRequestorWs,
+ ROLE_CLIENT_SECONDARY_LONG_LIVED, false)) {
+ return true;
+ }
+ }
+ if (isMultiInternetConnectionRequested()) {
+ if (mMultiInternetConnectionRequestorWs == null) {
+ Log.e(TAG, "mMultiInternetConnectionRequestorWs is null!");
+ } else if (mActiveModeWarden.canRequestMoreClientModeManagersInRole(
+ mMultiInternetConnectionRequestorWs, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)) {
+ return true;
+ }
+ }
+ if (mActiveModeWarden.canRequestMoreClientModeManagersInRole(
+ ActiveModeWarden.INTERNAL_REQUESTOR_WS, ROLE_CLIENT_SECONDARY_TRANSIENT, false)) {
+ return true;
+ }
+ return false;
+ }
+
/**
* Handles 'onResult' callbacks for the Periodic, Single & Pno ScanListener.
* Executes selection of potential network candidates, initiation of connection attempt to that
@@ -582,40 +624,7 @@ public class WifiConnectivityManager {
}
cmmStates.add(cmmState);
}
- // We don't have any existing secondary CMM, but are we allowed to create a secondary CMM
- // and do we have a request for OEM_PAID/OEM_PRIVATE request? If yes, we need to perform
- // network selection to check if we have any potential candidate for the secondary CMM
- // creation.
- if (!hasExistingSecondaryCmm
- && (mOemPaidConnectionAllowed || mOemPrivateConnectionAllowed)) {
- // prefer OEM PAID requestor if it exists.
- WorkSource oemPaidOrOemPrivateRequestorWs =
- mOemPaidConnectionRequestorWs != null
- ? mOemPaidConnectionRequestorWs
- : mOemPrivateConnectionRequestorWs;
- if (oemPaidOrOemPrivateRequestorWs == null) {
- Log.e(TAG, "Both mOemPaidConnectionRequestorWs & mOemPrivateConnectionRequestorWs "
- + "are null!");
- }
- if (oemPaidOrOemPrivateRequestorWs != null
- && mActiveModeWarden.canRequestMoreClientModeManagersInRole(
- oemPaidOrOemPrivateRequestorWs,
- ROLE_CLIENT_SECONDARY_LONG_LIVED, false)) {
- // Add a placeholder CMM state to ensure network selection is performed for a
- // potential second STA creation.
- cmmStates.add(new WifiNetworkSelector.ClientModeManagerState());
- hasExistingSecondaryCmm = true;
- }
- }
- // If secondary cmm has not been created and need to connect secondary internet
- if (!hasExistingSecondaryCmm && isMultiInternetConnectionRequested()) {
- if (mMultiInternetConnectionRequestorWs == null) {
- Log.e(TAG, "mMultiInternetConnectionRequestorWs is null!");
- } else if (mActiveModeWarden.canRequestMoreClientModeManagersInRole(
- mMultiInternetConnectionRequestorWs, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)) {
- cmmStates.add(new WifiNetworkSelector.ClientModeManagerState());
- }
- }
+ boolean skipSufficiencyCheck = shouldSkipSufficiencyCheck(hasExistingSecondaryCmm);
// Check if any blocklisted BSSIDs can be freed.
List<ScanDetail> enabledDetails =
@@ -638,7 +647,7 @@ public class WifiConnectivityManager {
List<WifiCandidates.Candidate> candidates = mNetworkSelector.getCandidatesFromScan(
scanDetails, bssidBlocklist, cmmStates, mUntrustedConnectionAllowed,
mOemPaidConnectionAllowed, mOemPrivateConnectionAllowed,
- mRestrictedConnectionAllowedUids, isMultiInternetConnectionRequested());
+ mRestrictedConnectionAllowedUids, skipSufficiencyCheck);
mLatestCandidates = candidates;
mLatestCandidatesTimestampMs = mClock.getElapsedSinceBootMillis();
diff --git a/service/java/com/android/server/wifi/WifiCountryCode.java b/service/java/com/android/server/wifi/WifiCountryCode.java
index cad634aa67..46c23937c9 100644
--- a/service/java/com/android/server/wifi/WifiCountryCode.java
+++ b/service/java/com/android/server/wifi/WifiCountryCode.java
@@ -61,6 +61,9 @@ public class WifiCountryCode {
private static final String BOOT_DEFAULT_WIFI_COUNTRY_CODE = "ro.boot.wificountrycode";
private static final int PKT_COUNT_HIGH_PKT_PER_SEC = 16;
private static final int DISCONNECT_WIFI_COUNT_MAX = 1;
+ /* TODO: replace with PackageManager.FEATURE_TELEPHONY_CALLING once
+ * wifi-module-sdk-version-defaults min_sdk_version bumps to API 33. */
+ private static final String FEATURE_TELEPHONY_CALLING = "android.hardware.telephony.calling";
static final int MIN_COUNTRY_CODE_COUNT_US = 3;
static final int MIN_COUNTRY_CODE_COUNT_OTHER = 2;
static final String COUNTRY_CODE_US = "US";
@@ -77,6 +80,7 @@ public class WifiCountryCode {
private final WifiPermissionsUtil mWifiPermissionsUtil;
private List<ChangeListener> mListeners = new ArrayList<>();
private boolean mVerboseLoggingEnabled = false;
+ private boolean mIsCountryCodePendingToUpdateToCmm = true; // default to true for first update.
/**
* Map of active ClientModeManager instance to whether it is ready for country code change.
*
@@ -301,6 +305,15 @@ public class WifiCountryCode {
mVerboseLoggingEnabled = verbose;
}
+ private boolean hasCalling() {
+ return mContext.getPackageManager().hasSystemFeature(FEATURE_TELEPHONY_CALLING);
+ }
+
+ /**
+ * Check if Wi-Fi calling is available.
+ *
+ * This method can only be called if device has calling feature (see hasCalling()).
+ */
private boolean isWifiCallingAvailable() {
SubscriptionManager subscriptionManager =
mContext.getSystemService(SubscriptionManager.class);
@@ -364,7 +377,7 @@ public class WifiCountryCode {
*/
private void evaluateAllCmmStateAndApplyIfAllReady() {
Log.d(TAG, "evaluateAllCmmStateAndApplyIfAllReady: " + mAmmToReadyForChangeMap);
- if (isAllCmmReady()) {
+ if (isAllCmmReady() && mIsCountryCodePendingToUpdateToCmm) {
mAllCmmReadyTimestamp = FORMATTER.format(new Date(mClock.getWallClockMillis()));
// We are ready to set country code now.
// We need to post pending country code request.
@@ -534,7 +547,7 @@ public class WifiCountryCode {
}
private boolean shouldDisconnectWifiToForceUpdate() {
- if (isWifiCallingAvailable()) {
+ if (!hasCalling() || isWifiCallingAvailable()) {
return false;
}
@@ -699,8 +712,12 @@ public class WifiCountryCode {
Log.d(TAG, "setCountryCodeNative: " + country + ", isClientModeOnly: " + isClientModeOnly
+ " mDriverCountryCode: " + mDriverCountryCode);
for (ActiveModeManager am : amms) {
- if (isNeedToUpdateCCToSta && !isConcreteClientModeManagerUpdated
+ if (!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
@@ -731,7 +748,7 @@ public class WifiCountryCode {
SoftApModeConfiguration modeConfig = sm.getSoftApModeConfiguration();
SoftApModeConfiguration newModeConfig = new SoftApModeConfiguration(
modeConfig.getTargetMode(), modeConfig.getSoftApConfiguration(),
- modeConfig.getCapability(), country);
+ modeConfig.getCapability(), country, modeConfig.getTetheringRequest());
mActiveModeWarden.stopSoftAp(modeConfig.getTargetMode());
mActiveModeWarden.startSoftAp(newModeConfig, sm.getRequestorWs());
} else {
@@ -768,6 +785,9 @@ public class WifiCountryCode {
mDriverCountryCode = country;
mWifiP2pMetrics.setIsCountryCodeWorldMode(isDriverCountryCodeWorldMode());
notifyListener(country);
+ if (country == null) {
+ mIsCountryCodePendingToUpdateToCmm = true;
+ }
}
/**
diff --git a/service/java/com/android/server/wifi/WifiDataStall.java b/service/java/com/android/server/wifi/WifiDataStall.java
index 85d40760c2..64e370bd9e 100644
--- a/service/java/com/android/server/wifi/WifiDataStall.java
+++ b/service/java/com/android/server/wifi/WifiDataStall.java
@@ -595,7 +595,7 @@ public class WifiDataStall {
private void logd(String string) {
if (mVerboseLoggingEnabled) {
- Log.d(TAG, string);
+ Log.d(TAG, string, null);
}
}
}
diff --git a/service/java/com/android/server/wifi/WifiDialogManager.java b/service/java/com/android/server/wifi/WifiDialogManager.java
index b7a0c40a48..c189590ef6 100644
--- a/service/java/com/android/server/wifi/WifiDialogManager.java
+++ b/service/java/com/android/server/wifi/WifiDialogManager.java
@@ -90,17 +90,7 @@ public class WifiDialogManager {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Received action: " + action);
}
- if (Intent.ACTION_SCREEN_OFF.equals(action)) {
- // Change all window types to TYPE_APPLICATION_OVERLAY to
- // prevent the dialogs from appearing over the lock screen when
- // the screen turns on again.
- for (LegacySimpleDialogHandle dialogHandle :
- mActiveLegacySimpleDialogs) {
- dialogHandle.changeWindowType(
- WindowManager.LayoutParams
- .TYPE_APPLICATION_OVERLAY);
- }
- } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
+ if (Intent.ACTION_USER_PRESENT.equals(action)) {
// Change all window types to TYPE_KEYGUARD_DIALOG to show the
// dialogs over the QuickSettings after the screen is unlocked.
for (LegacySimpleDialogHandle dialogHandle :
@@ -139,12 +129,11 @@ public class WifiDialogManager {
public WifiDialogManager(
@NonNull WifiContext context,
@NonNull WifiThreadRunner wifiThreadRunner,
- @NonNull FrameworkFacade frameworkFacade) {
+ @NonNull FrameworkFacade frameworkFacade, WifiInjector wifiInjector) {
mContext = context;
mWifiThreadRunner = wifiThreadRunner;
mFrameworkFacade = frameworkFacade;
IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_USER_PRESENT);
intentFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
int flags = 0;
@@ -152,6 +141,34 @@ public class WifiDialogManager {
flags = Context.RECEIVER_EXPORTED;
}
mContext.registerReceiver(mBroadcastReceiver, intentFilter, flags);
+ wifiInjector.getWifiDeviceStateChangeManager()
+ .registerStateChangeCallback(
+ new WifiDeviceStateChangeManager.StateChangeCallback() {
+ @Override
+ public void onScreenStateChanged(boolean screenOn) {
+ handleScreenStateChanged(screenOn);
+ }
+ });
+ }
+
+ private void handleScreenStateChanged(boolean screenOn) {
+ // Change all window types to TYPE_APPLICATION_OVERLAY to
+ // prevent the dialogs from appearing over the lock screen when
+ // the screen turns on again.
+ if (!screenOn) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "onScreenStateChanged: screen off");
+ }
+ // Change all window types to TYPE_APPLICATION_OVERLAY to
+ // prevent the dialogs from appearing over the lock screen when
+ // the screen turns on again.
+ for (LegacySimpleDialogHandle dialogHandle :
+ mActiveLegacySimpleDialogs) {
+ dialogHandle.changeWindowType(
+ WindowManager.LayoutParams
+ .TYPE_APPLICATION_OVERLAY);
+ }
+ }
}
/**
diff --git a/service/java/com/android/server/wifi/WifiGlobals.java b/service/java/com/android/server/wifi/WifiGlobals.java
index b6cc4153e6..454d8c25c7 100644
--- a/service/java/com/android/server/wifi/WifiGlobals.java
+++ b/service/java/com/android/server/wifi/WifiGlobals.java
@@ -55,10 +55,12 @@ public class WifiGlobals {
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 final boolean mIsWpa3SaeUpgradeOffloadEnabled;
+ private boolean mIsWpa3SaeUpgradeOffloadEnabled;
private final boolean mIsOweUpgradeEnabled;
private final boolean mFlushAnqpCacheOnWifiToggleOffEvent;
private final boolean mIsWpa3SaeH2eSupported;
@@ -76,10 +78,13 @@ public class WifiGlobals {
private final int mClientRssiMonitorHysteresisDb;
private boolean mDisableFirmwareRoamingInIdleMode = false;
private final boolean mIsSupportMultiInternetDual5G;
+ private final int mRepeatedNudFailuresThreshold;
+ private final int mRepeatedNudFailuresWindowMs;
private final boolean mAdjustPollRssiIntervalEnabled;
private final boolean mWifiInterfaceAddedSelfRecoveryEnabled;
private final int mNetworkNotFoundEventThreshold;
private boolean mIsBackgroundScanSupported;
+ private boolean mIsSwPnoEnabled;
private final boolean mIsWepDeprecated;
private final boolean mIsWpaPersonalDeprecated;
private final Map<String, List<String>> mCountryCodeToAfcServers;
@@ -90,6 +95,7 @@ public class WifiGlobals {
private boolean mDisableUnwantedNetworkOnLowRssi = false;
private final boolean mIsAfcSupportedOnDevice;
private boolean mDisableNudDisconnectsForWapiInSpecificCc = false;
+ private boolean mD2dAllowedControlSupportedWhenInfraStaDisabled = false;
private Set<String> mMacRandomizationUnsupportedSsidPrefixes = new ArraySet<>();
private Map<String, BiFunction<String, Boolean, Boolean>> mOverrideMethods = new HashMap<>();
@@ -142,6 +148,10 @@ public class WifiGlobals {
.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(
@@ -152,6 +162,8 @@ public class WifiGlobals {
R.integer.config_wifiNetworkNotFoundEventThreshold);
mIsBackgroundScanSupported = mContext.getResources()
.getBoolean(R.bool.config_wifi_background_scan_support);
+ mIsSwPnoEnabled = mContext.getResources()
+ .getBoolean(R.bool.config_wifiSwPnoEnabled);
mIsWepDeprecated = mContext.getResources()
.getBoolean(R.bool.config_wifiWepDeprecated);
mIsWpaPersonalDeprecated = mContext.getResources()
@@ -161,6 +173,8 @@ public class WifiGlobals {
&& 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(
R.array.config_wifiForceDisableMacRandomizationSsidPrefixList));
mCountryCodeToAfcServers = getCountryCodeToAfcServersMap();
@@ -389,6 +403,20 @@ public class WifiGlobals {
}
/**
+ * Get number of repeated NUD failures needed to disable a network.
+ */
+ public int getRepeatedNudFailuresThreshold() {
+ return mRepeatedNudFailuresThreshold;
+ }
+
+ /**
+ * Get the time window in millis to count for repeated NUD failures.
+ */
+ public int getRepeatedNudFailuresWindowMs() {
+ return mRepeatedNudFailuresWindowMs;
+ }
+
+ /**
* Helper method to check if the device may not connect to the configuration
* due to deprecated security type
*/
@@ -424,6 +452,16 @@ public class WifiGlobals {
}
/**
+ * Helper method to enable WPA3 SAE auto-upgrade offload based on the device capability for
+ * CROSS-AKM support.
+ */
+ public void setWpa3SaeUpgradeOffloadEnabled() {
+ Log.d(TAG, "Device supports CROSS-AKM feature - Enable WPA3 SAE auto-upgrade offload");
+ mIsWpa3SaeUpgradeOffloadEnabled = true;
+ }
+
+
+ /**
* Help method to check if OWE auto-upgrade is enabled.
*
* @return boolean true if auto-upgrade is enabled, false otherwise.
@@ -573,6 +611,13 @@ public class WifiGlobals {
};
/**
+ * Get whether software pno is enabled.
+ */
+ public boolean isSwPnoEnabled() {
+ return mIsSwPnoEnabled;
+ };
+
+ /**
* Get whether to temporarily disable a unwanted network that has low RSSI.
*/
public boolean disableUnwantedNetworkOnLowRssi() {
@@ -608,6 +653,37 @@ public class WifiGlobals {
}
/**
+ * Set whether the device supports device-to-device + STA concurrency.
+ */
+ public void setD2dStaConcurrencySupported(boolean isSupported) {
+ mIsD2dStaConcurrencySupported.set(isSupported);
+ }
+
+ /**
+ * Returns whether the device supports device-to-device when infra STA is disabled.
+ */
+ public boolean isD2dSupportedWhenInfraStaDisabled() {
+ return mD2dAllowedControlSupportedWhenInfraStaDisabled
+ && !mIsD2dStaConcurrencySupported.get();
+ }
+
+ /**
+ * Set the global dhcp hostname restriction.
+ */
+ public void setSendDhcpHostnameRestriction(
+ @WifiManager.SendDhcpHostnameRestriction int restriction) {
+ mSendDhcpHostnameRestriction.set(restriction);
+ }
+
+ /**
+ * Get the global dhcp hostname restriction.
+ */
+ @WifiManager.SendDhcpHostnameRestriction
+ public int getSendDhcpHostnameRestriction() {
+ return mSendDhcpHostnameRestriction.get();
+ }
+
+ /**
* Get the maximum Wifi temporary disable duration.
*/
public long getWifiConfigMaxDisableDurationMs() {
@@ -654,12 +730,19 @@ public class WifiGlobals {
pw.println("mDisableUnwantedNetworkOnLowRssi=" + mDisableUnwantedNetworkOnLowRssi);
pw.println("mNetworkNotFoundEventThreshold=" + mNetworkNotFoundEventThreshold);
pw.println("mIsBackgroundScanSupported=" + mIsBackgroundScanSupported);
+ pw.println("mIsSwPnoEnabled=" + mIsSwPnoEnabled);
pw.println("mIsWepDeprecated=" + mIsWepDeprecated);
pw.println("mIsWpaPersonalDeprecated=" + mIsWpaPersonalDeprecated);
pw.println("mIsWepAllowed=" + mIsWepAllowed.get());
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());
for (int i = 0; i < mCarrierSpecificEapFailureConfigMapPerCarrierId.size(); i++) {
int carrierId = mCarrierSpecificEapFailureConfigMapPerCarrierId.keyAt(i);
SparseArray<CarrierSpecificEapFailureConfig> perFailureMap =
@@ -674,5 +757,6 @@ public class WifiGlobals {
}
}
pw.println("mIsSupportMultiInternetDual5G=" + mIsSupportMultiInternetDual5G);
+ pw.println("mSendDhcpHostnameRestriction=" + mSendDhcpHostnameRestriction.get());
}
}
diff --git a/service/java/com/android/server/wifi/WifiHealthMonitor.java b/service/java/com/android/server/wifi/WifiHealthMonitor.java
index 7c26902f00..9ed1491f83 100644
--- a/service/java/com/android/server/wifi/WifiHealthMonitor.java
+++ b/service/java/com/android/server/wifi/WifiHealthMonitor.java
@@ -319,7 +319,7 @@ public class WifiHealthMonitor {
}
private void setPostBootDetectionAlarm() {
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
mClock.getElapsedSinceBootMillis() + POST_BOOT_DETECTION_WAIT_TIME_MS,
POST_BOOT_DETECTION_TIMER_TAG,
mPostBootDetectionListener, mHandler);
@@ -1026,7 +1026,7 @@ public class WifiHealthMonitor {
private void logd(String string) {
if (mVerboseLoggingEnabled) {
- Log.d(TAG, string);
+ Log.d(TAG, string, null);
}
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 889c935f06..ff699bbc57 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -33,6 +33,7 @@ import android.net.NetworkCapabilities;
import android.net.NetworkProvider;
import android.net.wifi.WifiContext;
import android.net.wifi.WifiScanner;
+import android.net.wifi.WifiTwtSession;
import android.net.wifi.nl80211.WifiNl80211Manager;
import android.os.BatteryManager;
import android.os.BatteryStatsManager;
@@ -54,6 +55,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.BackgroundThread;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.aware.WifiAwareMetrics;
+import com.android.server.wifi.b2b.WifiRoamingModeManager;
import com.android.server.wifi.coex.CoexManager;
import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.hotspot2.PasspointNetworkNominateHelper;
@@ -183,9 +185,11 @@ public class WifiInjector {
private final PropertyService mPropertyService = new SystemPropertyService();
private final BuildProperties mBuildProperties = new SystemBuildProperties();
private final WifiBackupRestore mWifiBackupRestore;
+ private final BackupRestoreController mBackupRestoreController;
// This will only be null if SdkLevel is not at least S
@Nullable private final CoexManager mCoexManager;
private final SoftApBackupRestore mSoftApBackupRestore;
+ private final WifiSettingsBackupRestore mWifiSettingsBackupRestore;
private final WifiMulticastLockManager mWifiMulticastLockManager;
private final WifiConfigStore mWifiConfigStore;
private final WifiKeyStore mWifiKeyStore;
@@ -266,6 +270,8 @@ public class WifiInjector {
@NonNull private final WifiDialogManager mWifiDialogManager;
@NonNull private final SsidTranslator mSsidTranslator;
@NonNull private final ApplicationQosPolicyRequestHandler mApplicationQosPolicyRequestHandler;
+ private final WifiRoamingModeManager mWifiRoamingModeManager;
+ private final TwtManager mTwtManager;
public WifiInjector(WifiContext context) {
if (context == null) {
@@ -322,7 +328,8 @@ public class WifiInjector {
mSoftApBackupRestore = new SoftApBackupRestore(mContext, mSettingsMigrationDataHolder);
mWifiStateTracker = new WifiStateTracker(mBatteryStats);
mWifiThreadRunner = new WifiThreadRunner(wifiHandler);
- mWifiDialogManager = new WifiDialogManager(mContext, mWifiThreadRunner, mFrameworkFacade);
+ mWifiDialogManager = new WifiDialogManager(mContext, mWifiThreadRunner, mFrameworkFacade,
+ this);
mSsidTranslator = new SsidTranslator(mContext, wifiHandler);
mWifiP2pServiceHandlerThread = new HandlerThread("WifiP2pService");
mWifiP2pServiceHandlerThread.start();
@@ -354,7 +361,7 @@ public class WifiInjector {
mWifiP2pMonitor = new WifiP2pMonitor();
mSupplicantP2pIfaceHal = new SupplicantP2pIfaceHal(mWifiP2pMonitor, mWifiGlobals, this);
mWifiP2pNative = new WifiP2pNative(mWifiCondManager, mWifiNative, mWifiMetrics,
- mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager, mPropertyService);
+ mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager, mPropertyService, this);
SubscriptionManager subscriptionManager =
mContext.getSystemService(SubscriptionManager.class);
if (SdkLevel.isAtLeastS()) {
@@ -439,6 +446,7 @@ public class WifiInjector {
wifiHandler);
mSettingsConfigStore = new WifiSettingsConfigStore(context, wifiHandler,
mSettingsMigrationDataHolder, mWifiConfigManager, mWifiConfigStore);
+ mWifiSettingsBackupRestore = new WifiSettingsBackupRestore(mSettingsConfigStore);
mSettingsStore = new WifiSettingsStore(mContext, mSettingsConfigStore, mWifiThreadRunner,
mFrameworkFacade, mWifiNotificationManager, mDeviceConfigFacade,
mWifiMetrics, mClock);
@@ -614,6 +622,13 @@ public class WifiInjector {
// {@link LocationManager#getCurrentLocation}, so we need to pass mContextWithAttributionTag
// instead of mContext to the AfcManager.
mAfcManager = new AfcManager(mContextWithAttributionTag, this);
+ mWifiRoamingModeManager = new WifiRoamingModeManager(mWifiNative,
+ mActiveModeWarden, new WifiRoamingConfigStore(mWifiConfigManager,
+ mWifiConfigStore));
+
+ mTwtManager = new TwtManager(this, mCmiMonitor, mWifiNative, wifiHandler, mClock,
+ WifiTwtSession.MAX_TWT_SESSIONS, 1);
+ mBackupRestoreController = new BackupRestoreController(mWifiSettingsBackupRestore, mClock);
}
/**
@@ -673,6 +688,7 @@ public class WifiInjector {
mWifiDialogManager.enableVerboseLogging(verboseEnabled);
mExternalPnoScanRequestManager.enableVerboseLogging(verboseEnabled);
mMultiInternetWifiNetworkFactory.enableVerboseLogging(verboseEnabled);
+ mWifiRoamingModeManager.enableVerboseLogging(verboseEnabled);
}
public UserManager getUserManager() {
@@ -1128,6 +1144,11 @@ public class WifiInjector {
return mSettingsConfigStore;
}
+ @NonNull
+ public WifiSettingsBackupRestore getWifiSettingsBackupRestore() {
+ return mWifiSettingsBackupRestore;
+ }
+
public WifiScanAlwaysAvailableSettingsCompatibility
getWifiScanAlwaysAvailableSettingsCompatibility() {
return mWifiScanAlwaysAvailableSettingsCompatibility;
@@ -1307,4 +1328,17 @@ public class WifiInjector {
public AlarmManager getAlarmManager() {
return mAlarmManager;
}
+
+ public WifiRoamingModeManager getWifiRoamingModeManager() {
+ return mWifiRoamingModeManager;
+ }
+
+ public TwtManager getTwtManager() {
+ return mTwtManager;
+ }
+
+ @NonNull
+ public BackupRestoreController getBackupRestoreController() {
+ return mBackupRestoreController;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
index 86228edded..462e2b92ef 100644
--- a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
+++ b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
@@ -850,13 +850,13 @@ public class WifiLastResortWatchdog {
private void logv(String s) {
mLocalLog.log(s);
if (mVerboseLoggingEnabled) {
- Log.v(TAG, s);
+ Log.v(TAG, s, null);
}
}
private void loge(String s) {
mLocalLog.log(s);
- Log.e(TAG, s);
+ Log.e(TAG, s, null);
}
/**
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index a6c6d8f31b..402ea5491d 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -711,6 +711,7 @@ public class WifiMetrics {
private boolean mIsEcpsPriorityAccessSupported = false;
private NetworkDetail.HSRelease mHsRelease = NetworkDetail.HSRelease.Unknown;
private ApType6GHz mApType6GHz = ApType6GHz.AP_TYPE_6GHZ_UNKNOWN;
+ public @WifiAnnotations.ChannelWidth int mChannelWidth = ScanResult.UNSPECIFIED;
public String toString() {
StringBuilder sb = new StringBuilder();
@@ -746,6 +747,7 @@ public class WifiMetrics {
sb.append(", mApType6Ghz=" + mApType6GHz);
sb.append(", mIsEcpsPriorityAccessSupported=" + mIsEcpsPriorityAccessSupported);
sb.append(", mHsRelease=" + mHsRelease);
+ sb.append(", mChannelWidth" + mChannelWidth);
}
return sb.toString();
}
@@ -1175,6 +1177,7 @@ public class WifiMetrics {
private boolean mIsCarrierWifi;
private boolean mIsOobPseudonymEnabled;
private int mRole;
+ private int mUid;
private int mCarrierId;
private int mEapType;
private int mPhase2Method;
@@ -1428,6 +1431,7 @@ public class WifiMetrics {
+ mConnectionEvent.isFirstConnectionAfterBoot);
sb.append(", isCarrierWifi=" + mIsCarrierWifi);
sb.append(", isOobPseudonymEnabled=" + mIsOobPseudonymEnabled);
+ sb.append(", uid=" + mUid);
return sb.toString();
}
}
@@ -1922,7 +1926,7 @@ public class WifiMetrics {
*/
public int startConnectionEvent(
String ifaceName, WifiConfiguration config, String targetBSSID, int roamType,
- boolean isOobPseudonymEnabled, int role) {
+ boolean isOobPseudonymEnabled, int role, int uid) {
synchronized (mLock) {
int overlapWithLastConnectionMs = 0;
ConnectionEvent currentConnectionEvent = mCurrentConnectionEventPerIface.get(ifaceName);
@@ -1974,6 +1978,7 @@ public class WifiMetrics {
currentConnectionEvent.mConnectionEvent.isFirstConnectionAfterBoot =
mFirstConnectionAfterBoot;
currentConnectionEvent.mRole = role;
+ currentConnectionEvent.mUid = uid;
mFirstConnectionAfterBoot = false;
mConnectionEventList.add(currentConnectionEvent);
mScanResultRssiTimestampMillis = -1;
@@ -2126,6 +2131,20 @@ public class WifiMetrics {
}
/**
+ * Set channel width of the current connection.
+ */
+ public void setConnectionChannelWidth(String interfaceName,
+ @WifiAnnotations.ChannelWidth int channelWidth) {
+ synchronized (mLock) {
+ ConnectionEvent currentConnectionEvent = mCurrentConnectionEventPerIface.get(
+ interfaceName);
+ if (currentConnectionEvent != null) {
+ currentConnectionEvent.mRouterFingerPrint.mChannelWidth = channelWidth;
+ }
+ }
+ }
+
+ /**
* Set the max link speed supported by current network
*/
public void setConnectionMaxSupportedLinkSpeedMbps(
@@ -2210,10 +2229,10 @@ public class WifiMetrics {
currentConnectionEvent.mConfigSsid,
mClock.getElapsedSinceBootMillis(),
band, currentConnectionEvent.mAuthType);
-
- // TODO(b/166309727) need to add ifaceName to WifiStatsLog
- WifiStatsLog.write(WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED,
- true, band, currentConnectionEvent.mAuthType);
+ if (currentConnectionEvent.mRole == WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY) {
+ WifiStatsLog.write(WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED,
+ true, band, currentConnectionEvent.mAuthType);
+ }
}
currentConnectionEvent.mConnectionEvent.connectionResult =
@@ -2247,7 +2266,8 @@ public class WifiMetrics {
toMetricPhase2Method(currentConnectionEvent.mPhase2Method),
currentConnectionEvent.mPasspointRoamingType,
currentConnectionEvent.mCarrierId,
- currentConnectionEvent.mTofuConnectionState);
+ currentConnectionEvent.mTofuConnectionState,
+ currentConnectionEvent.mUid);
if (connectionSucceeded) {
reportRouterCapabilities(currentConnectionEvent.mRouterFingerPrint);
@@ -2642,6 +2662,25 @@ public class WifiMetrics {
== WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__PASSPOINT_ROAMING_TYPE__ROAMING_RCOI_OPENROAMING_SETTLED;
}
+ private int convertChannelWidthToProto(@WifiAnnotations.ChannelWidth int channelWidth) {
+ switch(channelWidth) {
+ case ScanResult.CHANNEL_WIDTH_20MHZ:
+ return WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__CHANNEL_WIDTH_MHZ__CHANNEL_WIDTH_20MHZ;
+ case ScanResult.CHANNEL_WIDTH_40MHZ:
+ return WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__CHANNEL_WIDTH_MHZ__CHANNEL_WIDTH_40MHZ;
+ case ScanResult.CHANNEL_WIDTH_80MHZ:
+ return WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__CHANNEL_WIDTH_MHZ__CHANNEL_WIDTH_80MHZ;
+ case ScanResult.CHANNEL_WIDTH_160MHZ:
+ return WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__CHANNEL_WIDTH_MHZ__CHANNEL_WIDTH_160MHZ;
+ case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
+ return WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__CHANNEL_WIDTH_MHZ__CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
+ case ScanResult.CHANNEL_WIDTH_320MHZ:
+ return WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__CHANNEL_WIDTH_MHZ__CHANNEL_WIDTH_320MHZ;
+ default:
+ return WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__CHANNEL_WIDTH_MHZ__CHANNEL_WIDTH_UNKNOWN;
+ }
+ }
+
private void reportRouterCapabilities(RouterFingerPrint r) {
WifiStatsLog.write(WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED,
r.mIsFrameworkInitiatedRoaming, r.mRouterFingerPrintProto.channelInfo,
@@ -2657,7 +2696,8 @@ public class WifiMetrics {
r.mIsBroadcastTwtSupported, r.mIsRestrictedTwtSupported, r.mIs11McSupported,
r.mIs11AzSupported, convertHsReleasetoProto(r.mHsRelease),
r.mRouterFingerPrintProto.isPasspointHomeProvider,
- convertApType6GhzToProto(r.mApType6GHz), r.mIsEcpsPriorityAccessSupported);
+ convertApType6GhzToProto(r.mApType6GHz), r.mIsEcpsPriorityAccessSupported,
+ convertChannelWidthToProto(r.mChannelWidth));
}
/**
@@ -2673,12 +2713,13 @@ public class WifiMetrics {
if (!isPrimary(ifaceName)) {
return;
}
- WifiStatsLog.write(WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED,
- false,
- mCurrentSession != null ? mCurrentSession.mBand : 0,
- mCurrentSession != null ? mCurrentSession.mAuthType : 0);
-
if (mCurrentSession != null) {
+ if (mCurrentSession.mConnectionEvent.mRole == WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY) {
+ WifiStatsLog.write(WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED,
+ false,
+ mCurrentSession.mBand,
+ mCurrentSession.mAuthType);
+ }
mCurrentSession.mSessionEndTimeMillis = mClock.getElapsedSinceBootMillis();
int durationSeconds = (int) (mCurrentSession.mSessionEndTimeMillis
- mCurrentSession.mSessionStartTimeMillis) / 1000;
@@ -2849,7 +2890,7 @@ public class WifiMetrics {
currentConnectionEvent.mRouterFingerPrint.mIsTwtRequired = networkDetail.isTwtRequired();
currentConnectionEvent.mRouterFingerPrint.mIsFilsSupported = networkDetail.isFilsCapable();
currentConnectionEvent.mRouterFingerPrint.mIs11AzSupported =
- networkDetail.is11azSupported();
+ networkDetail.is80211azNtbResponder() || networkDetail.is80211azTbResponder();
currentConnectionEvent.mRouterFingerPrint.mIs11McSupported =
networkDetail.is80211McResponderSupport();
currentConnectionEvent.mRouterFingerPrint.mIsMboSupported = networkDetail.isMboSupported();
@@ -4860,9 +4901,6 @@ public class WifiMetrics {
+ mContext.getResources().getBoolean(
R.bool.config_wifi_connected_mac_randomization_supported));
pw.println("mWifiLogProto.scoreExperimentId=" + mWifiLogProto.scoreExperimentId);
- pw.println("mExperimentValues.wifiIsUnusableLoggingEnabled="
- + mContext.getResources().getBoolean(
- R.bool.config_wifiIsUnusableEventMetricsEnabled));
pw.println("mExperimentValues.wifiDataStallMinTxBad="
+ mContext.getResources().getInteger(
R.integer.config_wifiDataStallMinTxBad));
@@ -5565,8 +5603,6 @@ public class WifiMetrics {
mWifiLogProto.wifiWakeStats = mWifiWakeMetrics.buildProto();
mWifiLogProto.isMacRandomizationOn = mContext.getResources().getBoolean(
R.bool.config_wifi_connected_mac_randomization_supported);
- mExperimentValues.wifiIsUnusableLoggingEnabled = mContext.getResources().getBoolean(
- R.bool.config_wifiIsUnusableEventMetricsEnabled);
mExperimentValues.linkSpeedCountsLoggingEnabled = mContext.getResources().getBoolean(
R.bool.config_wifiLinkSpeedMetricsEnabled);
mExperimentValues.wifiDataStallMinTxBad = mContext.getResources().getInteger(
@@ -6876,9 +6912,6 @@ public class WifiMetrics {
return;
}
mScoreBreachLowTimeMillis = -1;
- if (!mContext.getResources().getBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled)) {
- return;
- }
long currentBootTime = mClock.getElapsedSinceBootMillis();
switch (triggerType) {
@@ -7768,7 +7801,7 @@ public class WifiMetrics {
/**
* Add a new listener for Wi-Fi usability stats handling.
*/
- public void addOnWifiUsabilityListener(IOnWifiUsabilityStatsListener listener) {
+ public void addOnWifiUsabilityListener(@NonNull IOnWifiUsabilityStatsListener listener) {
if (!mOnWifiUsabilityListeners.register(listener)) {
Log.e(TAG, "Failed to add listener");
return;
@@ -7782,7 +7815,7 @@ public class WifiMetrics {
/**
* Remove an existing listener for Wi-Fi usability stats handling.
*/
- public void removeOnWifiUsabilityListener(IOnWifiUsabilityStatsListener listener) {
+ public void removeOnWifiUsabilityListener(@NonNull IOnWifiUsabilityStatsListener listener) {
mOnWifiUsabilityListeners.unregister(listener);
if (DBG) {
Log.v(TAG, "Removing listener. Num listeners: "
@@ -9424,6 +9457,10 @@ public class WifiMetrics {
getSoftApStartedStaApConcurrency(isStaApSupported, isStaDbsSupported),
getSoftApStartedStaStatus(staFreqMhz),
getSoftApStartedAuthType(securityType));
+ if (startResult == SoftApManager.START_RESULT_SUCCESS) {
+ WifiStatsLog.write(WifiStatsLog.SOFT_AP_STATE_CHANGED,
+ WifiStatsLog.SOFT_AP_STATE_CHANGED__HOTSPOT_ON__STATE_ON);
+ }
}
private static int getSoftApStoppedStopEvent(@SoftApManager.StopEvent int stopEvent) {
@@ -9608,5 +9645,7 @@ public class WifiMetrics {
dbsFailureBand,
dbsTimeoutBand,
getSoftApStoppedUpstreamType(upstreamCaps));
+ WifiStatsLog.write(WifiStatsLog.SOFT_AP_STATE_CHANGED,
+ WifiStatsLog.SOFT_AP_STATE_CHANGED__HOTSPOT_ON__STATE_OFF);
}
}
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 69f61808da..9c2237e7a3 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -21,7 +21,10 @@ 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_STA;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_P2P;
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 android.annotation.IntDef;
import android.annotation.NonNull;
@@ -32,6 +35,7 @@ import android.net.MacAddress;
import android.net.TrafficStats;
import android.net.apf.ApfCapabilities;
import android.net.wifi.CoexUnsafeChannel;
+import android.net.wifi.MscsParams;
import android.net.wifi.OuiKeyedData;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.ScanResult;
@@ -42,13 +46,17 @@ import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.RoamingMode;
import android.net.wifi.WifiScanner;
+import android.net.wifi.WifiScanner.ScanData;
import android.net.wifi.WifiSsid;
import android.net.wifi.nl80211.DeviceWiphyCapabilities;
import android.net.wifi.nl80211.NativeScanResult;
import android.net.wifi.nl80211.NativeWifiClient;
import android.net.wifi.nl80211.RadioChainInfo;
import android.net.wifi.nl80211.WifiNl80211Manager;
+import android.net.wifi.twt.TwtRequest;
+import android.net.wifi.twt.TwtSessionCallback;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -59,6 +67,7 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import com.android.internal.annotations.Immutable;
import com.android.internal.annotations.VisibleForTesting;
@@ -86,6 +95,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -133,6 +143,15 @@ public class WifiNative {
private InterfaceObserverInternal mInterfaceObserver;
private InterfaceEventCallback mInterfaceListener;
private @WifiManager.MloMode int mCachedMloMode = WifiManager.MLO_MODE_DEFAULT;
+ private boolean mIsLocationModeEnabled = false;
+ private long mLastLocationModeEnabledTimeMs = 0;
+ private Map<String, Bundle> mCachedTwtCapabilities = new ArrayMap<>();
+ /**
+ * Mapping of unknown AKMs configured in overlay config item
+ * config_wifiUnknownAkmToKnownAkmMapping to ScanResult security key management scheme
+ * (ScanResult.KEY_MGMT_XX)
+ */
+ @VisibleForTesting @Nullable SparseIntArray mUnknownAkmMap;
public WifiNative(WifiVendorHal vendorHal,
SupplicantStaIfaceHal staIfaceHal, HostapdHal hostapdHal,
@@ -152,6 +171,70 @@ public class WifiNative {
mBuildProperties = buildProperties;
mWifiInjector = wifiInjector;
mContext = wifiInjector.getContext();
+ initializeUnknownAkmMapping();
+ }
+
+ private void initializeUnknownAkmMapping() {
+ String[] unknownAkmMapping =
+ mContext.getResources()
+ .getStringArray(R.array.config_wifiUnknownAkmToKnownAkmMapping);
+ if (unknownAkmMapping == null) {
+ return;
+ }
+ for (String line : unknownAkmMapping) {
+ if (line == null) {
+ continue;
+ }
+ String[] items = line.split(",");
+ if (items.length != 2) {
+ Log.e(
+ TAG,
+ "Failed to parse config_wifiUnknownAkmToKnownAkmMapping line="
+ + line
+ + ". Should contain only two values separated by comma");
+ continue;
+ }
+ try {
+ int unknownAkm = Integer.parseInt(items[0].trim());
+ int knownAkm = Integer.parseInt(items[1].trim());
+ // Convert the OEM configured known AKM suite selector to
+ // ScanResult security key management scheme(ScanResult.KEY_MGMT_XX)*/
+ int keyMgmtScheme =
+ InformationElementUtil.Capabilities.akmToScanResultKeyManagementScheme(
+ knownAkm);
+ if (keyMgmtScheme != ScanResult.KEY_MGMT_UNKNOWN) {
+ if (mUnknownAkmMap == null) {
+ mUnknownAkmMap = new SparseIntArray();
+ }
+ mUnknownAkmMap.put(unknownAkm, keyMgmtScheme);
+ Log.d(
+ TAG,
+ "unknown AKM = "
+ + unknownAkm
+ + " - converted keyMgmtScheme: "
+ + keyMgmtScheme);
+ } else {
+ Log.e(
+ TAG,
+ "Known AKM: "
+ + knownAkm
+ + " is not defined in the framework."
+ + " Hence Failed to add AKM: "
+ + unknownAkm
+ + " in UnknownAkmMap."
+ + " Parsed config from overlay: "
+ + line);
+ }
+ } catch (Exception e) {
+ // failure to parse. Something is wrong with the configuration.
+ Log.e(
+ TAG,
+ "Parsing config_wifiUnknownAkmToKnownAkmMapping line="
+ + line
+ + ". Exception occurred:"
+ + e);
+ }
+ }
}
/**
@@ -168,6 +251,13 @@ public class WifiNative {
}
/**
+ * Get TWT capabilities for the interface
+ */
+ public Bundle getTwtCapabilities(String interfaceName) {
+ return mCachedTwtCapabilities.get(interfaceName);
+ }
+
+ /**
* Callbacks for SoftAp interface.
*/
public class SoftApHalCallbackFromWificond implements WifiNl80211Manager.SoftApCallback {
@@ -190,7 +280,7 @@ public class WifiNative {
@Override
public void onSoftApChannelSwitched(int frequency, int bandwidth) {
mSoftApHalCallback.onInfoChanged(mIfaceName, frequency, bandwidth,
- ScanResult.WIFI_STANDARD_UNKNOWN, null);
+ ScanResult.WIFI_STANDARD_UNKNOWN, null, Collections.emptyList());
}
@Override
@@ -248,9 +338,12 @@ public class WifiNative {
* indication that the SoftAp is not enabled.
* @param bandwidth The new bandwidth of the SoftAp.
* @param generation The new generation of the SoftAp.
+ * @param vendorData List of {@link OuiKeyedData} containing vendor-specific configuration
+ * data, or empty list if not provided.
*/
void onInfoChanged(String apIfaceInstance, int frequency, int bandwidth,
- int generation, MacAddress apIfaceInstanceMacAddress);
+ int generation, MacAddress apIfaceInstanceMacAddress,
+ @NonNull List<OuiKeyedData> vendorData);
/**
* Invoked when there is a change in the associated station (STA).
*
@@ -269,13 +362,15 @@ public class WifiNative {
/**
* Meta-info about every iface that is active.
*/
- private static class Iface {
+ public static class Iface {
/** Type of ifaces possible */
public static final int IFACE_TYPE_AP = 0;
public static final int IFACE_TYPE_STA_FOR_CONNECTIVITY = 1;
public static final int IFACE_TYPE_STA_FOR_SCAN = 2;
+ public static final int IFACE_TYPE_P2P = 3;
- @IntDef({IFACE_TYPE_AP, IFACE_TYPE_STA_FOR_CONNECTIVITY, IFACE_TYPE_STA_FOR_SCAN})
+ @IntDef({IFACE_TYPE_AP, IFACE_TYPE_STA_FOR_CONNECTIVITY, IFACE_TYPE_STA_FOR_SCAN,
+ IFACE_TYPE_P2P})
@Retention(RetentionPolicy.SOURCE)
public @interface IfaceType{}
@@ -399,6 +494,11 @@ public class WifiNative {
return false;
}
+ /** Checks if there are any P2P iface active. */
+ private boolean hasAnyP2pIface() {
+ return hasAnyIfaceOfType(Iface.IFACE_TYPE_P2P);
+ }
+
/** Checks if there are any STA (for connectivity) iface active. */
private boolean hasAnyStaIfaceForConnectivity() {
return hasAnyIfaceOfType(Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY);
@@ -622,10 +722,19 @@ public class WifiNative {
private void stopSupplicantIfNecessary() {
synchronized (mLock) {
if (!mIfaceMgr.hasAnyStaIfaceForConnectivity()) {
- if (!mSupplicantStaIfaceHal.deregisterDeathHandler()) {
- Log.e(TAG, "Failed to deregister supplicant death handler");
+ if (mSupplicantStaIfaceHal.isInitializationStarted()) {
+ if (!mSupplicantStaIfaceHal.deregisterDeathHandler()) {
+ Log.e(TAG, "Failed to deregister supplicant death handler");
+ }
+
+ }
+ if (!mIfaceMgr.hasAnyP2pIface()) {
+ if (mSupplicantStaIfaceHal.isInitializationStarted()) {
+ mSupplicantStaIfaceHal.terminate();
+ } else {
+ mWifiInjector.getWifiP2pNative().stopP2pSupplicantIfNecessary();
+ }
}
- mSupplicantStaIfaceHal.terminate();
}
}
}
@@ -1118,6 +1227,68 @@ public class WifiNative {
}
}
+ private String createP2pIfaceFromHalOrGetNameFromProperty(
+ HalDeviceManager.InterfaceDestroyedListener p2pInterfaceDestroyedListener,
+ Handler handler, WorkSource requestorWs) {
+ synchronized (mLock) {
+ if (mWifiVendorHal.isVendorHalSupported()) {
+ return mWifiInjector.getHalDeviceManager().createP2pIface(
+ p2pInterfaceDestroyedListener, handler, requestorWs);
+ } else {
+ Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
+ return mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME);
+ }
+ }
+ }
+
+ /**
+ * Helper function to handle creation of P2P iface.
+ * For devices which do not the support the HAL, this will bypass HalDeviceManager &
+ * teardown any existing iface.
+ */
+ public Iface createP2pIface(
+ HalDeviceManager.InterfaceDestroyedListener p2pInterfaceDestroyedListener,
+ Handler handler, WorkSource requestorWs) {
+ synchronized (mLock) {
+ // Make sure HAL is started for p2p
+ if (!startHal()) {
+ Log.e(TAG, "Failed to start Hal");
+ mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToHal();
+ return null;
+ }
+ // maintain iface status in WifiNative
+ Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_P2P);
+ if (iface == null) {
+ Log.e(TAG, "Failed to allocate new P2P iface");
+ stopHalAndWificondIfNecessary();
+ return null;
+ }
+ iface.name = createP2pIfaceFromHalOrGetNameFromProperty(
+ p2pInterfaceDestroyedListener, handler, requestorWs);
+ if (TextUtils.isEmpty(iface.name)) {
+ Log.e(TAG, "Failed to create P2p iface in HalDeviceManager");
+ mIfaceMgr.removeIface(iface.id);
+ mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToHal();
+ stopHalAndWificondIfNecessary();
+ return null;
+ }
+ return iface;
+ }
+ }
+
+ /**
+ * Teardown P2p iface with input interface Id which was returned by createP2pIface.
+ *
+ * @param interfaceId the interface identify which was gerenated when creating P2p iface.
+ */
+ public void teardownP2pIface(int interfaceId) {
+ synchronized (mLock) {
+ mIfaceMgr.removeIface(interfaceId);
+ stopHalAndWificondIfNecessary();
+ stopSupplicantIfNecessary();
+ }
+ }
+
/**
* Get list of instance name from this bridged AP iface.
*
@@ -1531,7 +1702,8 @@ public class WifiNative {
return false;
}
if (mContext.getResources().getBoolean(
- R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled)) {
+ R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled)
+ && isSupplicantUsingAidlService()) {
mQosPolicyFeatureEnabled = mSupplicantStaIfaceHal
.setNetworkCentricQosPolicyFeatureEnabled(iface.name, true);
if (!mQosPolicyFeatureEnabled) {
@@ -1871,8 +2043,12 @@ public class WifiNative {
InformationElementUtil.parseInformationElements(result.getInformationElements());
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(ies, result.getCapabilities(), mIsEnhancedOpenSupported,
- result.getFrequencyMhz());
+ capabilities.from(
+ ies,
+ result.getCapabilities(),
+ mIsEnhancedOpenSupported,
+ result.getFrequencyMhz(),
+ mUnknownAkmMap);
String flags = capabilities.generateCapabilitiesString();
NetworkDetail networkDetail;
try {
@@ -3126,6 +3302,15 @@ public class WifiNative {
}
/**
+ * Check whether Supplicant is using the AIDL HAL service.
+ *
+ * @return true if the Supplicant is using the AIDL service, false otherwise.
+ */
+ public boolean isSupplicantUsingAidlService() {
+ return mSupplicantStaIfaceHal.isAidlService();
+ }
+
+ /**
* Check whether the Supplicant AIDL service is running at least the expected version.
*
* @param expectedVersion Version number to check.
@@ -3460,6 +3645,62 @@ public class WifiNative {
}
/**
+ * Sets whether global location mode is enabled.
+ */
+ public void setLocationModeEnabled(boolean enabled) {
+ if (!mIsLocationModeEnabled && enabled) {
+ mLastLocationModeEnabledTimeMs = SystemClock.elapsedRealtime();
+ }
+ Log.d(TAG, "mIsLocationModeEnabled " + enabled
+ + " mLastLocationModeEnabledTimeMs " + mLastLocationModeEnabledTimeMs);
+ mIsLocationModeEnabled = enabled;
+ }
+
+ @NonNull
+ private ScanResult[] getCachedScanResultsFilteredByLocationModeEnabled(
+ @NonNull ScanResult[] scanResults) {
+ List<ScanResult> resultList = new ArrayList<ScanResult>();
+ for (ScanResult scanResult : scanResults) {
+ if (mIsLocationModeEnabled
+ && scanResult.timestamp >= mLastLocationModeEnabledTimeMs * 1000) {
+ resultList.add(scanResult);
+ }
+ }
+ return resultList.toArray(new ScanResult[0]);
+ }
+
+ /**
+ * Gets the cached scan data from the given client interface
+ */
+ @Nullable
+ ScanData getCachedScanResults(String ifaceName) {
+ ScanData scanData = mWifiVendorHal.getCachedScanData(ifaceName);
+ if (scanData == null || scanData.getResults() == null) {
+ return null;
+ }
+ ScanResult[] results = getCachedScanResultsFilteredByLocationModeEnabled(
+ scanData.getResults());
+ return new ScanData(0, 0, 0, scanData.getScannedBands(), results);
+ }
+
+ /**
+ * Gets the cached scan data from all client interfaces
+ */
+ @NonNull
+ public ScanData getCachedScanResultsFromAllClientIfaces() {
+ ScanData consolidatedScanData = new ScanData();
+ Set<String> ifaceNames = getClientInterfaceNames();
+ for (String ifaceName : ifaceNames) {
+ ScanData scanData = getCachedScanResults(ifaceName);
+ if (scanData == null) {
+ continue;
+ }
+ consolidatedScanData.addResults(scanData.getResults());
+ }
+ return consolidatedScanData;
+ }
+
+ /**
* Gets the latest link layer stats
* @param ifaceName Name of the interface.
*/
@@ -3521,6 +3762,19 @@ public class WifiNative {
}
/**
+ * Returns whether P2p + STA concurrency is supported or not.
+ */
+ public boolean isP2pStaConcurrencySupported() {
+ synchronized (mLock) {
+ return mWifiVendorHal.canDeviceSupportCreateTypeCombo(
+ new SparseArray<Integer>() {{
+ put(HDM_CREATE_IFACE_STA, 1);
+ put(HDM_CREATE_IFACE_P2P, 1);
+ }});
+ }
+ }
+
+ /**
* Returns whether a new AP iface can be created or not.
*/
public boolean isItPossibleToCreateApIface(@NonNull WorkSource requestorWs) {
@@ -3674,6 +3928,8 @@ public class WifiNative {
Log.v(TAG, ": DPP AKM supported");
}
}
+ Bundle twtCapabilities = mWifiVendorHal.getTwtCapabilities(ifaceName);
+ if (twtCapabilities != null) mCachedTwtCapabilities.put(ifaceName, twtCapabilities);
return featureSet;
}
@@ -3729,12 +3985,14 @@ public class WifiNative {
public boolean is11bMode;
/** Indicates the AP support for TID-to-link mapping negotiation. */
public boolean apTidToLinkMapNegotiationSupported;
+ public @NonNull List<OuiKeyedData> vendorData;
ConnectionCapabilities() {
wifiStandard = ScanResult.WIFI_STANDARD_UNKNOWN;
channelBandwidth = ScanResult.CHANNEL_WIDTH_20MHZ;
maxNumberTxSpatialStreams = 1;
maxNumberRxSpatialStreams = 1;
is11bMode = false;
+ vendorData = Collections.emptyList();
}
}
@@ -4112,6 +4370,9 @@ public class WifiNative {
* @param pw PrintWriter to write dump to
*/
protected void dump(PrintWriter pw) {
+ pw.println("Dump of " + TAG);
+ pw.println("mIsLocationModeEnabled: " + mIsLocationModeEnabled);
+ pw.println("mLastLocationModeEnabledTimeMs: " + mLastLocationModeEnabledTimeMs);
mHostapdHal.dump(pw);
}
@@ -4584,6 +4845,20 @@ public class WifiNative {
* @return the device capabilities for this interface
*/
public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName) {
+ return getDeviceWiphyCapabilities(ifaceName, false);
+ }
+
+ /**
+ * Get the Wiphy capabilities of a device for a given interface
+ * If the interface is not associated with one,
+ * it will be read from the device through wificond
+ *
+ * @param ifaceName name of the interface
+ * @param isBridgedAp If the iface is bridge AP iface or not.
+ * @return the device capabilities for this interface
+ */
+ public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName,
+ boolean isBridgedAp) {
synchronized (mLock) {
Iface iface = mIfaceMgr.getIface(ifaceName);
if (iface == null) {
@@ -4591,7 +4866,15 @@ public class WifiNative {
return null;
}
if (iface.phyCapabilities == null) {
- iface.phyCapabilities = mWifiCondManager.getDeviceWiphyCapabilities(ifaceName);
+ if (isBridgedAp) {
+ List<String> instances = getBridgedApInstances(ifaceName);
+ if (instances != null && instances.size() != 0) {
+ iface.phyCapabilities = mWifiCondManager.getDeviceWiphyCapabilities(
+ instances.get(0));
+ }
+ } else {
+ iface.phyCapabilities = mWifiCondManager.getDeviceWiphyCapabilities(ifaceName);
+ }
}
if (iface.phyCapabilities != null
&& iface.phyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE)
@@ -4848,30 +5131,36 @@ public class WifiNative {
return mHostapdHal.isSoftApInstanceDiedHandlerSupported();
}
- @VisibleForTesting
/** Checks if there are any STA (for connectivity) iface active. */
+ @VisibleForTesting
boolean hasAnyStaIfaceForConnectivity() {
return mIfaceMgr.hasAnyStaIfaceForConnectivity();
}
- @VisibleForTesting
/** Checks if there are any STA (for scan) iface active. */
+ @VisibleForTesting
boolean hasAnyStaIfaceForScan() {
return mIfaceMgr.hasAnyStaIfaceForScan();
}
- @VisibleForTesting
/** Checks if there are any AP iface active. */
+ @VisibleForTesting
boolean hasAnyApIface() {
return mIfaceMgr.hasAnyApIface();
}
- @VisibleForTesting
/** Checks if there are any iface active. */
+ @VisibleForTesting
boolean hasAnyIface() {
return mIfaceMgr.hasAnyIface();
}
+ /** Checks if there are any P2P iface active. */
+ @VisibleForTesting
+ boolean hasAnyP2pIface() {
+ return mIfaceMgr.hasAnyP2pIface();
+ }
+
/**
* Sets or clean mock wifi service
*
@@ -5055,4 +5344,135 @@ public class WifiNative {
public boolean setAfcChannelAllowance(WifiChip.AfcChannelAllowance afcChannelAllowance) {
return mWifiVendorHal.setAfcChannelAllowance(afcChannelAllowance);
}
+
+ /**
+ * Enable Mirrored Stream Classification Service (MSCS) and configure using
+ * the provided configuration values.
+ *
+ * @param mscsParams {@link MscsParams} object containing the configuration parameters.
+ * @param ifaceName Name of the interface.
+ */
+ public void enableMscs(@NonNull MscsParams mscsParams, String ifaceName) {
+ mSupplicantStaIfaceHal.enableMscs(mscsParams, ifaceName);
+ }
+
+ /**
+ * Resend the previously configured MSCS parameters on this interface, if any exist.
+ *
+ * @param ifaceName Name of the interface.
+ */
+ public void resendMscs(String ifaceName) {
+ mSupplicantStaIfaceHal.resendMscs(ifaceName);
+ }
+
+ /**
+ * Disable Mirrored Stream Classification Service (MSCS).
+ *
+ * @param ifaceName Name of the interface.
+ */
+ public void disableMscs(String ifaceName) {
+ mSupplicantStaIfaceHal.disableMscs(ifaceName);
+ }
+
+ /**
+ * Set the roaming mode value.
+ *
+ * @param ifaceName Name of the interface.
+ * @param roamingMode {@link android.net.wifi.WifiManager.RoamingMode}.
+ * @return {@link WifiStatusCode#SUCCESS} if success, otherwise error code.
+ */
+ public @WifiStatusCode int setRoamingMode(@NonNull String ifaceName,
+ @RoamingMode int roamingMode) {
+ return mWifiVendorHal.setRoamingMode(ifaceName, roamingMode);
+ }
+
+ /*
+ * TWT callback events
+ */
+ public interface WifiTwtEvents {
+ /**
+ * Called when a TWT operation fails
+ *
+ * @param cmdId Unique command id.
+ * @param twtErrorCode Error code
+ */
+ void onTwtFailure(int cmdId, @TwtSessionCallback.TwtErrorCode int twtErrorCode);
+
+ /**
+ * Called when {@link #setupTwtSession(int, String, TwtRequest)} succeeds.
+ *
+ * @param cmdId Unique command id used in {@link #setupTwtSession(int, String, TwtRequest)}
+ * @param wakeDurationUs TWT wake duration for the session in microseconds
+ * @param wakeIntervalUs TWT wake interval for the session in microseconds
+ * @param linkId Multi link operation link id
+ * @param sessionId TWT session id
+ */
+ void onTwtSessionCreate(int cmdId, int wakeDurationUs, long wakeIntervalUs, int linkId,
+ int sessionId);
+ /**
+ * Called when TWT session is torn down by {@link #tearDownTwtSession(int, String, int)}.
+ * Can also be called unsolicitedly by the vendor software with proper reason code.
+ *
+ * @param cmdId Unique command id used in {@link #tearDownTwtSession(int, String, int)}
+ * @param twtSessionId TWT session Id
+ * @param twtReasonCode Reason code for teardown
+ */
+ void onTwtSessionTeardown(int cmdId, int twtSessionId,
+ @TwtSessionCallback.TwtReasonCode int twtReasonCode);
+
+ /**
+ * Called as a response to {@link #getStatsTwtSession(int, String, int)}
+ *
+ * @param cmdId Unique command id used in {@link #getStatsTwtSession(int, String, int)}
+ * @param twtSessionId TWT session Id
+ * @param twtStats TWT stats object
+ */
+ void onTwtSessionStats(int cmdId, int twtSessionId, Bundle twtStats);
+ }
+
+
+ /**
+ * Sets up a TWT session for the interface
+ *
+ * @param commandId A unique command id to identify this command
+ * @param interfaceName Interface name
+ * @param twtRequest TWT request parameters
+ * @return true if successful, otherwise false
+ */
+ public boolean setupTwtSession(int commandId, String interfaceName, TwtRequest twtRequest) {
+ return mWifiVendorHal.setupTwtSession(commandId, interfaceName, twtRequest);
+ }
+
+ /**
+ * Registers TWT callbacks
+ *
+ * @param wifiTwtCallback TWT callbacks
+ */
+ public void registerTwtCallbacks(WifiTwtEvents wifiTwtCallback) {
+ mWifiVendorHal.registerTwtCallbacks(wifiTwtCallback);
+ }
+
+ /**
+ * Teardown the TWT session
+ *
+ * @param commandId A unique command id to identify this command
+ * @param interfaceName Interface name
+ * @param sessionId TWT session id
+ * @return true if successful, otherwise false
+ */
+ public boolean tearDownTwtSession(int commandId, String interfaceName, int sessionId) {
+ return mWifiVendorHal.tearDownTwtSession(commandId, interfaceName, sessionId);
+ }
+
+ /**
+ * Gets stats of the TWT session
+ *
+ * @param commandId A unique command id to identify this command
+ * @param interfaceName Interface name
+ * @param sessionId TWT session id
+ * @return true if successful, otherwise false
+ */
+ public boolean getStatsTwtSession(int commandId, String interfaceName, int sessionId) {
+ return mWifiVendorHal.getStatsTwtSession(commandId, interfaceName, sessionId);
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index a03dd40b5b..9313733182 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -31,6 +31,7 @@ import static java.lang.Math.toIntExact;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
@@ -147,6 +148,7 @@ public class WifiNetworkFactory extends NetworkFactory {
private final ClientModeImplMonitor mClientModeImplMonitor;
private final FrameworkFacade mFacade;
private final MultiInternetManager mMultiInternetManager;
+ private final NetworkCapabilities mCapabilitiesFilter;
private RemoteCallbackList<INetworkRequestMatchCallback> mRegisteredCallbacks;
// Store all user approved access points for apps.
@VisibleForTesting
@@ -592,6 +594,7 @@ public class WifiNetworkFactory extends NetworkFactory {
mUserApprovedAccessPointMap = new HashMap<>();
mFacade = facade;
mMultiInternetManager = multiInternetManager;
+ mCapabilitiesFilter = nc;
// register the data store for serializing/deserializing data.
configStore.registerStoreData(
@@ -611,6 +614,18 @@ public class WifiNetworkFactory extends NetworkFactory {
});
}
+ // package-private
+ @TargetApi(Build.VERSION_CODES.S)
+ void updateSubIdsInCapabilitiesFilter(Set<Integer> subIds) {
+ // setSubscriptionIds is only available on Android S+ devices.
+ if (SdkLevel.isAtLeastS()) {
+ NetworkCapabilities newFilter =
+ new NetworkCapabilities.Builder(mCapabilitiesFilter)
+ .setSubscriptionIds(subIds).build();
+ setCapabilityFilter(newFilter);
+ }
+ }
+
private void saveToStore() {
// Set the flag to let WifiConfigStore that we have new data to write.
mHasNewDataToSerialize = true;
@@ -906,12 +921,12 @@ public class WifiNetworkFactory extends NetworkFactory {
mActiveSpecificNetworkRequest.getRequestorPackageName()));
}
-
- if (!triggerConnectIfUserApprovedMatchFound(revokeNormalBypass)) {
+ ScanResult[] cachedScanResults = getFilteredCachedScanResults();
+ if (!triggerConnectIfUserApprovedMatchFound(revokeNormalBypass, cachedScanResults)) {
// Didn't find an approved match, send the matching results to UI and trigger
// periodic scans for finding a network in the request.
// Fetch the latest cached scan results to speed up network matching.
- ScanResult[] cachedScanResults = getFilteredCachedScanResults();
+
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Using cached " + cachedScanResults.length + " scan results");
}
@@ -1125,7 +1140,7 @@ public class WifiNetworkFactory extends NetworkFactory {
new NetworkUpdateResult(networkId),
new ActionListenerWrapper(listener),
mActiveSpecificNetworkRequest.getRequestorUid(),
- mActiveSpecificNetworkRequest.getRequestorPackageName());
+ mActiveSpecificNetworkRequest.getRequestorPackageName(), null);
// Post an alarm to handle connection timeout.
scheduleConnectionTimeout();
@@ -1271,7 +1286,7 @@ public class WifiNetworkFactory extends NetworkFactory {
return;
}
- if (!mPendingConnectionSuccess) {
+ if (!mPendingConnectionSuccess || mActiveSpecificNetworkRequest == null) {
if (mConnectedSpecificNetworkRequest != null) {
Log.w(TAG, "Connection is terminated, cancelling "
+ mConnectedSpecificNetworkRequest);
@@ -1645,7 +1660,7 @@ public class WifiNetworkFactory extends NetworkFactory {
ScanResult[] scanResults) {
if (mActiveSpecificNetworkRequestSpecifier == null) {
Log.e(TAG, "Scan results received with no active network request. Ignoring...");
- return new ArrayList<>();
+ return Collections.emptyList();
}
List<ScanResult> matchedScanResults = new ArrayList<>();
WifiNetworkSpecifier wns = mActiveSpecificNetworkRequestSpecifier;
@@ -1914,7 +1929,8 @@ public class WifiNetworkFactory extends NetworkFactory {
*
* @return true if a pre-approved network was found for connection, false otherwise.
*/
- private boolean triggerConnectIfUserApprovedMatchFound(boolean revokeNormalBypass) {
+ private boolean triggerConnectIfUserApprovedMatchFound(boolean revokeNormalBypass,
+ ScanResult[] scanResults) {
if (mActiveSpecificNetworkRequestSpecifier == null) return false;
boolean requestForSingleAccessPoint = isActiveRequestForSingleAccessPoint();
if (!requestForSingleAccessPoint && !isActiveRequestForSingleNetwork()) {
@@ -1939,7 +1955,9 @@ public class WifiNetworkFactory extends NetworkFactory {
}
return false;
}
- if (requestForSingleAccessPoint) {
+ List<ScanResult> matchedScanResults =
+ getNetworksMatchingActiveNetworkRequest(scanResults);
+ if (requestForSingleAccessPoint && !matchedScanResults.isEmpty()) {
Log.v(TAG, "Approved access point found in matching scan results. "
+ "Triggering connect " + ssid + "/" + bssid);
// Request is for a single AP which is already approved. Connect directly.
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 445bf562f8..35316d65d4 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -21,6 +21,8 @@ import static android.net.wifi.WifiNetworkSelectionConfig.ASSOCIATED_NETWORK_SEL
import static android.net.wifi.WifiNetworkSelectionConfig.ASSOCIATED_NETWORK_SELECTION_OVERRIDE_ENABLED;
import static android.net.wifi.WifiNetworkSelectionConfig.ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE;
+import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -218,7 +220,7 @@ public class WifiNetworkSelector {
// be retrieved in bugreport. It is also used to print the log in the console.
private void localLog(String log) {
mLocalLog.log(log);
- if (mVerboseLoggingEnabled) Log.d(TAG, log);
+ if (mVerboseLoggingEnabled) Log.d(TAG, log, null);
}
/**
@@ -426,12 +428,7 @@ public class WifiNetworkSelector {
}
- private boolean isNetworkSelectionNeeded(@NonNull List<ScanDetail> scanDetails,
- @NonNull List<ClientModeManagerState> cmmStates) {
- if (scanDetails.size() == 0) {
- localLog("Empty connectivity scan results. Skip network selection.");
- return false;
- }
+ private boolean isNetworkSelectionNeeded(@NonNull List<ClientModeManagerState> cmmStates) {
for (ClientModeManagerState cmmState : cmmStates) {
// network selection needed by this CMM instance, perform network selection
if (isNetworkSelectionNeededForCmm(cmmState)) {
@@ -927,6 +924,7 @@ public class WifiNetworkSelector {
public final boolean ipProvisioningTimedOut;
/** Currently connected network */
public final WifiInfo wifiInfo;
+ public final ActiveModeManager.ClientRole role;
ClientModeManagerState(@NonNull ClientModeManager clientModeManager) {
ifaceName = clientModeManager.getInterfaceName();
@@ -934,6 +932,7 @@ public class WifiNetworkSelector {
disconnected = clientModeManager.isDisconnected();
ipProvisioningTimedOut = clientModeManager.isIpProvisioningTimedOut();
wifiInfo = clientModeManager.getConnectionInfo();
+ role = clientModeManager.getRole();
}
ClientModeManagerState() {
@@ -942,16 +941,19 @@ public class WifiNetworkSelector {
disconnected = true;
wifiInfo = new WifiInfo();
ipProvisioningTimedOut = false;
+ role = null;
}
@VisibleForTesting
ClientModeManagerState(@NonNull String ifaceName, boolean connected, boolean disconnected,
- @NonNull WifiInfo wifiInfo, boolean ipProvisioningTimedOut) {
+ @NonNull WifiInfo wifiInfo, boolean ipProvisioningTimedOut,
+ ActiveModeManager.ClientRole role) {
this.ifaceName = ifaceName;
this.connected = connected;
this.disconnected = disconnected;
this.wifiInfo = wifiInfo;
this.ipProvisioningTimedOut = ipProvisioningTimedOut;
+ this.role = role;
}
@Override
@@ -962,6 +964,7 @@ public class WifiNetworkSelector {
return Objects.equals(ifaceName, thatCmmState.ifaceName)
&& connected == thatCmmState.connected
&& disconnected == thatCmmState.disconnected
+ && role == thatCmmState.role
// Since wifiinfo does not have equals currently.
&& Objects.equals(wifiInfo.getSSID(), thatCmmState.wifiInfo.getSSID())
&& Objects.equals(wifiInfo.getBSSID(), thatCmmState.wifiInfo.getBSSID());
@@ -970,12 +973,13 @@ public class WifiNetworkSelector {
@Override
public int hashCode() {
return Objects.hash(ifaceName, connected, disconnected,
- wifiInfo.getSSID(), wifiInfo.getBSSID());
+ wifiInfo.getSSID(), wifiInfo.getBSSID(), role);
}
@Override
public String toString() {
return "ClientModeManagerState: " + ifaceName
+ + ", role:" + role
+ ", connection state: "
+ (connected ? " connected" : (disconnected ? " disconnected" : "unknown"))
+ ", WifiInfo: " + wifiInfo;
@@ -1036,6 +1040,20 @@ public class WifiNetworkSelector {
mLastSelectionWeightEnabled = enabled;
}
+ private String getConnectChoiceKey(@NonNull List<ClientModeManagerState> cmmStates) {
+ for (ClientModeManagerState cmmState : cmmStates) {
+ if (cmmState.role != ROLE_CLIENT_PRIMARY) {
+ continue;
+ }
+ WifiConfiguration currentNetwork =
+ mWifiConfigManager.getConfiguredNetwork(cmmState.wifiInfo.getNetworkId());
+ if (currentNetwork != null) {
+ return currentNetwork.getNetworkSelectionStatus().getConnectChoice();
+ }
+ }
+ return null;
+ }
+
/**
* Returns the list of Candidates from networks in range.
*
@@ -1048,15 +1066,14 @@ public class WifiNetworkSelector {
* @param oemPaidNetworkAllowed True if oem paid networks are allowed for connection
* @param oemPrivateNetworkAllowed True if oem private networks are allowed for connection
* @param restrictedNetworkAllowedUids a set of Uids are allowed for restricted network
- * @param multiInternetNetworkAllowed True if multi internet networks are allowed for
- * connection.
+ * @param skipSufficiencyCheck True to skip network sufficiency check
* @return list of valid Candidate(s)
*/
public List<WifiCandidates.Candidate> getCandidatesFromScan(
@NonNull List<ScanDetail> scanDetails, @NonNull Set<String> bssidBlocklist,
@NonNull List<ClientModeManagerState> cmmStates, boolean untrustedNetworkAllowed,
boolean oemPaidNetworkAllowed, boolean oemPrivateNetworkAllowed,
- Set<Integer> restrictedNetworkAllowedUids, boolean multiInternetNetworkAllowed) {
+ Set<Integer> restrictedNetworkAllowedUids, boolean skipSufficiencyCheck) {
mFilteredNetworks.clear();
mConnectableNetworks.clear();
if (scanDetails.size() == 0) {
@@ -1071,58 +1088,73 @@ public class WifiNetworkSelector {
for (NetworkNominator registeredNominator : mNominators) {
registeredNominator.update(scanDetails);
}
- // Update the matching profiles into WifiConfigManager, help displaying Passpoint networks
- // in Wifi Picker
- mWifiInjector.getPasspointNetworkNominateHelper().updatePasspointConfig(scanDetails);
-
- // Shall we start network selection at all?
- if (!multiInternetNetworkAllowed && !isNetworkSelectionNeeded(scanDetails, cmmStates)) {
- return null;
- }
// Filter out unwanted networks.
mFilteredNetworks = filterScanResults(scanDetails, bssidBlocklist, cmmStates);
if (mFilteredNetworks.size() == 0) {
return null;
}
+ // Update the matching profiles into WifiConfigManager, help displaying Passpoint networks
+ // in Wifi Picker
+ mWifiInjector.getPasspointNetworkNominateHelper().updatePasspointConfig(mFilteredNetworks);
+
+ boolean networkSelectionNeeded = skipSufficiencyCheck
+ || isNetworkSelectionNeeded(cmmStates);
+ final String userConnectChoiceKey;
+ if (!networkSelectionNeeded) {
+ userConnectChoiceKey = getConnectChoiceKey(cmmStates);
+ if (userConnectChoiceKey == null) {
+ return null;
+ }
+ // Continue candidate selection but only allow the user connect choice as candidate
+ localLog("Current network is sufficient. Continue network selection only "
+ + "considering user connect choice: " + userConnectChoiceKey);
+ } else {
+ userConnectChoiceKey = null;
+ }
WifiCandidates wifiCandidates = new WifiCandidates(mWifiScoreCard, mContext);
- for (ClientModeManagerState cmmState : cmmStates) {
- // Always get the current BSSID from WifiInfo in case that firmware initiated
- // roaming happened.
- String currentBssid = cmmState.wifiInfo.getBSSID();
- WifiConfiguration currentNetwork =
- mWifiConfigManager.getConfiguredNetwork(cmmState.wifiInfo.getNetworkId());
- if (currentNetwork != null) {
- wifiCandidates.setCurrent(currentNetwork.networkId, currentBssid);
- // We always want the current network to be a candidate so that it can participate.
- // It may also get re-added by a nominator, in which case this fallback
- // will be replaced.
- MacAddress bssid = MacAddress.fromString(currentBssid);
- SecurityParams params = currentNetwork.getNetworkSelectionStatus()
- .getLastUsedSecurityParams();
- if (null == params) {
- localLog("No known candidate security params for current network.");
- continue;
+ if (userConnectChoiceKey == null) {
+ // Add connected network as candidates unless only considering connect choice.
+ for (ClientModeManagerState cmmState : cmmStates) {
+ // Always get the current BSSID from WifiInfo in case that firmware initiated
+ // roaming happened.
+ String currentBssid = cmmState.wifiInfo.getBSSID();
+ WifiConfiguration currentNetwork =
+ mWifiConfigManager.getConfiguredNetwork(cmmState.wifiInfo.getNetworkId());
+ if (currentNetwork != null) {
+ wifiCandidates.setCurrent(currentNetwork.networkId, currentBssid);
+ // We always want the current network to be a candidate so that it can
+ // participate.
+ // It may also get re-added by a nominator, in which case this fallback
+ // will be replaced.
+ MacAddress bssid = MacAddress.fromString(currentBssid);
+ SecurityParams params = currentNetwork.getNetworkSelectionStatus()
+ .getLastUsedSecurityParams();
+ if (null == params) {
+ localLog("No known candidate security params for current network.");
+ continue;
+ }
+ WifiCandidates.Key key = new WifiCandidates.Key(
+ ScanResultMatchInfo.fromWifiConfiguration(currentNetwork),
+ bssid, currentNetwork.networkId,
+ params.getSecurityType());
+ ScanDetail scanDetail = findScanDetailForBssid(mFilteredNetworks, currentBssid);
+ int predictedTputMbps = (scanDetail == null) ? 0
+ : predictThroughput(scanDetail);
+ wifiCandidates.add(key, currentNetwork,
+ NetworkNominator.NOMINATOR_ID_CURRENT,
+ cmmState.wifiInfo.getRssi(),
+ cmmState.wifiInfo.getFrequency(),
+ ScanResult.CHANNEL_WIDTH_20MHZ, // channel width unavailable in WifiInfo
+ calculateLastSelectionWeight(currentNetwork.networkId,
+ WifiConfiguration.isMetered(currentNetwork, cmmState.wifiInfo)),
+ WifiConfiguration.isMetered(currentNetwork, cmmState.wifiInfo),
+ isFromCarrierOrPrivilegedApp(currentNetwork),
+ predictedTputMbps,
+ (scanDetail != null) ? scanDetail.getScanResult().getApMldMacAddress()
+ : null);
}
- WifiCandidates.Key key = new WifiCandidates.Key(
- ScanResultMatchInfo.fromWifiConfiguration(currentNetwork),
- bssid, currentNetwork.networkId,
- params.getSecurityType());
- ScanDetail scanDetail = findScanDetailForBssid(mFilteredNetworks, currentBssid);
- int predictedTputMbps = (scanDetail == null) ? 0 : predictThroughput(scanDetail);
- wifiCandidates.add(key, currentNetwork,
- NetworkNominator.NOMINATOR_ID_CURRENT,
- cmmState.wifiInfo.getRssi(),
- cmmState.wifiInfo.getFrequency(),
- ScanResult.CHANNEL_WIDTH_20MHZ, // channel width not available in WifiInfo
- calculateLastSelectionWeight(currentNetwork.networkId,
- WifiConfiguration.isMetered(currentNetwork, cmmState.wifiInfo)),
- WifiConfiguration.isMetered(currentNetwork, cmmState.wifiInfo),
- isFromCarrierOrPrivilegedApp(currentNetwork),
- predictedTputMbps,
- (scanDetail != null) ? scanDetail.getScanResult().getApMldMacAddress()
- : null);
}
}
@@ -1141,6 +1173,10 @@ public class WifiNetworkSelector {
WifiCandidates.Key key = wifiCandidates.keyFromScanDetailAndConfig(
scanDetail, config);
if (key != null) {
+ if (userConnectChoiceKey != null
+ && !userConnectChoiceKey.equals(config.getProfileKey())) {
+ return;
+ }
boolean metered = false;
for (ClientModeManagerState cmmState : cmmStates) {
if (isEverMetered(config, cmmState.wifiInfo, scanDetail)) {
@@ -1181,6 +1217,16 @@ public class WifiNetworkSelector {
}
/**
+ * Check Wi-Fi7 is enabled for all candidates.
+ */
+ private boolean isWifi7Enabled(List<WifiCandidates.Candidate> candidates) {
+ for (WifiCandidates.Candidate candidate : candidates) {
+ if (!mWifiConfigManager.isWifi7Enabled(candidate.getNetworkConfigId())) return false;
+ }
+ return true;
+ }
+
+ /**
* Update multi link candidate's throughput which is used in network selection by
* {@link ThroughputScorer}
*
@@ -1221,6 +1267,7 @@ public class WifiNetworkSelector {
for (List<WifiCandidates.Candidate> mlCandidates :
wifiCandidates.getMultiLinkCandidates()) {
+ if (!isWifi7Enabled(mlCandidates)) continue;
for (List<Integer> bands : simultaneousBandCombinations) {
// Limit the radios/bands to maximum STR link supported in multi link operation.
if (bands.size() > maxMloStrLinkCount) break;
@@ -1453,7 +1500,7 @@ public class WifiNetworkSelector {
/**
* Using the registered Scorers, choose the best network from the list of Candidate(s).
* The ScanDetailCache is also updated here.
- * @param candidates - Candidates to perferm network selection on.
+ * @param candidates - Candidates to perform network selection on.
* @param overrideEnabled If it is allowed to override candidate with User Connect Choice.
* @return WifiConfiguration - the selected network, or null.
*/
diff --git a/service/java/com/android/server/wifi/WifiPseudonymManager.java b/service/java/com/android/server/wifi/WifiPseudonymManager.java
index e102dd6e0a..5418a632ec 100644
--- a/service/java/com/android/server/wifi/WifiPseudonymManager.java
+++ b/service/java/com/android/server/wifi/WifiPseudonymManager.java
@@ -428,7 +428,7 @@ public final class WifiPseudonymManager {
if (!mVerboseLogEnabled) {
return;
}
- Log.d(TAG, msg);
+ Log.d(TAG, msg, null);
}
@VisibleForTesting
diff --git a/service/java/com/android/server/wifi/WifiRoamingConfigStore.java b/service/java/com/android/server/wifi/WifiRoamingConfigStore.java
new file mode 100644
index 0000000000..adce4365fc
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiRoamingConfigStore.java
@@ -0,0 +1,235 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.wifi.WifiManager;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
+import com.android.server.wifi.util.XmlUtil;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Store data for storing B2B wifi roaming policies.
+ * These are key (string) / value pairs that are stored in
+ * WifiConfigStore.xml file in a separate section.
+ */
+public class WifiRoamingConfigStore {
+ private static final String TAG = "WifiRoamingConfigStore";
+ private static final int INVALID_ROAMING_MODE = -1;
+
+ // To store roaming policies that are added by the device owner (DO) or
+ // the profile owner of an organization owned device (COPE).
+ private final Map<String, Integer> mDeviceAdminRoamingPolicies = new ArrayMap<>();
+ // To store roaming policies that are added by non-admins.
+ private final Map<String, Integer> mNonAdminRoamingPolicies = new ArrayMap<>();
+ private final WifiConfigManager mWifiConfigManager;
+ private boolean mHasNewDataToSerialize = false;
+
+ public WifiRoamingConfigStore(@NonNull WifiConfigManager wifiConfigManager,
+ @NonNull WifiConfigStore wifiConfigStore) {
+ mWifiConfigManager = wifiConfigManager;
+ // Register our data store.
+ wifiConfigStore.registerStoreData(new StoreData());
+ }
+
+ /**
+ * Trigger config store writes in the main wifi service looper's handler.
+ */
+ private void triggerSaveToStore() {
+ mHasNewDataToSerialize = true;
+ mWifiConfigManager.saveToStore(true);
+ }
+
+ /**
+ * Add a roaming policy to the corresponding stored policies.
+ *
+ * @param ssid of the network on which policy to be added.
+ * @param roamingMode denotes roaming mode value configured.
+ * @param isDeviceOwner flag denoting whether API is called by the device owner.
+ */
+ public void addRoamingMode(@NonNull String ssid, @NonNull int roamingMode,
+ boolean isDeviceOwner) {
+ if (isDeviceOwner) {
+ mDeviceAdminRoamingPolicies.put(ssid, roamingMode);
+ } else {
+ mNonAdminRoamingPolicies.put(ssid, roamingMode);
+ }
+ triggerSaveToStore();
+ }
+
+ /**
+ * Remove a roaming policy from the corresponding stored policies.
+ *
+ * @param ssid of the network on which policy to be removed.
+ * @param isDeviceOwner flag denoting whether API is called by the device owner.
+ */
+ public void removeRoamingMode(@NonNull String ssid, boolean isDeviceOwner) {
+ if (isDeviceOwner) {
+ mDeviceAdminRoamingPolicies.remove(ssid);
+ } else {
+ mNonAdminRoamingPolicies.remove(ssid);
+ }
+ triggerSaveToStore();
+ }
+
+ /**
+ * Retrieve roaming policy/mode for the given network name.
+ *
+ * @param ssid of the network which needs to be queried to fetch policy.
+ * @return roaming mode stored in policy list,
+ * {@value WifiManager#ROAMING_MODE_NORMAL} if the key does not exist.
+ */
+ public @NonNull int getRoamingMode(@NonNull String ssid) {
+ int roamingMode;
+ roamingMode = mDeviceAdminRoamingPolicies.getOrDefault(ssid, INVALID_ROAMING_MODE);
+ if (roamingMode == INVALID_ROAMING_MODE) {
+ roamingMode = mNonAdminRoamingPolicies.getOrDefault(ssid,
+ WifiManager.ROAMING_MODE_NORMAL);
+ }
+ return roamingMode;
+ }
+
+ /**
+ * Get all the network roaming policies configured.
+ *
+ * @param isDeviceOwner flag denoting whether API is called by the device owner.
+ * @return Map of corresponding policies for the API caller,
+ * where key is ssid and value is roaming mode/policy configured for that ssid.
+ */
+ public Map<String, Integer> getPerSsidRoamingModes(boolean isDeviceOwner) {
+ Map<String, Integer> roamingPolicies = new ArrayMap<>();
+ if (isDeviceOwner) {
+ roamingPolicies.putAll(mDeviceAdminRoamingPolicies);
+ } else {
+ roamingPolicies.putAll(mNonAdminRoamingPolicies);
+ }
+ return roamingPolicies;
+ }
+
+ /**
+ * Dump all roaming policies for debugging.
+ */
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println();
+ pw.println("Dump of " + TAG);
+ pw.println("DEVICE_ADMIN_POLICIES");
+ for (Map.Entry<String, Integer> entry : mDeviceAdminRoamingPolicies.entrySet()) {
+ pw.print(entry.getKey());
+ pw.print("=");
+ pw.println(entry.getValue());
+ }
+ pw.println();
+ pw.println("NON_ADMIN_POLICIES");
+ for (Map.Entry<String, Integer> entry : mNonAdminRoamingPolicies.entrySet()) {
+ pw.print(entry.getKey());
+ pw.print("=");
+ pw.println(entry.getValue());
+ }
+ }
+
+ /**
+ * Store data for persisting the roaming policies data to config store.
+ */
+ private class StoreData implements WifiConfigStore.StoreData {
+ private static final String XML_TAG_SECTION_HEADER = "RoamingPolicies";
+ private static final String XML_TAG_DEVICE_ADMIN_POLICIES = "DeviceAdminPolicies";
+ private static final String XML_TAG_NON_ADMIN_POLICIES = "NonAdminPolicies";
+
+ @Override
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
+ throws XmlPullParserException, IOException {
+ XmlUtil.writeNextValue(out, XML_TAG_DEVICE_ADMIN_POLICIES, mDeviceAdminRoamingPolicies);
+ XmlUtil.writeNextValue(out, XML_TAG_NON_ADMIN_POLICIES, mNonAdminRoamingPolicies);
+ mHasNewDataToSerialize = false;
+ }
+
+ @Override
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
+ throws XmlPullParserException, IOException {
+ if (in == null) {
+ mDeviceAdminRoamingPolicies.clear();
+ mNonAdminRoamingPolicies.clear();
+ return;
+ }
+ Map<String, Integer> deviceAdminPolicies = null, nonAdminPolicies = null;
+ while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
+ String[] valueName = new String[1];
+ Object value = XmlUtil.readCurrentValue(in, valueName);
+ if (TextUtils.isEmpty(valueName[0])) {
+ throw new XmlPullParserException("Missing value name");
+ }
+ switch (valueName[0]) {
+ case XML_TAG_DEVICE_ADMIN_POLICIES:
+ deviceAdminPolicies = (HashMap) value;
+ break;
+ case XML_TAG_NON_ADMIN_POLICIES:
+ nonAdminPolicies = (HashMap) value;
+ break;
+ default:
+ Log.w(TAG, "Ignoring unknown tag under " + XML_TAG_SECTION_HEADER + ": "
+ + valueName[0]);
+ break;
+ }
+ }
+ if (deviceAdminPolicies != null) {
+ mDeviceAdminRoamingPolicies.putAll(deviceAdminPolicies);
+ }
+ if (nonAdminPolicies != null) {
+ mNonAdminRoamingPolicies.putAll(nonAdminPolicies);
+ }
+ }
+
+ @Override
+ public void resetData() {
+ mDeviceAdminRoamingPolicies.clear();
+ mNonAdminRoamingPolicies.clear();
+ }
+
+ @Override
+ public boolean hasNewDataToSerialize() {
+ return mHasNewDataToSerialize;
+ }
+
+ @Override
+ public String getName() {
+ return XML_TAG_SECTION_HEADER;
+ }
+
+ @Override
+ public @WifiConfigStore.StoreFileId int getStoreFileId() {
+ // Shared general store.
+ return WifiConfigStore.STORE_FILE_SHARED_GENERAL;
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/WifiScoreCard.java b/service/java/com/android/server/wifi/WifiScoreCard.java
index 4de21283c0..e94e337874 100644
--- a/service/java/com/android/server/wifi/WifiScoreCard.java
+++ b/service/java/com/android/server/wifi/WifiScoreCard.java
@@ -119,7 +119,7 @@ public class WifiScoreCard {
static final int SUFFICIENT_RECENT_STATS_ONLY = 1;
static final int SUFFICIENT_RECENT_PREV_STATS = 2;
- private static final int MAX_FREQUENCIES_PER_SSID = 10;
+ private static final int MAX_FREQUENCIES_PER_SSID = 30;
private static final int MAX_TRAFFIC_STATS_POLL_TIME_DELTA_MS = 6_000;
private final Clock mClock;
@@ -2097,13 +2097,13 @@ public class WifiScoreCard {
private void logd(String string) {
if (mVerboseLoggingEnabled) {
- Log.d(TAG, string);
+ Log.d(TAG, string, null);
}
}
private void logv(String string) {
if (mVerboseLoggingEnabled) {
- Log.v(TAG, string);
+ Log.v(TAG, string, null);
}
mLocalLog.log(string);
}
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index bf162ceb08..697d908d85 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -27,6 +27,7 @@ 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.SAP_START_FAILURE_GENERAL;
import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL;
import static android.net.wifi.WifiManager.VERBOSE_LOGGING_LEVEL_WIFI_AWARE_ENABLED_ONLY;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
@@ -55,6 +56,7 @@ 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.ScanRequestProxy.createBroadcastOptionsForScanResultsAvailable;
import static com.android.server.wifi.SelfRecovery.REASON_API_CALL;
+import static com.android.server.wifi.WifiSettingsConfigStore.D2D_ALLOWED_WHEN_INFRA_STA_DISABLED;
import static com.android.server.wifi.WifiSettingsConfigStore.SHOW_DIALOG_WHEN_THIRD_PARTY_APPS_ENABLE_WIFI;
import static com.android.server.wifi.WifiSettingsConfigStore.SHOW_DIALOG_WHEN_THIRD_PARTY_APPS_ENABLE_WIFI_SET_BY_API;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_AWARE_VERBOSE_LOGGING_ENABLED;
@@ -93,12 +95,14 @@ import android.net.MacAddress;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkStack;
+import android.net.TetheringManager;
import android.net.Uri;
import android.net.ip.IpClientUtil;
import android.net.wifi.BaseWifiService;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.IActionListener;
import android.net.wifi.IBooleanListener;
+import android.net.wifi.IByteArrayListener;
import android.net.wifi.ICoexCallback;
import android.net.wifi.IDppCallback;
import android.net.wifi.IIntegerListener;
@@ -107,6 +111,7 @@ import android.net.wifi.ILastCallerListener;
import android.net.wifi.IListListener;
import android.net.wifi.ILocalOnlyConnectionStatusListener;
import android.net.wifi.ILocalOnlyHotspotCallback;
+import android.net.wifi.IMapListener;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.IOnWifiActivityEnergyInfoListener;
import android.net.wifi.IOnWifiDriverCountryCodeChangedListener;
@@ -119,17 +124,22 @@ import android.net.wifi.ISubsystemRestartCallback;
import android.net.wifi.ISuggestionConnectionStatusListener;
import android.net.wifi.ISuggestionUserApprovalStatusListener;
import android.net.wifi.ITrafficStateCallback;
+import android.net.wifi.ITwtCallback;
+import android.net.wifi.ITwtCapabilitiesListener;
+import android.net.wifi.ITwtStatsListener;
import android.net.wifi.IWifiBandsListener;
import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.IWifiLowLatencyLockListener;
import android.net.wifi.IWifiNetworkSelectionConfigListener;
import android.net.wifi.IWifiNetworkStateChangedListener;
import android.net.wifi.IWifiVerboseLoggingStatusChangedListener;
+import android.net.wifi.MscsParams;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApInfo;
+import android.net.wifi.SoftApState;
import android.net.wifi.WifiAnnotations.WifiStandard;
import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiBands;
@@ -142,10 +152,9 @@ import android.net.wifi.WifiManager.AddNetworkResult;
import android.net.wifi.WifiManager.CoexRestriction;
import android.net.wifi.WifiManager.DeviceMobilityState;
import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
+import android.net.wifi.WifiManager.RoamingMode;
import android.net.wifi.WifiManager.SapClientBlockedReason;
-import android.net.wifi.WifiManager.SapStartFailure;
import android.net.wifi.WifiManager.SuggestionConnectionStatusListener;
-import android.net.wifi.WifiManager.WifiApState;
import android.net.wifi.WifiNetworkSelectionConfig;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
@@ -153,6 +162,9 @@ import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.twt.TwtRequest;
+import android.net.wifi.twt.TwtSession;
+import android.net.wifi.twt.TwtSessionCallback;
import android.net.wifi.util.ScanResultUtil;
import android.os.AsyncTask;
import android.os.Binder;
@@ -239,6 +251,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
+import java.util.function.IntConsumer;
/**
* WifiService handles remote WiFi operation requests by implementing
@@ -276,6 +289,8 @@ public class WifiServiceImpl extends BaseWifiService {
/** Backup/Restore Module */
private final WifiBackupRestore mWifiBackupRestore;
private final SoftApBackupRestore mSoftApBackupRestore;
+ private final WifiSettingsBackupRestore mWifiSettingsBackupRestore;
+ private final BackupRestoreController mBackupRestoreController;
private final CoexManager mCoexManager;
private final WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
private final WifiConfigManager mWifiConfigManager;
@@ -381,6 +396,7 @@ public class WifiServiceImpl extends BaseWifiService {
private WifiNetworkSelectionConfig mNetworkSelectionConfig;
private ApplicationQosPolicyRequestHandler mApplicationQosPolicyRequestHandler;
private final AfcManager mAfcManager;
+ private final TwtManager mTwtManager;
/**
* The wrapper of SoftApCallback is used in WifiService internally.
@@ -390,7 +406,7 @@ public class WifiServiceImpl extends BaseWifiService {
/**
* see: {@code WifiManager.SoftApCallback#onStateChanged(int, int)}
*/
- void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason) {}
+ void onStateChanged(SoftApState state) {}
/**
* The callback which only is used in service internally and pass to WifiManager.
@@ -418,12 +434,11 @@ public class WifiServiceImpl extends BaseWifiService {
* Notify register the state of soft AP changed.
*/
public void notifyRegisterOnStateChanged(RemoteCallbackList<ISoftApCallback> callbacks,
- int state, int failureReason) {
+ SoftApState state) {
int itemCount = callbacks.beginBroadcast();
for (int i = 0; i < itemCount; i++) {
try {
- callbacks.getBroadcastItem(i).onStateChanged(state,
- failureReason);
+ callbacks.getBroadcastItem(i).onStateChanged(state);
} catch (RemoteException e) {
Log.e(TAG, "onStateChanged: remote exception -- " + e);
}
@@ -497,7 +512,6 @@ public class WifiServiceImpl extends BaseWifiService {
}
}
-
public WifiServiceImpl(WifiContext context, WifiInjector wifiInjector) {
mContext = context;
mWifiInjector = wifiInjector;
@@ -518,6 +532,8 @@ public class WifiServiceImpl extends BaseWifiService {
mWifiMulticastLockManager = mWifiInjector.getWifiMulticastLockManager();
mWifiBackupRestore = mWifiInjector.getWifiBackupRestore();
mSoftApBackupRestore = mWifiInjector.getSoftApBackupRestore();
+ mWifiSettingsBackupRestore = mWifiInjector.getWifiSettingsBackupRestore();
+ mBackupRestoreController = mWifiInjector.getBackupRestoreController();
mWifiApConfigStore = mWifiInjector.getWifiApConfigStore();
mWifiPermissionsUtil = mWifiInjector.getWifiPermissionsUtil();
mLog = mWifiInjector.makeLog(TAG);
@@ -560,6 +576,7 @@ public class WifiServiceImpl extends BaseWifiService {
mApplicationQosPolicyRequestHandler = mWifiInjector.getApplicationQosPolicyRequestHandler();
mWifiPulledAtomLogger = mWifiInjector.getWifiPulledAtomLogger();
mAfcManager = mWifiInjector.getAfcManager();
+ mTwtManager = mWifiInjector.getTwtManager();
}
/**
@@ -586,6 +603,15 @@ public class WifiServiceImpl extends BaseWifiService {
mWifiInjector.getWifiScanAlwaysAvailableSettingsCompatibility().initialize();
mWifiInjector.getWifiNotificationManager().createNotificationChannels();
// Align the value between config stroe (i.e.WifiConfigStore.xml) and WifiGlobals.
+ mSettingsConfigStore.registerChangeListener(WIFI_WEP_ALLOWED,
+ (key, value) -> {
+ if (mWifiGlobals.isWepAllowed() != value) {
+ // It should only happen when settings is restored from cloud.
+ handleWepAllowedChanged(value);
+ Log.i(TAG, "(Cloud Restoration) Wep allowed is changed to " + value);
+ }
+ },
+ new Handler(mWifiHandlerThread.getLooper()));
mWifiGlobals.setWepAllowed(mSettingsConfigStore.get(WIFI_WEP_ALLOWED));
mContext.registerReceiver(
new BroadcastReceiver() {
@@ -694,7 +720,6 @@ public class WifiServiceImpl extends BaseWifiService {
mWifiTetheringDisallowed = mUserManager.getUserRestrictions()
.getBoolean(UserManager.DISALLOW_WIFI_TETHERING);
}
- setPulledAtomCallbacks();
// Adding optimizations of only receiving broadcasts when wifi is enabled
// can result in race conditions when apps toggle wifi in the background
@@ -705,7 +730,6 @@ public class WifiServiceImpl extends BaseWifiService {
mActiveModeWarden.start();
registerForCarrierConfigChange();
mWifiInjector.getAdaptiveConnectivityEnabledSettingObserver().initialize();
- mWifiInjector.getWifiDeviceStateChangeManager().handleBootCompleted();
mIsWifiServiceStarted = true;
});
}
@@ -720,6 +744,7 @@ public class WifiServiceImpl extends BaseWifiService {
private void updateLocationMode() {
mIsLocationModeEnabled = mWifiPermissionsUtil.isLocationModeEnabled();
mWifiConnectivityManager.setLocationModeEnabled(mIsLocationModeEnabled);
+ mWifiNative.setLocationModeEnabled(mIsLocationModeEnabled);
}
/**
@@ -843,8 +868,6 @@ public class WifiServiceImpl extends BaseWifiService {
// Start to listen country code change to avoid query supported channels causes boot
// time increased.
mCountryCode.registerListener(mCountryCodeTracker);
- mTetheredSoftApTracker.handleBootCompleted();
- mLohsSoftApTracker.handleBootCompleted();
mWifiInjector.getSarManager().handleBootCompleted();
mWifiInjector.getSsidTranslator().handleBootCompleted();
mWifiInjector.getPasspointManager().handleBootCompleted();
@@ -855,6 +878,9 @@ public class WifiServiceImpl extends BaseWifiService {
mWifiConfigManager.updateTrustOnFirstUseFlag(isTrustOnFirstUseSupported());
}
updateVerboseLoggingEnabled();
+ mWifiInjector.getWifiDeviceStateChangeManager().handleBootCompleted();
+ setPulledAtomCallbacks();
+ mTwtManager.registerWifiNativeTwtEvents();
});
}
@@ -1166,10 +1192,7 @@ public class WifiServiceImpl extends BaseWifiService {
&& !isGuestUser())
|| isPrivileged(pid, uid)
|| mWifiPermissionsUtil.isAdmin(uid, packageName)
- || mWifiPermissionsUtil.isSystem(packageName, uid)
- // TODO(b/140540984): Remove this bypass.
- || (mWifiPermissionsUtil.checkSystemAlertWindowPermission(uid, packageName)
- && !isGuestUser());
+ || mWifiPermissionsUtil.isSystem(packageName, uid);
}
private boolean isGuestUser() {
@@ -1261,7 +1284,7 @@ public class WifiServiceImpl extends BaseWifiService {
// for any requester. To prevent non-privileged apps from deleting a tethering AP by
// enabling Wi-Fi, only allow privileged apps to toggle Wi-Fi if tethering AP is up.
if (!SdkLevel.isAtLeastS() && !isPrivileged
- && mTetheredSoftApTracker.getState() == WIFI_AP_STATE_ENABLED) {
+ && mTetheredSoftApTracker.getState().getState() == WIFI_AP_STATE_ENABLED) {
mLog.err("setWifiEnabled with SoftAp enabled: only Settings can toggle wifi").flush();
return false;
}
@@ -1528,7 +1551,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("getWifiApEnabledState uid=%").c(Binder.getCallingUid()).flush();
}
- return mTetheredSoftApTracker.getState();
+ return mTetheredSoftApTracker.getState().getState();
}
/**
@@ -1685,7 +1708,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (!startSoftApInternal(new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
mTetheredSoftApTracker.getSoftApCapability(),
- mCountryCode.getCountryCode()), requestorWs)) {
+ mCountryCode.getCountryCode(), null), requestorWs)) {
mTetheredSoftApTracker.setFailedWhileEnabling();
return false;
}
@@ -1715,7 +1738,49 @@ public class WifiServiceImpl extends BaseWifiService {
}
mLog.info("startTetheredHotspot uid=%").c(callingUid).flush();
+ return startTetheredHotspotInternal(new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
+ mTetheredSoftApTracker.getSoftApCapability(),
+ mCountryCode.getCountryCode(), null /* request */), callingUid, packageName);
+ }
+
+ /**
+ * see {@link WifiManager#startTetheredHotspotRequest(TetheringManager.TetheringRequest)}
+ * @param request TetheringRequest details of the Soft AP.
+ * @return {@code true} if softap start was triggered
+ * @throws SecurityException if the caller does not have permission to start softap
+ */
+ @Override
+ public boolean startTetheredHotspotRequest(@NonNull TetheringManager.TetheringRequest request,
+ @NonNull String packageName) {
+ if (request == null) {
+ throw new IllegalArgumentException("TetheringRequest must not be null");
+ }
+
+ // NETWORK_STACK is a signature only permission.
+ enforceNetworkStackPermission();
+ int callingUid = Binder.getCallingUid();
+ mWifiPermissionsUtil.checkPackage(callingUid, packageName);
+
+ // If user restriction is set, cannot start softap
+ if (mWifiTetheringDisallowed) {
+ mLog.err("startTetheredHotspotRequest with user restriction: not permitted").flush();
+ return false;
+ }
+ mLog.info("startTetheredHotspotRequest uid=%").c(callingUid).flush();
+ return startTetheredHotspotInternal(new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, null /* config */,
+ mTetheredSoftApTracker.getSoftApCapability(),
+ mCountryCode.getCountryCode(), request), callingUid, packageName);
+ }
+
+ /**
+ * Internal method to start tethered hotspot. Callers of this method should have already checked
+ * proper permissions beyond the NetworkStack permission.
+ */
+ private boolean startTetheredHotspotInternal(@NonNull SoftApModeConfiguration modeConfig,
+ int callingUid, String packageName) {
if (!mTetheredSoftApTracker.setEnablingIfAllowed()) {
mLog.err("Tethering is already active or activating.").flush();
return false;
@@ -1732,10 +1797,7 @@ public class WifiServiceImpl extends BaseWifiService {
Binder.restoreCallingIdentity(id);
}
- if (!startSoftApInternal(new SoftApModeConfiguration(
- WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
- mTetheredSoftApTracker.getSoftApCapability(),
- mCountryCode.getCountryCode()), requestorWs)) {
+ if (!startSoftApInternal(modeConfig, requestorWs)) {
mTetheredSoftApTracker.setFailedWhileEnabling();
return false;
}
@@ -1873,31 +1935,44 @@ public class WifiServiceImpl extends BaseWifiService {
Log.e(TAG, "Country code not consistent! expect " + countryCode + " actual "
+ mCountryCode.getCurrentDriverCountryCode());
}
- mTetheredSoftApTracker.updateAvailChannelListInSoftApCapability(countryCode);
- mLohsSoftApTracker.updateAvailChannelListInSoftApCapability(countryCode);
- mActiveModeWarden.updateSoftApCapability(
- mTetheredSoftApTracker.getSoftApCapability(),
- WifiManager.IFACE_IP_MODE_TETHERED);
- // TODO: b/197529327 trigger Lohs capability callback & update available
- // channels
- mActiveModeWarden.updateSoftApCapability(
- mLohsSoftApTracker.getSoftApCapability(),
- WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
// 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<>();
+ SparseArray<int[]> channelMap = new SparseArray<>(
+ SoftApConfiguration.BAND_TYPES.length);
for (int band : SoftApConfiguration.BAND_TYPES) {
+ if (!ApConfigUtil.isSoftApBandSupported(mContext, band)) {
+ continue;
+ }
List<Integer> freqsForBand = ApConfigUtil.getAvailableChannelFreqsForBand(
band, mWifiNative, res, true);
if (freqsForBand != null) {
freqs.addAll(freqsForBand);
+ int[] channel = new int[freqsForBand.size()];
+ for (int i = 0; i < freqsForBand.size(); i++) {
+ channel[i] = ScanResult.convertFrequencyMhzToChannelIfSupported(
+ freqsForBand.get(i));
+ }
+ channelMap.put(band, channel);
}
}
mSettingsConfigStore.put(
WifiSettingsConfigStore.WIFI_AVAILABLE_SOFT_AP_FREQS_MHZ,
new JSONArray(freqs).toString());
+ mTetheredSoftApTracker.updateAvailChannelListInSoftApCapability(countryCode,
+ channelMap);
+ mLohsSoftApTracker.updateAvailChannelListInSoftApCapability(countryCode,
+ channelMap);
+ mActiveModeWarden.updateSoftApCapability(
+ mTetheredSoftApTracker.getSoftApCapability(),
+ WifiManager.IFACE_IP_MODE_TETHERED);
+ // TODO: b/197529327 trigger Lohs capability callback & update available
+ // channels
+ mActiveModeWarden.updateSoftApCapability(
+ mLohsSoftApTracker.getSoftApCapability(),
+ WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
}
if (SdkLevel.isAtLeastT()) {
int itemCount = mRegisteredDriverCountryCodeListeners.beginBroadcast();
@@ -1943,7 +2018,9 @@ public class WifiServiceImpl extends BaseWifiService {
* {@link WifiManager#WIFI_AP_STATE_FAILED}
*/
private final Object mLock = new Object();
- private int mSoftApState = WIFI_AP_STATE_DISABLED;
+ @NonNull
+ private SoftApState mSoftApState =
+ new SoftApState(WIFI_AP_STATE_DISABLED, 0, null, null);
private Map<String, List<WifiClient>> mSoftApConnectedClientsMap = new HashMap();
private Map<String, SoftApInfo> mSoftApInfoMap = new HashMap();
private boolean mIsBridgedMode = false;
@@ -1952,33 +2029,37 @@ public class WifiServiceImpl extends BaseWifiService {
protected final RemoteCallbackList<ISoftApCallback> mRegisteredSoftApCallbacks =
new RemoteCallbackList<>();
- public int getState() {
+ public SoftApState getState() {
synchronized (mLock) {
return mSoftApState;
}
}
- public void setState(int state) {
+ public void setState(SoftApState softApState) {
synchronized (mLock) {
- mSoftApState = state;
+ mSoftApState = softApState;
}
}
public boolean setEnablingIfAllowed() {
synchronized (mLock) {
- if (mSoftApState != WIFI_AP_STATE_DISABLED
- && mSoftApState != WIFI_AP_STATE_FAILED) {
+ int state = mSoftApState.getState();
+ if (state != WIFI_AP_STATE_DISABLED
+ && state != WIFI_AP_STATE_FAILED) {
return false;
}
- mSoftApState = WIFI_AP_STATE_ENABLING;
+ mSoftApState = new SoftApState(
+ WIFI_AP_STATE_ENABLING, 0, null, null);
return true;
}
}
public void setFailedWhileEnabling() {
synchronized (mLock) {
- if (mSoftApState == WIFI_AP_STATE_ENABLING) {
- mSoftApState = WIFI_AP_STATE_FAILED;
+ int state = mSoftApState.getState();
+ if (state == WIFI_AP_STATE_ENABLING) {
+ mSoftApState = new SoftApState(
+ WIFI_AP_STATE_FAILED, 0, null, null);
}
}
}
@@ -2017,10 +2098,6 @@ public class WifiServiceImpl extends BaseWifiService {
}
}
- public void handleBootCompleted() {
- updateAvailChannelListInSoftApCapability(mCountryCode.getCurrentDriverCountryCode());
- }
-
public SoftApCapability getSoftApCapability() {
synchronized (mLock) {
if (mSoftApCapability == null) {
@@ -2029,14 +2106,15 @@ public class WifiServiceImpl extends BaseWifiService {
mSoftApCapability, mWifiInjector.getSettingsConfigStore());
// Default country code
mSoftApCapability = updateSoftApCapabilityWithAvailableChannelList(
- mSoftApCapability, mCountryCode.getCountryCode());
+ mSoftApCapability, mCountryCode.getCountryCode(), null);
}
return mSoftApCapability;
}
}
private SoftApCapability updateSoftApCapabilityWithAvailableChannelList(
- @NonNull SoftApCapability softApCapability, @Nullable String countryCode) {
+ @NonNull SoftApCapability softApCapability, @Nullable String countryCode,
+ @Nullable SparseArray<int[]> channelMap) {
if (!mIsBootComplete) {
// The available channel list is from wificond or HAL.
// It might be a failure or stuck during wificond or HAL init.
@@ -2046,16 +2124,30 @@ public class WifiServiceImpl extends BaseWifiService {
mSoftApCapability.setCountryCode(countryCode);
}
return ApConfigUtil.updateSoftApCapabilityWithAvailableChannelList(
- softApCapability, mContext, mWifiNative);
+ softApCapability, mContext, mWifiNative, channelMap);
}
- public void updateAvailChannelListInSoftApCapability(@Nullable String countryCode) {
+ public void updateAvailChannelListInSoftApCapability(@Nullable String countryCode,
+ @Nullable SparseArray<int[]> channelMap) {
onCapabilityChanged(updateSoftApCapabilityWithAvailableChannelList(
- getSoftApCapability(), countryCode));
+ getSoftApCapability(), countryCode, channelMap));
}
public boolean registerSoftApCallback(ISoftApCallback callback) {
- return mRegisteredSoftApCallbacks.register(callback);
+ if (!mRegisteredSoftApCallbacks.register(callback)) {
+ return false;
+ }
+
+ // Update the client about the current state immediately after registering the callback
+ try {
+ callback.onStateChanged(getState());
+ callback.onConnectedClientsOrInfoChanged(getSoftApInfos(),
+ getConnectedClients(), getIsBridgedMode(), true);
+ callback.onCapabilityChanged(getSoftApCapability());
+ } catch (RemoteException e) {
+ Log.e(TAG, "registerSoftApCallback: remote exception -- " + e);
+ }
+ return true;
}
public void unregisterSoftApCallback(ISoftApCallback callback) {
@@ -2064,19 +2156,11 @@ public class WifiServiceImpl extends BaseWifiService {
/**
* Called when soft AP state changes.
- *
- * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED},
- * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
- * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
- * @param failureReason reason when in failed state. One of
- * {@link #SAP_START_FAILURE_GENERAL}, {@link #SAP_START_FAILURE_NO_CHANNEL}
*/
@Override
- public void onStateChanged(int state, int failureReason) {
- synchronized (mLock) {
- mSoftApState = state;
- }
- notifyRegisterOnStateChanged(mRegisteredSoftApCallbacks, state, failureReason);
+ public void onStateChanged(SoftApState softApState) {
+ setState(softApState);
+ notifyRegisterOnStateChanged(mRegisteredSoftApCallbacks, softApState);
}
/**
@@ -2344,11 +2428,13 @@ public class WifiServiceImpl extends BaseWifiService {
mActiveConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_LOCAL_ONLY,
- softApConfig, lohsCapability, mCountryCode.getCountryCode());
+ softApConfig, lohsCapability, mCountryCode.getCountryCode(), null);
mIsExclusive = (request.getCustomConfig() != null);
// Report the error if we got failure in startSoftApInternal
if (!startSoftApInternal(mActiveConfig, request.getWorkSource())) {
- onStateChanged(WIFI_AP_STATE_FAILED, ERROR_GENERIC);
+ onStateChanged(new SoftApState(
+ WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL,
+ mActiveConfig.getTetheringRequest(), null /* iface */));
}
}
@@ -2428,12 +2514,12 @@ public class WifiServiceImpl extends BaseWifiService {
}
@Override
- public void onStateChanged(int state, int failureReason) {
+ public void onStateChanged(SoftApState softApState) {
// The AP state update from ClientModeImpl for softap
synchronized (mLocalOnlyHotspotRequests) {
- Log.d(TAG, "lohs.onStateChanged: currentState=" + state
- + " previousState=" + getState() + " errorCode= " + failureReason
- + " ifaceName=" + mLohsInterfaceName);
+ Log.d(TAG, "lohs.onStateChanged: " + softApState);
+ int state = softApState.getState();
+ int failureReason = softApState.getFailureReasonInternal();
// check if we have a failure - since it is possible (worst case scenario where
// WifiController and ClientModeImpl are out of sync wrt modes) to get two FAILED
@@ -2467,8 +2553,8 @@ public class WifiServiceImpl extends BaseWifiService {
WifiManager.IFACE_IP_MODE_UNSPECIFIED);
}
// For enabling and enabled, just record the new state
- setState(state);
- notifyRegisterOnStateChanged(mRegisteredSoftApCallbacks, state, failureReason);
+ setState(softApState);
+ notifyRegisterOnStateChanged(mRegisteredSoftApCallbacks, softApState);
}
}
}
@@ -2510,16 +2596,6 @@ public class WifiServiceImpl extends BaseWifiService {
Log.e(TAG, "registerSoftApCallback: Failed to add callback");
return;
}
- // Update the client about the current state immediately after registering the callback
- try {
- callback.onStateChanged(mTetheredSoftApTracker.getState(), 0);
- callback.onConnectedClientsOrInfoChanged(mTetheredSoftApTracker.getSoftApInfos(),
- mTetheredSoftApTracker.getConnectedClients(),
- mTetheredSoftApTracker.getIsBridgedMode(), true);
- callback.onCapabilityChanged(mTetheredSoftApTracker.getSoftApCapability());
- } catch (RemoteException e) {
- Log.e(TAG, "registerSoftApCallback: remote exception -- " + e);
- }
});
}
@@ -2651,7 +2727,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
// check if we are currently tethering
if (!mActiveModeWarden.canRequestMoreSoftApManagers(requestorWs)
- && mTetheredSoftApTracker.getState() == WIFI_AP_STATE_ENABLED) {
+ && mTetheredSoftApTracker.getState().getState() == WIFI_AP_STATE_ENABLED) {
// Tethering is enabled, cannot start LocalOnlyHotspot
mLog.info("Cannot start localOnlyHotspot when WiFi Tethering is active.")
.flush();
@@ -2716,16 +2792,6 @@ public class WifiServiceImpl extends BaseWifiService {
Log.e(TAG, "registerSoftApCallback: Failed to add callback");
return;
}
- // Update the client about the current state immediately after registering the callback
- try {
- callback.onStateChanged(mLohsSoftApTracker.getState(), 0);
- callback.onConnectedClientsOrInfoChanged(mLohsSoftApTracker.getSoftApInfos(),
- mLohsSoftApTracker.getConnectedClients(),
- mLohsSoftApTracker.getIsBridgedMode(), true);
- callback.onCapabilityChanged(mLohsSoftApTracker.getSoftApCapability());
- } catch (RemoteException e) {
- Log.e(TAG, "registerSoftApCallback: remote exception -- " + e);
- }
});
}
@@ -2850,7 +2916,7 @@ public class WifiServiceImpl extends BaseWifiService {
listener.onResult(mWifiApConfigStore
.getLastConfiguredTetheredApPassphraseSinceBoot());
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -3060,7 +3126,11 @@ public class WifiServiceImpl extends BaseWifiService {
}
@Override
- public void getWifiActivityEnergyInfoAsync(IOnWifiActivityEnergyInfoListener listener) {
+ public void getWifiActivityEnergyInfoAsync(@NonNull IOnWifiActivityEnergyInfoListener
+ listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener should not be null");
+ }
enforceAccessPermission();
if (mVerboseLoggingEnabled) {
mLog.info("getWifiActivityEnergyInfoAsync uid=%")
@@ -3363,7 +3433,7 @@ public class WifiServiceImpl extends BaseWifiService {
mNetworkSelectionConfig = builder.build();
listener.onResult(mNetworkSelectionConfig);
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -3911,7 +3981,7 @@ public class WifiServiceImpl extends BaseWifiService {
mConnectHelper.connectToNetwork(
new NetworkUpdateResult(netId),
new ActionListenerWrapper(connectListener),
- callingUid, packageName)
+ callingUid, packageName, null)
)
);
// now wait for response.
@@ -4121,7 +4191,7 @@ public class WifiServiceImpl extends BaseWifiService {
try {
listener.onResult(mWifiConnectivityManager.getAutoJoinEnabledExternal());
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -4412,7 +4482,7 @@ public class WifiServiceImpl extends BaseWifiService {
try {
listener.onResult(getChannelDataInternal());
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -5020,7 +5090,7 @@ public class WifiServiceImpl extends BaseWifiService {
mActiveModeWarden.getPrimaryClientModeManager()
.enableTdlsWithRemoteIpAddress(remoteAddress, enable));
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -5068,7 +5138,7 @@ public class WifiServiceImpl extends BaseWifiService {
mActiveModeWarden.getPrimaryClientModeManager()
.enableTdls(remoteMacAddress, enable));
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -5087,7 +5157,7 @@ public class WifiServiceImpl extends BaseWifiService {
mActiveModeWarden.getPrimaryClientModeManager()
.isTdlsOperationCurrentlyAvailable());
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -5110,7 +5180,7 @@ public class WifiServiceImpl extends BaseWifiService {
mActiveModeWarden.getPrimaryClientModeManager()
.getMaxSupportedConcurrentTdlsSessions());
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -5129,7 +5199,7 @@ public class WifiServiceImpl extends BaseWifiService {
mActiveModeWarden.getPrimaryClientModeManager()
.getNumberOfEnabledTdlsSessions());
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -5334,6 +5404,8 @@ public class WifiServiceImpl extends BaseWifiService {
pw.println();
mWifiBackupRestore.dump(fd, pw, args);
pw.println();
+ mBackupRestoreController.dump(fd, pw, args);
+ pw.println();
pw.println("ScoringParams: " + mWifiInjector.getScoringParams());
pw.println();
mSettingsConfigStore.dump(fd, pw, args);
@@ -5349,6 +5421,8 @@ public class WifiServiceImpl extends BaseWifiService {
pw.println();
mWifiConfigManager.dump(fd, pw, args);
pw.println();
+ pw.println("WifiApConfigStore config: " + mWifiApConfigStore.getApConfiguration());
+ pw.println();
mPasspointManager.dump(pw);
mWifiInjector.getPasspointNetworkNominateHelper().dump(pw);
pw.println();
@@ -5369,6 +5443,8 @@ public class WifiServiceImpl extends BaseWifiService {
mWifiInjector.getLinkProbeManager().dump(fd, pw, args);
pw.println();
mWifiNative.dump(pw);
+ pw.println();
+ mWifiInjector.getWifiRoamingModeManager().dump(fd, pw, args);
}
});
}
@@ -5540,6 +5616,8 @@ public class WifiServiceImpl extends BaseWifiService {
}
ApConfigUtil.enableVerboseLogging(mVerboseLoggingEnabled);
mApplicationQosPolicyRequestHandler.enableVerboseLogging(mVerboseLoggingEnabled);
+ mWifiSettingsBackupRestore.enableVerboseLogging(mVerboseLoggingEnabled);
+ mBackupRestoreController.enableVerboseLogging(mVerboseLoggingEnabled);
}
@Override
@@ -5673,6 +5751,54 @@ public class WifiServiceImpl extends BaseWifiService {
/**
* Retrieve the data to be backed to save the current state.
*
+ * The data includes:
+ * 1. Wifi Settings (WifiSettingsConfigStore)
+ * 2. WifiConfiguration/IpConfiguration (original backup by retrieveBackupData)
+ * 3. SoftApConfiguration (original backup by retrieveSoftApBackupData)
+ *
+ * @param listener the listener to be used to receive backup data.
+ */
+ @Override
+ public void retrieveWifiBackupData(IByteArrayListener listener) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException("SDK level too old");
+ }
+ enforceNetworkSettingsPermission();
+ mLog.info("retrieveWifiBackupData uid=%").c(Binder.getCallingUid()).flush();
+ if (listener == null) {
+ throw new IllegalArgumentException("listener should not be null");
+ }
+ mWifiThreadRunner.post(() -> {
+ try {
+ listener.onResult(mBackupRestoreController.retrieveBackupData());
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ }
+ });
+ }
+
+ /**
+ * Restore state from the backed up data.
+ *
+ * The api will guarantee the device would not damage when adding new XML tag.
+ *
+ * @param data Raw byte stream of the backed up data.
+ */
+ @Override
+ public void restoreWifiBackupData(byte[] data) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException("SDK level too old");
+ }
+ enforceNetworkSettingsPermission();
+ mWifiThreadRunner.post(() -> {
+ mLog.info("restoreWifiBackupData uid=%").c(Binder.getCallingUid()).flush();
+ mBackupRestoreController.parserBackupDataAndDispatch(data);
+ });
+ }
+
+ /**
+ * Retrieve the data to be backed to save the current state.
+ *
* @return Raw byte stream of the data to be backed up.
*/
@Override
@@ -6338,6 +6464,9 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public void removeOnWifiUsabilityStatsListener(IOnWifiUsabilityStatsListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("Listener must not be null");
+ }
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE, "WifiService");
if (mVerboseLoggingEnabled) {
@@ -6412,21 +6541,61 @@ public class WifiServiceImpl extends BaseWifiService {
* @param netId Network ID of existing config to connect to if the supplied config is null
* @param callback Listener to notify action result
* @param packageName Package name of the requesting App
+ * @param extras Bundle of extras
*
* see: {@link WifiManager#connect(WifiConfiguration, WifiManager.ActionListener)}
* {@link WifiManager#connect(int, WifiManager.ActionListener)}
*/
@Override
public void connect(WifiConfiguration config, int netId, @Nullable IActionListener callback,
- @NonNull String packageName) {
- int uid = Binder.getCallingUid();
+ @NonNull String packageName, Bundle extras) {
+ int uid = getMockableCallingUid();
if (!isPrivileged(Binder.getCallingPid(), uid)) {
throw new SecurityException(TAG + ": Permission denied");
}
if (packageName == null) {
throw new IllegalArgumentException("packageName must not be null");
}
- mLog.info("connect uid=%").c(uid).flush();
+ final String attributionTagToUse;
+ final int uidToUse;
+ final String packageNameToUse;
+ if (SdkLevel.isAtLeastS() && UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
+ AttributionSource as = extras.getParcelable(
+ WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE);
+ if (as == null) {
+ throw new SecurityException("connect attributionSource is null");
+ }
+ if (!as.checkCallingUid()) {
+ throw new SecurityException(
+ "connect invalid (checkCallingUid fails) attribution source="
+ + as);
+ }
+ // an attribution chain is either of size 1: unregistered (valid by definition) or
+ // size >1: in which case all are validated.
+ AttributionSource asIt = as;
+ AttributionSource asLast = as;
+ if (as.getNext() != null) {
+ do {
+ if (!asIt.isTrusted(mContext)) {
+ throw new SecurityException(
+ "connect invalid (isTrusted fails) attribution source="
+ + asIt);
+ }
+ asIt = asIt.getNext();
+ if (asIt != null) asLast = asIt;
+ } while (asIt != null);
+ }
+ // use the last AttributionSource in the chain - i.e. the original caller
+ attributionTagToUse = asLast.getAttributionTag();
+ uidToUse = asLast.getUid();
+ packageNameToUse = asLast.getPackageName();
+ } else {
+ attributionTagToUse = mContext.getAttributionTag();
+ uidToUse = uid;
+ packageNameToUse = packageName;
+ }
+ mLog.info("connect uid=% uidToUse=% packageNameToUse=% attributionTagToUse=%")
+ .c(uid).c(uidToUse).c(packageNameToUse).c(attributionTagToUse).flush();
mLastCallerInfoManager.put(config != null
? WifiManager.API_CONNECT_CONFIG : WifiManager.API_CONNECT_NETWORK_ID,
Process.myTid(), uid, Binder.getCallingPid(), packageName, true);
@@ -6552,7 +6721,8 @@ public class WifiServiceImpl extends BaseWifiService {
mMakeBeforeBreakManager.stopAllSecondaryTransientClientModeManagers(
() ->
mConnectHelper.connectToNetwork(
- result, wrapper, uid, packageName));
+ result, wrapper, uidToUse, packageNameToUse,
+ attributionTagToUse));
});
}
@@ -6846,7 +7016,7 @@ public class WifiServiceImpl extends BaseWifiService {
mWifiConnectivityManager.setExternalPnoScanRequest(
uid, packageName, binder, callback, ssids, frequencies);
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -6899,7 +7069,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
listener.onResult(lastCallerInfo.getPackageName(), lastCallerInfo.getToggleState());
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -7302,10 +7472,19 @@ public class WifiServiceImpl extends BaseWifiService {
);
}
- @VisibleForTesting
+ /**
+ * See {@link android.net.wifi.WifiManager#isPreferredNetworkOffloadSupported()}.
+ */
+ @Override
public boolean isPnoSupported() {
- return mWifiGlobals.isBackgroundScanSupported()
- || (getSupportedFeatures() & WifiManager.WIFI_FEATURE_PNO) != 0;
+ return mWifiGlobals.isSwPnoEnabled()
+ || (mWifiGlobals.isBackgroundScanSupported()
+ && (getSupportedFeatures() & WifiManager.WIFI_FEATURE_PNO) != 0);
+ }
+
+ private boolean isAggressiveRoamingModeSupported() {
+ return (getSupportedFeatures() & WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT)
+ != 0;
}
/**
@@ -7609,8 +7788,8 @@ public class WifiServiceImpl extends BaseWifiService {
return policyIdSet.size() == policyIds.length;
}
- private boolean policiesHaveDirection(List<QosPolicyParams> policyList,
- @QosPolicyParams.Direction int direction) {
+ private boolean policiesHaveSameDirection(List<QosPolicyParams> policyList) {
+ int direction = policyList.get(0).getDirection();
for (QosPolicyParams policy : policyList) {
if (policy.getDirection() != direction) {
return false;
@@ -7628,7 +7807,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
listener.onResult(statusList);
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
}
@@ -7661,14 +7840,21 @@ public class WifiServiceImpl extends BaseWifiService {
return;
}
- // Only downlink policies are currently supported.
if (policyParamsList.size() == 0
|| policyParamsList.size() > WifiManager.getMaxNumberOfPoliciesPerQosRequest()
|| !policyIdsAreUnique(policyParamsList)
- || !policiesHaveDirection(policyParamsList, QosPolicyParams.DIRECTION_DOWNLINK)) {
+ || !policiesHaveSameDirection(policyParamsList)) {
throw new IllegalArgumentException("policyParamsList is invalid");
}
+ if (!(SdkLevel.isAtLeastV() && isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX))
+ && policyParamsList.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);
+ return;
+ }
+
mWifiThreadRunner.post(() -> {
mApplicationQosPolicyRequestHandler.queueAddRequest(
policyParamsList, listener, binder, uid);
@@ -7762,7 +7948,7 @@ public class WifiServiceImpl extends BaseWifiService {
try {
listener.onResult(mWifiGlobals.getPollRssiIntervalMillis());
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -7792,7 +7978,7 @@ public class WifiServiceImpl extends BaseWifiService {
try {
listener.onResult(mWifiNative.setMloMode(mode) == WifiStatusCode.SUCCESS);
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -7819,7 +8005,7 @@ public class WifiServiceImpl extends BaseWifiService {
try {
listener.onResult(mWifiNative.getMloMode());
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -7902,7 +8088,7 @@ public class WifiServiceImpl extends BaseWifiService {
listener.onResult(mWifiNative.getMaxMloAssociationLinkCount(
mActiveModeWarden.getPrimaryClientModeManager().getInterfaceName()));
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -7934,7 +8120,7 @@ public class WifiServiceImpl extends BaseWifiService {
listener.onResult(mWifiNative.getMaxMloStrLinkCount(
mActiveModeWarden.getPrimaryClientModeManager().getInterfaceName()));
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -7979,7 +8165,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
listener.onResult(supportedBands);
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -8021,10 +8207,28 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("setWepAllowed=% uid=%").c(isAllowed).c(callingUid).flush();
mWifiThreadRunner.post(() -> {
mSettingsConfigStore.put(WIFI_WEP_ALLOWED, isAllowed);
- mWifiGlobals.setWepAllowed(isAllowed);
+ handleWepAllowedChanged(isAllowed);
});
}
+ private void handleWepAllowedChanged(boolean isAllowed) {
+ mWifiGlobals.setWepAllowed(isAllowed);
+ if (!isAllowed) {
+ for (ClientModeManager clientModeManager
+ : mActiveModeWarden.getClientModeManagers()) {
+ if (!(clientModeManager instanceof ConcreteClientModeManager)) {
+ continue;
+ }
+ ConcreteClientModeManager cmm = (ConcreteClientModeManager) clientModeManager;
+ WifiInfo info = cmm.getConnectionInfo();
+ if (info != null
+ && info.getCurrentSecurityType() == WifiInfo.SECURITY_TYPE_WEP) {
+ clientModeManager.disconnect();
+ }
+ }
+ }
+ }
+
/**
* See {@link WifiManager#queryWepAllowed(Executor, Consumer)}
*/
@@ -8042,7 +8246,100 @@ public class WifiServiceImpl extends BaseWifiService {
try {
listener.onResult(mSettingsConfigStore.get(WIFI_WEP_ALLOWED));
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
+ }
+ });
+ }
+
+ /**
+ * See {@link WifiManager#enableMscs(MscsParams)}
+ */
+ @Override
+ public void enableMscs(@NonNull MscsParams mscsParams) {
+ int uid = Binder.getCallingUid();
+ if (!mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(uid)) {
+ throw new SecurityException(
+ "UID=" + uid + " is not allowed to set network selection config");
+ }
+ Objects.requireNonNull(mscsParams);
+ mWifiThreadRunner.post(() -> {
+ List<ClientModeManager> clientModeManagers =
+ mActiveModeWarden.getInternetConnectivityClientModeManagers();
+ for (ClientModeManager cmm : clientModeManagers) {
+ mWifiNative.enableMscs(mscsParams, cmm.getInterfaceName());
+ }
+ });
+ }
+
+ /**
+ * See {@link WifiManager#disableMscs()}
+ */
+ @Override
+ public void disableMscs() {
+ int uid = Binder.getCallingUid();
+ if (!mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(uid)) {
+ throw new SecurityException(
+ "UID=" + uid + " is not allowed to set network selection config");
+ }
+ mWifiThreadRunner.post(() -> {
+ List<ClientModeManager> clientModeManagers =
+ mActiveModeWarden.getInternetConnectivityClientModeManagers();
+ for (ClientModeManager cmm : clientModeManagers) {
+ mWifiNative.disableMscs(cmm.getInterfaceName());
+ }
+ });
+ }
+
+ /**
+ * See {@link android.net.wifi.WifiManager#setSendDhcpHostnameRestriction(int)}.
+ */
+ public void setSendDhcpHostnameRestriction(@NonNull String packageName,
+ @WifiManager.SendDhcpHostnameRestriction int restriction) {
+ int callingUid = Binder.getCallingUid();
+ int callingPid = Binder.getCallingPid();
+ if (mVerboseLoggingEnabled) {
+ mLog.info("setSendDhcpHostnameRestriction:% uid=% package=%").c(restriction)
+ .c(callingUid).c(packageName).flush();
+ }
+ if ((restriction
+ & ~WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN
+ & ~WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_SECURE) != 0) {
+ throw new IllegalArgumentException("Unknown dhcp hostname restriction flags: "
+ + restriction);
+ }
+ if (!isSettingsOrSuw(callingPid, callingUid)
+ && !mWifiPermissionsUtil.isDeviceOwner(callingUid, packageName)) {
+ throw new SecurityException("Uid " + callingUid
+ + " is not allowed to query the global dhcp hostname restriction");
+ }
+ mWifiThreadRunner.post(() -> mWifiGlobals.setSendDhcpHostnameRestriction(restriction));
+ }
+
+ /**
+ * See {@link WifiManager#querySendDhcpHostnameRestriction(Executor, IntConsumer)}
+ */
+ @Override
+ public void querySendDhcpHostnameRestriction(@NonNull String packageName,
+ @NonNull IIntegerListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener should not be null");
+ }
+ int callingUid = Binder.getCallingUid();
+ int callingPid = Binder.getCallingPid();
+ if (mVerboseLoggingEnabled) {
+ mLog.info("querySendDhcpHostnameRestriction: uid=% package=%")
+ .c(callingUid).c(packageName).flush();
+ }
+ if (!isSettingsOrSuw(callingPid, callingUid)
+ && !mWifiPermissionsUtil.isDeviceOwner(callingUid, packageName)) {
+ throw new SecurityException("Uid " + callingUid
+ + " is not allowed to query the global dhcp hostname restriction");
+ }
+ mWifiThreadRunner.post(() -> {
+ try {
+ listener.onResult(mWifiGlobals.getSendDhcpHostnameRestriction());
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -8058,4 +8355,243 @@ public class WifiServiceImpl extends BaseWifiService {
}
return mWifiGlobals.forceOverlayConfigValue(configString, value, isEnabled);
}
+
+ /**
+ * See {@link WifiManager#setPerSsidRoamingMode(WifiSsid, int)}
+ */
+ @Override
+ public void setPerSsidRoamingMode(WifiSsid ssid, @RoamingMode int roamingMode,
+ @NonNull String packageName) {
+ 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");
+
+ if (roamingMode < WifiManager.ROAMING_MODE_NONE
+ || roamingMode > WifiManager.ROAMING_MODE_AGGRESSIVE) {
+ throw new IllegalArgumentException("invalid roaming mode: " + roamingMode);
+ }
+
+ int uid = Binder.getCallingUid();
+ mWifiPermissionsUtil.checkPackage(uid, packageName);
+ boolean isDeviceOwner = mWifiPermissionsUtil.isOrganizationOwnedDeviceAdmin(
+ uid, packageName);
+ if (!isDeviceOwner && !mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
+ && !mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(uid)) {
+ throw new SecurityException("Uid=" + uid + " is not allowed to add roaming policies");
+ }
+
+ //Store Roaming Mode per ssid
+ mWifiThreadRunner.post(() -> {
+ mWifiInjector.getWifiRoamingModeManager().setPerSsidRoamingMode(ssid,
+ roamingMode, isDeviceOwner);
+ });
+ }
+
+ /**
+ * See {@link WifiManager#removePerSsidRoamingMode(WifiSsid)}
+ */
+ @Override
+ public void removePerSsidRoamingMode(WifiSsid ssid, @NonNull String packageName) {
+ 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");
+
+ int uid = Binder.getCallingUid();
+ mWifiPermissionsUtil.checkPackage(uid, packageName);
+ boolean isDeviceOwner = mWifiPermissionsUtil.isOrganizationOwnedDeviceAdmin(
+ uid, packageName);
+ if (!isDeviceOwner && !mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
+ && !mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(uid)) {
+ throw new SecurityException("Uid=" + uid + " is not allowed "
+ + "to remove roaming policies");
+ }
+
+ // Remove Roaming Mode per ssid
+ mWifiThreadRunner.post(() -> {
+ mWifiInjector.getWifiRoamingModeManager().removePerSsidRoamingMode(
+ ssid, isDeviceOwner);
+ });
+ }
+
+ /**
+ * See {@link WifiManager#getPerSsidRoamingModes(Executor, Consumer)}
+ */
+ @Override
+ public void getPerSsidRoamingModes(@NonNull String packageName,
+ @NonNull IMapListener listener) {
+ 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");
+
+ int uid = Binder.getCallingUid();
+ boolean isDeviceOwner = mWifiPermissionsUtil.isOrganizationOwnedDeviceAdmin(
+ uid, packageName);
+ mWifiPermissionsUtil.checkPackage(uid, packageName);
+ if (!isDeviceOwner && !mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
+ && !mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(uid)) {
+ throw new SecurityException("Uid=" + uid + " is not allowed to get roaming policies");
+ }
+
+ // Get Roaming Modes per ssid
+ mWifiThreadRunner.post(() -> {
+ try {
+ Map<String, Integer> roamingPolicies =
+ mWifiInjector.getWifiRoamingModeManager().getPerSsidRoamingModes(
+ isDeviceOwner);
+ listener.onResult(roamingPolicies);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ });
+ }
+
+ /**
+ * See {@link WifiManager#getTwtCapabilities(Executor, Consumer)}
+ */
+ @Override
+ public void getTwtCapabilities(ITwtCapabilitiesListener listener, Bundle extras) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException("SDK level too old");
+ }
+ enforceAnyPermissionOf(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION);
+ if (mVerboseLoggingEnabled) {
+ mLog.info("getTwtCapabilities: Uid=% Package Name=%").c(Binder.getCallingUid()).c(
+ getPackageName(extras)).flush();
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener should not be null");
+ }
+ mWifiThreadRunner.post(() -> {
+ mTwtManager.getTwtCapabilities(
+ mActiveModeWarden.getPrimaryClientModeManager().getInterfaceName(), listener);
+ });
+ }
+
+ /**
+ * See {@link WifiManager#setupTwtSession(TwtRequest, Executor, TwtSessionCallback)}
+ */
+ @Override
+ public void setupTwtSession(TwtRequest twtRequest, ITwtCallback iTwtCallback, Bundle extras) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException("SDK level too old");
+ }
+ if (iTwtCallback == null) {
+ throw new IllegalArgumentException("Callback should not be null");
+ }
+ if (twtRequest == null) {
+ throw new IllegalArgumentException("twtRequest should not be null");
+ }
+ enforceAnyPermissionOf(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION);
+ int callingUid = Binder.getCallingUid();
+ if (mVerboseLoggingEnabled) {
+ mLog.info("setupTwtSession: Uid=% Package Name=%").c(callingUid).c(
+ getPackageName(extras)).flush();
+ }
+ mWifiThreadRunner.post(() -> {
+ try {
+ String bssid = mActiveModeWarden.getPrimaryClientModeManager().getConnectedBssid();
+ if (!mActiveModeWarden.getPrimaryClientModeManager().isConnected()
+ || bssid == null) {
+ iTwtCallback.onFailure(TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ return;
+ }
+ mTwtManager.setupTwtSession(
+ mActiveModeWarden.getPrimaryClientModeManager().getInterfaceName(),
+ twtRequest, iTwtCallback, callingUid, bssid);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ }
+ });
+ }
+
+ /**
+ /**
+ * See {@link TwtSession#getStats(Executor, Consumer)}}
+ */
+ @Override
+ public void getStatsTwtSession(int sessionId, ITwtStatsListener iTwtStatsListener,
+ Bundle extras) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException("SDK level too old");
+ }
+ if (iTwtStatsListener == null) {
+ throw new IllegalArgumentException("Callback should not be null");
+ }
+ enforceAnyPermissionOf(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION);
+ if (mVerboseLoggingEnabled) {
+ mLog.info("getStatsTwtSession: Uid=% Package Name=%").c(Binder.getCallingUid()).c(
+ getPackageName(extras)).flush();
+ }
+ mWifiThreadRunner.post(() -> {
+ mTwtManager.getStatsTwtSession(
+ mActiveModeWarden.getPrimaryClientModeManager().getInterfaceName(),
+ iTwtStatsListener, sessionId);
+ });
+ }
+
+ /**
+ * See {@link TwtSession#teardown()}
+ */
+ @Override
+ public void teardownTwtSession(int sessionId, Bundle extras) {
+ if (!SdkLevel.isAtLeastV()) {
+ throw new UnsupportedOperationException("SDK level too old");
+ }
+ enforceAnyPermissionOf(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION);
+ if (mVerboseLoggingEnabled) {
+ mLog.info("teardownTwtSession: Uid=% Package Name=%").c(Binder.getCallingUid()).c(
+ getPackageName(extras)).flush();
+ }
+ mWifiThreadRunner.post(() -> {
+ mTwtManager.tearDownTwtSession(
+ mActiveModeWarden.getPrimaryClientModeManager().getInterfaceName(), sessionId);
+ });
+ }
+
+ /**
+ * See {@link WifiManager#setD2dAllowedWhenInfraStaDisabled(boolean)}.
+ */
+ @Override
+ public void setD2dAllowedWhenInfraStaDisabled(boolean isAllowed) {
+ int callingUid = Binder.getCallingUid();
+ if (!isSettingsOrSuw(Binder.getCallingPid(), callingUid)) {
+ throw new SecurityException("Uid " + callingUid
+ + " is not allowed to set d2d allowed when infra Sta is disabled");
+ }
+ mLog.info("setD2dAllowedWhenInfraStaDisabled=% uid=%").c(isAllowed).c(callingUid).flush();
+ mWifiThreadRunner.post(
+ () -> mSettingsConfigStore.put(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED, isAllowed));
+ }
+
+ /**
+ * See {@link WifiManager#queryD2dAllowedWhenInfraStaDisabled(Executor, Consumer)}
+ */
+ @Override
+ public void queryD2dAllowedWhenInfraStaDisabled(@NonNull IBooleanListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener should not be null");
+ }
+ mWifiThreadRunner.post(() -> {
+ try {
+ listener.onResult(mSettingsConfigStore.get(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED));
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ }
+ });
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiSettingsBackupRestore.java b/service/java/com/android/server/wifi/WifiSettingsBackupRestore.java
new file mode 100644
index 0000000000..e539655c9e
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiSettingsBackupRestore.java
@@ -0,0 +1,135 @@
+/*
+ * 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;
+
+import android.util.Log;
+
+import com.android.server.wifi.util.XmlUtil;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class used to backup/restore data using the SettingsBackupAgent.
+ * There are 2 symmetric API's exposed here:
+ * 1. retrieveBackupDataFromSettingsConfigStore: Retrieve the configuration data to be backed up.
+ * 2. retrieveSettingsFromBackupData: Restore the configuration using the provided data.
+ * The byte stream to be backed up is XML encoded and versioned to migrate the data easily across
+ * revisions.
+ */
+public class WifiSettingsBackupRestore {
+ private static final String TAG = "WifiSettingsBackupRestore";
+
+ public static final String XML_TAG_SECTION_HEADER_WIFI_SETTINGS_DATA =
+ "WifiSettingsSection";
+
+ private WifiSettingsConfigStore mWifiSettingsConfigStore;
+ private Map<String, WifiSettingsConfigStore.Key> mRestoreSettingsMap = new HashMap<>();
+ /**
+ * Verbose logging flag.
+ */
+ private boolean mVerboseLoggingEnabled = false;
+
+ public WifiSettingsBackupRestore(WifiSettingsConfigStore settingsConfigStore) {
+ mWifiSettingsConfigStore = settingsConfigStore;
+ for (WifiSettingsConfigStore.Key key : mWifiSettingsConfigStore.getAllKeys()) {
+ mRestoreSettingsMap.put(key.key, key);
+ }
+ }
+
+ /**
+ * Retrieve a byte stream representing the data that needs to be backed up from the
+ * provided WifiSettingsConfigStore.
+ */
+ public void retrieveBackupDataFromSettingsConfigStore(XmlSerializer out,
+ ByteArrayOutputStream outputStream) {
+ Map<String, Object> backupSettingsMap = new HashMap<>();
+ try {
+ out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+ // Start writing the XML stream.
+ XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_WIFI_SETTINGS_DATA);
+ XmlUtil.writeNextSectionStart(out,
+ WifiSettingsConfigStore.StoreData.XML_TAG_SECTION_HEADER);
+ // Prepare the setting's map.
+ for (WifiSettingsConfigStore.Key key
+ : mWifiSettingsConfigStore.getAllBackupRestoreKeys()) {
+ backupSettingsMap.put(key.key, mWifiSettingsConfigStore.get(key));
+ }
+ XmlUtil.writeNextValue(out, WifiSettingsConfigStore.StoreData.XML_TAG_VALUES,
+ backupSettingsMap);
+
+ XmlUtil.writeNextSectionEnd(out,
+ WifiSettingsConfigStore.StoreData.XML_TAG_SECTION_HEADER);
+ XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_SETTINGS_DATA);
+ } catch (XmlPullParserException | IOException e) {
+ Log.e(TAG, "Error retrieving the backup data: " + e);
+ }
+ }
+
+ /**
+ * Parse out the wifi settings from the back up data and restore it.
+ *
+ * @param in the xml parser.
+ * @param depth the current depth which the tag XML_TAG_SECTION_HEADER_WIFI_SETTINGS_DATA.
+ */
+ public void restoreSettingsFromBackupData(XmlPullParser in, int depth) {
+ if (in == null) {
+ Log.e(TAG, "Invalid backup data received");
+ return;
+ }
+ try {
+ XmlUtil.gotoNextSectionWithName(in,
+ WifiSettingsConfigStore.StoreData.XML_TAG_SECTION_HEADER, depth + 1);
+ Map<String, Object> values =
+ WifiSettingsConfigStore.StoreData.deserializeSettingsData(in, depth + 2);
+ if (values != null) {
+ for (String keyString : values.keySet()) {
+ if (mRestoreSettingsMap.containsKey(keyString)) {
+ if (mVerboseLoggingEnabled) {
+ Log.i(TAG, "Restored Settings: " + keyString
+ + " with value: " + values.get(keyString));
+ }
+ mWifiSettingsConfigStore.put(mRestoreSettingsMap.get(keyString),
+ values.get(keyString));
+ } else {
+ Log.e(TAG, "Unexpcected Settings found: " + keyString
+ + " with value: " + values.get(keyString));
+ }
+ }
+ }
+ } catch (XmlPullParserException | IOException | ClassCastException
+ | IllegalArgumentException e) {
+ Log.e(TAG, "Error parsing the backup data: " + e);
+ }
+ }
+
+ /**
+ * Enable verbose logging.
+ *
+ * @param verboseEnabled whether or not verbosity log level is enabled.
+ */
+ public void enableVerboseLogging(boolean verboseEnabled) {
+ mVerboseLoggingEnabled = verboseEnabled;
+ }
+}
diff --git a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
index c49ec13cc1..09988abc3b 100644
--- a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
@@ -26,6 +26,7 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.util.SettingsMigrationDataHolder;
import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
@@ -39,7 +40,9 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* Store data for storing wifi settings. These are key (string) / value pairs that are stored in
@@ -193,6 +196,16 @@ public class WifiSettingsConfigStore {
public static final Key<Boolean> WIFI_WIPHY_11BE_SUPPORTED =
new Key<>("wifi_wiphy_11be_supported", true);
+ /**
+ * Whether the D2D is allowed or not when infra sta is disabled.
+ */
+ public static final Key<Boolean> D2D_ALLOWED_WHEN_INFRA_STA_DISABLED =
+ new Key<>("d2d_allowed_when_infra_sta_disabled", false);
+
+ // List of all keys which require to backup and restore.
+ private static final List<Key> sBackupRestoreKeys = List.of(
+ WIFI_WEP_ALLOWED,
+ D2D_ALLOWED_WHEN_INFRA_STA_DISABLED);
/******** Wifi shared pref keys ***************/
private final Context mContext;
@@ -237,6 +250,14 @@ public class WifiSettingsConfigStore {
wifiConfigStore.registerStoreData(new StoreData());
}
+ public ArrayList<Key> getAllKeys() {
+ return sKeys;
+ }
+
+ public List<Key> getAllBackupRestoreKeys() {
+ return sBackupRestoreKeys;
+ }
+
private void invokeAllListeners() {
synchronized (mLock) {
for (Key key : sKeys) {
@@ -417,18 +438,44 @@ public class WifiSettingsConfigStore {
sKeys.add(this);
}
+ @VisibleForTesting
+ public String getKey() {
+ return key;
+ }
+
@Override
public String toString() {
return "[Key " + key + ", DefaultValue: " + defaultValue + "]";
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+
+ // null instanceof [type]" also returns false
+ if (!(o instanceof Key)) {
+ return false;
+ }
+
+ Key anotherKey = (Key) o;
+ return Objects.equals(key, anotherKey.key)
+ && Objects.equals(defaultValue, anotherKey.defaultValue);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(key, defaultValue);
+ }
}
/**
* Store data for persisting the settings data to config store.
*/
- private class StoreData implements WifiConfigStore.StoreData {
- private static final String XML_TAG_SECTION_HEADER = "Settings";
- private static final String XML_TAG_VALUES = "Values";
+ public class StoreData implements WifiConfigStore.StoreData {
+ public static final String XML_TAG_SECTION_HEADER = "Settings";
+ public static final String XML_TAG_VALUES = "Values";
@Override
public void serializeData(XmlSerializer out,
@@ -450,6 +497,22 @@ public class WifiSettingsConfigStore {
migrateFromSettingsIfNeeded();
return;
}
+ Map<String, Object> values = deserializeSettingsData(in, outerTagDepth);
+ if (values != null) {
+ synchronized (mLock) {
+ mSettings.putAll(values);
+ // Invoke all the registered listeners.
+ invokeAllListeners();
+ }
+ }
+ }
+
+ /**
+ * Parse out the wifi settings from the input xml stream.
+ */
+ public static Map<String, Object> deserializeSettingsData(
+ XmlPullParser in, int outerTagDepth)
+ throws XmlPullParserException, IOException {
Map<String, Object> values = null;
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
String[] valueName = new String[1];
@@ -467,13 +530,7 @@ public class WifiSettingsConfigStore {
break;
}
}
- if (values != null) {
- synchronized (mLock) {
- mSettings.putAll(values);
- // Invoke all the registered listeners.
- invokeAllListeners();
- }
- }
+ return values;
}
@Override
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index 1541273ba5..98807410f7 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -61,6 +61,7 @@ import android.net.wifi.ScanResult;
import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApInfo;
+import android.net.wifi.SoftApState;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiClient;
@@ -232,17 +233,17 @@ public class WifiShellCommand extends BasicShellCommandHandler {
}
@Override
- public void onStateChanged(int state, int failureReason) {
- mPrintWriter.println("onStateChanged with state: " + state
- + " failure reason: " + failureReason);
- mSapState = state;
- if (state == WifiManager.WIFI_AP_STATE_ENABLED) {
+ public void onStateChanged(SoftApState state) {
+ mPrintWriter.println("onStateChanged with state: " + state);
+
+ mSapState = state.getState();
+ if (mSapState == WifiManager.WIFI_AP_STATE_ENABLED) {
mPrintWriter.println(" SAP is enabled successfully");
// Skip countDown() and wait for onInfoChanged() which has
// the confirmed softAp channel information
- } else if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
+ } else if (mSapState == WifiManager.WIFI_AP_STATE_DISABLED) {
mPrintWriter.println(" SAP is disabled");
- } else if (state == WifiManager.WIFI_AP_STATE_FAILED) {
+ } else if (mSapState == WifiManager.WIFI_AP_STATE_FAILED) {
mPrintWriter.println(" SAP failed to start");
mCountDownLatch.countDown();
}
@@ -596,21 +597,22 @@ public class WifiShellCommand extends BasicShellCommandHandler {
}
case "imsi-protection-exemption-clear-user-approved-for-carrier": {
String arg1 = getNextArgRequired();
- int carrierId = -1;
try {
- carrierId = Integer.parseInt(arg1);
+ final int carrierId = Integer.parseInt(arg1);
+ mWifiThreadRunner.post(() ->
+ mWifiCarrierInfoManager.clearImsiPrivacyExemptionForCarrier(
+ carrierId));
} catch (NumberFormatException e) {
pw.println("Invalid argument to "
+ "'imsi-protection-exemption-clear-user-approved-for-carrier' "
+ "- 'carrierId' must be an Integer");
return -1;
}
- mWifiCarrierInfoManager.clearImsiPrivacyExemptionForCarrier(carrierId);
return 0;
}
case "network-requests-remove-user-approved-access-points": {
String packageName = getNextArgRequired();
- mWifiNetworkFactory.removeApp(packageName);
+ mWifiThreadRunner.post(() -> mWifiNetworkFactory.removeApp(packageName));
return 0;
}
case "clear-user-disabled-networks": {
@@ -1005,7 +1007,8 @@ public class WifiShellCommand extends BasicShellCommandHandler {
}
};
WifiConfiguration config = buildWifiConfiguration(pw);
- mWifiService.connect(config, -1, actionListener, SHELL_PACKAGE_NAME);
+ mWifiService.connect(config, -1, actionListener, SHELL_PACKAGE_NAME,
+ new Bundle());
// wait for status.
countDownLatch.await(500, TimeUnit.MILLISECONDS);
setAutoJoin(pw, config.SSID, config.allowAutojoin);
@@ -2057,6 +2060,19 @@ public class WifiShellCommand extends BasicShellCommandHandler {
return 0;
}
+ case "get-cached-scan-data":
+ WifiScanner.ScanData scanData =
+ mWifiNative.getCachedScanResultsFromAllClientIfaces();
+
+ if (scanData.getResults().length > 0) {
+ pw.println("Successfully get cached scan data: ");
+ for (ScanResult scanResult : scanData.getResults()) {
+ pw.println(scanResult);
+ }
+ } else {
+ pw.println("Cached scan data is empty");
+ }
+ return 0;
case "configure-afc-server":
final String url = getNextArgRequired();
@@ -2960,6 +2976,8 @@ public class WifiShellCommand extends BasicShellCommandHandler {
pw.println(" '15' - band 2.4, 5, and 6 GHz with DFS channels");
pw.println(" '16' - band 60 GHz");
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 <overlayName> <configString> enabled|disabled");
pw.println(" Force overlay to a specified value. See below for supported overlays.");
pw.println(" <overlayName> - name of the overlay whose value is overridden.");
diff --git a/service/java/com/android/server/wifi/WifiSignalPollResults.java b/service/java/com/android/server/wifi/WifiSignalPollResults.java
index c82281d8b7..9e83c001e2 100644
--- a/service/java/com/android/server/wifi/WifiSignalPollResults.java
+++ b/service/java/com/android/server/wifi/WifiSignalPollResults.java
@@ -180,4 +180,14 @@ public class WifiSignalPollResults {
public int getFrequency(int linkId) {
return mEntries.getOrDefault(linkId, mDefault).frequencyMHz;
}
+
+ /**
+ * Return whether the poll results available for the specific link.
+ *
+ * @param linkId Identifier of the link.
+ * @return true if available, otherwise false
+ */
+ public boolean isAvailable(int linkId) {
+ return mEntries.containsKey(linkId);
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiThreadRunner.java b/service/java/com/android/server/wifi/WifiThreadRunner.java
index c3210de5c9..0a9eb524df 100644
--- a/service/java/com/android/server/wifi/WifiThreadRunner.java
+++ b/service/java/com/android/server/wifi/WifiThreadRunner.java
@@ -16,10 +16,13 @@
package com.android.server.wifi;
+import static com.android.server.wifi.RunnerHandler.KEY_SIGNATURE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Handler;
import android.os.Looper;
+import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
@@ -186,6 +189,20 @@ public class WifiThreadRunner {
}
/**
+ * Asynchronously runs a Runnable on the main Wifi thread. With specified task name for metrics
+ * logging
+ * @return true if the runnable was successfully posted <b>(not executed)</b> to the main Wifi
+ * thread, false otherwise
+ * @param runnable The Runnable that will be executed.
+ * @param taskName The task name for performance logging
+ */
+ public boolean post(@NonNull Runnable runnable, String taskName) {
+ Message m = Message.obtain(mHandler, runnable);
+ m.getData().putString(KEY_SIGNATURE, taskName);
+ return mHandler.sendMessage(m);
+ }
+
+ /**
* Asynchronously runs a Runnable on the main Wifi thread with delay.
*
* @param runnable The Runnable that will be executed.
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index 6dadd23364..9e50b0b1d4 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -31,8 +31,11 @@ import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.RoamingMode;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
+import android.net.wifi.twt.TwtRequest;
+import android.os.Bundle;
import android.os.Handler;
import android.os.WorkSource;
import android.text.TextUtils;
@@ -116,6 +119,7 @@ public class WifiVendorHal {
private final HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
private final WifiStaIface.Callback mWifiStaIfaceEventCallback;
private final ChipEventCallback mWifiChipEventCallback;
+ private WifiNative.WifiTwtEvents mWifiTwtEvents;
// Plumbing for event handling.
//
@@ -124,7 +128,6 @@ public class WifiVendorHal {
// https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5
private final Handler mHalEventHandler;
-
/**
* Wi-Fi chip related info.
*/
@@ -716,6 +719,20 @@ public class WifiVendorHal {
}
/**
+ * Gets the cached scan data.
+ *
+ * @param ifaceName Name of the interface.
+ */
+ @Nullable
+ public WifiScanner.ScanData getCachedScanData(@NonNull String ifaceName) {
+ synchronized (sLock) {
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return null;
+ return iface.getCachedScanData();
+ }
+ }
+
+ /**
* Get the link layer statistics
*
* Note - we always enable link layer stats on a STA interface.
@@ -1715,6 +1732,82 @@ public class WifiVendorHal {
}
eventHandler.onRssiThresholdBreached((byte) currRssi);
}
+
+ /**
+ * Called when a TWT operation fails.
+ *
+ * @param cmdId Unique command id which is failed
+ * @param twtErrorCode Error code
+ */
+ @Override
+ public void onTwtFailure(int cmdId, int twtErrorCode) {
+ synchronized (sLock) {
+ mHalEventHandler.post(() -> {
+ if (mWifiTwtEvents == null) return;
+ mWifiTwtEvents.onTwtFailure(cmdId, twtErrorCode);
+ });
+ }
+ }
+
+ /**
+ * Called when {@link WifiStaIface#setupTwtSession(int, TwtRequest)} succeeds.
+ *
+ * @param cmdId Unique command id used in
+ * {@link WifiStaIface#setupTwtSession(int, TwtRequest)}
+ * @param wakeDurationUs TWT wake duration for the session in microseconds
+ * @param wakeIntervalUs TWT wake interval for the session in microseconds
+ * @param linkId Multi link operation link id
+ * @param sessionId TWT session id
+ */
+ @Override
+ public void onTwtSessionCreate(int cmdId, int wakeDurationUs, long wakeIntervalUs,
+ int linkId, int sessionId) {
+ synchronized (sLock) {
+ mHalEventHandler.post(() -> {
+ if (mWifiTwtEvents == null) return;
+ mWifiTwtEvents.onTwtSessionCreate(cmdId, wakeDurationUs, wakeIntervalUs,
+ linkId,
+ sessionId);
+ });
+ }
+
+ }
+
+ /**
+ * Called when TWT session is torndown by {@link WifiStaIface#tearDownTwtSession(int, int)}.
+ * Can also be called unsolicitedly by the vendor software with proper reason code.
+ *
+ * @param cmdId Unique command id used in
+ * {@link WifiStaIface#tearDownTwtSession(int, int)}
+ * @param twtSessionId TWT session Id
+ */
+ @Override
+ public void onTwtSessionTeardown(int cmdId, int twtSessionId, int twtReasonCode) {
+ synchronized (sLock) {
+ mHalEventHandler.post(() -> {
+ if (mWifiTwtEvents == null) return;
+ mWifiTwtEvents.onTwtSessionTeardown(cmdId, twtSessionId, twtReasonCode);
+ });
+ }
+ }
+
+ /**
+ * Called as a response to {@link WifiStaIface#getStatsTwtSession(int, int)}
+ *
+ * @param cmdId Unique command id used in
+ * {@link WifiStaIface#getStatsTwtSession(int, int)}
+ * @param twtSessionId TWT session Id
+ * @param twtStats TWT stats bundle
+ */
+ @Override
+ public void onTwtSessionStats(int cmdId, int twtSessionId, Bundle twtStats) {
+ synchronized (sLock) {
+ mHalEventHandler.post(() -> {
+ if (mWifiTwtEvents == null) return;
+ mWifiTwtEvents.onTwtSessionStats(cmdId, twtSessionId, twtStats);
+ });
+ }
+ }
}
/**
@@ -2006,4 +2099,67 @@ public class WifiVendorHal {
if (mWifiChip == null) return false;
return mWifiChip.setAfcChannelAllowance(afcChannelAllowance);
}
+
+ /**
+ * See {@link WifiNative#setRoamingMode(String, int)}.
+ */
+ public @WifiStatusCode int setRoamingMode(@NonNull String ifaceName,
+ @RoamingMode int roamingMode) {
+ synchronized (sLock) {
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return WifiStatusCode.ERROR_WIFI_IFACE_INVALID;
+ return iface.setRoamingMode(roamingMode);
+ }
+ }
+
+ /**
+ * See {@link WifiNative#getTwtCapabilities(String)}
+ */
+ public Bundle getTwtCapabilities(String ifaceName) {
+ synchronized (sLock) {
+ WifiStaIface wifiStaIface = getStaIface(ifaceName);
+ if (wifiStaIface == null) return null;
+ return wifiStaIface.getTwtCapabilities();
+ }
+ }
+
+ /**
+ * See {@link WifiNative#registerTwtCallbacks(TwtManager.WifiNativeTwtEvents)}
+ */
+ public void registerTwtCallbacks(WifiNative.WifiTwtEvents wifiTwtCallback) {
+ mWifiTwtEvents = wifiTwtCallback;
+ }
+
+ /**
+ * See {@link WifiNative#setupTwtSession(int, String, TwtRequest)}
+ */
+ public boolean setupTwtSession(int cmdId, String ifaceName, TwtRequest twtRequest) {
+ synchronized (sLock) {
+ WifiStaIface wifiStaIface = getStaIface(ifaceName);
+ if (wifiStaIface == null) return false;
+ return wifiStaIface.setupTwtSession(cmdId, twtRequest);
+ }
+ }
+
+ /**
+ * See {@link WifiNative#tearDownTwtSession(int, String, int)}
+ */
+ public boolean tearDownTwtSession(int cmdId, String ifaceName, int sessionId) {
+ synchronized (sLock) {
+ WifiStaIface wifiStaIface = getStaIface(ifaceName);
+ if (wifiStaIface == null) return false;
+ return wifiStaIface.tearDownTwtSession(cmdId, sessionId);
+ }
+ }
+
+ /**
+ * See {@link WifiNative#getStatsTwtSession(int, String, int)}
+ */
+ public boolean getStatsTwtSession(int cmdId, String ifaceName, int sessionId) {
+ synchronized (sLock) {
+ WifiStaIface wifiStaIface = getStaIface(ifaceName);
+ if (wifiStaIface == null) return false;
+ return wifiStaIface.getStatsTwtSession(cmdId, sessionId);
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java b/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java
index 06bc0a7262..e5fdeed2ff 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java
@@ -24,6 +24,8 @@ import static com.android.server.wifi.aware.WifiAwareStateManager.INSTANT_MODE_D
import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_REQUEST_TYPE_SETUP;
import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_REQUEST_TYPE_VERIFICATION;
+import android.annotation.NonNull;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.WifiScanner;
import android.net.wifi.aware.AwarePairingConfig;
import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
@@ -41,6 +43,7 @@ import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
+import java.util.List;
/**
* Manages the state of a single Aware discovery session (publish or subscribe).
@@ -512,10 +515,11 @@ public class WifiAwareDiscoverySessionState {
* @param peerId ID of the peer. Obtained through previous communication (a
* match indication).
* @param method proposed bootstrapping method
+ * @param isComeBack If the request is for a previous comeback response
* @return True if the request send succeed.
*/
public boolean initiateBootstrapping(short transactionId,
- int peerId, int method, byte[] cookie) {
+ int peerId, int method, byte[] cookie, boolean isComeBack) {
PeerInfo peerInfo = mPeerInfoByRequestorInstanceId.get(peerId);
if (peerInfo == null) {
Log.e(TAG, "initiateBootstrapping: attempting to send pairing request to an address"
@@ -529,7 +533,7 @@ public class WifiAwareDiscoverySessionState {
}
boolean success = mWifiAwareNativeApi.initiateBootstrapping(transactionId,
- peerInfo.mInstanceId, peerInfo.mMac, method, cookie);
+ peerInfo.mInstanceId, peerInfo.mMac, method, cookie, mPubSubId, isComeBack);
if (!success) {
try {
mCallback.onBootstrappingVerificationConfirmed(peerId, false, method);
@@ -563,7 +567,7 @@ public class WifiAwareDiscoverySessionState {
}
boolean success = mWifiAwareNativeApi.respondToBootstrappingRequest(transactionId,
- bootstrappingId, accept);
+ bootstrappingId, accept, mPubSubId);
return success;
}
@@ -585,16 +589,21 @@ public class WifiAwareDiscoverySessionState {
public int onMatch(int requestorInstanceId, byte[] peerMac, byte[] serviceSpecificInfo,
byte[] matchFilter, int rangingIndication, int rangeMm, int peerCipherSuite,
byte[] scid, String pairingAlias,
- AwarePairingConfig pairingConfig) {
+ AwarePairingConfig pairingConfig, @NonNull List<OuiKeyedData> vendorDataList) {
int peerId = getPeerIdOrAddIfNew(requestorInstanceId, peerMac);
+ OuiKeyedData[] vendorDataArray = null;
+ if (!vendorDataList.isEmpty()) {
+ vendorDataArray = new OuiKeyedData[vendorDataList.size()];
+ vendorDataList.toArray(vendorDataArray);
+ }
try {
if (rangingIndication == 0) {
mCallback.onMatch(peerId, serviceSpecificInfo, matchFilter, peerCipherSuite, scid,
- pairingAlias, pairingConfig);
+ pairingAlias, pairingConfig, vendorDataArray);
} else {
mCallback.onMatchWithDistance(peerId, serviceSpecificInfo, matchFilter, rangeMm,
- peerCipherSuite, scid, pairingAlias, pairingConfig);
+ peerCipherSuite, scid, pairingAlias, pairingConfig, vendorDataArray);
}
} catch (RemoteException e) {
Log.w(TAG, "onMatch: RemoteException (FYI): " + e);
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
index f7391971c3..44f8bce00d 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
@@ -798,10 +798,12 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
* indication).
* @param peer The MAC address of the peer to create a connection with.
* @param method proposed bootstrapping method
+ * @param pubSubId ID of the publish/subscribe session - obtained when creating a session.
+ * @param isComeBack If the request is for a previous comeback response
* @return True if the request send success
*/
public boolean initiateBootstrapping(short transactionId, int peerId, byte[] peer, int method,
- byte[] cookie) {
+ byte[] cookie, byte pubSubId, boolean isComeBack) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "initiateBootstrapping: transactionId=" + transactionId
+ ", peerId=" + peerId + ", method=" + method
@@ -817,7 +819,8 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
try {
MacAddress peerMac = MacAddress.fromBytes(peer);
- return iface.initiateBootstrapping(transactionId, peerId, peerMac, method, cookie);
+ return iface.initiateBootstrapping(transactionId, peerId, peerMac, method, cookie,
+ pubSubId, isComeBack);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Invalid peer mac received: " + Arrays.toString(peer));
return false;
@@ -826,14 +829,17 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
/**
* Response to a bootstrapping request for this from this session
- * @param transactionId Transaction ID for the transaction - used in the
- * async callback to match with the original request.
+ *
+ * @param transactionId Transaction ID for the transaction - used in the
+ * async callback to match with the original request.
* @param bootstrappingId The id of the current boostraping session
- * @param accept True is proposed method is accepted
+ * @param accept True is proposed method is accepte
+ * @param pubSubId ID of the publish/subscribe session - obtained when creating a
+ * session.
* @return True if the request send success
*/
public boolean respondToBootstrappingRequest(short transactionId, int bootstrappingId,
- boolean accept) {
+ boolean accept, byte pubSubId) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "respondToBootstrappingRequest: transactionId=" + transactionId);
}
@@ -845,7 +851,8 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
return false;
}
- return iface.respondToBootstrappingRequest(transactionId, bootstrappingId, accept);
+ return iface.respondToBootstrappingRequest(transactionId, bootstrappingId, accept,
+ pubSubId);
}
/**
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
index 0e8e33e268..d6f02bcd78 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
@@ -16,6 +16,8 @@
package com.android.server.wifi.aware;
+import android.annotation.Nullable;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.aware.AwarePairingConfig;
import android.net.wifi.aware.IdentityChangedListener;
import android.net.wifi.aware.WifiAwareChannelInfo;
@@ -337,11 +339,12 @@ public class WifiAwareNativeCallback implements WifiNanIface.Callback,
public void eventMatch(byte discoverySessionId, int peerId, byte[] addr,
byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndicationType,
int rangingMeasurementInMm, byte[] scid, int peerCipherType, byte[] nonce, byte[] tag,
- AwarePairingConfig pairingConfig) {
+ AwarePairingConfig pairingConfig, @Nullable List<OuiKeyedData> vendorData) {
incrementCbCount(CB_EV_MATCH);
mWifiAwareStateManager.onMatchNotification(discoverySessionId, peerId,
addr, serviceSpecificInfo, matchFilter, rangingIndicationType,
- rangingMeasurementInMm, scid, peerCipherType, nonce, tag, pairingConfig);
+ rangingMeasurementInMm, scid, peerCipherType, nonce, tag, pairingConfig,
+ vendorData);
}
@Override
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
index c75b0df4be..8d0e2ce51a 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
@@ -58,6 +58,7 @@ import com.android.server.wifi.BuildProperties;
import com.android.server.wifi.Clock;
import com.android.server.wifi.FrameworkFacade;
import com.android.server.wifi.InterfaceConflictManager;
+import com.android.server.wifi.RunnerHandler;
import com.android.server.wifi.SystemBuildProperties;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiSettingsConfigStore;
@@ -129,7 +130,9 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub {
mWifiPermissionsUtil = wifiPermissionsUtil;
mStateManager = awareStateManager;
mShellCommand = awareShellCommand;
- mHandler = new Handler(handlerThread.getLooper());
+ mHandler = new RunnerHandler(handlerThread.getLooper(), mContext.getResources()
+ .getInteger(R.integer.config_wifiConfigurationWifiRunnerThresholdInMs),
+ WifiInjector.getInstance().getWifiHandlerLocalLog());
mWifiAwareNativeManager = wifiAwareNativeManager;
mWifiAwareNativeApi = wifiAwareNativeApi;
mWifiAwareNativeCallback = wifiAwareNativeCallback;
@@ -334,7 +337,22 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub {
}
if (configRequest != null) {
- enforceNetworkStackPermission();
+ boolean networkStackPermission = checkNetworkStackPermission();
+ boolean manageNetworkSelectionPermission =
+ mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(uid);
+ if (!(networkStackPermission || manageNetworkSelectionPermission)) {
+ throw new SecurityException("Insufficient permission to include a ConfigRequest");
+ }
+
+ if (!networkStackPermission) {
+ // OEM apps with only the network selection permission can provide a config request,
+ // but they should only modify the vendor data field.
+ ConfigRequest.Builder builder = new ConfigRequest.Builder();
+ if (SdkLevel.isAtLeastV()) {
+ builder.setVendorData(configRequest.getVendorData());
+ }
+ configRequest = builder.build();
+ }
} else {
configRequest = new ConfigRequest.Builder().build();
}
@@ -349,7 +367,7 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub {
}
if (mVerboseLoggingEnabled) {
- Log.v(TAG, "connect: uid=" + uid + ", clientId=" + clientId + ", configRequest"
+ Log.v(TAG, "connect: uid=" + uid + ", clientId=" + clientId + ", configRequest="
+ configRequest + ", notifyOnIdentityChanged=" + notifyOnIdentityChanged);
}
@@ -832,4 +850,9 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub {
private void enforceNetworkStackPermission() {
mContext.enforceCallingOrSelfPermission(Manifest.permission.NETWORK_STACK, TAG);
}
+
+ private boolean checkNetworkStackPermission() {
+ return mContext.checkCallingOrSelfPermission(Manifest.permission.NETWORK_STACK)
+ == PackageManager.PERMISSION_GRANTED;
+ }
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index 4c099d72c7..14a60547a1 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -68,6 +68,7 @@ import android.net.MacAddress;
import android.net.wifi.IBooleanListener;
import android.net.wifi.IIntegerListener;
import android.net.wifi.IListListener;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
@@ -107,7 +108,6 @@ import android.util.StatsEvent;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.MessageUtils;
-import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.internal.util.WakeupMessage;
import com.android.modules.utils.BasicShellCommandHandler;
@@ -116,6 +116,7 @@ import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.Clock;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.InterfaceConflictManager;
+import com.android.server.wifi.RunnerState;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.aware.PairingConfigManager.PairingSecurityAssociationInfo;
import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
@@ -347,6 +348,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
private static final String MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_IS_COME_BACK_REQUEST =
"bootstrapping_is_come_back";
private static final String MESSAGE_BUNDLE_KEY_CALLER_TYPE = "caller_type";
+ private static final String MESSAGE_BUNDLE_KEY_VENDOR_DATA = "vendor_data";
private WifiAwareNativeApi mWifiAwareNativeApi;
private WifiAwareNativeManager mWifiAwareNativeManager;
@@ -1065,7 +1067,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
listener.onResult(mPairingConfigManager
.getAllPairedDevices(callingPackage));
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
}
);
@@ -1099,7 +1101,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
try {
listener.onResult(state.getConfigRequest().mMasterPreference);
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -1131,7 +1133,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
try {
listener.onResult(mOpportunisticSet.contains(ctxPkg));
} catch (RemoteException e) {
- Log.e(TAG, e.getMessage());
+ Log.e(TAG, e.getMessage(), e);
}
});
}
@@ -1938,7 +1940,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
public void onMatchNotification(int pubSubId, int requestorInstanceId, byte[] peerMac,
byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndication, int rangeMm,
byte[] scid, int peerCipherSuite, byte[] nonce, byte[] tag,
- AwarePairingConfig pairingConfig) {
+ AwarePairingConfig pairingConfig, @Nullable List<OuiKeyedData> vendorData) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
msg.arg1 = NOTIFICATION_TYPE_MATCH;
msg.arg2 = pubSubId;
@@ -1953,6 +1955,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_NONCE, nonce);
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_TAG, tag);
msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_PAIRING_CONFIG, pairingConfig);
+ msg.getData().putParcelableArrayList(MESSAGE_BUNDLE_KEY_VENDOR_DATA,
+ vendorData != null ? new ArrayList<>(vendorData) : new ArrayList<>());
mSm.sendMessage(msg);
}
@@ -2167,9 +2171,9 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
class WifiAwareStateMachine extends StateMachine {
private static final int TRANSACTION_ID_IGNORE = 0;
- private final DefaultState mDefaultState = new DefaultState();
- private final WaitState mWaitState = new WaitState();
- private final WaitForResponseState mWaitForResponseState = new WaitForResponseState();
+ private final DefaultState mDefaultState;
+ private final WaitState mWaitState;
+ private final WaitForResponseState mWaitForResponseState;
private final WaitingState mWaitingState = new WaitingState(this);
private short mNextTransactionId = 1;
@@ -2198,7 +2202,11 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
WifiAwareStateMachine(String name, Looper looper) {
super(name, looper);
-
+ final int threshold = mContext.getResources().getInteger(
+ R.integer.config_wifiConfigurationWifiRunnerThresholdInMs);
+ mDefaultState = new DefaultState(threshold);
+ mWaitState = new WaitState(threshold);
+ mWaitForResponseState = new WaitForResponseState(threshold);
addState(mDefaultState);
/* --> */ addState(mWaitState, mDefaultState);
/* ----> */ addState(mWaitingState, mWaitState);
@@ -2207,15 +2215,160 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
setInitialState(mWaitState);
}
+ @Override
+ protected String getWhatToString(int what) {
+ return switch (what) {
+ case COMMAND_TYPE_CONNECT -> "COMMAND_TYPE_CONNECT";
+ case COMMAND_TYPE_DISCONNECT -> "COMMAND_TYPE_DISCONNECT";
+ case COMMAND_TYPE_TERMINATE_SESSION -> "COMMAND_TYPE_TERMINATE_SESSION";
+ case COMMAND_TYPE_PUBLISH -> "COMMAND_TYPE_PUBLISH";
+ case COMMAND_TYPE_UPDATE_PUBLISH -> "COMMAND_TYPE_UPDATE_PUBLISH";
+ case COMMAND_TYPE_SUBSCRIBE -> "COMMAND_TYPE_SUBSCRIBE";
+ case COMMAND_TYPE_UPDATE_SUBSCRIBE -> "COMMAND_TYPE_UPDATE_SUBSCRIBE";
+ case COMMAND_TYPE_ENQUEUE_SEND_MESSAGE -> "COMMAND_TYPE_ENQUEUE_SEND_MESSAGE";
+ case COMMAND_TYPE_ENABLE_USAGE -> "COMMAND_TYPE_ENABLE_USAGE";
+ case COMMAND_TYPE_DISABLE_USAGE -> "COMMAND_TYPE_DISABLE_USAGE";
+ case COMMAND_TYPE_GET_CAPABILITIES -> "COMMAND_TYPE_GET_CAPABILITIES";
+ case COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES
+ -> "COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES";
+ case COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE
+ -> "COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE";
+ case COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE
+ -> "COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE";
+ case COMMAND_TYPE_INITIATE_DATA_PATH_SETUP
+ -> "COMMAND_TYPE_INITIATE_DATA_PATH_SETUP";
+ case COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST
+ -> "COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST";
+ case COMMAND_TYPE_END_DATA_PATH -> "COMMAND_TYPE_END_DATA_PATH";
+ case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE -> "COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE";
+ case COMMAND_TYPE_RECONFIGURE -> "COMMAND_TYPE_RECONFIGURE";
+ case COMMAND_TYPE_DELAYED_INITIALIZATION -> "COMMAND_TYPE_DELAYED_INITIALIZATION";
+ case COMMAND_TYPE_GET_AWARE -> "COMMAND_TYPE_GET_AWARE";
+ case COMMAND_TYPE_RELEASE_AWARE -> "COMMAND_TYPE_RELEASE_AWARE";
+ case COMMAND_TYPE_DISABLE -> "COMMAND_TYPE_DISABLE";
+ case COMMAND_TYPE_INITIATE_PAIRING_REQUEST
+ -> "COMMAND_TYPE_INITIATE_PAIRING_REQUEST";
+ case COMMAND_TYPE_RESPONSE_PAIRING_REQUEST
+ -> "COMMAND_TYPE_RESPONSE_PAIRING_REQUEST";
+ case COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST
+ -> "COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST";
+ case COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST
+ -> "COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST";
+ case COMMAND_TYPE_SUSPEND_SESSION -> "COMMAND_TYPE_SUSPEND_SESSION";
+ case COMMAND_TYPE_RESUME_SESSION -> "COMMAND_TYPE_RESUME_SESSION";
+ case COMMAND_TYPE_END_PAIRING -> "COMMAND_TYPE_END_PAIRING";
+
+ case RESPONSE_TYPE_ON_CONFIG_SUCCESS -> "RESPONSE_TYPE_ON_CONFIG_SUCCESS";
+ case RESPONSE_TYPE_ON_CONFIG_FAIL -> "RESPONSE_TYPE_ON_CONFIG_FAIL";
+ case RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS
+ -> "RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS";
+ case RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL -> "RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL";
+ case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS
+ -> "RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS";
+ case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL
+ -> "RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL";
+ case RESPONSE_TYPE_ON_CAPABILITIES_UPDATED
+ -> "RESPONSE_TYPE_ON_CAPABILITIES_UPDATED";
+ case RESPONSE_TYPE_ON_CREATE_INTERFACE -> "RESPONSE_TYPE_ON_CREATE_INTERFACE";
+ case RESPONSE_TYPE_ON_DELETE_INTERFACE -> "RESPONSE_TYPE_ON_DELETE_INTERFACE";
+ case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS
+ -> "RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS";
+ case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL
+ -> "RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL";
+ case RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST
+ -> "RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST";
+ case RESPONSE_TYPE_ON_END_DATA_PATH -> "RESPONSE_TYPE_ON_END_DATA_PATH";
+ case RESPONSE_TYPE_ON_DISABLE -> "RESPONSE_TYPE_ON_DISABLE";
+ case RESPONSE_TYPE_ON_INITIATE_PAIRING_SUCCESS
+ -> "RESPONSE_TYPE_ON_INITIATE_PAIRING_SUCCESS";
+ case RESPONSE_TYPE_ON_INITIATE_PAIRING_FAIL
+ -> "RESPONSE_TYPE_ON_INITIATE_PAIRING_FAIL";
+ case RESPONSE_TYPE_ON_RESPONSE_PAIRING_SUCCESS
+ -> "RESPONSE_TYPE_ON_RESPONSE_PAIRING_SUCCESS";
+ case RESPONSE_TYPE_ON_RESPONSE_PAIRING_FAIL
+ -> "RESPONSE_TYPE_ON_RESPONSE_PAIRING_FAIL";
+ case RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_SUCCESS
+ -> "RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_SUCCESS";
+ case RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_FAIL
+ -> "RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_FAIL";
+ case RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_SUCCESS
+ -> "RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_SUCCESS";
+ case RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_FAIL
+ -> "RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_FAIL";
+ case RESPONSE_TYPE_ON_SUSPEND -> "RESPONSE_TYPE_ON_SUSPEND";
+ case RESPONSE_TYPE_ON_RESUME -> "RESPONSE_TYPE_ON_RESUME";
+ case RESPONSE_TYPE_ON_END_PAIRING -> "RESPONSE_TYPE_ON_END_PAIRING";
+
+ case NOTIFICATION_TYPE_INTERFACE_CHANGE -> "NOTIFICATION_TYPE_INTERFACE_CHANGE";
+ case NOTIFICATION_TYPE_CLUSTER_CHANGE -> "NOTIFICATION_TYPE_CLUSTER_CHANGE";
+ case NOTIFICATION_TYPE_MATCH -> "NOTIFICATION_TYPE_MATCH";
+ case NOTIFICATION_TYPE_SESSION_TERMINATED -> "NOTIFICATION_TYPE_SESSION_TERMINATED";
+ case NOTIFICATION_TYPE_MESSAGE_RECEIVED -> "NOTIFICATION_TYPE_MESSAGE_RECEIVED";
+ case NOTIFICATION_TYPE_AWARE_DOWN -> "NOTIFICATION_TYPE_AWARE_DOWN";
+ case NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS
+ -> "NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS";
+ case NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL
+ -> "NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL";
+ case NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST
+ -> "NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST";
+ case NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM
+ -> "NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM";
+ case NOTIFICATION_TYPE_ON_DATA_PATH_END -> "NOTIFICATION_TYPE_ON_DATA_PATH_END";
+ case NOTIFICATION_TYPE_ON_DATA_PATH_SCHED_UPDATE
+ -> "NOTIFICATION_TYPE_ON_DATA_PATH_SCHED_UPDATE";
+ case NOTIFICATION_TYPE_MATCH_EXPIRED -> "NOTIFICATION_TYPE_MATCH_EXPIRED";
+ case NOTIFICATION_TYPE_ON_PAIRING_REQUEST -> "NOTIFICATION_TYPE_ON_PAIRING_REQUEST";
+ case NOTIFICATION_TYPE_ON_PAIRING_CONFIRM -> "NOTIFICATION_TYPE_ON_PAIRING_CONFIRM";
+ case NOTIFICATION_TYPE_ON_BOOTSTRAPPING_REQUEST
+ -> "NOTIFICATION_TYPE_ON_BOOTSTRAPPING_REQUEST";
+ case NOTIFICATION_TYPE_ON_BOOTSTRAPPING_CONFIRM
+ -> "NOTIFICATION_TYPE_ON_BOOTSTRAPPING_CONFIRM";
+ case NOTIFICATION_TYPE_ON_SUSPENSION_MODE_CHANGED
+ -> "NOTIFICATION_TYPE_ON_SUSPENSION_MODE_CHANGED";
+ case RunnerState.STATE_ENTER_CMD -> "Enter";
+ case RunnerState.STATE_EXIT_CMD -> "Exit";
+ case MESSAGE_TYPE_COMMAND -> "MESSAGE_TYPE_COMMAND";
+ case MESSAGE_TYPE_RESPONSE -> "MESSAGE_TYPE_RESPONSE";
+ case MESSAGE_TYPE_NOTIFICATION -> "MESSAGE_TYPE_NOTIFICATION";
+ case MESSAGE_TYPE_RESPONSE_TIMEOUT -> "MESSAGE_TYPE_RESPONSE_TIMEOUT";
+ case MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT -> "MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT";
+ case MESSAGE_TYPE_DATA_PATH_TIMEOUT -> "MESSAGE_TYPE_DATA_PATH_TIMEOUT";
+ case MESSAGE_TYPE_PAIRING_TIMEOUT -> "MESSAGE_TYPE_PAIRING_TIMEOUT";
+ case MESSAGE_TYPE_BOOTSTRAPPING_TIMEOUT -> "MESSAGE_TYPE_BOOTSTRAPPING_TIMEOUT";
+ default -> {
+ Log.e(TAG, "unknown message what: " + what);
+ yield "what:" + what;
+ }
+ };
+ }
+
public void onAwareDownCleanupSendQueueState() {
mSendQueueBlocked = false;
mHostQueuedSendMessages.clear();
mFwQueuedSendMessages.clear();
}
- private class DefaultState extends State {
+ private class DefaultState extends RunnerState {
+
+ DefaultState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public boolean processMessage(Message msg) {
+ public String getMessageLogRec(int what) {
+ return WifiAwareStateManager.class.getSimpleName() + "."
+ + DefaultState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public void enterImpl() {
+ }
+
+ @Override
+ public void exitImpl() {
+ }
+ @Override
+ public boolean processMessageImpl(Message msg) {
if (mVdbg) {
Log.v(TAG, getName() + msg.toString());
}
@@ -2264,9 +2417,27 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
}
- private class WaitState extends State {
+ private class WaitState extends RunnerState {
+
+ WaitState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public boolean processMessage(Message msg) {
+ public String getMessageLogRec(int what) {
+ return WifiAwareStateManager.class.getSimpleName() + "."
+ + WaitState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public void enterImpl() {
+ }
+
+ @Override
+ public void exitImpl() {
+ }
+ @Override
+ public boolean processMessageImpl(Message msg) {
if (mVdbg) {
Log.v(TAG, getName() + msg.toString());
}
@@ -2295,12 +2466,22 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
}
- private class WaitForResponseState extends State {
+ private class WaitForResponseState extends RunnerState {
private static final long AWARE_COMMAND_TIMEOUT = 5_000;
private WakeupMessage mTimeoutMessage;
+ WaitForResponseState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public String getMessageLogRec(int what) {
+ return WifiAwareStateManager.class.getSimpleName() + "."
+ + WaitForResponseState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public void enterImpl() {
mTimeoutMessage = new WakeupMessage(mContext, getHandler(), HAL_COMMAND_TIMEOUT_TAG,
MESSAGE_TYPE_RESPONSE_TIMEOUT, mCurrentCommand.arg1, mCurrentTransactionId);
mTimeoutMessage.schedule(SystemClock.elapsedRealtime() + AWARE_COMMAND_TIMEOUT);
@@ -2308,12 +2489,12 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
@Override
- public void exit() {
+ public void exitImpl() {
mTimeoutMessage.cancel();
}
@Override
- public boolean processMessage(Message msg) {
+ public boolean processMessageImpl(Message msg) {
if (mVdbg) {
Log.v(TAG, getName() + msg.toString());
}
@@ -2392,10 +2573,12 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
byte[] tag = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_TAG);
AwarePairingConfig pairingConfig = msg.getData()
.getParcelable(MESSAGE_BUNDLE_KEY_PAIRING_CONFIG);
+ ArrayList<OuiKeyedData> vendorData =
+ msg.getData().getParcelableArrayList(MESSAGE_BUNDLE_KEY_VENDOR_DATA);
onMatchLocal(pubSubId, requesterInstanceId, peerMac, serviceSpecificInfo,
matchFilter, rangingIndication, rangeMm, cipherSuite, scid, nonce, tag,
- pairingConfig);
+ pairingConfig, vendorData);
break;
}
case NOTIFICATION_TYPE_MATCH_EXPIRED: {
@@ -2834,8 +3017,10 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
int method = data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD);
byte[] cookie = data.getByteArray(
MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_COME_BACK_COOKIE);
+ boolean isComeBack = data
+ .getBoolean(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_IS_COME_BACK_REQUEST);
waitForResponse = initiateBootstrappingRequestLocal(mCurrentTransactionId,
- clientId, sessionId, peerId, method, cookie);
+ clientId, sessionId, peerId, method, cookie, isComeBack);
break;
}
case COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST: {
@@ -3963,7 +4148,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
private boolean initiateBootstrappingRequestLocal(short transactionId, int clientId,
- int sessionId, int peerId, int method, byte[] cookie) {
+ int sessionId, int peerId, int method, byte[] cookie, boolean isComeBack) {
String methodString = "initiateBootstrappingRequestLocal";
if (mVdbg) {
Log.v(TAG, methodString + ": transactionId=" + transactionId
@@ -3974,7 +4159,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
if (session == null) {
return false;
}
- return session.initiateBootstrapping(transactionId, peerId, method, cookie);
+ return session.initiateBootstrapping(transactionId, peerId, method, cookie, isComeBack);
}
private boolean respondToBootstrappingRequestLocal(short transactionId, int clientId,
@@ -4950,7 +5135,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
private void onMatchLocal(int pubSubId, int requestorinstanceid, byte[] peerMac,
byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndication, int rangeMm,
int cipherSuite, byte[] scid, byte[] nonce, byte[] tag,
- AwarePairingConfig pairingConfig) {
+ AwarePairingConfig pairingConfig, @NonNull List<OuiKeyedData> vendorData) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "onMatch: pubSubId=" + pubSubId
+ ", requestorInstanceId=" + requestorinstanceid
@@ -4974,7 +5159,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
data.first.getCallingPackage(), nonce, tag, peerMac);
int peerId = data.second.onMatch(requestorinstanceid, peerMac, serviceSpecificInfo,
matchFilter, rangingIndication, rangeMm, cipherSuite, scid, pairingAlias,
- pairingConfig);
+ pairingConfig, vendorData);
if (TextUtils.isEmpty(pairingAlias)) {
return;
}
@@ -5287,6 +5472,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
int clusterHigh = ConfigRequest.CLUSTER_ID_MAX;
int[] discoveryWindowInterval =
{ConfigRequest.DW_INTERVAL_NOT_INIT, ConfigRequest.DW_INTERVAL_NOT_INIT};
+ List<OuiKeyedData> vendorData = null;
if (configRequest != null) {
support5gBand = configRequest.mSupport5gBand;
support6gBand = configRequest.mSupport6gBand;
@@ -5338,6 +5524,10 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
cr.mDiscoveryWindowInterval[band]);
}
}
+
+ if (SdkLevel.isAtLeastV() && !cr.getVendorData().isEmpty()) {
+ vendorData = cr.getVendorData();
+ }
}
ConfigRequest.Builder builder = new ConfigRequest.Builder().setSupport5gBand(support5gBand)
.setMasterPreference(masterPreference).setClusterLow(clusterLow)
@@ -5347,6 +5537,16 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
builder.setDiscoveryWindowInterval(band, discoveryWindowInterval[band]);
}
}
+ if (SdkLevel.isAtLeastV()) {
+ // Always use the vendor data from the incoming ConfigRequest if provided.
+ // Otherwise, use the most recent vendor data in the mClients list.
+ if (configRequest != null && !configRequest.getVendorData().isEmpty()) {
+ vendorData = configRequest.getVendorData();
+ }
+ if (vendorData != null) {
+ builder.setVendorData(vendorData);
+ }
+ }
return builder.build();
}
diff --git a/service/java/com/android/server/wifi/b2b/WifiRoamingModeManager.java b/service/java/com/android/server/wifi/b2b/WifiRoamingModeManager.java
new file mode 100644
index 0000000000..acbefb4305
--- /dev/null
+++ b/service/java/com/android/server/wifi/b2b/WifiRoamingModeManager.java
@@ -0,0 +1,147 @@
+/*
+ * 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.b2b;
+
+import android.hardware.wifi.WifiStatusCode;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
+import android.util.Log;
+
+import com.android.server.wifi.ActiveModeWarden;
+import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.WifiRoamingConfigStore;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Map;
+
+public class WifiRoamingModeManager {
+ private static final String TAG = "WifiRoamingModeManager";
+ private final WifiNative mWifiNative;
+ private final WifiRoamingConfigStore mWifiRoamingConfigStore;
+ private final ActiveModeWarden mActiveModeWarden;
+ private boolean mVerboseLoggingEnabled = false;
+
+ public WifiRoamingModeManager(WifiNative wifiNative,
+ ActiveModeWarden activeModeWarden,
+ WifiRoamingConfigStore wifiRoamingConfigStore) {
+ this.mWifiNative = wifiNative;
+ this.mWifiRoamingConfigStore = wifiRoamingConfigStore;
+ this.mActiveModeWarden = activeModeWarden;
+ }
+
+ /**
+ * To handle policy updates when device is already in connected state
+ * and also when policy get removed in connected state.
+ */
+ private void checkAndUpdatePolicy(String updatedSsid) {
+ String currentSsid = mActiveModeWarden.getConnectionInfo().getSSID();
+ if (!updatedSsid.equals(currentSsid)) return;
+ String ifaceName = mActiveModeWarden.getPrimaryClientModeManager().getInterfaceName();
+ if (currentSsid != null && ifaceName != null) {
+ if (mVerboseLoggingEnabled) {
+ Log.i(TAG, "Re-applying roaming policy as it updated");
+ }
+ applyWifiRoamingMode(ifaceName, currentSsid);
+ }
+ }
+
+ /**
+ * Add a new network roaming policy.
+ *
+ * @param ssid name of the network on which policy is to be added.
+ * @param roamingMode denotes roaming mode value configured.
+ * @param isDeviceOwner flag denoting whether API is called by the device owner.
+ */
+ public void setPerSsidRoamingMode(WifiSsid ssid, @WifiManager.RoamingMode int roamingMode,
+ boolean isDeviceOwner) {
+ mWifiRoamingConfigStore.addRoamingMode(ssid.toString(), roamingMode, isDeviceOwner);
+ checkAndUpdatePolicy(ssid.toString());
+ }
+
+ /**
+ * Remove the network roaming policy for the given ssid.
+ *
+ * @param ssid name of the network on which policy is to be removed.
+ * @param isDeviceOwner flag denoting whether API is called by the device owner.
+ */
+ public void removePerSsidRoamingMode(WifiSsid ssid, boolean isDeviceOwner) {
+ mWifiRoamingConfigStore.removeRoamingMode(ssid.toString(), isDeviceOwner);
+ checkAndUpdatePolicy(ssid.toString());
+ }
+
+ /**
+ * Get all the network roaming policies configured.
+ *
+ * @param isDeviceOwner flag denoting whether API is called by the device owner.
+ * @return Map of corresponding policies for the API caller,
+ * where key is ssid and value is roaming mode/policy configured for that ssid.
+ */
+ public Map<String, Integer> getPerSsidRoamingModes(boolean isDeviceOwner) {
+ return mWifiRoamingConfigStore.getPerSsidRoamingModes(isDeviceOwner);
+ }
+
+ /**
+ * Apply roaming policy to the provided network.
+ * If policy does not exist, apply normal roaming policy.
+ *
+ * @param iface represents the name of the wifi interface.
+ * @param ssid represents the name of the network.
+ */
+ public void applyWifiRoamingMode(String iface, String ssid) {
+ int roamingMode = mWifiRoamingConfigStore.getRoamingMode(ssid);
+ if (mVerboseLoggingEnabled) {
+ Log.i(TAG, "Applying roaming policy for network "
+ + ssid + " with value " + roamingMode);
+ }
+ @WifiStatusCode int errorCode = mWifiNative.setRoamingMode(iface, roamingMode);
+ switch (errorCode) {
+ case WifiStatusCode.SUCCESS:
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "Roaming mode value successfully set to: " + roamingMode);
+ }
+ break;
+ case WifiStatusCode.ERROR_NOT_STARTED:
+ Log.e(TAG, "Failed to set roaming mode as WifiStaIfaceAidlImpl"
+ + " instance is not created.");
+ break;
+ case WifiStatusCode.ERROR_WIFI_IFACE_INVALID:
+ Log.e(TAG, "Failed to set roaming mode as interface is invalid.");
+ break;
+ case WifiStatusCode.ERROR_INVALID_ARGS:
+ Log.e(TAG, "Failed to set roaming mode due to invalid parameter "
+ + roamingMode);
+ break;
+ default:
+ Log.e(TAG, "Failed to set roaming mode due to unknown error.");
+ }
+ }
+
+ /**
+ * Enable verbose logging.
+ */
+ public void enableVerboseLogging(boolean verboseEnabled) {
+ mVerboseLoggingEnabled = verboseEnabled;
+ }
+
+ /**
+ * Dump roaming policies for debugging.
+ */
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mWifiRoamingConfigStore.dump(fd, pw, args);
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/IWifiNanIface.java b/service/java/com/android/server/wifi/hal/IWifiNanIface.java
index a975b9e3a5..3e0f544f19 100644
--- a/service/java/com/android/server/wifi/hal/IWifiNanIface.java
+++ b/service/java/com/android/server/wifi/hal/IWifiNanIface.java
@@ -276,21 +276,26 @@ public interface IWifiNanIface {
* match indication).
* @param peer The MAC address of the peer to create a connection with.
* @param method the proposed bootstrapping method
+ * @param pubSubId ID of the publish/subscribe session - obtained when creating a session.
+ * @param isComeBack If the request is for a previous comeback response
* @return True if the request send succeed.
*/
boolean initiateNanBootstrappingRequest(short transactionId, int peerId, MacAddress peer,
- int method, byte[] cookie);
+ int method, byte[] cookie, byte pubSubId, boolean isComeBack);
/**
* Respond to a bootstrapping request
- * @param transactionId Transaction ID for the transaction - used in the
- * async callback to match with the original request.
+ *
+ * @param transactionId Transaction ID for the transaction - used in the
+ * async callback to match with the original request.
* @param bootstrappingId the id of this bootstrapping session
- * @param accept True if the proposed bootstrapping method is accepted.
+ * @param accept True if the proposed bootstrapping method is accepted.
+ * @param pubSubId ID of the publish/subscribe session - obtained when creating a
+ * session.
* @return True if the request send succeed.
*/
boolean respondToNanBootstrappingRequest(short transactionId, int bootstrappingId,
- boolean accept);
+ boolean accept, byte pubSubId);
/**
* Suspend the specified Aware session. During the suspend state, the Wi-Fi Aware device
diff --git a/service/java/com/android/server/wifi/hal/IWifiStaIface.java b/service/java/com/android/server/wifi/hal/IWifiStaIface.java
index da06ef7a9f..3e4078531a 100644
--- a/service/java/com/android/server/wifi/hal/IWifiStaIface.java
+++ b/service/java/com/android/server/wifi/hal/IWifiStaIface.java
@@ -17,8 +17,13 @@
package com.android.server.wifi.hal;
import android.annotation.Nullable;
+import android.hardware.wifi.WifiStatusCode;
import android.net.MacAddress;
import android.net.apf.ApfCapabilities;
+import android.net.wifi.WifiManager.RoamingMode;
+import android.net.wifi.WifiScanner;
+import android.net.wifi.twt.TwtRequest;
+import android.os.Bundle;
import com.android.server.wifi.WifiLinkLayerStats;
import com.android.server.wifi.WifiLoggerHal;
@@ -123,6 +128,14 @@ public interface IWifiStaIface {
MacAddress getFactoryMacAddress();
/**
+ * Retrieve the cached scan data.
+ *
+ * @return Instance of {@link ScanData}, or null on error.
+ */
+ @Nullable
+ WifiScanner.ScanData getCachedScanData();
+
+ /**
* Retrieve the latest link layer stats.
* Note: will fail if link layer stats collection has not been explicitly enabled.
*
@@ -256,4 +269,54 @@ public interface IWifiStaIface {
* @return true if successful, false otherwise.
*/
boolean setDtimMultiplier(int multiplier);
+
+ /**
+ * Set the roaming mode.
+ *
+ * @param roamingMode {@link android.net.wifi.WifiManager.RoamingMode}.
+ * @return {@link WifiStatusCode#SUCCESS} if success, otherwise error code.
+ */
+ @WifiStatusCode int setRoamingMode(@RoamingMode int roamingMode);
+
+ /**
+ * Get target wake time (TWT) capabilities.
+ *
+ * @return TWT capabilities as Bundle
+ */
+ default Bundle getTwtCapabilities() {
+ return null;
+ }
+
+ /**
+ * Set up a TWT session
+ *
+ * @param cmdId Command ID to use for this invocation.
+ * @param twtRequest TWT request configuration to setup TWT session
+ * @return true if successful, false otherwise.
+ */
+ default boolean setupTwtSession(int cmdId, TwtRequest twtRequest) {
+ return false;
+ }
+
+ /**
+ * Teardown a TWT session.
+ *
+ * @param cmdId Command ID to use for this invocation.
+ * @param sessionId TWT session identifier
+ * @return true if successful, false otherwise.
+ */
+ default boolean tearDownTwtSession(int cmdId, int sessionId) {
+ return false;
+ }
+
+ /**
+ * Get stats for the TWT session.
+ *
+ * @param cmdId Command ID to use for this invocation.
+ * @param sessionId TWT session identifier
+ * @return true if successful, false otherwise.
+ */
+ default boolean getStatsTwtSession(int cmdId, int sessionId) {
+ return false;
+ }
}
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIface.java b/service/java/com/android/server/wifi/hal/WifiNanIface.java
index 62541c90ee..9fcf9e2038 100644
--- a/service/java/com/android/server/wifi/hal/WifiNanIface.java
+++ b/service/java/com/android/server/wifi/hal/WifiNanIface.java
@@ -19,6 +19,7 @@ package com.android.server.wifi.hal;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.aware.AwarePairingConfig;
import android.net.wifi.aware.ConfigRequest;
import android.net.wifi.aware.PublishConfig;
@@ -513,22 +514,22 @@ public class WifiNanIface implements WifiHal.WifiInterface {
cipherSuite));
}
/**
- * {@link IWifiNanIface#initiateNanBootstrappingRequest(short, int, MacAddress, int, byte[])}
+ * {@link IWifiNanIface#initiateNanBootstrappingRequest(short, int, MacAddress, int, byte[], byte, boolean)}
*/
public boolean initiateBootstrapping(short transactionId, int peerId, MacAddress peer,
- int method, byte[] cookie) {
+ int method, byte[] cookie, byte pubSubId, boolean isComeBack) {
return validateAndCall("initiateBootstrapping", false,
() -> mWifiNanIface.initiateNanBootstrappingRequest(transactionId, peerId, peer,
- method, cookie));
+ method, cookie, pubSubId, isComeBack));
}
/**
- * {@link IWifiNanIface#respondToNanBootstrappingRequest(short, int, boolean)}
+ * {@link IWifiNanIface#respondToNanBootstrappingRequest(short, int, boolean, byte)}
*/
public boolean respondToBootstrappingRequest(short transactionId, int bootstrappingId,
- boolean accept) {
+ boolean accept, byte pubSubId) {
return validateAndCall("initiateBootstrapping", false,
() -> mWifiNanIface.respondToNanBootstrappingRequest(transactionId, bootstrappingId,
- accept));
+ accept, pubSubId));
}
/**
@@ -741,11 +742,13 @@ public class WifiNanIface implements WifiHal.WifiInterface {
* identifying the PMK used for setting up the Secure Data Path.
* @param peerCipherType Cipher type for data-paths constructed in the context of this
* discovery session.
+ * @param vendorData Additional vendor-specific parameters, or null if not provided.
*/
void eventMatch(byte discoverySessionId, int peerId, byte[] addr,
byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndicationType,
int rangingMeasurementInMm, byte[] scid, int peerCipherType, byte[] nonce,
- byte[] tag, AwarePairingConfig pairingConfig);
+ byte[] tag, AwarePairingConfig pairingConfig,
+ @Nullable List<OuiKeyedData> vendorData);
/**
* Indicates that a previously discovered match (service) has expired.
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java
index 0f10214a34..2b5a7da08a 100644
--- a/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java
@@ -65,6 +65,7 @@ import android.util.Log;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.aware.Capabilities;
+import com.android.server.wifi.util.HalAidlUtil;
import java.nio.charset.StandardCharsets;
@@ -173,7 +174,7 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
/**
* See comments for {@link IWifiNanIface#enableAndConfigure(short, ConfigRequest, boolean,
- * boolean, boolean, boolean, int, int, WifiNanIface.PowerParameters)}
+ * boolean, boolean, boolean, int, int, int, WifiNanIface.PowerParameters)}
*/
@Override
public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest,
@@ -512,10 +513,10 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
@Override
public boolean initiateNanBootstrappingRequest(short transactionId, int peerId, MacAddress peer,
- int method, byte[] cookie) {
+ int method, byte[] cookie, byte pubSubId, boolean isComeBack) {
String methodStr = "initiateNanBootstrappingRequest";
NanBootstrappingRequest request = createNanBootstrappingRequest(peerId, peer, method,
- cookie);
+ cookie, pubSubId, isComeBack);
synchronized (mLock) {
try {
if (!checkIfaceAndLogFailure(methodStr)) return false;
@@ -532,9 +533,10 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
@Override
public boolean respondToNanBootstrappingRequest(short transactionId, int bootstrappingId,
- boolean accept) {
+ boolean accept, byte pubSubId) {
String methodStr = "respondToNanBootstrappingRequest";
- NanBootstrappingResponse request = createNanBootstrappingResponse(bootstrappingId, accept);
+ NanBootstrappingResponse request = createNanBootstrappingResponse(bootstrappingId, accept,
+ pubSubId);
synchronized (mLock) {
try {
if (!checkIfaceAndLogFailure(methodStr)) return false;
@@ -587,20 +589,23 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
// Utilities
private static NanBootstrappingResponse createNanBootstrappingResponse(int bootstrappingId,
- boolean accept) {
+ boolean accept, byte pubSubId) {
NanBootstrappingResponse request = new NanBootstrappingResponse();
request.acceptRequest = accept;
request.bootstrappingInstanceId = bootstrappingId;
+ request.discoverySessionId = pubSubId;
return request;
}
private static NanBootstrappingRequest createNanBootstrappingRequest(int peerId,
- MacAddress peer, int method, byte[] cookie) {
+ MacAddress peer, int method, byte[] cookie, byte pubSubId, boolean isComeBack) {
NanBootstrappingRequest request = new NanBootstrappingRequest();
request.peerId = peerId;
request.peerDiscMacAddr = peer.toByteArray();
request.requestBootstrappingMethod = method;
request.cookie = copyArray(cookie);
+ request.discoverySessionId = pubSubId;
+ request.isComeback = isComeBack;
return request;
}
@@ -727,6 +732,7 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_6GHZ] = true;
updateConfigForPowerSettings(req.configParams, configSupplemental, powerParameters);
+ updateConfigRequestVendorData(req.configParams, configRequest);
return req;
}
@@ -754,6 +760,7 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = nanBandSpecificConfigs[1];
req.bandSpecificConfig[NanBandIndex.NAN_BAND_6GHZ] = nanBandSpecificConfigs[2];
updateConfigForPowerSettings(req, configSupplemental, powerParameters);
+ updateConfigRequestVendorData(req, configRequest);
return req;
}
@@ -785,6 +792,15 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
}
}
+ private static void updateConfigRequestVendorData(
+ NanConfigRequest halReq, ConfigRequest frameworkReq) {
+ if (SdkLevel.isAtLeastV() && WifiHalAidlImpl.isServiceVersionAtLeast(2)
+ && !frameworkReq.getVendorData().isEmpty()) {
+ halReq.vendorData =
+ HalAidlUtil.frameworkToHalOuiKeyedDataList(frameworkReq.getVendorData());
+ }
+ }
+
private static NanPublishRequest createNanPublishRequest(
byte publishId, PublishConfig publishConfig, byte[] nik) {
NanPublishRequest req = new NanPublishRequest();
@@ -852,6 +868,12 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
req.txType = NanTxType.BROADCAST;
req.pairingConfig = createAidlPairingConfig(publishConfig.getPairingConfig());
req.identityKey = copyArray(nik, 16);
+
+ if (SdkLevel.isAtLeastV() && !publishConfig.getVendorData().isEmpty()) {
+ req.vendorData =
+ HalAidlUtil.frameworkToHalOuiKeyedDataList(publishConfig.getVendorData());
+ }
+
return req;
}
@@ -915,6 +937,12 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
req.pairingConfig = createAidlPairingConfig(subscribeConfig.getPairingConfig());
req.identityKey = copyArray(nik, 16);
req.intfAddr = new android.hardware.wifi.MacAddress[0];
+
+ if (SdkLevel.isAtLeastV() && !subscribeConfig.getVendorData().isEmpty()) {
+ req.vendorData =
+ HalAidlUtil.frameworkToHalOuiKeyedDataList(subscribeConfig.getVendorData());
+ }
+
return req;
}
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java
index 648b344b93..bb1a2e1bf2 100644
--- a/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java
@@ -47,10 +47,8 @@ import android.hardware.wifi.NanStatus;
import android.hardware.wifi.NanStatusCode;
import android.hardware.wifi.NanSuspensionModeChangeInd;
import android.hardware.wifi.NpkSecurityAssociation;
-import android.hardware.wifi.WifiChannelWidthInMhz;
import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiAnnotations;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.aware.AwarePairingConfig;
import android.net.wifi.aware.Characteristics;
import android.net.wifi.aware.WifiAwareChannelInfo;
@@ -61,6 +59,7 @@ import com.android.server.wifi.aware.Capabilities;
import com.android.server.wifi.aware.PairingConfigManager.PairingSecurityAssociationInfo;
import com.android.server.wifi.hal.WifiNanIface.NanClusterEventType;
import com.android.server.wifi.hal.WifiNanIface.NanRangingIndication;
+import com.android.server.wifi.util.HalAidlUtil;
import java.util.ArrayList;
import java.util.Arrays;
@@ -399,6 +398,10 @@ public class WifiNanIfaceCallbackAidlImpl extends IWifiNanIfaceEventCallback.Stu
serviceSpecificInfo = event.extendedServiceSpecificInfo;
isExtendedServiceSpecificInfo = true;
}
+ List<OuiKeyedData> vendorData = null;
+ if (WifiHalAidlImpl.isServiceVersionAtLeast(2) && event.vendorData != null) {
+ vendorData = HalAidlUtil.halToFrameworkOuiKeyedDataList(event.vendorData);
+ }
if (mVerboseLoggingEnabled) {
Log.v(
TAG,
@@ -440,7 +443,8 @@ public class WifiNanIfaceCallbackAidlImpl extends IWifiNanIfaceEventCallback.Stu
toPublicDataPathCipherSuites(event.peerCipherType),
event.peerNira.nonce,
event.peerNira.tag,
- createPublicPairingConfig(event.peerPairingConfig));
+ createPublicPairingConfig(event.peerPairingConfig),
+ vendorData);
}
private AwarePairingConfig createPublicPairingConfig(NanPairingConfig nativePairingConfig) {
@@ -773,26 +777,6 @@ public class WifiNanIfaceCallbackAidlImpl extends IWifiNanIfaceEventCallback.Stu
return sb.toString();
}
- /**
- * Convert HAL channelBandwidth to framework enum
- */
- @WifiAnnotations.ChannelWidth
- private int getChannelBandwidthFromHal(int channelBandwidth) {
- switch (channelBandwidth) {
- case WifiChannelWidthInMhz.WIDTH_40:
- return ScanResult.CHANNEL_WIDTH_40MHZ;
- case WifiChannelWidthInMhz.WIDTH_80:
- return ScanResult.CHANNEL_WIDTH_80MHZ;
- case WifiChannelWidthInMhz.WIDTH_160:
- return ScanResult.CHANNEL_WIDTH_160MHZ;
- case WifiChannelWidthInMhz.WIDTH_80P80:
- return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
- case WifiChannelWidthInMhz.WIDTH_320:
- return ScanResult.CHANNEL_WIDTH_320MHZ;
- default:
- return ScanResult.CHANNEL_WIDTH_20MHZ;
- }
- }
/**
* Convert HAL NanDataPathChannelInfo to WifiAwareChannelInfo
@@ -805,7 +789,7 @@ public class WifiNanIfaceCallbackAidlImpl extends IWifiNanIfaceEventCallback.Stu
}
for (android.hardware.wifi.NanDataPathChannelInfo channelInfo : channelInfos) {
wifiAwareChannelInfos.add(new WifiAwareChannelInfo(channelInfo.channelFreq,
- getChannelBandwidthFromHal(channelInfo.channelBandwidth),
+ HalAidlUtil.getChannelBandwidthFromHal(channelInfo.channelBandwidth),
channelInfo.numSpatialStreams));
}
return wifiAwareChannelInfos;
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackHidlImpl.java
index 2d2dc28760..800362a760 100644
--- a/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackHidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackHidlImpl.java
@@ -343,7 +343,7 @@ public class WifiNanIfaceCallbackHidlImpl extends IWifiNanIfaceEventCallback.Stu
event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo),
convertArrayListToNativeByteArray(event.matchFilter),
NanRangingIndication.fromHidl(event.rangingIndicationType),
- event.rangingMeasurementInCm * 10, new byte[0], 0, null, null, null);
+ event.rangingMeasurementInCm * 10, new byte[0], 0, null, null, null, null);
}
@Override
@@ -368,7 +368,7 @@ public class WifiNanIfaceCallbackHidlImpl extends IWifiNanIfaceEventCallback.Stu
convertArrayListToNativeByteArray(event.matchFilter),
NanRangingIndication.fromHidl(event.rangingIndicationType),
event.rangingMeasurementInMm, convertArrayListToNativeByteArray(event.scid),
- toPublicCipherSuites(event.peerCipherType), null, null, null);
+ toPublicCipherSuites(event.peerCipherType), null, null, null, null);
}
@Override
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceHidlImpl.java
index 038fc1775d..c5b9776fbe 100644
--- a/service/java/com/android/server/wifi/hal/WifiNanIfaceHidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceHidlImpl.java
@@ -259,13 +259,13 @@ public class WifiNanIfaceHidlImpl implements IWifiNanIface {
@Override
public boolean initiateNanBootstrappingRequest(short transactionId, int peerId, MacAddress peer,
- int method, byte[] cookie) {
+ int method, byte[] cookie, byte pubSubId, boolean isComeBack) {
return false;
}
@Override
public boolean respondToNanBootstrappingRequest(short transactionId, int bootstrappingId,
- boolean accept) {
+ boolean accept, byte pubSubId) {
return false;
}
diff --git a/service/java/com/android/server/wifi/hal/WifiRttController.java b/service/java/com/android/server/wifi/hal/WifiRttController.java
index 2a0f7a6281..9061a01515 100644
--- a/service/java/com/android/server/wifi/hal/WifiRttController.java
+++ b/service/java/com/android/server/wifi/hal/WifiRttController.java
@@ -108,6 +108,14 @@ public class WifiRttController {
public byte mcVersion;
// Whether ftm rtt data collection is supported.
public boolean rttFtmSupported;
+ // IEEE 802.11az preamble supported, see bit mask definition above.
+ public int azPreambleSupported;
+ // IEE 802.11az RTT bandwidth supported.
+ public int azBwSupported;
+ // Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported.
+ public boolean ntbInitiatorSupported;
+ // Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported.
+ public boolean ntbResponderSupported;
public Capabilities() {
}
@@ -154,6 +162,10 @@ public class WifiRttController {
mcVersion = rttHalCapabilities.mcVersion;
bwSupported = rttHalCapabilities.bwSupport;
rttFtmSupported = rttHalCapabilities.rttFtmSupported;
+ azPreambleSupported = rttHalCapabilities.azPreambleSupport;
+ azBwSupported = rttHalCapabilities.azBwSupport;
+ ntbInitiatorSupported = rttHalCapabilities.ntbInitiatorSupported;
+ ntbResponderSupported = rttHalCapabilities.ntbResponderSupported;
}
}
diff --git a/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java
index 1201a84a14..9c10ee0937 100644
--- a/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java
@@ -29,7 +29,10 @@ import android.hardware.wifi.RttStatus;
import android.hardware.wifi.RttType;
import android.hardware.wifi.WifiChannelInfo;
import android.hardware.wifi.WifiChannelWidthInMhz;
+import android.hardware.wifi.common.OuiKeyedData;
import android.net.MacAddress;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiAnnotations;
import android.net.wifi.rtt.RangingRequest;
import android.net.wifi.rtt.RangingResult;
import android.net.wifi.rtt.ResponderConfig;
@@ -38,6 +41,9 @@ import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.Log;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.server.wifi.util.HalAidlUtil;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
@@ -269,19 +275,57 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
}
rttResult.distanceSdInMm = 0;
}
- rangingResults.add(new RangingResult(
- halToFrameworkRttStatus(rttResult.status),
- MacAddress.fromBytes(rttResult.addr),
- rttResult.distanceInMm, rttResult.distanceSdInMm,
- rttResult.rssi / -2, rttResult.numberPerBurstPeer,
- rttResult.successNumber, lci, lcr, responderLocation,
- rttResult.timeStampInUs / WifiRttController.CONVERSION_US_TO_MS,
- rttResult.type == RttType.TWO_SIDED, rttResult.channelFreqMHz,
- rttResult.packetBw));
+ RangingResult.Builder resultBuilder = new RangingResult.Builder()
+ .setStatus(halToFrameworkRttStatus(rttResult.status))
+ .setMacAddress(MacAddress.fromBytes(rttResult.addr))
+ .setDistanceMm(rttResult.distanceInMm)
+ .setDistanceStdDevMm(rttResult.distanceSdInMm)
+ .setRssi(rttResult.rssi / -2)
+ .setNumAttemptedMeasurements(rttResult.numberPerBurstPeer)
+ .setNumSuccessfulMeasurements(rttResult.successNumber)
+ .setLci(lci)
+ .setLcr(lcr)
+ .setUnverifiedResponderLocation(responderLocation)
+ .setRangingTimestampMillis(
+ rttResult.timeStampInUs / WifiRttController.CONVERSION_US_TO_MS)
+ .set80211mcMeasurement(rttResult.type == RttType.TWO_SIDED_11MC)
+ .setMeasurementChannelFrequencyMHz(rttResult.channelFreqMHz)
+ .setMeasurementBandwidth(halToFrameworkChannelBandwidth(rttResult.packetBw))
+ .set80211azNtbMeasurement(rttResult.type == RttType.TWO_SIDED_11AZ_NTB)
+ .setMinTimeBetweenNtbMeasurementsMicros(rttResult.ntbMinMeasurementTime)
+ .setMaxTimeBetweenNtbMeasurementsMicros(rttResult.ntbMaxMeasurementTime)
+ .set80211azInitiatorTxLtfRepetitionsCount(rttResult.i2rTxLtfRepetitionCount)
+ .set80211azResponderTxLtfRepetitionsCount(rttResult.r2iTxLtfRepetitionCount)
+ .set80211azNumberOfTxSpatialStreams(rttResult.numTxSpatialStreams)
+ .set80211azNumberOfRxSpatialStreams(rttResult.numRxSpatialStreams);
+ if (SdkLevel.isAtLeastV() && WifiHalAidlImpl.isServiceVersionAtLeast(2)
+ && rttResult.vendorData != null) {
+ resultBuilder.setVendorData(
+ HalAidlUtil.halToFrameworkOuiKeyedDataList(rttResult.vendorData));
+ }
+ rangingResults.add(resultBuilder.build());
}
return rangingResults;
}
+ private static @WifiAnnotations.ChannelWidth int halToFrameworkChannelBandwidth(
+ @RttBw int packetBw) {
+ switch (packetBw) {
+ case RttBw.BW_20MHZ:
+ return ScanResult.CHANNEL_WIDTH_20MHZ;
+ case RttBw.BW_40MHZ:
+ return ScanResult.CHANNEL_WIDTH_40MHZ;
+ case RttBw.BW_80MHZ:
+ return ScanResult.CHANNEL_WIDTH_80MHZ;
+ case RttBw.BW_160MHZ:
+ return ScanResult.CHANNEL_WIDTH_160MHZ;
+ case RttBw.BW_320MHZ:
+ return ScanResult.CHANNEL_WIDTH_320MHZ;
+ default:
+ return RangingResult.UNSPECIFIED;
+ }
+ }
+
private static @WifiRttController.FrameworkRttStatus int halToFrameworkRttStatus(
int halStatus) {
switch (halStatus) {
@@ -343,6 +387,53 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
}
}
+ /**
+ * Get optimum burst duration corresponding to a burst size.
+ *
+ * IEEE 802.11 spec, Section 11.21.6.3 Fine timing measurement procedure negotiation, burst
+ * duration is defined as
+ *
+ * Burst duration = (N_FTMPB * (K + 1)) – 1) * T_MDFTM + T_FTM + aSIFSTime + T_Ack, where
+ * - N_FTMPB is the value of the FTMs Per Burst subfield
+ * - K is the maximum number of Fine Timing Measurement frame retransmissions the
+ * responding STA might attempt
+ * - T_MDFTM is the duration indicated by the Min Delta FTM subfield of the Fine Timing
+ * Measurement Parameters field of the initial Fine Timing Measurement frame (FTM_1)
+ * - T_FTM is the duration of the initial Fine Timing Measurement frame if the FTMs Per Burst
+ * subfield of the Fine Timing Measurement Parameters field of FTM_1 is set to 1,
+ * and the duration of the non-initial Fine Timing Measurement frame otherwise
+ * T_Ack is the duration of the Ack frame expected as a response
+ *
+ * Since many of the parameters are dependent on the chip and the vendor software, framework is
+ * doing a simple conversion with experimented values. Vendor Software may override the burst
+ * duration with more optimal values.
+ *
+ * Section '9.4.2.167 Fine Timing Measurement Parameters element' defines Burst Duration
+ * subfield encoding as,
+ * +--------------------+
+ * |Value| Represents |
+ * +--------------------+
+ * | 0-1 | Reserved |
+ * | 2 | 250 us |
+ * | 3 | 500 us |
+ * | 4 | 1 ms |
+ * | 5 | 2 ms |
+ * | 6 | 4 ms |
+ * | 7 | 8 ms |
+ * | 8 | 16 ms |
+ * | 9 | 32 ms |
+ * | 10 | 64 ms |
+ * | 11 | 128 ms |
+ * |12-14| Reserved |
+ * | 15 | No Preference|
+ * +-----+--------------+
+ */
+ private static int getOptimumBurstDuration(int burstSize) {
+ if (burstSize <= 8) return 9; // 32 ms
+ if (burstSize <= 24) return 10; // 64 ms
+ return 11; // 128 ms
+ }
+
private static RttConfig[] convertRangingRequestToRttConfigs(RangingRequest request,
WifiRttController.Capabilities cap) {
ArrayList<RttConfig> rttConfigs = new ArrayList<>();
@@ -353,11 +444,32 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
RttConfig config = new RttConfig();
config.addr = responder.macAddress.toByteArray();
+ OuiKeyedData[] vendorData = null;
+ if (SdkLevel.isAtLeastV() && request.getVendorData() != null
+ && !request.getVendorData().isEmpty()) {
+ vendorData = HalAidlUtil.frameworkToHalOuiKeyedDataList(request.getVendorData());
+ }
+
try {
- config.type = responder.supports80211mc ? RttType.TWO_SIDED : RttType.ONE_SIDED;
- if (config.type == RttType.ONE_SIDED && cap != null && !cap.oneSidedRttSupported) {
- Log.w(TAG, "Device does not support one-sided RTT");
- continue;
+ if (cap != null) {
+ if (responder.supports80211azNtb && cap.ntbInitiatorSupported) {
+ config.type = RttType.TWO_SIDED_11AZ_NTB;
+ } else if (responder.supports80211mc) {
+ // IEEE 802.11mc is supported by the device
+ config.type = RttType.TWO_SIDED_11MC;
+ } else if (cap.oneSidedRttSupported) {
+ config.type = RttType.ONE_SIDED;
+ } else {
+ Log.w(TAG, "Device does not support one-sided RTT");
+ continue;
+ }
+ } else {
+ if (responder.supports80211mc) {
+ // IEEE 802.11mc is supported by the device
+ config.type = RttType.TWO_SIDED_11MC;
+ } else {
+ config.type = RttType.ONE_SIDED;
+ }
}
config.peer = frameworkToHalRttPeerType(responder.responderType);
@@ -369,7 +481,16 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
config.channel.centerFreq1 = responder.centerFreq1;
config.bw = frameworkToHalChannelBandwidth(responder.channelWidth);
config.preamble = frameworkToHalResponderPreamble(responder.preamble);
+ if (WifiHalAidlImpl.isServiceVersionAtLeast(2) && vendorData != null) {
+ config.vendorData = vendorData;
+ }
validateBwAndPreambleCombination(config.bw, config.preamble);
+ // ResponderConfig#ntbMaxMeasurementTime is in units of 10 milliseconds
+ config.ntbMaxMeasurementTime =
+ responder.getNtbMaxTimeBetweenMeasurementsMicros() / 10000;
+ // ResponderConfig#ntbMinMeasurementTime is in units of 100 microseconds
+ config.ntbMinMeasurementTime =
+ responder.getNtbMinTimeBetweenMeasurementsMicros() / 100;
if (config.peer == RttPeerType.NAN_TYPE) {
config.mustRequestLci = false;
@@ -379,7 +500,7 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
config.numFramesPerBurst = request.mRttBurstSize;
config.numRetriesPerRttFrame = 0; // irrelevant for 2-sided RTT
config.numRetriesPerFtmr = 3;
- config.burstDuration = 9;
+ config.burstDuration = getOptimumBurstDuration(request.mRttBurstSize);
} else { // AP + all non-NAN requests
config.mustRequestLci = true;
config.mustRequestLcr = true;
@@ -388,13 +509,15 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
config.numFramesPerBurst = request.mRttBurstSize;
config.numRetriesPerRttFrame = (config.type == RttType.TWO_SIDED ? 0 : 3);
config.numRetriesPerFtmr = 3;
- config.burstDuration = 9;
+ config.burstDuration = getOptimumBurstDuration(request.mRttBurstSize);
if (cap != null) { // constrain parameters per device capabilities
config.mustRequestLci = config.mustRequestLci && cap.lciSupported;
config.mustRequestLcr = config.mustRequestLcr && cap.lcrSupported;
- config.bw = halRttChannelBandwidthCapabilityLimiter(config.bw, cap);
- config.preamble = halRttPreambleCapabilityLimiter(config.preamble, cap);
+ config.bw = halRttChannelBandwidthCapabilityLimiter(config.bw, cap,
+ config.type);
+ config.preamble = halRttPreambleCapabilityLimiter(config.preamble, cap,
+ config.type);
}
}
} catch (IllegalArgumentException e) {
@@ -515,9 +638,12 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
* Note: the halRttChannelBandwidth is a single bit flag from the HAL RttBw type.
*/
private static int halRttChannelBandwidthCapabilityLimiter(int halRttChannelBandwidth,
- WifiRttController.Capabilities cap) throws IllegalArgumentException {
+ WifiRttController.Capabilities cap, @RttType int rttType)
+ throws IllegalArgumentException {
int requestedBandwidth = halRttChannelBandwidth;
- while ((halRttChannelBandwidth != 0) && ((halRttChannelBandwidth & cap.bwSupported) == 0)) {
+ int bwSupported =
+ (rttType == RttType.TWO_SIDED_11AZ_NTB) ? cap.azBwSupported : cap.bwSupported;
+ while ((halRttChannelBandwidth != 0) && ((halRttChannelBandwidth & bwSupported) == 0)) {
halRttChannelBandwidth >>= 1;
}
@@ -539,9 +665,12 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
* Note: the halRttPreamble is a single bit flag from the HAL RttPreamble type.
*/
private static int halRttPreambleCapabilityLimiter(int halRttPreamble,
- WifiRttController.Capabilities cap) throws IllegalArgumentException {
+ WifiRttController.Capabilities cap, @RttType int rttType)
+ throws IllegalArgumentException {
int requestedPreamble = halRttPreamble;
- while ((halRttPreamble != 0) && ((halRttPreamble & cap.preambleSupported) == 0)) {
+ int preambleSupported = (rttType == RttType.TWO_SIDED_11AZ_NTB) ? cap.azPreambleSupported
+ : cap.preambleSupported;
+ while ((halRttPreamble != 0) && ((halRttPreamble & preambleSupported) == 0)) {
halRttPreamble >>= 1;
}
diff --git a/service/java/com/android/server/wifi/hal/WifiRttControllerHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiRttControllerHidlImpl.java
index 6ef2eaabff..cce8bb1372 100644
--- a/service/java/com/android/server/wifi/hal/WifiRttControllerHidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiRttControllerHidlImpl.java
@@ -396,14 +396,21 @@ public class WifiRttControllerHidlImpl implements IWifiRttController {
}
rttResult.distanceSdInMm = 0;
}
- rangingResults.add(new RangingResult(
- convertHalStatusToFrameworkStatus(rttResult.status),
- MacAddress.fromBytes(rttResult.addr),
- rttResult.distanceInMm, rttResult.distanceSdInMm,
- rttResult.rssi / -2, rttResult.numberPerBurstPeer,
- rttResult.successNumber, lci, lcr, responderLocation,
- rttResult.timeStampInUs / WifiRttController.CONVERSION_US_TO_MS,
- rttResult.type == RttType.TWO_SIDED));
+ rangingResults.add(new RangingResult.Builder()
+ .setStatus(convertHalStatusToFrameworkStatus(rttResult.status))
+ .setMacAddress(MacAddress.fromBytes(rttResult.addr))
+ .setDistanceMm(rttResult.distanceInMm)
+ .setDistanceStdDevMm(rttResult.distanceSdInMm)
+ .setRssi(rttResult.rssi / -2)
+ .setNumAttemptedMeasurements(rttResult.numberPerBurstPeer)
+ .setNumSuccessfulMeasurements(rttResult.successNumber)
+ .setLci(lci)
+ .setLcr(lcr)
+ .setUnverifiedResponderLocation(responderLocation)
+ .setRangingTimestampMillis(
+ rttResult.timeStampInUs / WifiRttController.CONVERSION_US_TO_MS)
+ .set80211mcMeasurement(rttResult.type == RttType.TWO_SIDED)
+ .build());
}
return rangingResults;
}
@@ -432,14 +439,21 @@ public class WifiRttControllerHidlImpl implements IWifiRttController {
}
rttResult.distanceSdInMm = 0;
}
- rangingResults.add(new RangingResult(
- convertHalStatusToFrameworkStatus(rttResult.status),
- MacAddress.fromBytes(rttResult.addr),
- rttResult.distanceInMm, rttResult.distanceSdInMm,
- rttResult.rssi / -2, rttResult.numberPerBurstPeer,
- rttResult.successNumber, lci, lcr, responderLocation,
- rttResult.timeStampInUs / WifiRttController.CONVERSION_US_TO_MS,
- rttResult.type == RttType.TWO_SIDED));
+ rangingResults.add(new RangingResult.Builder()
+ .setStatus(convertHalStatusToFrameworkStatus(rttResult.status))
+ .setMacAddress(MacAddress.fromBytes(rttResult.addr))
+ .setDistanceMm(rttResult.distanceInMm)
+ .setDistanceStdDevMm(rttResult.distanceSdInMm)
+ .setRssi(rttResult.rssi / -2)
+ .setNumAttemptedMeasurements(rttResult.numberPerBurstPeer)
+ .setNumSuccessfulMeasurements(rttResult.successNumber)
+ .setLci(lci)
+ .setLcr(lcr)
+ .setUnverifiedResponderLocation(responderLocation)
+ .setRangingTimestampMillis(
+ rttResult.timeStampInUs / WifiRttController.CONVERSION_US_TO_MS)
+ .set80211mcMeasurement(rttResult.type == RttType.TWO_SIDED)
+ .build());
}
return rangingResults;
}
@@ -468,14 +482,21 @@ public class WifiRttControllerHidlImpl implements IWifiRttController {
}
rttResult.distanceSdInMm = 0;
}
- rangingResults.add(new RangingResult(
- convertHalStatusToFrameworkStatus(rttResult.status),
- MacAddress.fromBytes(rttResult.addr),
- rttResult.distanceInMm, rttResult.distanceSdInMm,
- rttResult.rssi / -2, rttResult.numberPerBurstPeer,
- rttResult.successNumber, lci, lcr, responderLocation,
- rttResult.timeStampInUs / WifiRttController.CONVERSION_US_TO_MS,
- rttResult.type == RttType.TWO_SIDED));
+ rangingResults.add(new RangingResult.Builder()
+ .setStatus(convertHalStatusToFrameworkStatus(rttResult.status))
+ .setMacAddress(MacAddress.fromBytes(rttResult.addr))
+ .setDistanceMm(rttResult.distanceInMm)
+ .setDistanceStdDevMm(rttResult.distanceSdInMm)
+ .setRssi(rttResult.rssi / -2)
+ .setNumAttemptedMeasurements(rttResult.numberPerBurstPeer)
+ .setNumSuccessfulMeasurements(rttResult.successNumber)
+ .setLci(lci)
+ .setLcr(lcr)
+ .setUnverifiedResponderLocation(responderLocation)
+ .setRangingTimestampMillis(
+ rttResult.timeStampInUs / WifiRttController.CONVERSION_US_TO_MS)
+ .set80211mcMeasurement(rttResult.type == RttType.TWO_SIDED)
+ .build());
}
return rangingResults;
}
diff --git a/service/java/com/android/server/wifi/hal/WifiStaIface.java b/service/java/com/android/server/wifi/hal/WifiStaIface.java
index e847bd832a..ca4cd785d1 100644
--- a/service/java/com/android/server/wifi/hal/WifiStaIface.java
+++ b/service/java/com/android/server/wifi/hal/WifiStaIface.java
@@ -16,13 +16,20 @@
package com.android.server.wifi.hal;
+import static android.net.wifi.WifiManager.ROAMING_MODE_NORMAL;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.hardware.wifi.WifiStatusCode;
import android.net.MacAddress;
import android.net.apf.ApfCapabilities;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager.RoamingMode;
import android.net.wifi.WifiScanner;
+import android.net.wifi.twt.TwtRequest;
+import android.net.wifi.twt.TwtSessionCallback;
+import android.os.Bundle;
import android.util.Log;
import com.android.server.wifi.SsidTranslator;
@@ -110,6 +117,47 @@ public class WifiStaIface implements WifiHal.WifiInterface {
* @param currRssi RSSI of the currently connected access point.
*/
void onRssiThresholdBreached(int cmdId, byte[] currBssid, int currRssi);
+
+ /**
+ * Called when TWT operation fails.
+ *
+ * @param cmdId Unique command id which is failed
+ * @param twtErrorCode Error code
+ */
+ void onTwtFailure(int cmdId, @TwtSessionCallback.TwtErrorCode int twtErrorCode);
+
+ /**
+ * Called when {@link WifiStaIface#setupTwtSession(int, TwtRequest)} succeeds.
+ *
+ * @param cmdId Unique command id used in
+ * {@link WifiStaIface#setupTwtSession(int, TwtRequest)}
+ * @param wakeDurationUs TWT wake duration for the session in microseconds
+ * @param wakeIntervalUs TWT wake interval for the session in microseconds
+ * @param linkId Multi link operation link id
+ * @param sessionId TWT session id
+ */
+ void onTwtSessionCreate(int cmdId, int wakeDurationUs, long wakeIntervalUs, int linkId,
+ int sessionId);
+
+ /**
+ * Called when TWT session is torndown by {@link WifiStaIface#tearDownTwtSession(int, int)}.
+ * Can also be called unsolicitedly by the vendor software with proper reason code.
+ *
+ * @param cmdId Unique command id used in {@link WifiStaIface#tearDownTwtSession(int, int)}
+ * @param twtSessionId TWT session Id
+ * @param twtReasonCode Reason code for teardown
+ */
+ void onTwtSessionTeardown(int cmdId, int twtSessionId,
+ @TwtSessionCallback.TwtReasonCode int twtReasonCode);
+
+ /**
+ * Called as a response to {@link WifiStaIface#getStatsTwtSession(int, int)}
+ *
+ * @param cmdId Unique command id used in {@link WifiStaIface#getStatsTwtSession(int, int)}
+ * @param twtSessionId TWT session Id
+ * @param twtStats TWT stats bundle
+ */
+ void onTwtSessionStats(int cmdId, int twtSessionId, Bundle twtStats);
}
public WifiStaIface(@NonNull android.hardware.wifi.V1_0.IWifiStaIface staIface,
@@ -236,6 +284,16 @@ public class WifiStaIface implements WifiHal.WifiInterface {
}
/**
+ * See comments for {@link IWifiStaIface#getCachedScanData()}
+ */
+ @Nullable
+ public WifiScanner.ScanData getCachedScanData() {
+ return validateAndCall("getCachedScanData", null,
+ () -> mWifiStaIface.getCachedScanData());
+ }
+
+
+ /**
* See comments for {@link IWifiStaIface#getLinkLayerStats()}
*/
@Nullable
@@ -361,4 +419,45 @@ public class WifiStaIface implements WifiHal.WifiInterface {
return validateAndCall("setDtimMultiplier", false,
() -> mWifiStaIface.setDtimMultiplier(multiplier));
}
+
+ /**
+ * See comments for {@link IWifiStaIface#setRoamingMode(int)}
+ */
+ public @WifiStatusCode int setRoamingMode(@RoamingMode int roamingMode) {
+ return validateAndCall("setRoamingMode", ROAMING_MODE_NORMAL,
+ () -> mWifiStaIface.setRoamingMode(roamingMode));
+ }
+
+ /**
+ * See {@link IWifiStaIface#getTwtCapabilities()}
+ */
+ public Bundle getTwtCapabilities() {
+ return validateAndCall("getTwtCapabilities", null,
+ () -> mWifiStaIface.getTwtCapabilities());
+ }
+
+ /**
+ * See {@link IWifiStaIface#setupTwtSession(int, TwtRequest)}
+ */
+ public boolean setupTwtSession(int cmdId, TwtRequest twtRequest) {
+ return validateAndCall("setupTwtSession", false,
+ () -> mWifiStaIface.setupTwtSession(cmdId, twtRequest));
+ }
+
+ /**
+ * See {@link IWifiStaIface#tearDownTwtSession(int, int)}
+ */
+ public boolean tearDownTwtSession(int commandId, int sessionId) {
+ return validateAndCall("tearDownTwtSession", false,
+ () -> mWifiStaIface.tearDownTwtSession(commandId, sessionId));
+ }
+
+ /**
+ * See {@link IWifiStaIface#getStatsTwtSession(int, int)}
+ */
+ public boolean getStatsTwtSession(int commandId, int sessionId) {
+ return validateAndCall("getStatsTwtSession", false,
+ () -> mWifiStaIface.getStatsTwtSession(commandId, sessionId));
+ }
}
+
diff --git a/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java
index 0950ecfe79..628bfc5918 100644
--- a/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java
@@ -16,9 +16,13 @@
package com.android.server.wifi.hal;
+import static com.android.server.wifi.hal.WifiHalAidlImpl.isServiceVersionAtLeast;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.hardware.wifi.CachedScanData;
+import android.hardware.wifi.CachedScanResult;
import android.hardware.wifi.IWifiStaIfaceEventCallback;
import android.hardware.wifi.Ssid;
import android.hardware.wifi.StaApfPacketFilterCapabilities;
@@ -47,14 +51,20 @@ import android.hardware.wifi.WifiDebugRxPacketFate;
import android.hardware.wifi.WifiDebugRxPacketFateReport;
import android.hardware.wifi.WifiDebugTxPacketFate;
import android.hardware.wifi.WifiDebugTxPacketFateReport;
+import android.hardware.wifi.WifiRatePreamble;
import android.hardware.wifi.WifiStatusCode;
import android.net.MacAddress;
import android.net.apf.ApfCapabilities;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiAnnotations;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.RoamingMode;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.net.wifi.WifiUsabilityStatsEntry;
+import android.net.wifi.twt.TwtRequest;
+import android.net.wifi.twt.TwtSessionCallback;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.Log;
@@ -65,6 +75,7 @@ import com.android.server.wifi.WifiLinkLayerStats;
import com.android.server.wifi.WifiLoggerHal;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.util.BitMask;
+import com.android.server.wifi.util.HalAidlUtil;
import com.android.server.wifi.util.NativeUtil;
import com.android.wifi.resources.R;
@@ -369,6 +380,28 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
}
/**
+ * See comments for {@link IWifiStaIface#getCachedScanData()}
+ */
+ @Override
+ @Nullable
+ public WifiScanner.ScanData getCachedScanData() {
+ final String methodStr = "getCachedScanData";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ CachedScanData scanData = mWifiStaIface.getCachedScanData();
+ return halToFrameworkCachedScanData(scanData);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+
+ /**
* See comments for {@link IWifiStaIface#getLinkLayerStats()}
*/
@Override
@@ -384,6 +417,9 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
handleRemoteException(e, methodStr);
} catch (ServiceSpecificException e) {
handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ // May indicate a malformed return value in the HAL.
+ Log.wtf(TAG, methodStr + " encountered IllegalArgumentException: " + e);
}
return null;
}
@@ -688,6 +724,172 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
}
}
+ /**
+ * See comments for {@link IWifiStaIface#setRoamingMode(int)}
+ */
+ public @WifiStatusCode int setRoamingMode(@RoamingMode int roamingMode) {
+ final String methodStr = "setRoamingMode";
+ @WifiStatusCode int errorCode = WifiStatusCode.ERROR_UNKNOWN;
+ synchronized (mLock) {
+ try {
+ if (checkIfaceAndLogFailure(methodStr)) {
+ mWifiStaIface.setRoamingState(frameworkToHalRoamingMode(roamingMode));
+ errorCode = WifiStatusCode.SUCCESS;
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ errorCode = WifiStatusCode.ERROR_NOT_STARTED;
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ errorCode = e.errorCode;
+ } catch (IllegalArgumentException e) {
+ handleIllegalArgumentException(e, methodStr);
+ errorCode = WifiStatusCode.ERROR_INVALID_ARGS;
+ }
+ return errorCode;
+ }
+ }
+
+ private static byte frameworkToHalRoamingMode(
+ @WifiManager.RoamingMode int mode) {
+ switch (mode) {
+ case WifiManager.ROAMING_MODE_NONE:
+ return StaRoamingState.DISABLED;
+ case WifiManager.ROAMING_MODE_NORMAL:
+ return StaRoamingState.ENABLED;
+ case WifiManager.ROAMING_MODE_AGGRESSIVE:
+ return StaRoamingState.AGGRESSIVE;
+ default:
+ throw new IllegalArgumentException("frameworkToHalRoamingMode Invalid mode: "
+ + mode);
+ }
+ }
+
+ /**
+ * Get target wake time (TWT) capabilities.
+ *
+ * @return TWT capabilities as Bundle
+ */
+ @Override
+ public Bundle getTwtCapabilities() {
+ final String methodStr = "getTwtCapabilities";
+ synchronized (mLock) {
+ try {
+ if (!isServiceVersionAtLeast(2) || !checkIfaceAndLogFailure(methodStr)) {
+ return null;
+ }
+ android.hardware.wifi.TwtCapabilities halTwtCapabilities =
+ mWifiStaIface.twtGetCapabilities();
+ if (halTwtCapabilities == null) return null;
+ Bundle twtCapabilities = new Bundle();
+ twtCapabilities.putBoolean(WifiManager.TWT_CAPABILITIES_KEY_BOOLEAN_TWT_REQUESTER,
+ halTwtCapabilities.isTwtRequesterSupported);
+ twtCapabilities.putInt(
+ WifiManager.TWT_CAPABILITIES_KEY_INT_MIN_WAKE_DURATION_MICROS,
+ halTwtCapabilities.minWakeDurationUs);
+ twtCapabilities.putInt(
+ WifiManager.TWT_CAPABILITIES_KEY_INT_MAX_WAKE_DURATION_MICROS,
+ halTwtCapabilities.maxWakeDurationUs);
+ twtCapabilities.putLong(
+ WifiManager.TWT_CAPABILITIES_KEY_LONG_MIN_WAKE_INTERVAL_MICROS,
+ halTwtCapabilities.minWakeIntervalUs);
+ twtCapabilities.putLong(
+ WifiManager.TWT_CAPABILITIES_KEY_LONG_MAX_WAKE_INTERVAL_MICROS,
+ halTwtCapabilities.maxWakeIntervalUs);
+ return twtCapabilities;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Set up a TWT session
+ *
+ * @param cmdId Command ID to use for this invocation.
+ * @param twtRequest TWT request configuration to setup TWT session
+ * @return true if successful, false otherwise.
+ */
+ @Override
+ public boolean setupTwtSession(int cmdId, TwtRequest twtRequest) {
+ final String methodStr = "setupTwtSession";
+ synchronized (mLock) {
+ try {
+ if (!isServiceVersionAtLeast(2) || !checkIfaceAndLogFailure(methodStr)) {
+ return false;
+ }
+ android.hardware.wifi.TwtRequest halTwtRequest =
+ new android.hardware.wifi.TwtRequest();
+ halTwtRequest.maxWakeDurationUs = twtRequest.getMaxWakeDurationMicros();
+ halTwtRequest.minWakeDurationUs = twtRequest.getMinWakeDurationMicros();
+ halTwtRequest.maxWakeIntervalUs = twtRequest.getMaxWakeIntervalMicros();
+ halTwtRequest.minWakeIntervalUs = twtRequest.getMinWakeIntervalMicros();
+ mWifiStaIface.twtSessionSetup(cmdId, halTwtRequest);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Teardown a TWT session.
+ *
+ * @param cmdId Command ID to use for this invocation.
+ * @param sessionId TWT session identifier
+ * @return true if successful, false otherwise.
+ */
+ @Override
+ public boolean tearDownTwtSession(int cmdId, int sessionId) {
+ final String methodStr = "tearDownTwtSession";
+ synchronized (mLock) {
+ try {
+ if (!isServiceVersionAtLeast(2) || !checkIfaceAndLogFailure(methodStr)) {
+ return false;
+ }
+ mWifiStaIface.twtSessionTeardown(cmdId, sessionId);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Get stats for the TWT session.
+ *
+ * @param cmdId Command ID to use for this invocation.
+ * @param sessionId TWT session identifier
+ * @return true if successful, false otherwise.
+ */
+ @Override
+ public boolean getStatsTwtSession(int cmdId, int sessionId) {
+ final String methodStr = "getStatsTwtSession";
+ synchronized (mLock) {
+ try {
+ if (!isServiceVersionAtLeast(2) || !checkIfaceAndLogFailure(methodStr)) {
+ return false;
+ }
+ mWifiStaIface.twtSessionGetStats(cmdId, sessionId);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
private class StaIfaceEventCallback extends IWifiStaIfaceEventCallback.Stub {
@Override
public void onBackgroundScanFailure(int cmdId) {
@@ -733,12 +935,44 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
@Override
public void onTwtFailure(int cmdId, byte twtErrorCode) {
- //TODO: Implementation
+ if (mFrameworkCallback == null) return;
+ @TwtErrorCode int errorCode;
+ switch (twtErrorCode) {
+ case TwtErrorCode.INVALID_PARAMS:
+ errorCode = TwtSessionCallback.TWT_ERROR_CODE_INVALID_PARAMS;
+ break;
+ case TwtErrorCode.MAX_SESSION_REACHED:
+ errorCode = TwtSessionCallback.TWT_ERROR_CODE_MAX_SESSIONS_REACHED;
+ break;
+ case TwtErrorCode.NOT_AVAILABLE:
+ errorCode = TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE;
+ break;
+ case TwtErrorCode.NOT_SUPPORTED:
+ errorCode = TwtSessionCallback.TWT_ERROR_CODE_NOT_SUPPORTED;
+ break;
+ case TwtErrorCode.PEER_NOT_SUPPORTED:
+ errorCode = TwtSessionCallback.TWT_ERROR_CODE_AP_NOT_SUPPORTED;
+ break;
+ case TwtErrorCode.PEER_REJECTED:
+ errorCode = TwtSessionCallback.TWT_ERROR_CODE_AP_REJECTED;
+ break;
+ case TwtErrorCode.TIMEOUT:
+ errorCode = TwtSessionCallback.TWT_ERROR_CODE_TIMEOUT;
+ break;
+ case TwtErrorCode.ALREADY_RESUMED:
+ case TwtErrorCode.ALREADY_SUSPENDED:
+ case TwtErrorCode.FAILURE_UNKNOWN:
+ default:
+ errorCode = TwtSessionCallback.TWT_REASON_CODE_UNKNOWN;
+ }
+ mFrameworkCallback.onTwtFailure(cmdId, errorCode);
}
@Override
public void onTwtSessionCreate(int cmdId, TwtSession twtSession) {
- //TODO: Implementation
+ if (mFrameworkCallback == null || twtSession == null) return;
+ mFrameworkCallback.onTwtSessionCreate(cmdId, twtSession.wakeDurationUs,
+ twtSession.wakeDurationUs, twtSession.mloLinkId, twtSession.sessionId);
}
@Override
@@ -758,17 +992,52 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
@Override
public void onTwtSessionTeardown(int cmdId, int twtSessionId, byte twtReasonCode) {
- //TODO: Implementation
+ if (mFrameworkCallback == null) return;
+ @TwtTeardownReasonCode int reasonCode;
+ switch (twtReasonCode) {
+ case TwtTeardownReasonCode.INTERNALLY_INITIATED:
+ reasonCode = TwtSessionCallback.TWT_REASON_CODE_INTERNALLY_INITIATED;
+ break;
+ case TwtTeardownReasonCode.LOCALLY_REQUESTED:
+ reasonCode = TwtSessionCallback.TWT_REASON_CODE_LOCALLY_REQUESTED;
+ break;
+ case TwtTeardownReasonCode.PEER_INITIATED:
+ reasonCode = TwtSessionCallback.TWT_REASON_CODE_PEER_INITIATED;
+ break;
+ case TwtTeardownReasonCode.UNKNOWN:
+ default:
+ reasonCode = TwtSessionCallback.TWT_REASON_CODE_UNKNOWN;
+ }
+ mFrameworkCallback.onTwtSessionTeardown(cmdId, twtSessionId, reasonCode);
}
@Override
public void onTwtSessionStats(int cmdId, int twtSessionId,
TwtSessionStats twtSessionStats) {
- //TODO: Implementation
+ if (mFrameworkCallback == null) return;
+ Bundle twtStats = new Bundle();
+ twtStats.putInt(
+ android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_COUNT,
+ twtSessionStats.avgTxPktCount);
+ twtStats.putInt(
+ android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_SIZE,
+ twtSessionStats.avgTxPktSize);
+ twtStats.putInt(
+ android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_COUNT,
+ twtSessionStats.avgRxPktCount);
+ twtStats.putInt(
+ android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_SIZE,
+ twtSessionStats.avgRxPktSize);
+ twtStats.putInt(
+ android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS,
+ twtSessionStats.avgEospDurationUs);
+ twtStats.putInt(
+ android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS,
+ twtSessionStats.eospCount);
+ mFrameworkCallback.onTwtSessionStats(cmdId, twtSessionId, twtStats);
}
}
-
// Utilities
// Only sets the fields of ScanResult used by Gscan clients.
@@ -830,6 +1099,76 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
return frameworkScanDatas;
}
+ @WifiAnnotations.WifiStandard
+ private static int wifiRatePreambleToWifiStandard(int wifiRatePreamble) {
+ switch (wifiRatePreamble) {
+ case WifiRatePreamble.CCK:
+ case WifiRatePreamble.OFDM:
+ return ScanResult.WIFI_STANDARD_LEGACY;
+ case WifiRatePreamble.HT:
+ return ScanResult.WIFI_STANDARD_11N;
+ case WifiRatePreamble.VHT:
+ return ScanResult.WIFI_STANDARD_11AC;
+ case WifiRatePreamble.HE:
+ return ScanResult.WIFI_STANDARD_11AX;
+ case WifiRatePreamble.EHT:
+ return ScanResult.WIFI_STANDARD_11BE;
+ default:
+ return ScanResult.WIFI_STANDARD_UNKNOWN;
+ }
+ }
+
+ private ScanResult halToFrameworkCachedScanResult(CachedScanResult scanResult) {
+ if (scanResult == null) return null;
+ WifiSsid originalSsid = WifiSsid.fromBytes(scanResult.ssid);
+ MacAddress bssid;
+ try {
+ bssid = MacAddress.fromString(NativeUtil.macAddressFromByteArray(scanResult.bssid));
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Failed to get BSSID of scan result: " + e);
+ return null;
+ }
+ ScanResult frameworkScanResult = new ScanResult();
+ frameworkScanResult.setWifiSsid(mSsidTranslator.getTranslatedSsidAndRecordBssidCharset(
+ originalSsid, bssid));
+ frameworkScanResult.BSSID = bssid.toString();
+ frameworkScanResult.level = scanResult.rssiDbm;
+ frameworkScanResult.frequency = scanResult.frequencyMhz;
+ frameworkScanResult.timestamp = scanResult.timeStampInUs;
+ frameworkScanResult.channelWidth = HalAidlUtil
+ .getChannelBandwidthFromHal(scanResult.channelWidthMhz);
+ frameworkScanResult.setWifiStandard(
+ wifiRatePreambleToWifiStandard(scanResult.preambleType));
+ return frameworkScanResult;
+ }
+
+ private ScanResult[] aidlToFrameworkCachedScanResults(CachedScanResult[] cachedScanResults) {
+ if (cachedScanResults == null) return new ScanResult[0];
+ List<ScanResult> frameworkScanResults = new ArrayList<>();
+ for (CachedScanResult cachedScanResult : cachedScanResults) {
+ ScanResult frameworkScanResult = halToFrameworkCachedScanResult(cachedScanResult);
+ if (frameworkScanResult == null) {
+ Log.e(TAG, "aidlToFrameworkCachedScanResults: unable to convert aidl to framework "
+ + "scan result!");
+ continue;
+ }
+ frameworkScanResults.add(frameworkScanResult);
+ }
+ return frameworkScanResults.toArray(new ScanResult[0]);
+ }
+
+ private WifiScanner.ScanData halToFrameworkCachedScanData(CachedScanData cachedScanData) {
+ if (cachedScanData == null) return null;
+ ScanResult[] scanResults = aidlToFrameworkCachedScanResults(
+ cachedScanData.cachedScanResults);
+
+ // Todo b/319658055: map cachedScanData.scannedFrequenciesMhz to WifiScanner.WifiBand
+ WifiScanner.ScanData frameworkScanData = new WifiScanner.ScanData(0, 0,
+ 0, WifiScanner.WIFI_BAND_UNSPECIFIED, scanResults);
+
+ return frameworkScanData;
+ }
+
private static StaRoamingConfig frameworkToHalStaRoamingConfig(List<MacAddress> bssidBlocklist,
List<byte[]> ssidAllowlist) {
StaRoamingConfig config = new StaRoamingConfig();
@@ -972,6 +1311,10 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
android.hardware.wifi.IWifiStaIface.FeatureSetMask.SCAN_RAND)) {
features |= WifiManager.WIFI_FEATURE_SCAN_RAND;
}
+ if (hasCapability(halFeatureSet,
+ android.hardware.wifi.IWifiStaIface.FeatureSetMask.ROAMING_MODE_CONTROL)) {
+ features |= 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 b44d6e0739..0472f89ef9 100644
--- a/service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java
@@ -191,6 +191,15 @@ public class WifiStaIfaceHidlImpl implements IWifiStaIface {
}
/**
+ * See comments for {@link IWifiStaIface#getCachedScanData()}
+ */
+ @Nullable
+ public WifiScanner.ScanData getCachedScanData() {
+ Log.d(TAG, "getCachedScanData is not implemented by HIDL");
+ return null;
+ }
+
+ /**
* See comments for {@link IWifiStaIface#getLinkLayerStats()}
*/
@Nullable
@@ -333,6 +342,14 @@ public class WifiStaIfaceHidlImpl implements IWifiStaIface {
return false;
}
+ /**
+ * See comments for {@link IWifiStaIface#setRoamingMode(int)}
+ */
+ public int setRoamingMode(int roamingMode) {
+ Log.d(TAG, "setRoamingMode is not implemented by HIDL");
+ return 0;
+ }
+
// Internal Implementations
private boolean registerFrameworkCallbackInternal(String methodStr,
diff --git a/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java b/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java
index 407240d1cb..e2facfe698 100644
--- a/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java
+++ b/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java
@@ -161,8 +161,9 @@ public class NetworkDetail {
// 6 GHz Access Point Type
private final InformationElementUtil.ApType6GHz mApType6GHz;
- // IEEE 802.11az
- private final boolean mIs11azSupported;
+ // IEEE 802.11az non-trigger based & trigger based
+ private final boolean mIs11azNtbResponder;
+ private final boolean mIs11azTbResponder;
// MLO Attributes
private MacAddress mMldMacAddress = null;
@@ -372,31 +373,35 @@ public class NetworkDetail {
mEpcsPriorityAccessSupported = ehtCapabilities.isEpcsPriorityAccessSupported();
mFilsCapable = extendedCapabilities.isFilsCapable();
mApType6GHz = heOperation.getApType6GHz();
- mIs11azSupported = extendedCapabilities.isTriggerBasedRangingRespSupported()
- || extendedCapabilities.isNonTriggerBasedRangingRespSupported();
+ mIs11azNtbResponder = extendedCapabilities.is80211azNtbResponder();
+ mIs11azTbResponder = extendedCapabilities.is80211azTbResponder();
int channelWidth = ScanResult.UNSPECIFIED;
int centerFreq0 = mPrimaryFreq;
int centerFreq1 = 0;
- if (ehtOperation.isPresent()) {
- //TODO: include parsing of EHT_Operation to collect BW and center freq.
+ // Check if EHT Operation Info is present in EHT operation IE.
+ if (ehtOperation.isEhtOperationInfoPresent()) {
+ int operatingBand = ScanResult.toBand(mPrimaryFreq);
+ channelWidth = ehtOperation.getChannelWidth();
+ centerFreq0 = ehtOperation.getCenterFreq0(operatingBand);
+ centerFreq1 = ehtOperation.getCenterFreq1(operatingBand);
mDisabledSubchannelBitmap = ehtOperation.getDisabledSubchannelBitmap();
}
- if (ehtOperation.isPresent()) {
- //TODO Add impact for using info from EHT capabilities and EHT operation IEs
- }
-
- // Check if HE Operation IE is present
- if (heOperation.isPresent()) {
- // If 6GHz info is present, then parameters should be acquired from HE Operation IE
- if (heOperation.is6GhzInfoPresent()) {
- channelWidth = heOperation.getChannelWidth();
- centerFreq0 = heOperation.getCenterFreq0();
- centerFreq1 = heOperation.getCenterFreq1();
- } else if (heOperation.isVhtInfoPresent()) {
- // VHT Operation Info could be included inside the HE Operation IE
- vhtOperation.from(heOperation.getVhtInfoElement());
+ // Proceed to HE Operation IE if channel width and center frequencies were not obtained
+ // from EHT Operation IE
+ if (channelWidth == ScanResult.UNSPECIFIED) {
+ // Check if HE Operation IE is present
+ if (heOperation.isPresent()) {
+ // If 6GHz info is present, then parameters should be acquired from HE Operation IE
+ if (heOperation.is6GhzInfoPresent()) {
+ channelWidth = heOperation.getChannelWidth();
+ centerFreq0 = heOperation.getCenterFreq0();
+ centerFreq1 = heOperation.getCenterFreq1();
+ } else if (heOperation.isVhtInfoPresent()) {
+ // VHT Operation Info could be included inside the HE Operation IE
+ vhtOperation.from(heOperation.getVhtInfoElement());
+ }
}
}
@@ -560,7 +565,8 @@ public class NetworkDetail {
mEpcsPriorityAccessSupported = base.mEpcsPriorityAccessSupported;
mFilsCapable = base.mFilsCapable;
mApType6GHz = base.mApType6GHz;
- mIs11azSupported = base.mIs11azSupported;
+ mIs11azNtbResponder = base.mIs11azNtbResponder;
+ mIs11azTbResponder = base.mIs11azTbResponder;
}
public NetworkDetail complete(Map<Constants.ANQPElementType, ANQPElement> anqpElements) {
@@ -790,10 +796,16 @@ public class NetworkDetail {
return mOceSupported;
}
- /** Return whether the AP supports IEEE 802.11az **/
- public boolean is11azSupported() {
- return mIs11azSupported;
+ /** Return whether the AP supports IEEE 802.11az non-trigger based ranging **/
+ public boolean is80211azNtbResponder() {
+ return mIs11azNtbResponder;
}
+
+ /** Return whether the AP supports IEEE 802.11az trigger based ranging **/
+ public boolean is80211azTbResponder() {
+ return mIs11azTbResponder;
+ }
+
/**
* Return whether the AP requires HE stations to participate either in individual TWT
* agreements or Broadcast TWT operation.
diff --git a/service/java/com/android/server/wifi/mockwifi/MockWifiServiceUtil.java b/service/java/com/android/server/wifi/mockwifi/MockWifiServiceUtil.java
index a36efab3b4..05948aadb2 100644
--- a/service/java/com/android/server/wifi/mockwifi/MockWifiServiceUtil.java
+++ b/service/java/com/android/server/wifi/mockwifi/MockWifiServiceUtil.java
@@ -121,8 +121,7 @@ public class MockWifiServiceUtil {
intent.setComponent(new ComponentName(mPackageName, mServiceName));
intent.setAction(actionName);
- status = mContext.createContextAsUser(CURRENT, 0)
- .bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
+ status = mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
return status;
}
diff --git a/service/java/com/android/server/wifi/p2p/ExternalApproverManager.java b/service/java/com/android/server/wifi/p2p/ExternalApproverManager.java
index bcb0414ba2..1fe58d9a54 100644
--- a/service/java/com/android/server/wifi/p2p/ExternalApproverManager.java
+++ b/service/java/com/android/server/wifi/p2p/ExternalApproverManager.java
@@ -138,7 +138,7 @@ public class ExternalApproverManager {
private void logd(String s) {
if (!mVerboseLoggingEnabled) return;
- Log.d(TAG, s);
+ Log.d(TAG, s, null);
}
/** The approver data. */
diff --git a/service/java/com/android/server/wifi/p2p/ISupplicantP2pIfaceHal.java b/service/java/com/android/server/wifi/p2p/ISupplicantP2pIfaceHal.java
index 1634fb87a5..72f669bb53 100644
--- a/service/java/com/android/server/wifi/p2p/ISupplicantP2pIfaceHal.java
+++ b/service/java/com/android/server/wifi/p2p/ISupplicantP2pIfaceHal.java
@@ -17,14 +17,19 @@
package com.android.server.wifi.p2p;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.ScanResult;
import android.net.wifi.p2p.WifiP2pConfig;
+import android.net.wifi.p2p.WifiP2pDiscoveryConfig;
+import android.net.wifi.p2p.WifiP2pExtListenParams;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pGroupList;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
+import com.android.server.wifi.WifiNative;
+
import java.util.List;
import java.util.Set;
@@ -108,6 +113,19 @@ interface ISupplicantP2pIfaceHal {
boolean find(@WifiP2pManager.WifiP2pScanType int type, int freq, int timeout);
/**
+ * Initiate P2P device discovery with config params.
+ *
+ * @param config The config parameters to initiate P2P discovery.
+ * @param timeout The maximum amount of time to be spent in performing discovery.
+ * Set to 0 to indefinitely continue discovery until an explicit
+ * |stopFind| is sent.
+ * @return boolean value indicating whether the operation was successful.
+ */
+ default boolean findWithParams(@NonNull WifiP2pDiscoveryConfig config, int timeout) {
+ return false;
+ }
+
+ /**
* Stop an ongoing P2P service discovery.
*
* @return boolean value indicating whether operation was successful.
@@ -317,10 +335,12 @@ interface ISupplicantP2pIfaceHal {
* @param enable Enables or disables listening.
* @param periodInMillis Period in milliseconds.
* @param intervalInMillis Interval in milliseconds.
+ * @param extListenParams Additional parameter struct for this request.
*
* @return true, if operation was successful.
*/
- boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis);
+ boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis,
+ @Nullable WifiP2pExtListenParams extListenParams);
/**
* Set P2P Listen channel.
@@ -585,4 +605,30 @@ interface ISupplicantP2pIfaceHal {
*/
boolean configureEapolIpAddressAllocationParams(int ipAddressGo, int ipAddressMask,
int ipAddressStart, int ipAddressEnd);
+
+ /**
+ * Terminate the supplicant daemon & wait for its death.
+ * Note: Aidl only since it was added from HIDL 1.1
+ */
+ default void terminate() {};
+
+ /**
+ * Registers a death notification for supplicant.
+ * @return Returns true on success.
+ *
+ * Note: Aidl only.
+ */
+ default boolean registerDeathHandler(@NonNull WifiNative.SupplicantDeathEventHandler handler) {
+ return true;
+ };
+
+ /**
+ * Deregisters a death notification for supplicant.
+ * @return Returns true on success.
+ *
+ * Note: Aidl only.
+ */
+ default boolean deregisterDeathHandler() {
+ return true;
+ };
}
diff --git a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java
index d6747552d5..e3eabad46c 100644
--- a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java
+++ b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java
@@ -23,7 +23,9 @@ import android.annotation.Nullable;
import android.hardware.wifi.supplicant.ISupplicantP2pIfaceCallback;
import android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo;
import android.hardware.wifi.supplicant.P2pDeviceFoundEventParams;
+import android.hardware.wifi.supplicant.P2pGoNegotiationReqEventParams;
import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
+import android.hardware.wifi.supplicant.P2pInvitationEventParams;
import android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams;
import android.hardware.wifi.supplicant.P2pPeerClientJoinedEventParams;
import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
@@ -31,6 +33,8 @@ import android.hardware.wifi.supplicant.P2pProvisionDiscoveryCompletedEventParam
import android.hardware.wifi.supplicant.P2pStatusCode;
import android.hardware.wifi.supplicant.WpsConfigMethods;
import android.hardware.wifi.supplicant.WpsDevPasswordId;
+import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.ScanResult;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
@@ -43,10 +47,12 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.internal.util.HexDump;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.server.wifi.util.HalAidlUtil;
import com.android.server.wifi.util.NativeUtil;
import java.io.ByteArrayInputStream;
-import java.net.Inet4Address;
+import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -60,11 +66,13 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
private final String mInterface;
private final WifiP2pMonitor mMonitor;
+ private final int mServiceVersion;
public SupplicantP2pIfaceCallbackAidlImpl(
- @NonNull String iface, @NonNull WifiP2pMonitor monitor) {
+ @NonNull String iface, @NonNull WifiP2pMonitor monitor, int serviceVersion) {
mInterface = iface;
mMonitor = monitor;
+ mServiceVersion = serviceVersion;
}
/**
@@ -76,7 +84,7 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
protected static void logd(String msg) {
if (sVerboseLoggingEnabled) {
- Log.d(TAG, msg);
+ Log.d(TAG, msg, null);
}
}
@@ -104,7 +112,7 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
byte[] wfdDeviceInfo) {
handleDeviceFound(srcAddress, p2pDeviceAddress, primaryDeviceType, deviceName,
configMethods, deviceCapabilities, groupCapabilities, wfdDeviceInfo,
- null, null);
+ null, null, null);
}
/**
@@ -147,6 +155,33 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
*/
@Override
public void onGoNegotiationRequest(byte[] srcAddress, int passwordId) {
+ handleGoNegotiationRequestEvent(srcAddress, passwordId, null);
+ }
+
+ /**
+ * Used to indicate the reception of a P2P Group Owner negotiation request.
+ *
+ * @param goNegotiationReqEventParams Parameters associated with
+ * GO negotiation request.
+ */
+ @Override
+ public void onGoNegotiationRequestWithParams(
+ P2pGoNegotiationReqEventParams goNegotiationReqEventParams) {
+ List<OuiKeyedData> vendorData = null;
+ if (mServiceVersion >= 3 && goNegotiationReqEventParams.vendorData != null) {
+ vendorData = HalAidlUtil.halToFrameworkOuiKeyedDataList(
+ goNegotiationReqEventParams.vendorData);
+ }
+ handleGoNegotiationRequestEvent(
+ goNegotiationReqEventParams.srcAddress,
+ goNegotiationReqEventParams.passwordId,
+ vendorData);
+ }
+
+ private void handleGoNegotiationRequestEvent(
+ byte[] srcAddress,
+ int passwordId,
+ @Nullable List<OuiKeyedData> vendorData) {
WifiP2pConfig config = new WifiP2pConfig();
try {
@@ -156,6 +191,10 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
return;
}
+ if (SdkLevel.isAtLeastV() && vendorData != null) {
+ config.setVendorData(vendorData);
+ }
+
config.wps = new WpsInfo();
switch (passwordId) {
@@ -231,7 +270,8 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
int frequency, byte[] psk, String passphrase, byte[] goDeviceAddress,
boolean isPersistent) {
onGroupStarted(groupIfName, isGroupOwner, ssid, frequency, psk, passphrase, goDeviceAddress,
- isPersistent, /* goInterfaceAddress */ null, /*p2pClientIpInfo */ null);
+ isPersistent, /* goInterfaceAddress */ null, /*p2pClientIpInfo */ null,
+ /* vendorData */ null);
}
/**
@@ -241,19 +281,26 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
*/
@Override
public void onGroupStartedWithParams(P2pGroupStartedEventParams groupStartedEventParams) {
+ List<OuiKeyedData> vendorData = null;
+ if (mServiceVersion >= 3 && groupStartedEventParams.vendorData != null) {
+ vendorData = HalAidlUtil.halToFrameworkOuiKeyedDataList(
+ groupStartedEventParams.vendorData);
+ }
onGroupStarted(groupStartedEventParams.groupInterfaceName,
groupStartedEventParams.isGroupOwner, groupStartedEventParams.ssid,
groupStartedEventParams.frequencyMHz, groupStartedEventParams.psk,
groupStartedEventParams.passphrase, groupStartedEventParams.goDeviceAddress,
groupStartedEventParams.isPersistent, groupStartedEventParams.goInterfaceAddress,
groupStartedEventParams.isP2pClientEapolIpAddressInfoPresent
- ? groupStartedEventParams.p2pClientIpInfo : null);
+ ? groupStartedEventParams.p2pClientIpInfo : null,
+ vendorData);
}
private void onGroupStarted(String groupIfName, boolean isGroupOwner, byte[] ssid,
int frequency, byte[] psk, String passphrase, byte[] goDeviceAddress,
boolean isPersistent, byte[] goInterfaceAddress,
- P2pClientEapolIpAddressInfo p2pClientIpInfo) {
+ P2pClientEapolIpAddressInfo p2pClientIpInfo,
+ @Nullable List<OuiKeyedData> vendorData) {
if (groupIfName == null) {
Log.e(TAG, "Missing group interface name.");
return;
@@ -309,6 +356,11 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
} else {
group.p2pClientEapolIpInfo = null;
}
+
+ if (SdkLevel.isAtLeastV() && vendorData != null) {
+ group.setVendorData(vendorData);
+ }
+
mMonitor.broadcastP2pGroupStarted(mInterface, group);
}
@@ -344,6 +396,39 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
@Override
public void onInvitationReceived(byte[] srcAddress, byte[] goDeviceAddress,
byte[] bssid, int persistentNetworkId, int operatingFrequency) {
+ handleInvitationReceivedEvent(srcAddress, goDeviceAddress, bssid,
+ persistentNetworkId, operatingFrequency, null);
+ }
+
+ /**
+ * Used to indicate the reception of a P2P invitation.
+ *
+ * @param invitationEventParams Parameters of the invitation event.
+ */
+ @Override
+ public void onInvitationReceivedWithParams(
+ P2pInvitationEventParams invitationEventParams) {
+ List<OuiKeyedData> vendorData = null;
+ if (mServiceVersion >= 3 && invitationEventParams.vendorData != null) {
+ vendorData =
+ HalAidlUtil.halToFrameworkOuiKeyedDataList(invitationEventParams.vendorData);
+ }
+ handleInvitationReceivedEvent(
+ invitationEventParams.srcAddress,
+ invitationEventParams.goDeviceAddress,
+ invitationEventParams.bssid,
+ invitationEventParams.persistentNetworkId,
+ invitationEventParams.operatingFrequencyMHz,
+ vendorData);
+ }
+
+ private void handleInvitationReceivedEvent(
+ byte[] srcAddress,
+ byte[] goDeviceAddress,
+ byte[] bssid,
+ int persistentNetworkId,
+ int operatingFrequency,
+ List<OuiKeyedData> vendorData) {
WifiP2pGroup group = new WifiP2pGroup();
group.setNetworkId(persistentNetworkId);
@@ -369,6 +454,10 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
group.setOwner(owner);
+ if (SdkLevel.isAtLeastV() && vendorData != null) {
+ group.setVendorData(vendorData);
+ }
+
logd("Invitation received on " + mInterface + ": " + group);
mMonitor.broadcastP2pInvitationReceived(mInterface, group);
}
@@ -417,7 +506,7 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
public void onProvisionDiscoveryCompleted(byte[] p2pDeviceAddress, boolean isRequest,
byte status, int configMethods, String generatedPin) {
handleProvisionDiscoveryCompletedEvent(
- p2pDeviceAddress, isRequest, status, configMethods, generatedPin, null);
+ p2pDeviceAddress, isRequest, status, configMethods, generatedPin, null, null);
}
/**
@@ -429,13 +518,19 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
@Override
public void onProvisionDiscoveryCompletedEvent(
P2pProvisionDiscoveryCompletedEventParams provisionDiscoveryCompletedEventParams) {
+ List<OuiKeyedData> vendorData = null;
+ if (mServiceVersion >= 3 && provisionDiscoveryCompletedEventParams.vendorData != null) {
+ vendorData = HalAidlUtil.halToFrameworkOuiKeyedDataList(
+ provisionDiscoveryCompletedEventParams.vendorData);
+ }
handleProvisionDiscoveryCompletedEvent(
provisionDiscoveryCompletedEventParams.p2pDeviceAddress,
provisionDiscoveryCompletedEventParams.isRequest,
provisionDiscoveryCompletedEventParams.status,
provisionDiscoveryCompletedEventParams.configMethods,
provisionDiscoveryCompletedEventParams.generatedPin,
- provisionDiscoveryCompletedEventParams.groupInterfaceName);
+ provisionDiscoveryCompletedEventParams.groupInterfaceName,
+ vendorData);
}
private void handleProvisionDiscoveryCompletedEvent(
@@ -444,7 +539,8 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
byte status,
int configMethods,
String generatedPin,
- String groupIfName) {
+ String groupIfName,
+ @Nullable List<OuiKeyedData> vendorData) {
logd(
"Provision discovery "
+ (isRequest ? "request" : "response")
@@ -474,6 +570,10 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
if (TextUtils.isEmpty(event.device.deviceAddress)) return;
+ if (SdkLevel.isAtLeastV() && vendorData != null) {
+ event.setVendorData(vendorData);
+ }
+
if ((configMethods & WpsConfigMethods.PUSHBUTTON) != 0) {
if (isRequest) {
event.event = WifiP2pProvDiscEvent.PBC_REQ;
@@ -527,22 +627,25 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
mMonitor.broadcastP2pServiceDiscoveryResponse(mInterface, response);
}
- private WifiP2pDevice createStaEventDevice(byte[] srcAddress, byte[] p2pDeviceAddress) {
+ private WifiP2pDevice createStaEventDevice(byte[] interfaceAddress, byte[] p2pDeviceAddress,
+ InetAddress ipAddress) {
WifiP2pDevice device = new WifiP2pDevice();
byte[] deviceAddressBytes;
// Legacy STAs may not supply a p2pDeviceAddress (signaled by a zero'd p2pDeviceAddress)
- // In this case, use srcAddress instead
+ // In this case, use interfaceAddress instead
if (!Arrays.equals(NativeUtil.ANY_MAC_BYTES, p2pDeviceAddress)) {
deviceAddressBytes = p2pDeviceAddress;
} else {
- deviceAddressBytes = srcAddress;
+ deviceAddressBytes = interfaceAddress;
}
try {
device.deviceAddress = NativeUtil.macAddressFromByteArray(deviceAddressBytes);
+ device.setInterfaceMacAddress(MacAddress.fromBytes(interfaceAddress));
} catch (Exception e) {
Log.e(TAG, "Could not decode MAC address", e);
return null;
}
+ device.setIpAddress(ipAddress);
return device;
}
@@ -554,7 +657,7 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
*/
@Override
public void onStaAuthorized(byte[] srcAddress, byte[] p2pDeviceAddress) {
- onP2pApStaConnected(null, srcAddress, p2pDeviceAddress, 0);
+ onP2pApStaConnected(null, srcAddress, p2pDeviceAddress, 0, null);
}
/**
@@ -564,24 +667,35 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
*/
@Override
public void onPeerClientJoined(P2pPeerClientJoinedEventParams clientJoinedEventParams) {
+ List<OuiKeyedData> vendorData = null;
+ if (mServiceVersion >= 3 && clientJoinedEventParams.vendorData != null) {
+ vendorData = HalAidlUtil.halToFrameworkOuiKeyedDataList(
+ clientJoinedEventParams.vendorData);
+ }
onP2pApStaConnected(
clientJoinedEventParams.groupInterfaceName,
clientJoinedEventParams.clientInterfaceAddress,
clientJoinedEventParams.clientDeviceAddress,
- clientJoinedEventParams.clientIpAddress);
+ clientJoinedEventParams.clientIpAddress,
+ vendorData);
}
private void onP2pApStaConnected(
- String groupIfName, byte[] srcAddress, byte[] p2pDeviceAddress, int ipAddress) {
+ String groupIfName, byte[] srcAddress, byte[] p2pDeviceAddress, int ipAddress,
+ @Nullable List<OuiKeyedData> vendorData) {
+ InetAddress ipAddressClient = null;
logd("STA authorized on " + (TextUtils.isEmpty(groupIfName) ? mInterface : groupIfName));
if (ipAddress != 0) {
- Inet4Address ipAddressClient = intToInet4AddressHTL(ipAddress);
+ ipAddressClient = intToInet4AddressHTL(ipAddress);
logd("IP Address of Client: " + ipAddressClient.getHostAddress());
}
- WifiP2pDevice device = createStaEventDevice(srcAddress, p2pDeviceAddress);
+ WifiP2pDevice device = createStaEventDevice(srcAddress, p2pDeviceAddress, ipAddressClient);
if (device == null) {
return;
}
+ if (SdkLevel.isAtLeastV() && vendorData != null) {
+ device.setVendorData(vendorData);
+ }
mMonitor.broadcastP2pApStaConnected(mInterface, device);
}
@@ -593,7 +707,7 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
*/
@Override
public void onStaDeauthorized(byte[] srcAddress, byte[] p2pDeviceAddress) {
- onP2pApStaDisconnected(null, srcAddress, p2pDeviceAddress);
+ onP2pApStaDisconnected(null, srcAddress, p2pDeviceAddress, null);
}
/**
@@ -605,19 +719,29 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
@Override
public void onPeerClientDisconnected(
P2pPeerClientDisconnectedEventParams clientDisconnectedEventParams) {
+ List<OuiKeyedData> vendorData = null;
+ if (mServiceVersion >= 3 && clientDisconnectedEventParams.vendorData != null) {
+ vendorData = HalAidlUtil.halToFrameworkOuiKeyedDataList(
+ clientDisconnectedEventParams.vendorData);
+ }
onP2pApStaDisconnected(
clientDisconnectedEventParams.groupInterfaceName,
clientDisconnectedEventParams.clientInterfaceAddress,
- clientDisconnectedEventParams.clientDeviceAddress);
+ clientDisconnectedEventParams.clientDeviceAddress,
+ vendorData);
}
private void onP2pApStaDisconnected(
- String groupIfName, byte[] srcAddress, byte[] p2pDeviceAddress) {
+ String groupIfName, byte[] srcAddress, byte[] p2pDeviceAddress,
+ @Nullable List<OuiKeyedData> vendorData) {
logd("STA deauthorized on " + (TextUtils.isEmpty(groupIfName) ? mInterface : groupIfName));
- WifiP2pDevice device = createStaEventDevice(srcAddress, p2pDeviceAddress);
+ WifiP2pDevice device = createStaEventDevice(srcAddress, p2pDeviceAddress, null);
if (device == null) {
return;
}
+ if (SdkLevel.isAtLeastV() && vendorData != null) {
+ device.setVendorData(vendorData);
+ }
mMonitor.broadcastP2pApStaDisconnected(mInterface, device);
}
@@ -733,7 +857,7 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
byte[] wfdR2DeviceInfo, byte[] vendorElemBytes) {
handleDeviceFound(srcAddress, p2pDeviceAddress, primaryDeviceType, deviceName,
configMethods, deviceCapabilities, groupCapabilities, wfdDeviceInfo,
- wfdR2DeviceInfo, vendorElemBytes);
+ wfdR2DeviceInfo, vendorElemBytes, null);
}
/**
@@ -743,6 +867,11 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
*/
@Override
public void onDeviceFoundWithParams(P2pDeviceFoundEventParams deviceFoundEventParams) {
+ List<OuiKeyedData> vendorData = null;
+ if (mServiceVersion >= 3 && deviceFoundEventParams.vendorData != null) {
+ vendorData = HalAidlUtil.halToFrameworkOuiKeyedDataList(
+ deviceFoundEventParams.vendorData);
+ }
handleDeviceFound(
deviceFoundEventParams.srcAddress,
deviceFoundEventParams.p2pDeviceAddress,
@@ -753,13 +882,15 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
deviceFoundEventParams.groupCapabilities,
deviceFoundEventParams.wfdDeviceInfo,
deviceFoundEventParams.wfdR2DeviceInfo,
- deviceFoundEventParams.vendorElemBytes);
+ deviceFoundEventParams.vendorElemBytes,
+ vendorData);
}
private void handleDeviceFound(byte[] srcAddress, byte[] p2pDeviceAddress,
byte[] primaryDeviceType, String deviceName, int configMethods,
byte deviceCapabilities, int groupCapabilities, byte[] wfdDeviceInfo,
- @Nullable byte[] wfdR2DeviceInfo, @Nullable byte[] vendorElemBytes) {
+ @Nullable byte[] wfdR2DeviceInfo, @Nullable byte[] vendorElemBytes,
+ @Nullable List<OuiKeyedData> vendorData) {
WifiP2pDevice device = new WifiP2pDevice();
device.deviceName = deviceName;
if (deviceName == null) {
@@ -820,6 +951,10 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
device.setVendorElements(vendorElements);
}
+ if (SdkLevel.isAtLeastV() && vendorData != null) {
+ device.setVendorData(vendorData);
+ }
+
logd("Device discovered on " + mInterface + ": " + device);
mMonitor.broadcastP2pDeviceFound(mInterface, device);
}
diff --git a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImpl.java b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImpl.java
index 4bdbe4487d..e1d9499287 100644
--- a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImpl.java
+++ b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImpl.java
@@ -63,7 +63,7 @@ public class SupplicantP2pIfaceCallbackHidlImpl extends ISupplicantP2pIfaceCallb
}
protected static void logd(String s) {
- if (sVerboseLoggingEnabled) Log.d(TAG, s);
+ if (sVerboseLoggingEnabled) Log.d(TAG, s, null);
}
/**
diff --git a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlV1_4Impl.java b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlV1_4Impl.java
index bacb5c7cba..7f965104c9 100644
--- a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlV1_4Impl.java
+++ b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlV1_4Impl.java
@@ -58,7 +58,7 @@ public class SupplicantP2pIfaceCallbackHidlV1_4Impl
}
protected static void logd(String s) {
- if (sVerboseLoggingEnabled) Log.d(TAG, s);
+ if (sVerboseLoggingEnabled) Log.d(TAG, s, null);
}
/**
diff --git a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java
index 34f20d279c..b621e76f6a 100644
--- a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java
+++ b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java
@@ -17,9 +17,12 @@
package com.android.server.wifi.p2p;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.ScanResult;
import android.net.wifi.p2p.WifiP2pConfig;
+import android.net.wifi.p2p.WifiP2pDiscoveryConfig;
+import android.net.wifi.p2p.WifiP2pExtListenParams;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pGroupList;
import android.net.wifi.p2p.WifiP2pManager;
@@ -29,6 +32,7 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.WifiGlobals;
import com.android.server.wifi.WifiInjector;
+import com.android.server.wifi.WifiNative;
import java.util.List;
import java.util.Set;
@@ -237,6 +241,21 @@ public class SupplicantP2pIfaceHal {
}
/**
+ * Initiate P2P device discovery with config params.
+ *
+ * See comments for {@link ISupplicantP2pIfaceHal#findWithParams(WifiP2pDiscoveryConfig, int)}.
+ */
+ public boolean findWithParams(WifiP2pDiscoveryConfig config, int timeout) {
+ synchronized (mLock) {
+ String methodStr = "findWithParams";
+ if (mP2pIfaceHal == null) {
+ return handleNullHal(methodStr);
+ }
+ return mP2pIfaceHal.findWithParams(config, timeout);
+ }
+ }
+
+ /**
* Stop an ongoing P2P service discovery.
*
* @return boolean value indicating whether operation was successful.
@@ -599,27 +618,20 @@ public class SupplicantP2pIfaceHal {
}
/**
- * Configure Extended Listen Timing.
- *
- * If enabled, listen state must be entered every |intervalInMillis| for at
- * least |periodInMillis|. Both values have acceptable range of 1-65535
- * (with interval obviously having to be larger than or equal to duration).
- * If the P2P module is not idle at the time the Extended Listen Timing
- * timeout occurs, the Listen State operation must be skipped.
- *
- * @param enable Enables or disables listening.
- * @param periodInMillis Period in milliseconds.
- * @param intervalInMillis Interval in milliseconds.
+ * Configure Extended Listen Timing. See comments for
+ * {@link ISupplicantP2pIfaceHal#configureExtListen(boolean, int, int, WifiP2pExtListenParams)}
*
* @return true, if operation was successful.
*/
- public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis) {
+ public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis,
+ @Nullable WifiP2pExtListenParams extListenParams) {
synchronized (mLock) {
String methodStr = "configureExtListen";
if (mP2pIfaceHal == null) {
return handleNullHal(methodStr);
}
- return mP2pIfaceHal.configureExtListen(enable, periodInMillis, intervalInMillis);
+ return mP2pIfaceHal.configureExtListen(
+ enable, periodInMillis, intervalInMillis, extListenParams);
}
}
@@ -1147,4 +1159,46 @@ public class SupplicantP2pIfaceHal {
ipAddressStart, ipAddressEnd);
}
}
+
+ /**
+ * Terminate the supplicant daemon & wait for its death.
+ */
+ public void terminate() {
+ synchronized (mLock) {
+ String methodStr = "terminate";
+ if (mP2pIfaceHal == null) {
+ handleNullHal(methodStr);
+ return;
+ }
+ mP2pIfaceHal.terminate();
+ }
+ }
+
+ /**
+ * Registers a death notification for supplicant.
+ * @return Returns true on success.
+ */
+ public boolean registerDeathHandler(@NonNull WifiNative.SupplicantDeathEventHandler handler) {
+ synchronized (mLock) {
+ String methodStr = "registerDeathHandler";
+ if (mP2pIfaceHal == null) {
+ return handleNullHal(methodStr);
+ }
+ return mP2pIfaceHal.registerDeathHandler(handler);
+ }
+ }
+
+ /**
+ * Deregisters a death notification for supplicant.
+ * @return Returns true on success.
+ */
+ public boolean deregisterDeathHandler() {
+ synchronized (mLock) {
+ String methodStr = "deregisterDeathHandler";
+ if (mP2pIfaceHal == null) {
+ return handleNullHal(methodStr);
+ }
+ return mP2pIfaceHal.deregisterDeathHandler();
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImpl.java b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImpl.java
index 1d2ce2a123..f186e0b560 100644
--- a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImpl.java
+++ b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImpl.java
@@ -17,6 +17,7 @@
package com.android.server.wifi.p2p;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.hardware.wifi.supplicant.DebugLevel;
import android.hardware.wifi.supplicant.FreqRange;
import android.hardware.wifi.supplicant.ISupplicant;
@@ -26,7 +27,11 @@ import android.hardware.wifi.supplicant.ISupplicantP2pNetwork;
import android.hardware.wifi.supplicant.IfaceInfo;
import android.hardware.wifi.supplicant.IfaceType;
import android.hardware.wifi.supplicant.MiracastMode;
+import android.hardware.wifi.supplicant.P2pConnectInfo;
+import android.hardware.wifi.supplicant.P2pDiscoveryInfo;
+import android.hardware.wifi.supplicant.P2pExtListenInfo;
import android.hardware.wifi.supplicant.P2pFrameTypeMask;
+import android.hardware.wifi.supplicant.P2pScanType;
import android.hardware.wifi.supplicant.WpsConfigMethods;
import android.hardware.wifi.supplicant.WpsProvisionMethod;
import android.net.wifi.CoexUnsafeChannel;
@@ -34,6 +39,8 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pDiscoveryConfig;
+import android.net.wifi.p2p.WifiP2pExtListenParams;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pGroupList;
import android.net.wifi.p2p.WifiP2pManager;
@@ -49,8 +56,10 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.WifiInjector;
+import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WifiSettingsConfigStore;
import com.android.server.wifi.util.ArrayUtils;
+import com.android.server.wifi.util.HalAidlUtil;
import com.android.server.wifi.util.NativeUtil;
import java.io.ByteArrayOutputStream;
@@ -60,6 +69,8 @@ import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -75,6 +86,7 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
private boolean mInitializationStarted = false;
private static final int RESULT_NOT_VALID = -1;
private static final int DEFAULT_OPERATING_CLASS = 81;
+ public static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L;
/**
* Regex pattern for extracting the wps device type bytes.
* Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
@@ -83,14 +95,19 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
private final Object mLock = new Object();
+ private CountDownLatch mWaitForDeathLatch;
+ private WifiNative.SupplicantDeathEventHandler mDeathEventHandler;
// Supplicant HAL AIDL interface objects
private ISupplicant mISupplicant = null;
private ISupplicantP2pIface mISupplicantP2pIface = null;
private final DeathRecipient mSupplicantDeathRecipient =
() -> {
- Log.w(TAG, "ISupplicant/ISupplicantP2pIface died");
+ Log.d(TAG, "ISupplicant/ISupplicantP2pIface died");
synchronized (mLock) {
+ if (mWaitForDeathLatch != null) {
+ mWaitForDeathLatch.countDown();
+ }
supplicantServiceDiedHandler();
}
};
@@ -205,7 +222,8 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
if (mMonitor != null) {
ISupplicantP2pIfaceCallback callback =
- new SupplicantP2pIfaceCallbackAidlImpl(ifaceName, mMonitor);
+ new SupplicantP2pIfaceCallbackAidlImpl(ifaceName, mMonitor,
+ getCachedServiceVersion());
if (!registerCallback(callback)) {
Log.e(TAG, "Unable to register callback for iface " + ifaceName);
return false;
@@ -270,6 +288,9 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
mISupplicant = null;
mISupplicantP2pIface = null;
mInitializationStarted = false;
+ if (mDeathEventHandler != null) {
+ mDeathEventHandler.onDeath();
+ }
}
}
@@ -523,6 +544,65 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
}
}
+ private static int frameworkToHalScanType(@WifiP2pManager.WifiP2pScanType int scanType) {
+ switch (scanType) {
+ case WifiP2pManager.WIFI_P2P_SCAN_FULL:
+ return P2pScanType.FULL;
+ case WifiP2pManager.WIFI_P2P_SCAN_SOCIAL:
+ return P2pScanType.SOCIAL;
+ case WifiP2pManager.WIFI_P2P_SCAN_SINGLE_FREQ:
+ return P2pScanType.SPECIFIC_FREQ;
+ default:
+ Log.e(TAG, "Invalid discovery scan type: " + scanType);
+ return -1;
+ }
+ }
+
+ /**
+ * Initiate P2P device discovery with config params.
+ *
+ * See comments for {@link ISupplicantP2pIfaceHal#findWithParams(WifiP2pDiscoveryConfig, int)}.
+ */
+ public boolean findWithParams(WifiP2pDiscoveryConfig config, int timeout) {
+ synchronized (mLock) {
+ String methodStr = "findWithParams";
+ if (!checkP2pIfaceAndLogFailure(methodStr)) {
+ return false;
+ }
+ if (getCachedServiceVersion() < 3) {
+ // HAL does not support findWithParams before V3.
+ return find(config.getScanType(), config.getFrequencyMhz(), timeout);
+ }
+
+ P2pDiscoveryInfo halInfo = new P2pDiscoveryInfo();
+ halInfo.scanType = frameworkToHalScanType(config.getScanType());
+ halInfo.timeoutInSec = timeout;
+ halInfo.frequencyMhz = config.getFrequencyMhz();
+ if (halInfo.scanType == -1) {
+ return false;
+ }
+ if (halInfo.frequencyMhz < 0) {
+ Log.e(TAG, "Invalid freq value: " + halInfo.frequencyMhz);
+ return false;
+ }
+
+ if (!config.getVendorData().isEmpty()) {
+ halInfo.vendorData =
+ HalAidlUtil.frameworkToHalOuiKeyedDataList(config.getVendorData());
+ }
+
+ try {
+ mISupplicantP2pIface.findWithParams(halInfo);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
/**
* Stop an ongoing P2P service discovery.
*
@@ -694,6 +774,38 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
}
}
+ private String connectWithParams(boolean joinExistingGroup, byte[] peerAddress,
+ int provisionMethod, String preSelectedPin, boolean persistent, int groupOwnerIntent,
+ WifiP2pConfig config) {
+ synchronized (mLock) {
+ String methodStr = "connectWithParams";
+
+ // Parameters should be pre-validated.
+ P2pConnectInfo info = new P2pConnectInfo();
+ info.joinExistingGroup = joinExistingGroup;
+ info.peerAddress = peerAddress;
+ info.provisionMethod = provisionMethod;
+ info.preSelectedPin = preSelectedPin;
+ info.persistent = persistent;
+ info.goIntent = groupOwnerIntent;
+
+ if (SdkLevel.isAtLeastV() && config.getVendorData() != null
+ && !config.getVendorData().isEmpty()) {
+ info.vendorData =
+ HalAidlUtil.frameworkToHalOuiKeyedDataList(config.getVendorData());
+ }
+
+ try {
+ return mISupplicantP2pIface.connectWithParams(info);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
/**
* Start P2P group formation with a discovered P2P peer. This includes
* optional group owner negotiation, group interface setup, provisioning,
@@ -710,7 +822,8 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
*/
public String connect(WifiP2pConfig config, boolean joinExistingGroup) {
synchronized (mLock) {
- String methodStr = "setSsidPostfix";
+ String methodStr = "connect";
+
if (!checkP2pIfaceAndLogFailure(methodStr)) {
return null;
}
@@ -749,6 +862,11 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
return null;
}
+ if (getCachedServiceVersion() >= 3) {
+ return connectWithParams(joinExistingGroup, peerAddress, provisionMethod,
+ preSelectedPin, persistent, config.groupOwnerIntent, config);
+ }
+
try {
return mISupplicantP2pIface.connect(
peerAddress, provisionMethod, preSelectedPin, joinExistingGroup,
@@ -1209,21 +1327,13 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
}
/**
- * Configure Extended Listen Timing.
- *
- * If enabled, listen state must be entered every |intervalInMillis| for at
- * least |periodInMillis|. Both values have acceptable range of 1-65535
- * (with interval obviously having to be larger than or equal to duration).
- * If the P2P module is not idle at the time the Extended Listen Timing
- * timeout occurs, the Listen State operation must be skipped.
- *
- * @param enable Enables or disables listening.
- * @param periodInMillis Period in milliseconds.
- * @param intervalInMillis Interval in milliseconds.
+ * Configure Extended Listen Timing. See comments for
+ * {@link ISupplicantP2pIfaceHal#configureExtListen(boolean, int, int, WifiP2pExtListenParams)}
*
* @return true, if operation was successful.
*/
- public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis) {
+ public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis,
+ @Nullable WifiP2pExtListenParams extListenParams) {
synchronized (mLock) {
String methodStr = "configureExtListen";
if (!checkP2pIfaceAndLogFailure(methodStr)) {
@@ -1247,6 +1357,11 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
return false;
}
+ if (getCachedServiceVersion() >= 3) {
+ return configureExtListenWithParams(
+ periodInMillis, intervalInMillis, extListenParams);
+ }
+
try {
mISupplicantP2pIface.configureExtListen(periodInMillis, intervalInMillis);
return true;
@@ -1259,6 +1374,32 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
}
}
+ private boolean configureExtListenWithParams(int periodInMillis, int intervalInMillis,
+ @Nullable WifiP2pExtListenParams extListenParams) {
+ String methodStr = "configureExtListenWithParams";
+
+ // Expect that these parameters are already validated.
+ P2pExtListenInfo extListenInfo = new P2pExtListenInfo();
+ extListenInfo.periodMs = periodInMillis;
+ extListenInfo.intervalMs = intervalInMillis;
+
+ if (SdkLevel.isAtLeastV() && extListenParams != null
+ && extListenParams.getVendorData() != null) {
+ extListenInfo.vendorData =
+ HalAidlUtil.frameworkToHalOuiKeyedDataList(extListenParams.getVendorData());
+ }
+
+ try {
+ mISupplicantP2pIface.configureExtListenWithParams(extListenInfo);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+
/**
* Set P2P Listen channel.
*
@@ -2559,4 +2700,64 @@ public class SupplicantP2pIfaceHalAidlImpl implements ISupplicantP2pIfaceHal {
"Invalid WPS config method: " + configMethod);
}
}
+
+ /**
+ * Terminate the supplicant daemon & wait for its death.
+ */
+ public void terminate() {
+ synchronized (mLock) {
+ final String methodStr = "terminate";
+ if (!checkSupplicantAndLogFailure(methodStr)) {
+ return;
+ }
+ Log.i(TAG, "Terminate supplicant service");
+ try {
+ mWaitForDeathLatch = new CountDownLatch(1);
+ mISupplicant.terminate();
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ }
+
+ // Wait for death recipient to confirm the service death.
+ try {
+ if (!mWaitForDeathLatch.await(WAIT_FOR_DEATH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ Log.w(TAG, "Timed out waiting for confirmation of supplicant death");
+ supplicantServiceDiedHandler();
+ } else {
+ Log.d(TAG, "Got service death confirmation");
+ }
+ } catch (InterruptedException e) {
+ Log.w(TAG, "Failed to wait for supplicant death");
+ }
+ }
+
+ /**
+ * Registers a death notification for supplicant.
+ * @return Returns true on success.
+ */
+ public boolean registerDeathHandler(@NonNull WifiNative.SupplicantDeathEventHandler handler) {
+ synchronized (mLock) {
+ if (mDeathEventHandler != null) {
+ Log.e(TAG, "Death handler already present");
+ }
+ mDeathEventHandler = handler;
+ return true;
+ }
+ }
+
+ /**
+ * Deregisters a death notification for supplicant.
+ * @return Returns true on success.
+ */
+ public boolean deregisterDeathHandler() {
+ synchronized (mLock) {
+ if (mDeathEventHandler == null) {
+ Log.e(TAG, "No Death handler present");
+ }
+ mDeathEventHandler = null;
+ return true;
+ }
+ }
+
}
diff --git a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImpl.java b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImpl.java
index 2aa45f36f1..7f28476699 100644
--- a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImpl.java
+++ b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImpl.java
@@ -17,6 +17,7 @@
package com.android.server.wifi.p2p;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.hardware.wifi.supplicant.V1_0.ISupplicant;
import android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
import android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
@@ -34,6 +35,7 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pExtListenParams;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pGroupList;
import android.net.wifi.p2p.WifiP2pManager;
@@ -586,11 +588,11 @@ public class SupplicantP2pIfaceHalHidlImpl implements ISupplicantP2pIfaceHal {
}
protected static void logd(String s) {
- if (sVerboseLoggingEnabled) Log.d(TAG, s);
+ if (sVerboseLoggingEnabled) Log.d(TAG, s, null);
}
protected static void logw(String s) {
- Log.w(TAG, s);
+ Log.w(TAG, s, null);
}
protected static <S> void logCompletion(String operation, int code, String debugMessage) {
@@ -1472,21 +1474,13 @@ public class SupplicantP2pIfaceHalHidlImpl implements ISupplicantP2pIfaceHal {
/**
- * Configure Extended Listen Timing.
- *
- * If enabled, listen state must be entered every |intervalInMillis| for at
- * least |periodInMillis|. Both values have acceptable range of 1-65535
- * (with interval obviously having to be larger than or equal to duration).
- * If the P2P module is not idle at the time the Extended Listen Timing
- * timeout occurs, the Listen State operation must be skipped.
- *
- * @param enable Enables or disables listening.
- * @param periodInMillis Period in milliseconds.
- * @param intervalInMillis Interval in milliseconds.
+ * Configure Extended Listen Timing. See comments for
+ * {@link ISupplicantP2pIfaceHal#configureExtListen(boolean, int, int, WifiP2pExtListenParams)}
*
* @return true, if operation was successful.
*/
- public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis) {
+ public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis,
+ @Nullable WifiP2pExtListenParams extListenParams) {
if (enable && intervalInMillis < periodInMillis) {
return false;
}
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pMetrics.java b/service/java/com/android/server/wifi/p2p/WifiP2pMetrics.java
index 0ae1bf76fd..b2d2ea740d 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pMetrics.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pMetrics.java
@@ -190,24 +190,8 @@ public class WifiP2pMetrics {
} else {
sb.append(StringUtil.calendarToString(c));
}
- sb.append(", connectionType=");
- switch (event.connectionType) {
- case P2pConnectionEvent.CONNECTION_FRESH:
- sb.append("FRESH");
- break;
- case P2pConnectionEvent.CONNECTION_REINVOKE:
- sb.append("REINVOKE");
- break;
- case P2pConnectionEvent.CONNECTION_LOCAL:
- sb.append("LOCAL");
- break;
- case P2pConnectionEvent.CONNECTION_FAST:
- sb.append("FAST");
- break;
- default:
- sb.append("UNKNOWN");
- break;
- }
+ sb.append(", connectionType=").append(
+ getconnectionTypeToString(event.connectionType));
sb.append(", wpsMethod=");
switch (event.wpsMethod) {
case P2pConnectionEvent.WPS_NA:
@@ -231,19 +215,7 @@ public class WifiP2pMetrics {
}
sb.append(", durationTakenToConnectMillis=");
sb.append(event.durationTakenToConnectMillis);
- sb.append(", groupRole=");
- switch (event.groupRole) {
- case GroupEvent.GROUP_OWNER:
- sb.append("OWNER");
- break;
- case GroupEvent.GROUP_CLIENT:
- sb.append("CLIENT");
- break;
- default:
- sb.append("UNKNOWN DURING CONNECT");
- break;
- }
-
+ sb.append(", groupRole=").append(getGroupRoleToString(event.groupRole));
sb.append(", tryCount=");
sb.append(event.tryCount);
sb.append(", inviteToNeg=");
@@ -258,40 +230,9 @@ public class WifiP2pMetrics {
sb.append(event.staFrequencyMhz);
sb.append(", uid=");
sb.append(event.uid);
- sb.append(", connectivityLevelFailureCode=");
- switch (event.connectivityLevelFailureCode) {
- case P2pConnectionEvent.CLF_NONE:
- sb.append("NONE");
- break;
- case P2pConnectionEvent.CLF_TIMEOUT:
- sb.append("TIMEOUT");
- break;
- case P2pConnectionEvent.CLF_CANCEL:
- sb.append("CANCEL");
- break;
- case P2pConnectionEvent.CLF_PROV_DISC_FAIL:
- sb.append("PROV_DISC_FAIL");
- break;
- case P2pConnectionEvent.CLF_INVITATION_FAIL:
- sb.append("INVITATION_FAIL");
- break;
- case P2pConnectionEvent.CLF_USER_REJECT:
- sb.append("USER_REJECT");
- break;
- case P2pConnectionEvent.CLF_NEW_CONNECTION_ATTEMPT:
- sb.append("NEW_CONNECTION_ATTEMPT");
- break;
- case P2pConnectionEvent.CLF_GROUP_REMOVED:
- sb.append("GROUP_REMOVED");
- break;
- case P2pConnectionEvent.CLF_CREATE_GROUP_FAILED:
- sb.append("CREATE_GROUP_FAILED");
- break;
- case P2pConnectionEvent.CLF_UNKNOWN:
- default:
- sb.append("UNKNOWN");
- break;
- }
+ sb.append(", connectivityLevelFailureCode=").append(
+ getConnectivityLevelFailureCodeToString(
+ event.connectivityLevelFailureCode));
if (event == mCurrentConnectionEvent) {
sb.append(" CURRENTLY OPEN EVENT");
}
@@ -342,6 +283,58 @@ public class WifiP2pMetrics {
}
}
+ private String getconnectionTypeToString(int connectionType) {
+ switch (connectionType) {
+ case P2pConnectionEvent.CONNECTION_FRESH:
+ return "FRESH";
+ case P2pConnectionEvent.CONNECTION_REINVOKE:
+ return "REINVOKE";
+ case P2pConnectionEvent.CONNECTION_LOCAL:
+ return "LOCAL";
+ case P2pConnectionEvent.CONNECTION_FAST:
+ return "FAST";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ private String getGroupRoleToString(int groupRole) {
+ switch (groupRole) {
+ case GroupEvent.GROUP_OWNER:
+ return "OWNER";
+ case GroupEvent.GROUP_CLIENT:
+ return "CLIENT";
+ default:
+ return "UNKNOWN DURING CONNECT";
+ }
+ }
+
+ private String getConnectivityLevelFailureCodeToString(int connectivityLevelFailureCode) {
+ switch (connectivityLevelFailureCode) {
+ case P2pConnectionEvent.CLF_NONE:
+ return "NONE";
+ case P2pConnectionEvent.CLF_TIMEOUT:
+ return "TIMEOUT";
+ case P2pConnectionEvent.CLF_CANCEL:
+ return "CANCEL";
+ case P2pConnectionEvent.CLF_PROV_DISC_FAIL:
+ return "PROV_DISC_FAIL";
+ case P2pConnectionEvent.CLF_INVITATION_FAIL:
+ return "INVITATION_FAIL";
+ case P2pConnectionEvent.CLF_USER_REJECT:
+ return "USER_REJECT";
+ case P2pConnectionEvent.CLF_NEW_CONNECTION_ATTEMPT:
+ return "NEW_CONNECTION_ATTEMPT";
+ case P2pConnectionEvent.CLF_GROUP_REMOVED:
+ return "GROUP_REMOVED";
+ case P2pConnectionEvent.CLF_CREATE_GROUP_FAILED:
+ return "CREATE_GROUP_FAILED";
+ case P2pConnectionEvent.CLF_UNKNOWN:
+ default:
+ return "UNKNOWN";
+ }
+ }
+
/** Increment total number of peer scans */
public void incrementPeerScans() {
synchronized (mLock) {
@@ -392,6 +385,24 @@ public class WifiP2pMetrics {
public void startConnectionEvent(int connectionType, WifiP2pConfig config, int groupRole,
int uid) {
synchronized (mLock) {
+ StringBuilder stringBuilder = new StringBuilder("Start connection event");
+ if (mCurrentConnectionEvent == null) {
+ stringBuilder.append(", mCurrentConnectionEvent:null");
+ } else {
+ stringBuilder.append(", curConnectionType:")
+ .append(getconnectionTypeToString(mCurrentConnectionEvent.connectionType))
+ .append(", curGroupRole:")
+ .append(getGroupRoleToString(mCurrentConnectionEvent.groupRole))
+ .append(", curUid:").append(mCurrentConnectionEvent.uid)
+ .append(", curConnectivityLevelFailureCode:")
+ .append(getConnectivityLevelFailureCodeToString(
+ mCurrentConnectionEvent.connectivityLevelFailureCode));
+ }
+ stringBuilder.append(", startConnectionType:")
+ .append(getconnectionTypeToString(connectionType))
+ .append(", startGroupRole:").append(getGroupRoleToString(groupRole))
+ .append(", startUid:").append(uid);
+ Log.d(TAG, stringBuilder.toString());
// handle overlapping connection event first.
if (mCurrentConnectionEvent != null) {
endConnectionEvent(P2pConnectionEvent.CLF_NEW_CONNECTION_ATTEMPT);
@@ -443,6 +454,23 @@ public class WifiP2pMetrics {
*/
public void endConnectionEvent(int failure) {
synchronized (mLock) {
+ StringBuilder stringBuilder = new StringBuilder("End connection event");
+ if (mCurrentConnectionEvent == null) {
+ stringBuilder.append(", mCurrentConnectionEvent:null");
+ } else {
+ stringBuilder.append(", curConnectionType:")
+ .append(getconnectionTypeToString(mCurrentConnectionEvent.connectionType))
+ .append(", curGroupRole:")
+ .append(getGroupRoleToString(mCurrentConnectionEvent.groupRole))
+ .append(", curUid:")
+ .append(mCurrentConnectionEvent.uid)
+ .append(", curConnectivityLevelFailureCode:")
+ .append(getConnectivityLevelFailureCodeToString(
+ mCurrentConnectionEvent.connectivityLevelFailureCode));
+ }
+ stringBuilder.append(", endConnectivityLevelFailureCode:")
+ .append(getConnectivityLevelFailureCodeToString(failure));
+ Log.d(TAG, stringBuilder.toString());
if (mCurrentConnectionEvent == null) {
// Reinvoking a group with invitation will be handled in supplicant.
// There won't be a connection starting event in framework.
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
index 89284e9c1b..c32d593836 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
@@ -24,6 +24,8 @@ import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.ScanResult;
import android.net.wifi.nl80211.WifiNl80211Manager;
import android.net.wifi.p2p.WifiP2pConfig;
+import android.net.wifi.p2p.WifiP2pDiscoveryConfig;
+import android.net.wifi.p2p.WifiP2pExtListenParams;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pGroupList;
import android.net.wifi.p2p.WifiP2pManager;
@@ -35,9 +37,11 @@ import android.util.Log;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.PropertyService;
+import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WifiVendorHal;
+import com.android.wifi.flags.FeatureFlags;
import java.util.HashSet;
import java.util.List;
@@ -57,9 +61,26 @@ public class WifiP2pNative {
private final HalDeviceManager mHalDeviceManager;
private final PropertyService mPropertyService;
private final WifiVendorHal mWifiVendorHal;
+ private final WifiInjector mWifiInjector;
+ private final FeatureFlags mFeatureFlags;
+ private final Object mLock = new Object();
+ private WifiNative.Iface mP2pIface;
private String mP2pIfaceName;
private InterfaceDestroyedListenerInternal mInterfaceDestroyedListener;
+ /**
+ * Death handler for the supplicant daemon.
+ */
+ private class SupplicantDeathHandlerInternal implements WifiNative.SupplicantDeathEventHandler {
+ @Override
+ public void onDeath() {
+ if (mP2pIface != null) {
+ Log.i(TAG, "wpa_supplicant died. Cleaning up internal state.");
+ mInterfaceDestroyedListener.teardownAndInvalidate(mP2pIface.name);
+ mWifiMetrics.incrementNumSupplicantCrashes();
+ }
+ }
+ }
// Internal callback registered to HalDeviceManager.
private class InterfaceDestroyedListenerInternal implements
@@ -74,22 +95,35 @@ public class WifiP2pNative {
}
public void teardownAndInvalidate(@Nullable String ifaceName) {
- if (!TextUtils.isEmpty(ifaceName)) {
- mSupplicantP2pIfaceHal.teardownIface(ifaceName);
+ synchronized (mLock) {
+ if (mFeatureFlags.d2dWhenInfraStaOff()
+ && !mSupplicantP2pIfaceHal.deregisterDeathHandler()) {
+ Log.i(TAG, "Failed to deregister p2p supplicant death handler");
+ }
+ if (!TextUtils.isEmpty(ifaceName)) {
+ mSupplicantP2pIfaceHal.teardownIface(ifaceName);
+ if (mP2pIface != null) {
+ mWifiNative.teardownP2pIface(mP2pIface.id);
+ }
+ }
+ mP2pIfaceName = null;
+ mP2pIface = null;
+ mValid = false;
+ Log.i(TAG, "teardownAndInvalidate is completed");
}
- mP2pIfaceName = null;
- mValid = false;
}
@Override
public void onDestroyed(String ifaceName) {
- Log.d(TAG, "P2P InterfaceDestroyedListener " + ifaceName);
- if (!mValid) {
- Log.d(TAG, "Ignoring stale interface destroyed listener");
- return;
+ synchronized (mLock) {
+ Log.d(TAG, "P2P InterfaceDestroyedListener " + ifaceName);
+ if (!mValid) {
+ Log.d(TAG, "Ignoring stale interface destroyed listener");
+ return;
+ }
+ teardownAndInvalidate(ifaceName);
+ mExternalListener.onDestroyed(ifaceName);
}
- teardownAndInvalidate(ifaceName);
- mExternalListener.onDestroyed(ifaceName);
}
}
@@ -100,7 +134,8 @@ public class WifiP2pNative {
WifiVendorHal wifiVendorHal,
SupplicantP2pIfaceHal p2pIfaceHal,
HalDeviceManager halDeviceManager,
- PropertyService propertyService) {
+ PropertyService propertyService,
+ WifiInjector wifiInjector) {
mWifiNative = wifiNative;
mWifiMetrics = wifiMetrics;
mWifiNl80211Manager = wifiNl80211Manager;
@@ -108,6 +143,8 @@ public class WifiP2pNative {
mSupplicantP2pIfaceHal = p2pIfaceHal;
mHalDeviceManager = halDeviceManager;
mPropertyService = propertyService;
+ mWifiInjector = wifiInjector;
+ mFeatureFlags = wifiInjector.getDeviceConfigFacade().getFeatureFlags();
}
/**
@@ -148,8 +185,11 @@ public class WifiP2pNative {
/**
* Close supplicant connection.
*/
- public void closeSupplicantConnection() {
- // Nothing to do for HAL.
+ public void stopP2pSupplicantIfNecessary() {
+ if (mFeatureFlags.d2dWhenInfraStaOff()
+ && mSupplicantP2pIfaceHal.isInitializationStarted()) {
+ mSupplicantP2pIfaceHal.terminate();
+ }
}
/**
@@ -159,8 +199,8 @@ public class WifiP2pNative {
return mHalDeviceManager.isSupported();
}
- private static final String P2P_IFACE_NAME = "p2p0";
- private static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface";
+ public static final String P2P_IFACE_NAME = "p2p0";
+ public static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface";
/**
* Helper function to handle creation of P2P iface.
@@ -192,39 +232,58 @@ public class WifiP2pNative {
public String setupInterface(
@Nullable HalDeviceManager.InterfaceDestroyedListener destroyedListener,
@NonNull Handler handler, @NonNull WorkSource requestorWs) {
- Log.d(TAG, "Setup P2P interface");
- if (mP2pIfaceName == null) {
- mInterfaceDestroyedListener = (null == destroyedListener)
- ? null
- : new InterfaceDestroyedListenerInternal(destroyedListener);
- String ifaceName = createP2pIface(handler, requestorWs);
- if (ifaceName == null) {
- Log.e(TAG, "Failed to create P2p iface");
- if (mHalDeviceManager.isItPossibleToCreateIface(HDM_CREATE_IFACE_P2P,
- requestorWs)) {
- mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToHal();
+ synchronized (mLock) {
+ Log.d(TAG, "Setup P2P interface");
+ if (mP2pIfaceName == null) {
+ mInterfaceDestroyedListener = (null == destroyedListener)
+ ? null
+ : new InterfaceDestroyedListenerInternal(destroyedListener);
+ if (mFeatureFlags.d2dWhenInfraStaOff()) {
+ mP2pIface = mWifiNative.createP2pIface(mInterfaceDestroyedListener, handler,
+ requestorWs);
+ if (mP2pIface != null) {
+ mP2pIfaceName = mP2pIface.name;
+ }
+ } else {
+ mP2pIfaceName = createP2pIface(handler, requestorWs);
}
- return null;
- }
- if (!waitForSupplicantConnection()) {
- Log.e(TAG, "Failed to connect to supplicant");
- teardownInterface();
- mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant();
- return null;
- }
- if (!mSupplicantP2pIfaceHal.setupIface(ifaceName)) {
- Log.e(TAG, "Failed to setup P2p iface in supplicant");
- teardownInterface();
- mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant();
- return null;
+ if (mP2pIfaceName == null) {
+ Log.e(TAG, "Failed to create P2p iface");
+ if (mHalDeviceManager.isItPossibleToCreateIface(HDM_CREATE_IFACE_P2P,
+ requestorWs)) {
+ mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToHal();
+ }
+ return null;
+ }
+ if (!waitForSupplicantConnection()) {
+ Log.e(TAG, "Failed to connect to supplicant");
+ teardownInterface();
+ mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant();
+ return null;
+ }
+ if (!mSupplicantP2pIfaceHal.setupIface(mP2pIfaceName)) {
+ Log.e(TAG, "Failed to setup P2p iface in supplicant");
+ teardownInterface();
+ mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant();
+ return null;
+ }
+ if (mFeatureFlags.d2dWhenInfraStaOff()
+ && !mSupplicantP2pIfaceHal.registerDeathHandler(
+ new SupplicantDeathHandlerInternal())) {
+ Log.e(TAG, "Failed to register supplicant death handler"
+ + "(because hidl supplicant?)");
+ teardownInterface();
+ mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant();
+ return null;
+ }
+ Log.i(TAG, "P2P interface setup completed");
+ return mP2pIfaceName;
+ } else {
+ Log.i(TAG, "P2P interface already exists");
+ return mHalDeviceManager.isSupported()
+ ? mP2pIfaceName
+ : mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME);
}
- Log.i(TAG, "P2P interface setup completed");
- return ifaceName;
- } else {
- Log.i(TAG, "P2P interface already exists");
- return mHalDeviceManager.isSupported()
- ? mP2pIfaceName
- : mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME);
}
}
@@ -232,20 +291,25 @@ public class WifiP2pNative {
* Teardown P2p interface.
*/
public void teardownInterface() {
- Log.d(TAG, "Teardown P2P interface");
- if (mHalDeviceManager.isSupported()) {
- if (mP2pIfaceName != null) {
- mHalDeviceManager.removeP2pIface(mP2pIfaceName);
+ synchronized (mLock) {
+ Log.d(TAG, "Teardown P2P interface:" + mP2pIfaceName);
+ if (mHalDeviceManager.isSupported()) {
+ if (mP2pIfaceName != null) {
+ mHalDeviceManager.removeP2pIface(mP2pIfaceName);
+ Log.i(TAG, "P2P interface teardown completed");
+ if (!mFeatureFlags.d2dWhenInfraStaOff()) {
+ if (null != mInterfaceDestroyedListener) {
+ mInterfaceDestroyedListener.teardownAndInvalidate(mP2pIfaceName);
+ }
+ }
+ }
+ } else {
+ Log.i(TAG, "HAL is not supported. Destroy listener for the interface.");
+ String ifaceName = mPropertyService.getString(P2P_INTERFACE_PROPERTY,
+ P2P_IFACE_NAME);
if (null != mInterfaceDestroyedListener) {
- mInterfaceDestroyedListener.teardownAndInvalidate(mP2pIfaceName);
+ mInterfaceDestroyedListener.teardownAndInvalidate(ifaceName);
}
- Log.i(TAG, "P2P interface teardown completed");
- }
- } else {
- Log.i(TAG, "HAL is not supported. Destroy listener for the interface.");
- String ifaceName = mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME);
- if (null != mInterfaceDestroyedListener) {
- mInterfaceDestroyedListener.teardownAndInvalidate(ifaceName);
}
}
}
@@ -254,12 +318,14 @@ public class WifiP2pNative {
* Replace requestorWs in-place when iface is already enabled.
*/
public boolean replaceRequestorWs(WorkSource requestorWs) {
- if (mHalDeviceManager.isSupported()) {
- if (mP2pIfaceName == null) return false;
- return mHalDeviceManager.replaceRequestorWsForP2pIface(mP2pIfaceName, requestorWs);
- } else {
- Log.i(TAG, "HAL is not supported. Ignore replace requestorWs");
- return true;
+ synchronized (mLock) {
+ if (mHalDeviceManager.isSupported()) {
+ if (mP2pIfaceName == null) return false;
+ return mHalDeviceManager.replaceRequestorWsForP2pIface(mP2pIfaceName, requestorWs);
+ } else {
+ Log.i(TAG, "HAL is not supported. Ignore replace requestorWs");
+ return true;
+ }
}
}
@@ -469,6 +535,19 @@ public class WifiP2pNative {
}
/**
+ * Initiate a P2P service discovery with config parameters.
+ *
+ * @param config The config parameters to initiate P2P discovery.
+ * @param timeout The maximum amount of time to be spent in performing discovery.
+ * Set to 0 to indefinitely continue discovery until an explicit
+ * |stopFind| is sent.
+ * @return boolean value indicating whether the operation was successful.
+ */
+ public boolean p2pFindWithParams(@NonNull WifiP2pDiscoveryConfig config, int timeout) {
+ return mSupplicantP2pIfaceHal.findWithParams(config, timeout);
+ }
+
+ /**
* Stop an ongoing P2P service discovery.
*
* @return boolean value indicating whether operation was successful.
@@ -489,11 +568,13 @@ public class WifiP2pNative {
* @param enable Enables or disables listening.
* @param period Period in milliseconds.
* @param interval Interval in milliseconds.
+ * @param extListenParams Additional parameter struct for this request.
*
* @return true, if operation was successful.
*/
- public boolean p2pExtListen(boolean enable, int period, int interval) {
- return mSupplicantP2pIfaceHal.configureExtListen(enable, period, interval);
+ public boolean p2pExtListen(boolean enable, int period, int interval,
+ @Nullable WifiP2pExtListenParams extListenParams) {
+ return mSupplicantP2pIfaceHal.configureExtListen(enable, period, interval, extListenParams);
}
/**
@@ -919,9 +1000,11 @@ public class WifiP2pNative {
/** Indicate whether or not 5GHz/6GHz DBS is supported. */
public boolean is5g6gDbsSupported() {
- if (mP2pIfaceName == null) return false;
- if (!mHalDeviceManager.isSupported()) return false;
- return mHalDeviceManager.is5g6gDbsSupportedOnP2pIface(mP2pIfaceName);
+ synchronized (mLock) {
+ if (mP2pIfaceName == null) return false;
+ if (!mHalDeviceManager.isSupported()) return false;
+ return mHalDeviceManager.is5g6gDbsSupportedOnP2pIface(mP2pIfaceName);
+ }
}
/**
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index f16e1e249f..dd50fff514 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -21,6 +21,7 @@ import static android.net.wifi.p2p.WifiP2pConfig.GROUP_CLIENT_IP_PROVISIONING_MO
import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTL;
import static com.android.net.module.util.Inet4AddressUtils.netmaskToPrefixLength;
+import static com.android.server.wifi.WifiSettingsConfigStore.D2D_ALLOWED_WHEN_INFRA_STA_DISABLED;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_DEVICE_ADDRESS;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_DEVICE_NAME;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_PENDING_FACTORY_RESET;
@@ -50,6 +51,7 @@ import android.net.MacAddress;
import android.net.NetworkInfo;
import android.net.NetworkStack;
import android.net.StaticIpConfiguration;
+import android.net.TetheredClient;
import android.net.TetheringInterface;
import android.net.TetheringManager;
import android.net.TetheringManager.TetheringEventCallback;
@@ -63,10 +65,13 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WpsInfo;
+import android.net.wifi.p2p.IWifiP2pListener;
import android.net.wifi.p2p.IWifiP2pManager;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
+import android.net.wifi.p2p.WifiP2pDiscoveryConfig;
+import android.net.wifi.p2p.WifiP2pExtListenParams;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pGroupList;
import android.net.wifi.p2p.WifiP2pGroupList.GroupDeleteListener;
@@ -89,6 +94,7 @@ import android.os.Message;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
import android.os.Process;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -96,6 +102,7 @@ import android.os.UserManager;
import android.os.WorkSource;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.LocalLog;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
@@ -121,6 +128,7 @@ import com.android.server.wifi.Clock;
import com.android.server.wifi.FrameworkFacade;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.InterfaceConflictManager;
+import com.android.server.wifi.RunnerState;
import com.android.server.wifi.WifiDialogManager;
import com.android.server.wifi.WifiGlobals;
import com.android.server.wifi.WifiInjector;
@@ -137,6 +145,7 @@ import com.android.server.wifi.util.StringUtil;
import com.android.server.wifi.util.WaitingState;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
+import com.android.wifi.flags.FeatureFlags;
import com.android.wifi.resources.R;
import java.io.FileDescriptor;
@@ -154,6 +163,7 @@ import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
@@ -164,6 +174,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
import java.util.stream.Collectors;
/**
@@ -181,6 +192,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
@VisibleForTesting
public static final String P2P_IDLE_SHUTDOWN_MESSAGE_TIMEOUT_TAG = TAG
+ " Idle Shutdown Message Timeout";
+ private final LocalLog mThreadLocalLog;
+ private final int mThreshold;
private boolean mVerboseLoggingEnabled = false;
private boolean mVerboseHalLoggingEnabled = false;
private static final String NETWORK_TYPE = "WIFI_P2P";
@@ -234,6 +247,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private final WifiP2pNative mWifiNative;
private final LastCallerInfoManager mLastCallerInfoManager;
private HalDeviceManager mHalDeviceManager;
+ private final FeatureFlags mFeatureFlags;
private static final Boolean JOIN_GROUP = true;
private static final Boolean FORM_GROUP = false;
@@ -252,7 +266,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
android.Manifest.permission.ACCESS_WIFI_STATE
};
- private static final String[] RECEIVER_PERMISSIONS_FOR_TETHERING = {
+ private static final String[] RECEIVER_PERMISSIONS_MAINLINE_NETWORK_STACK = {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
};
@@ -338,6 +352,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// Delayed message to timeout group creation
public static final int P2P_REJECTION_RESUME_AFTER_DELAY = BASE + 37;
+
+ static final int TETHER_INTERFACE_CLIENTS_CHANGED = BASE + 38;
+
public static final int ENABLED = 1;
public static final int DISABLED = 0;
@@ -444,6 +461,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
@VisibleForTesting
static final String GO_EAPOL_IP_RANGE_DEFAULT_END_ADDRESS = "192.168.49.254";
+ private final RemoteCallbackList<IWifiP2pListener> mWifiP2pListeners =
+ new RemoteCallbackList<>();
+
/**
* Error code definition.
* see the Table.8 in the WiFi Direct specification for the detail.
@@ -657,6 +677,19 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private final Clock mClock;
+ private class D2DAllowWhenInfraStaDisabledValueListener
+ implements WifiSettingsConfigStore.OnSettingsChangedListener<Boolean> {
+ @Override
+ public void onSettingsChanged(@NonNull WifiSettingsConfigStore.Key<Boolean> key,
+ @Nullable Boolean newValue) {
+ if (!mP2pStateMachine.isWifiP2pAvailable()) {
+ Log.i(TAG, "D2d isn't allowed anymore when infra sta is disabled");
+ mP2pStateMachine.sendMessage(DISABLE_P2P);
+ mP2pStateMachine.checkAndSendP2pStateChangedBroadcast();
+ }
+ }
+ }
+
public WifiP2pServiceImpl(Context context, WifiInjector wifiInjector) {
mContext = context;
mWifiInjector = wifiInjector;
@@ -670,17 +703,20 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mUserManager = mWifiInjector.getUserManager();
mInterfaceConflictManager = mWifiInjector.getInterfaceConflictManager();
mClock = mWifiInjector.getClock();
+ mThreadLocalLog = mWifiInjector.getWifiHandlerLocalLog();
+ mThreshold = mContext.getResources().getInteger(
+ R.integer.config_wifiConfigurationWifiRunnerThresholdInMs);
mDetailedState = NetworkInfo.DetailedState.IDLE;
mP2pSupported = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_DIRECT);
-
HandlerThread wifiP2pThread = mWifiInjector.getWifiP2pServiceHandlerThread();
mClientHandler = new ClientHandler(TAG, wifiP2pThread.getLooper());
mWifiNative = mWifiInjector.getWifiP2pNative();
mLastCallerInfoManager = mWifiInjector.getLastCallerInfoManager();
mHalDeviceManager = mWifiInjector.getHalDeviceManager();
+ mFeatureFlags = mWifiInjector.getDeviceConfigFacade().getFeatureFlags();
mP2pStateMachine = new P2pStateMachine(TAG, wifiP2pThread.getLooper(), mP2pSupported);
mP2pStateMachine.setDbg(false); // can enable for very verbose logs
mP2pStateMachine.start();
@@ -1064,6 +1100,208 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return mWifiNative.getSupportedFeatures();
}
+ /**
+ * See {@link WifiP2pManager#registerWifiP2pListener(Executor, WifiP2pManager.WifiP2pListener)}
+ */
+ @Override
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ public void registerWifiP2pListener(IWifiP2pListener listener, String packageName,
+ Bundle extras) {
+ if (!SdkLevel.isAtLeastT()) {
+ throw new UnsupportedOperationException();
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener should not be null");
+ }
+ mWifiPermissionsUtil.enforceNearbyDevicesPermission(
+ extras.getParcelable(WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE), false,
+ TAG + " registerWifiP2pListener");
+ Log.i(TAG, "registerWifiP2pListener uid=" + Binder.getCallingUid());
+ mWifiP2pListeners.register(listener);
+ }
+
+ /**
+ * See {@link WifiP2pManager#unregisterWifiP2pListener(WifiP2pManager.WifiP2pListener)}
+ */
+ @Override
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ public void unregisterWifiP2pListener(IWifiP2pListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+ Log.i(TAG, "unregisterWifiP2pListener uid=" + Binder.getCallingUid());
+ mWifiP2pListeners.unregister(listener);
+ }
+
+ private void onP2pStateChanged(@WifiP2pManager.WifiP2pState int state) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onP2pStateChanged(state);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onP2pStateChanged" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onDiscoveryStateChanged(@WifiP2pManager.WifiP2pDiscoveryState int state) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onDiscoveryStateChanged(state);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onDiscoveryStateChanged" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onListenStateChanged(@WifiP2pManager.WifiP2pListenState int state) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onListenStateChanged(state);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onListenStateChanged" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onDeviceConfigurationChanged(WifiP2pDevice p2pDevice) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onDeviceConfigurationChanged(p2pDevice);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onDeviceConfigurationChanged" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onPeerListChanged(WifiP2pDeviceList p2pDeviceList) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onPeerListChanged(p2pDeviceList);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onPeerListChanged" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onPersistentGroupsChanged(WifiP2pGroupList p2pGroupList) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onPersistentGroupsChanged(p2pGroupList);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onPersistentGroupsChanged" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onGroupCreating() {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onGroupCreating();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onGroupCreating" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onGroupNegotiationRejectedByUser() {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onGroupNegotiationRejectedByUser();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onGroupNegotiationRejectedByUser" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onGroupCreationFailed(@WifiP2pManager.GroupCreationFailureReason int reason) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onGroupCreationFailed(reason);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onGroupCreationFailed" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onGroupCreated(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onGroupCreated(p2pInfo, p2pGroup);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onGroupCreated" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onPeerClientJoined(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onPeerClientJoined(p2pInfo, p2pGroup);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onPeerClientJoined" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onPeerClientDisconnected(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onPeerClientDisconnected(p2pInfo,
+ p2pGroup);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onPeerClientDisconnected" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onFrequencyChanged(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onFrequencyChanged(p2pInfo, p2pGroup);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onFrequencyChanged" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
+ private void onGroupRemoved() {
+ int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ for (int i = 0; i < numCallbacks; i++) {
+ try {
+ mWifiP2pListeners.getBroadcastItem(i).onGroupRemoved();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failure calling onGroupRemoved" + e);
+ }
+ }
+ mWifiP2pListeners.finishBroadcast();
+ }
+
private boolean getWfdPermission(int uid) {
WifiPermissionsWrapper wifiPermissionsWrapper = mWifiInjector.getWifiPermissionsWrapper();
return wifiPermissionsWrapper.getUidPermission(
@@ -1122,35 +1360,45 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
*/
private class P2pStateMachine extends StateMachine {
- private final DefaultState mDefaultState = new DefaultState();
- private final P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
- private final P2pDisablingState mP2pDisablingState = new P2pDisablingState();
+ private final DefaultState mDefaultState = new DefaultState(mThreshold, mThreadLocalLog);
+ private final P2pNotSupportedState mP2pNotSupportedState =
+ new P2pNotSupportedState(mThreshold, mThreadLocalLog);
+ private final P2pDisablingState mP2pDisablingState =
+ new P2pDisablingState(mThreshold, mThreadLocalLog);
private final P2pDisabledContainerState mP2pDisabledContainerState =
- new P2pDisabledContainerState();
- private final P2pDisabledState mP2pDisabledState = new P2pDisabledState();
+ new P2pDisabledContainerState(mThreshold, mThreadLocalLog);
+ private final P2pDisabledState mP2pDisabledState =
+ new P2pDisabledState(mThreshold, mThreadLocalLog);
private final WaitingState mWaitingState = new WaitingState(this);
- private final P2pEnabledState mP2pEnabledState = new P2pEnabledState();
+ private final P2pEnabledState mP2pEnabledState =
+ new P2pEnabledState(mThreshold, mThreadLocalLog);
// Inactive is when p2p is enabled with no connectivity
- private final InactiveState mInactiveState = new InactiveState();
- private final GroupCreatingState mGroupCreatingState = new GroupCreatingState();
+ private final InactiveState mInactiveState = new InactiveState(mThreshold, mThreadLocalLog);
+ private final GroupCreatingState mGroupCreatingState =
+ new GroupCreatingState(mThreshold, mThreadLocalLog);
private final UserAuthorizingInviteRequestState mUserAuthorizingInviteRequestState =
- new UserAuthorizingInviteRequestState();
+ new UserAuthorizingInviteRequestState(mThreshold, mThreadLocalLog);
private final UserAuthorizingNegotiationRequestState
mUserAuthorizingNegotiationRequestState =
- new UserAuthorizingNegotiationRequestState();
+ new UserAuthorizingNegotiationRequestState(mThreshold, mThreadLocalLog);
private final ProvisionDiscoveryState mProvisionDiscoveryState =
- new ProvisionDiscoveryState();
- private final GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
- private final FrequencyConflictState mFrequencyConflictState = new FrequencyConflictState();
-
- private final GroupCreatedState mGroupCreatedState = new GroupCreatedState();
+ new ProvisionDiscoveryState(mThreshold, mThreadLocalLog);
+ private final GroupNegotiationState mGroupNegotiationState =
+ new GroupNegotiationState(mThreshold, mThreadLocalLog);
+ private final FrequencyConflictState mFrequencyConflictState =
+ new FrequencyConflictState(mThreshold, mThreadLocalLog);
+
+ private final GroupCreatedState mGroupCreatedState =
+ new GroupCreatedState(mThreshold, mThreadLocalLog);
private final UserAuthorizingJoinState mUserAuthorizingJoinState =
- new UserAuthorizingJoinState();
+ new UserAuthorizingJoinState(mThreshold, mThreadLocalLog);
private final OngoingGroupRemovalState mOngoingGroupRemovalState =
- new OngoingGroupRemovalState();
- private final P2pRejectWaitState mP2pRejectWaitState = new P2pRejectWaitState();
+ new OngoingGroupRemovalState(mThreshold, mThreadLocalLog);
+ private final P2pRejectWaitState mP2pRejectWaitState =
+ new P2pRejectWaitState(mThreshold, mThreadLocalLog);
private final WifiP2pMonitor mWifiMonitor = mWifiInjector.getWifiP2pMonitor();
+
private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
private String mInterfaceName;
private TetheringEventCallback mTetheringEventCallback =
@@ -1164,6 +1412,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
+ " callback for ifaceList: " + ifaceList);
sendMessage(TETHER_INTERFACE_STATE_CHANGED, ifaceList);
}
+ @Override
+ public void onClientsChanged(Collection<TetheredClient> clients) {
+ synchronized (mLock) {
+ sendMessage(TETHER_INTERFACE_CLIENTS_CHANGED, clients);
+ }
+ }
};
private final List<CoexUnsafeChannel> mCoexUnsafeChannels = new ArrayList<>();
@@ -1249,8 +1503,17 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mIsWifiEnabled = true;
} else {
mIsWifiEnabled = false;
- // Teardown P2P if it's up already.
- sendMessage(DISABLE_P2P);
+ // P2P can be established even when infra STA is disabled.
+ // This implies that STA might be torn down by P2P
+ // (e.g., if STA was active initially).
+ // Check availability to determine whether to stop P2P
+ // upon receiving a Wi-Fi off signal.
+ if (!isWifiP2pAvailable()) {
+ sendMessage(DISABLE_P2P);
+ } else {
+ Log.i(TAG, "Infra STA is disabled but keep P2P on since"
+ + " d2d is allowed when infra sta is disabled");
+ }
}
if (wifistate == WifiManager.WIFI_STATE_ENABLED
|| wifistate == WifiManager.WIFI_STATE_DISABLING) {
@@ -1258,6 +1521,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
}
}, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
+ mSettingsConfigStore.registerChangeListener(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED,
+ new D2DAllowWhenInfraStaDisabledValueListener(), this.getHandler());
// Register for location mode on/off broadcasts
mContext.registerReceiver(new BroadcastReceiver() {
@Override
@@ -1398,6 +1663,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return "SET_MIRACAST_MODE";
case TETHER_INTERFACE_STATE_CHANGED:
return "TETHER_INTERFACE_STATE_CHANGED";
+ case TETHER_INTERFACE_CLIENTS_CHANGED:
+ return "TETHER_INTERFACE_CLIENTS_CHANGED";
case UPDATE_P2P_DISALLOWED_CHANNELS:
return "UPDATE_P2P_DISALLOWED_CHANNELS";
case WifiP2pManager.ADD_EXTERNAL_APPROVER:
@@ -1538,6 +1805,10 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return "WifiP2pManager.SET_VENDOR_ELEMENTS";
case P2P_REJECTION_RESUME_AFTER_DELAY:
return "P2P_REJECTION_RESUME_AFTER_DELAY";
+ case RunnerState.STATE_ENTER_CMD:
+ return "Enter";
+ case RunnerState.STATE_EXIT_CMD:
+ return "Exit";
default:
return "what:" + what;
}
@@ -1783,9 +2054,17 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
}
- class DefaultState extends State {
+ class DefaultState extends RunnerState {
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ DefaultState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
@@ -2085,6 +2364,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
case IPC_PROVISIONING_SUCCESS:
case IPC_PROVISIONING_FAILURE:
case TETHER_INTERFACE_STATE_CHANGED:
+ case TETHER_INTERFACE_CLIENTS_CHANGED:
case UPDATE_P2P_DISALLOWED_CHANNELS:
case WifiP2pMonitor.P2P_PROV_DISC_FAILURE_EVENT:
case SET_MIRACAST_MODE:
@@ -2319,11 +2599,37 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return HANDLED;
}
+
+ @Override
+ public void enterImpl() {
+
+ }
+
+ @Override
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class P2pNotSupportedState extends State {
+ class P2pNotSupportedState extends RunnerState {
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ P2pNotSupportedState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
case WifiP2pManager.DISCOVER_PEERS:
@@ -2432,11 +2738,37 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return HANDLED;
}
+
+ @Override
+ public void enterImpl() {
+
+ }
+
+ @Override
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class P2pDisablingState extends State {
+ class P2pDisablingState extends RunnerState {
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ P2pDisablingState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
sendMessageDelayed(obtainMessage(DISABLE_P2P_TIMED_OUT,
@@ -2444,7 +2776,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public boolean processMessage(Message message) {
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
case WifiP2pMonitor.SUP_DISCONNECTION_EVENT:
@@ -2467,11 +2804,27 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return HANDLED;
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class P2pDisabledContainerState extends State { // split due to b/220588514
+ class P2pDisabledContainerState extends RunnerState {
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ P2pDisabledContainerState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
mInterfaceName = null; // reset iface name on disable.
@@ -2483,9 +2836,36 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
resetWifiP2pInfo();
mGroup = null;
}
+
+ @Override
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public boolean processMessageImpl(Message msg) {
+ return false;
+ }
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class P2pDisabledState extends State {
+ class P2pDisabledState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ P2pDisabledState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
private void setupInterfaceFeatures() {
if (mWifiGlobals.isP2pMacRandomizationSupported()) {
Log.i(TAG, "Supported feature: P2P MAC randomization");
@@ -2535,7 +2915,17 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public boolean processMessage(Message message) {
+ public void enterImpl() {
+
+ }
+
+ @Override
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
boolean wasInWaitingState = WaitingState.wasMessageInWaitingState(message);
switch (message.what) {
@@ -2654,11 +3044,28 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return HANDLED;
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class P2pEnabledState extends State {
+ class P2pEnabledState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ P2pEnabledState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
@@ -2677,7 +3084,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
case WifiP2pMonitor.SUP_DISCONNECTION_EVENT:
@@ -2760,6 +3167,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
int freq = extras.getInt(
WifiP2pManager.EXTRA_PARAM_KEY_PEER_DISCOVERY_FREQ,
WifiP2pManager.WIFI_P2P_SCAN_FREQ_UNSPECIFIED);
+ WifiP2pDiscoveryConfig discoveryConfig = (WifiP2pDiscoveryConfig)
+ extras.getParcelable(
+ WifiP2pManager.EXTRA_PARAM_KEY_DISCOVERY_CONFIG);
boolean hasPermission = false;
if (scanType != WifiP2pManager.WIFI_P2P_SCAN_FULL
&& !isFeatureSupported(WifiP2pManager.FEATURE_FLEXIBLE_DISCOVERY)) {
@@ -2792,12 +3202,14 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
apiType = WifiManager.API_P2P_DISCOVER_PEERS_ON_SOCIAL_CHANNELS;
} else if (scanType == WifiP2pManager.WIFI_P2P_SCAN_SINGLE_FREQ) {
apiType = WifiManager.API_P2P_DISCOVER_PEERS_ON_SPECIFIC_FREQUENCY;
+ } else if (scanType == WifiP2pManager.WIFI_P2P_SCAN_WITH_CONFIG_PARAMS) {
+ apiType = WifiManager.API_P2P_DISCOVER_PEERS_WITH_CONFIG_PARAMS;
}
mLastCallerInfoManager.put(apiType, Process.myTid(), uid, 0, packageName,
true);
// do not send service discovery request while normal find operation.
clearSupplicantServiceRequest();
- if (p2pFind(scanType, freq, DISCOVER_TIMEOUT_S)) {
+ if (p2pFind(scanType, freq, DISCOVER_TIMEOUT_S, discoveryConfig)) {
mWifiP2pMetrics.incrementPeerScans();
replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
sendP2pDiscoveryChangedBroadcast(true);
@@ -2997,8 +3409,20 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
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(
@@ -3021,7 +3445,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mContext.getResources().getInteger(
R.integer.config_wifiP2pExtListenPeriodMs),
mContext.getResources().getInteger(
- R.integer.config_wifiP2pExtListenIntervalMs))) {
+ R.integer.config_wifiP2pExtListenIntervalMs),
+ extListenParams)) {
replyToMessage(message, WifiP2pManager.START_LISTEN_SUCCEEDED);
sendP2pListenChangedBroadcast(true);
} else {
@@ -3033,7 +3458,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
Process.myTid(), message.sendingUid, 0,
getCallingPkgName(message.sendingUid, message.replyTo), true);
if (mVerboseLoggingEnabled) logd(getName() + " stop listen mode");
- if (mWifiNative.p2pExtListen(false, 0, 0)) {
+ if (mWifiNative.p2pExtListen(false, 0, 0, null)) {
replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
sendP2pListenChangedBroadcast(false);
} else {
@@ -3095,7 +3520,14 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public void exit() {
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
+
+ @Override
+ public void exitImpl() {
sendP2pDiscoveryChangedBroadcast(false);
sendP2pListenChangedBroadcast(false);
mUserListenChannel = 0;
@@ -3107,9 +3539,19 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
}
- class InactiveState extends State {
+ class InactiveState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ InactiveState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
mPeerAuthorizingTimestamp.clear();
@@ -3119,12 +3561,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public void exit() {
+ public void exitImpl() {
cancelIdleShutdown();
}
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
// Re-schedule the shutdown timer since we got the new operation.
// only handle commands from clients.
@@ -3317,6 +3759,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
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);
@@ -3437,8 +3882,20 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
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(
@@ -3461,7 +3918,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mContext.getResources().getInteger(
R.integer.config_wifiP2pExtListenPeriodMs),
mContext.getResources().getInteger(
- R.integer.config_wifiP2pExtListenIntervalMs))) {
+ R.integer.config_wifiP2pExtListenIntervalMs),
+ extListenParams)) {
replyToMessage(message, WifiP2pManager.START_LISTEN_SUCCEEDED);
sendP2pListenChangedBroadcast(true);
} else {
@@ -3473,7 +3931,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
Process.myTid(), message.sendingUid, 0,
getCallingPkgName(message.sendingUid, message.replyTo), true);
if (mVerboseLoggingEnabled) logd(getName() + " stop listen mode");
- if (mWifiNative.p2pExtListen(false, 0, 0)) {
+ if (mWifiNative.p2pExtListen(false, 0, 0, null)) {
replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
sendP2pListenChangedBroadcast(false);
} else {
@@ -3544,16 +4002,38 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return HANDLED;
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class P2pRejectWaitState extends State {
+ class P2pRejectWaitState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ P2pRejectWaitState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
if (mVerboseLoggingEnabled) logd(getName());
}
@Override
- public boolean processMessage(Message message) {
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
boolean ret = HANDLED;
switch (message.what) {
case P2P_REJECTION_RESUME_AFTER_DELAY:
@@ -3562,7 +4042,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
"P2p rejection resume after delay - originated from "
+ getWhatToString(message.what));
if (message.arg2 == WifiP2pManager.CANCEL_CONNECT) {
- handleGroupCreationFailure();
+ handleGroupCreationFailure(WifiP2pManager
+ .GROUP_CREATION_FAILURE_REASON_CONNECTION_CANCELLED);
if (message.obj != null) {
replyToMessage(
(Message) message.obj,
@@ -3583,13 +4064,31 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return ret;
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class GroupCreatingState extends State {
+ class GroupCreatingState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ GroupCreatingState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
+ onGroupCreating();
if (SdkLevel.isAtLeastT()) {
mDetailedState = NetworkInfo.DetailedState.CONNECTING;
sendP2pConnectionChangedBroadcast();
@@ -3599,7 +4098,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public boolean processMessage(Message message) {
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
boolean ret = HANDLED;
switch (message.what) {
@@ -3614,7 +4118,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
mWifiP2pMetrics.endConnectionEvent(
P2pConnectionEvent.CLF_TIMEOUT);
- handleGroupCreationFailure();
+ handleGroupCreationFailure(
+ WifiP2pManager.GROUP_CREATION_FAILURE_REASON_TIMED_OUT);
smTransition(this, mInactiveState);
}
break;
@@ -3655,7 +4160,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (mVerboseLoggingEnabled) {
logd(getName() + " stop listen mode");
}
- if (mWifiNative.p2pExtListen(false, 0, 0)) {
+ if (mWifiNative.p2pExtListen(false, 0, 0, null)) {
replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
} else {
replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED);
@@ -3675,7 +4180,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
P2pConnectionEvent.CLF_CANCEL);
// Notify the peer about the rejection.
int delay = 0;
- if (mSavedPeerConfig != null) {
+ if (!TextUtils.isEmpty(mSavedPeerConfig.deviceAddress)) {
mWifiNative.p2pStopFind();
delay = sendP2pRejection();
}
@@ -3685,7 +4190,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
P2P_REJECTION_RESUME_AFTER_DELAY,
++sP2pRejectionResumeAfterDelayIndex,
WifiP2pManager.CANCEL_CONNECT,
- message),
+ Message.obtain(message)),
delay);
break;
case WifiP2pMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
@@ -3698,11 +4203,29 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return ret;
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class UserAuthorizingNegotiationRequestState extends State {
+ class UserAuthorizingNegotiationRequestState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ UserAuthorizingNegotiationRequestState(int threshold,
+ @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
if (mSavedPeerConfig.wps.setup == WpsInfo.PBC
@@ -3714,7 +4237,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
case PEER_CONNECTION_USER_ACCEPT:
@@ -3729,7 +4252,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (mVerboseLoggingEnabled) {
logd("User rejected negotiation " + mSavedPeerConfig);
}
- if (mSavedPeerConfig != null) {
+ if (!TextUtils.isEmpty(mSavedPeerConfig.deviceAddress)) {
WifiP2pDevice dev = fetchCurrentDeviceDetails(mSavedPeerConfig);
boolean join = (dev != null && dev.isGroupOwner())
|| mJoinExistingGroup;
@@ -3745,6 +4268,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
int delay = sendP2pRejection();
mDetailedState = NetworkInfo.DetailedState.DISCONNECTED;
+ onGroupNegotiationRejectedByUser();
sendP2pConnectionChangedBroadcast();
mSavedPeerConfig.invalidate();
transitionTo(mP2pRejectWaitState);
@@ -3756,7 +4280,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
delay);
} else {
mWifiNative.p2pCancelConnect();
- handleGroupCreationFailure();
+ handleGroupCreationFailure(
+ WifiP2pManager.GROUP_CREATION_FAILURE_REASON_USER_REJECTED);
smTransition(this, mInactiveState);
}
break;
@@ -3769,7 +4294,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
case WifiP2pMonitor.P2P_PROV_DISC_FAILURE_EVENT:
loge("provision discovery failed status: " + message.arg1);
- handleGroupCreationFailure();
+ handleGroupCreationFailure(WifiP2pManager
+ .GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED);
smTransition(this, mInactiveState);
break;
case WifiP2pManager.SET_CONNECTION_REQUEST_RESULT: {
@@ -3792,7 +4318,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public void exit() {
+ public void exitImpl() {
if (null != mInvitationDialogHandle) {
mInvitationDialogHandle.dismissDialog();
mInvitationDialogHandle = null;
@@ -3802,11 +4328,29 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mLegacyInvitationDialog = null;
}
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class UserAuthorizingInviteRequestState extends State {
+ class UserAuthorizingInviteRequestState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ UserAuthorizingInviteRequestState(int threshold,
+ @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
notifyInvitationReceived(
@@ -3814,7 +4358,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
case PEER_CONNECTION_USER_ACCEPT:
@@ -3836,7 +4380,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
case WifiP2pMonitor.P2P_PROV_DISC_FAILURE_EVENT:
loge("provision discovery failed status: " + message.arg1);
- handleGroupCreationFailure();
+ handleGroupCreationFailure(WifiP2pManager
+ .GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED);
smTransition(this, mInactiveState);
break;
case WifiP2pManager.SET_CONNECTION_REQUEST_RESULT:
@@ -3858,7 +4403,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public void exit() {
+ public void exitImpl() {
if (null != mInvitationDialogHandle) {
mInvitationDialogHandle.dismissDialog();
mInvitationDialogHandle = null;
@@ -3868,18 +4413,40 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mLegacyInvitationDialog = null;
}
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class ProvisionDiscoveryState extends State {
+ class ProvisionDiscoveryState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ ProvisionDiscoveryState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
mWifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
}
@Override
- public boolean processMessage(Message message) {
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
WifiP2pProvDiscEvent provDisc = null;
WifiP2pDevice device = null;
@@ -3970,7 +4537,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mWifiNative.p2pCancelConnect();
mWifiP2pMetrics.endConnectionEvent(
P2pConnectionEvent.CLF_PROV_DISC_FAIL);
- handleGroupCreationFailure();
+ handleGroupCreationFailure(WifiP2pManager
+ .GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED);
smTransition(this, mInactiveState);
break;
default:
@@ -3978,17 +4546,39 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return HANDLED;
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class GroupNegotiationState extends State {
+ class GroupNegotiationState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ GroupNegotiationState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
}
@Override
- public boolean processMessage(Message message) {
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
// We ignore these right now, since we get a GROUP_STARTED notification
@@ -4004,7 +4594,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
mGroup = (WifiP2pGroup) message.obj;
if (mVerboseLoggingEnabled) logd(getName() + " group started");
- if (mWifiNative.p2pExtListen(false, 0, 0)) {
+ if (mWifiNative.p2pExtListen(false, 0, 0, null)) {
sendP2pListenChangedBroadcast(false);
}
mWifiNative.p2pStopFind();
@@ -4041,7 +4631,10 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// As a result, P2P sends a unicast intent to tether service to trigger
// the whole flow before entering GroupCreatedState.
setWifiP2pInfoOnGroupFormation(null);
- if (!sendP2pTetherRequestBroadcast()) {
+ boolean isSendSuccessful = SdkLevel.isAtLeastU()
+ ? sendP2pTetherRequestBroadcastPostU()
+ : sendP2pTetherRequestBroadcastPreU();
+ if (!isSendSuccessful) {
loge("Cannot start tethering, remove " + mGroup);
mWifiNative.p2pGroupRemove(mGroup.getInterface());
}
@@ -4053,10 +4646,15 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mSavedPeerConfig.getGroupClientIpProvisioningMode(),
mGroup.p2pClientEapolIpInfo);
WifiP2pDevice groupOwner = mGroup.getOwner();
- WifiP2pDevice peer = mPeers.get(groupOwner.deviceAddress);
- if (peer != null) {
- // update group owner details with peer details found at discovery
- groupOwner.updateSupplicantDetails(peer);
+ if (!EMPTY_DEVICE_ADDRESS.equals(groupOwner.deviceAddress)) {
+ WifiP2pDevice peer = mPeers.get(groupOwner.deviceAddress);
+ if (peer != null) {
+ // update group owner details with peer details found at discovery
+ groupOwner.updateSupplicantDetails(peer);
+ } else {
+ logd("Add group owner into mPeers: " + groupOwner);
+ mPeers.updateSupplicantDetails(groupOwner);
+ }
mPeers.updateStatus(groupOwner.deviceAddress,
WifiP2pDevice.CONNECTED);
sendPeersChangedBroadcast();
@@ -4098,7 +4696,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
mWifiP2pMetrics.endConnectionEvent(
P2pConnectionEvent.CLF_GROUP_REMOVED);
- handleGroupCreationFailure();
+ handleGroupCreationFailure(
+ WifiP2pManager.GROUP_CREATION_FAILURE_REASON_GROUP_REMOVED);
smTransition(this, mInactiveState);
break;
case WifiP2pMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
@@ -4157,7 +4756,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mContext.getResources().getInteger(
R.integer.config_wifiP2pExtListenPeriodMs),
mContext.getResources().getInteger(
- R.integer.config_wifiP2pExtListenIntervalMs))) {
+ R.integer.config_wifiP2pExtListenIntervalMs),
+ null)) {
logd(" started listen to receive the invitation Request"
+ " frame from Peer device.");
sendP2pListenChangedBroadcast(true);
@@ -4168,7 +4768,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
} else {
mWifiP2pMetrics.endConnectionEvent(
P2pConnectionEvent.CLF_INVITATION_FAIL);
- handleGroupCreationFailure();
+ handleGroupCreationFailure(
+ WifiP2pManager.GROUP_CREATION_FAILURE_REASON_INVITATION_FAILED);
smTransition(this, mInactiveState);
}
break;
@@ -4176,7 +4777,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
loge("Peer rejected the connection request - status: " + message.arg1);
mWifiP2pMetrics.endConnectionEvent(
P2pConnectionEvent.CLF_GROUP_REMOVED);
- handleGroupCreationFailure();
+ handleGroupCreationFailure(WifiP2pManager
+ .GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED);
smTransition(this, mInactiveState);
break;
case WifiP2pMonitor.AP_STA_CONNECTED_EVENT:
@@ -4207,14 +4809,30 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return HANDLED;
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class FrequencyConflictState extends State {
+ class FrequencyConflictState extends RunnerState {
private WifiDialogManager.DialogHandle mFrequencyConflictDialog;
private AlertDialog mFrequencyConflictDialogPreT;
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ FrequencyConflictState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
notifyFrequencyConflict();
@@ -4287,7 +4905,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
case WifiP2pMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
@@ -4310,7 +4928,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mFrequencyConflictDialogPreT = null;
mWifiP2pMetrics.endConnectionEvent(
P2pConnectionEvent.CLF_USER_REJECT);
- handleGroupCreationFailure();
+ handleGroupCreationFailure(
+ WifiP2pManager.GROUP_CREATION_FAILURE_REASON_USER_REJECTED);
smTransition(this, mInactiveState);
break;
case DROP_WIFI_USER_ACCEPT:
@@ -4333,7 +4952,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return HANDLED;
}
- public void exit() {
+ public void exitImpl() {
if (mFrequencyConflictDialogPreT != null) {
mFrequencyConflictDialogPreT.dismiss();
}
@@ -4341,11 +4960,28 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mFrequencyConflictDialog.dismissDialog();
}
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class GroupCreatedState extends State {
+ class GroupCreatedState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ GroupCreatedState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
// Once connected, peer config details are invalid
@@ -4369,6 +5005,7 @@ 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));
sendP2pConnectionChangedBroadcast();
}
@@ -4378,18 +5015,19 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
WifiP2pDevice device;
String deviceAddress;
switch (message.what) {
- case WifiP2pMonitor.AP_STA_CONNECTED_EVENT:
+ case WifiP2pMonitor.AP_STA_CONNECTED_EVENT: {
if (message.obj == null) {
Log.e(TAG, "Illegal argument(s)");
break;
}
device = (WifiP2pDevice) message.obj;
deviceAddress = device.deviceAddress;
+ MacAddress interfaceMacAddress = device.getInterfaceMacAddress();
// Clear timeout that was set when group was started.
mWifiNative.setP2pGroupIdle(mGroup.getInterface(), 0);
if (deviceAddress != null) {
@@ -4398,6 +5036,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
} else {
mGroup.addClient(deviceAddress);
}
+ mGroup.setClientInterfaceMacAddress(deviceAddress, interfaceMacAddress);
+ if (SdkLevel.isAtLeastV() && device.getIpAddress() != null) {
+ mGroup.setClientIpAddress(interfaceMacAddress,
+ device.getIpAddress());
+ }
mPeers.updateStatus(deviceAddress, WifiP2pDevice.CONNECTED);
if (mVerboseLoggingEnabled) logd(getName() + " ap sta connected");
// When a peer is connected, flush it.
@@ -4407,9 +5050,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
} else {
loge("Connect on null device address, ignore");
}
+ onPeerClientJoined(new WifiP2pInfo(mWifiP2pInfo),
+ eraseOwnDeviceAddress(mGroup));
sendP2pConnectionChangedBroadcast();
break;
- case WifiP2pMonitor.AP_STA_DISCONNECTED_EVENT:
+ }
+ case WifiP2pMonitor.AP_STA_DISCONNECTED_EVENT: {
if (message.obj == null) {
Log.e(TAG, "Illegal argument(s)");
break;
@@ -4428,6 +5074,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// We end up sending connection changed broadcast
// when this happens at exit()
} else {
+ onPeerClientDisconnected(new WifiP2pInfo(mWifiP2pInfo),
+ eraseOwnDeviceAddress(mGroup));
// Notify when a client disconnects from group
sendP2pConnectionChangedBroadcast();
}
@@ -4448,6 +5096,34 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
loge("Disconnect on unknown device: " + device);
}
break;
+ }
+ case TETHER_INTERFACE_CLIENTS_CHANGED: {
+ if (mGroup == null) break;
+ if (!mGroup.isGroupOwner()) break;
+ if (TextUtils.isEmpty(mGroup.getInterface())) break;
+
+ Collection<TetheredClient> connectedClients =
+ (Collection<TetheredClient>) message.obj;
+ if (connectedClients == null) break;
+ for (TetheredClient client : connectedClients) {
+ logd("TETHER_INTERFACE_CLIENTS_CHANGED - client: " + client);
+ if (client.getTetheringType() == TetheringManager.TETHERING_WIFI_P2P) {
+ if (client.getAddresses().size() == 0) {
+ continue;
+ }
+ TetheredClient.AddressInfo info = client.getAddresses().get(0);
+ MacAddress interfaceMacAddress = client.getMacAddress();
+ LinkAddress linkAddressInfo = info.getAddress();
+ InetAddress ipAddress = linkAddressInfo.getAddress();
+ mGroup.setClientIpAddress(interfaceMacAddress, ipAddress);
+ } else {
+ loge("Received onClientsChanged cb from a non-p2p tether type: "
+ + client.getTetheringType());
+ }
+ }
+ sendP2pConnectionChangedBroadcast();
+ break;
+ }
case IPC_PRE_DHCP_ACTION:
mWifiNative.setP2pPowerSave(mGroup.getInterface(), false);
try {
@@ -4489,6 +5165,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
} catch (Exception e) {
loge("Failed to add iface to local network " + e);
}
+ onGroupCreated(new WifiP2pInfo(mWifiP2pInfo),
+ eraseOwnDeviceAddress(mGroup));
sendP2pConnectionChangedBroadcast();
break;
case IPC_PROVISIONING_SUCCESS:
@@ -4513,6 +5191,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
byte[] goInterfaceMacAddress = mGroup.interfaceAddress;
if (goInterfaceMacAddress == null) {
setWifiP2pInfoOnGroupFormationWithInetAddress(null);
+ onGroupCreated(new WifiP2pInfo(mWifiP2pInfo),
+ eraseOwnDeviceAddress(mGroup));
sendP2pConnectionChangedBroadcast();
break;
}
@@ -4523,6 +5203,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
InetAddress goIp = Inet6Address.getByAddress(null, goIpv6Address,
NetworkInterface.getByName(mGroup.getInterface()));
setWifiP2pInfoOnGroupFormationWithInetAddress(goIp);
+ onGroupCreated(new WifiP2pInfo(mWifiP2pInfo),
+ eraseOwnDeviceAddress(mGroup));
sendP2pConnectionChangedBroadcast();
} catch (UnknownHostException | SocketException e) {
loge("Unable to retrieve link-local IPv6 address of group owner "
@@ -4691,6 +5373,10 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
newPeerConfig.deviceAddress = provDisc.device.deviceAddress;
}
+ if (SdkLevel.isAtLeastV() && provDisc != null
+ && provDisc.getVendorData() != null) {
+ newPeerConfig.setVendorData(provDisc.getVendorData());
+ }
if (message.what == WifiP2pMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
newPeerConfig.wps.setup = WpsInfo.KEYPAD;
} else if (message.what == WifiP2pMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
@@ -4745,6 +5431,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
case WifiP2pMonitor.P2P_FREQUENCY_CHANGED_EVENT:
if (mGroup != null) {
mGroup.setFrequency(message.arg1);
+ onFrequencyChanged(new WifiP2pInfo(mWifiP2pInfo),
+ eraseOwnDeviceAddress(mGroup));
sendP2pConnectionChangedBroadcast();
}
break;
@@ -4786,7 +5474,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return HANDLED;
}
- public void exit() {
+ public void exitImpl() {
// The group is still there and handling incoming request,
// no need to update P2P connection information.
if (mGroup != null) return;
@@ -4795,17 +5483,35 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
updateThisDevice(WifiP2pDevice.AVAILABLE);
resetWifiP2pInfo();
mDetailedState = NetworkInfo.DetailedState.DISCONNECTED;
+ onGroupRemoved();
sendP2pConnectionChangedBroadcast();
if (!SdkLevel.isAtLeastU()) {
// Ensure tethering service to stop tethering.
- sendP2pTetherRequestBroadcast();
+ sendP2pTetherRequestBroadcastPreU();
}
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class UserAuthorizingJoinState extends State {
+ class UserAuthorizingJoinState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ UserAuthorizingJoinState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
notifyInvitationReceived(
@@ -4813,7 +5519,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
case WifiP2pMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
@@ -4831,7 +5537,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
case PEER_CONNECTION_USER_ACCEPT:
// Stop discovery to avoid failure due to channel switch
- mWifiNative.p2pStopFind();
+ if (mDiscoveryStarted) {
+ mWifiNative.p2pStopFind();
+ }
if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
mWifiNative.startWpsPbc(mGroup.getInterface(), null);
} else {
@@ -4863,7 +5571,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
- public void exit() {
+ public void exitImpl() {
if (null != mInvitationDialogHandle) {
mInvitationDialogHandle.dismissDialog();
mInvitationDialogHandle = null;
@@ -4873,17 +5581,39 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mLegacyInvitationDialog = null;
}
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
- class OngoingGroupRemovalState extends State {
+ class OngoingGroupRemovalState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ OngoingGroupRemovalState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
logSmStateName(this.getName(),
getCurrentState() != null ? getCurrentState().getName() : "");
}
@Override
- public boolean processMessage(Message message) {
+ public void exitImpl() {
+
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
logSmMessage(getName(), message);
switch (message.what) {
// Group removal ongoing. Multiple calls
@@ -4898,6 +5628,13 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
return HANDLED;
}
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
}
@Override
@@ -4910,13 +5647,20 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
pw.println();
}
- private boolean isWifiP2pAvailable() {
- return mIsWifiEnabled && !mIsP2pDisallowedByAdmin;
+ public boolean isWifiP2pAvailable() {
+ if (mIsP2pDisallowedByAdmin) return false;
+ if (mFeatureFlags.d2dWhenInfraStaOff()) {
+ return mIsWifiEnabled
+ || (mSettingsConfigStore.get(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED)
+ && mWifiGlobals.isD2dSupportedWhenInfraStaDisabled());
+ }
+ return mIsWifiEnabled;
}
- private void checkAndSendP2pStateChangedBroadcast() {
+ public void checkAndSendP2pStateChangedBroadcast() {
Log.d(TAG, "Wifi enabled=" + mIsWifiEnabled + ", P2P disallowed by admin="
- + mIsP2pDisallowedByAdmin);
+ + mIsP2pDisallowedByAdmin + ", D2D allowed when infra sta is disabled="
+ + mSettingsConfigStore.get(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED));
boolean wifiP2pAvailable = isWifiP2pAvailable();
if (mLastP2pState != wifiP2pAvailable) {
mLastP2pState = wifiP2pAvailable;
@@ -4925,6 +5669,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
private void sendP2pStateChangedBroadcast(boolean enabled) {
+ onP2pStateChanged(enabled ? WifiP2pManager.WIFI_P2P_STATE_ENABLED
+ : WifiP2pManager.WIFI_P2P_STATE_DISABLED);
final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
if (enabled) {
@@ -4942,6 +5688,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mDiscoveryStarted = started;
if (mVerboseLoggingEnabled) logd("discovery change broadcast " + started);
+ onDiscoveryStateChanged(started ? WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED
+ : WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -4956,6 +5704,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mListenStarted = started;
if (mVerboseLoggingEnabled) logd("wifi p2p listen change broadcast " + started);
+ onListenStateChanged(started ? WifiP2pManager.WIFI_P2P_LISTEN_STARTED
+ : WifiP2pManager.WIFI_P2P_LISTEN_STOPPED);
final Intent intent = new Intent(WifiP2pManager.ACTION_WIFI_P2P_LISTEN_STATE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -5013,16 +5763,21 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
private void sendThisDeviceChangedBroadcast() {
+ WifiP2pDevice p2pDevice = eraseOwnDeviceAddress(mThisDevice);
+ onDeviceConfigurationChanged(p2pDevice);
+
final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE,
- eraseOwnDeviceAddress(mThisDevice));
+ intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, p2pDevice);
sendBroadcastWithExcludedPermissions(intent, null);
}
private void sendPeersChangedBroadcast() {
+ WifiP2pDeviceList p2pDeviceList = new WifiP2pDeviceList(mPeers);
+ onPeerListChanged(p2pDeviceList);
+
final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
- intent.putExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST, new WifiP2pDeviceList(mPeers));
+ intent.putExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST, p2pDeviceList);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
sendBroadcastWithExcludedPermissions(intent, null);
}
@@ -5040,10 +5795,13 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (mVerboseLoggingEnabled) logd("sending p2p connection changed broadcast");
Intent intent = getP2pConnectionChangedIntent();
if (SdkLevel.isAtLeastU()) {
- // First send direct foreground broadcast to Tethering package
- sendP2pTetherRequestBroadcast();
- // Then send the same broadcast to remaining apps excluding Tethering package
- sendBroadcastWithExcludedPermissions(intent, RECEIVER_PERMISSIONS_FOR_TETHERING);
+ // First send direct foreground broadcast to Tethering package and system service
+ // with same android.permission.MAINLINE_NETWORK_STACK
+ sendBroadcastWithMainlineNetworkStackPermissionPostU();
+ // Then send the same broadcast to remaining apps without
+ // android.permission.MAINLINE_NETWORK_STACK
+ sendBroadcastWithExcludedPermissions(intent,
+ RECEIVER_PERMISSIONS_MAINLINE_NETWORK_STACK);
} else {
sendBroadcastWithExcludedPermissions(intent, null);
}
@@ -5123,33 +5881,49 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return null;
}
- private boolean sendP2pTetherRequestBroadcast() {
- String tetheringServicePackage = findTetheringServicePackage();
- if (TextUtils.isEmpty(tetheringServicePackage)) return false;
- Log.i(TAG, "sending p2p tether request broadcast to "
- + tetheringServicePackage);
-
+ private boolean sendP2pTetherRequestBroadcastPreU() {
String[] receiverPermissionsForTetheringRequest = {
android.Manifest.permission.TETHER_PRIVILEGED
};
- if (SdkLevel.isAtLeastU()) {
- receiverPermissionsForTetheringRequest = RECEIVER_PERMISSIONS_FOR_TETHERING;
- }
+ return sendP2pTetherRequestBroadcastCommon(receiverPermissionsForTetheringRequest,
+ false, 0);
+ }
+
+ private boolean sendP2pTetherRequestBroadcastPostU() {
+ return sendP2pTetherRequestBroadcastCommon(RECEIVER_PERMISSIONS_MAINLINE_NETWORK_STACK,
+ true, Intent.FLAG_RECEIVER_FOREGROUND);
+ }
+
+ private boolean sendP2pTetherRequestBroadcastCommon(String[] permissions,
+ boolean setAdditionalFlags, int flags) {
+ String tetheringServicePackage = findTetheringServicePackage();
+ if (TextUtils.isEmpty(tetheringServicePackage)) return false;
+ Log.i(TAG, "sending p2p tether request broadcast to " + tetheringServicePackage
+ + " with permission " + Arrays.toString(permissions));
Intent intent = getP2pConnectionChangedIntent();
- intent.setPackage(tetheringServicePackage);
- if (SdkLevel.isAtLeastU()) {
- // Adding the flag to allow recipient to run at foreground priority with a shorter
- // timeout interval.
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ if (setAdditionalFlags) {
+ intent.addFlags(flags);
}
-
+ intent.setPackage(tetheringServicePackage);
Context context = mContext.createContextAsUser(UserHandle.ALL, 0);
- context.sendBroadcastWithMultiplePermissions(
- intent, receiverPermissionsForTetheringRequest);
+ context.sendBroadcastWithMultiplePermissions(intent, permissions);
return true;
}
+ private void sendBroadcastWithMainlineNetworkStackPermissionPostU() {
+ String[] receiverPermissions = RECEIVER_PERMISSIONS_MAINLINE_NETWORK_STACK;
+ Intent intent = getP2pConnectionChangedIntent();
+ // Adding the flag to allow recipient to run at foreground priority with a shorter
+ // timeout interval.
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ Log.i(TAG, "sending p2p connection changed broadcast with permission "
+ + Arrays.toString(receiverPermissions));
+ Context context = mContext.createContextAsUser(UserHandle.ALL, 0);
+ context.sendBroadcastWithMultiplePermissions(intent, receiverPermissions);
+ }
+
private void sendP2pPersistentGroupsChangedBroadcast() {
+ onPersistentGroupsChanged(new WifiP2pGroupList(mGroups, null));
if (mVerboseLoggingEnabled) logd("sending p2p persistent groups changed broadcast");
Intent intent = new Intent(WifiP2pManager.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -6170,7 +6944,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return true;
}
- private void handleGroupCreationFailure() {
+ private void handleGroupCreationFailure(
+ @WifiP2pManager.GroupCreationFailureReason int reason) {
// A group is formed, but the tethering request is not proceed.
if (null != mGroup) {
// Clear any timeout that was set. This is essential for devices
@@ -6181,6 +6956,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
resetWifiP2pInfo();
mDetailedState = NetworkInfo.DetailedState.FAILED;
+ onGroupCreationFailed(reason);
sendP2pConnectionChangedBroadcast();
// Remove only the peer we failed to connect to so that other devices discovered
@@ -6309,12 +7085,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
@Override
protected void logd(String s) {
- Log.d(TAG, s);
+ Log.d(TAG, s, null);
}
@Override
protected void loge(String s) {
- Log.e(TAG, s);
+ Log.e(TAG, s, null);
}
/**
@@ -6688,11 +7464,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private boolean p2pFind(int timeout) {
return p2pFind(
WifiP2pManager.WIFI_P2P_SCAN_FULL,
- WifiP2pManager.WIFI_P2P_SCAN_FREQ_UNSPECIFIED, timeout);
+ WifiP2pManager.WIFI_P2P_SCAN_FREQ_UNSPECIFIED, timeout, null);
}
private boolean p2pFind(@WifiP2pManager.WifiP2pScanType int scanType, int freq,
- int timeout) {
+ int timeout, @Nullable WifiP2pDiscoveryConfig discoveryConfig) {
if (isFeatureSupported(WifiP2pManager.FEATURE_SET_VENDOR_ELEMENTS)) {
Set<ScanResult.InformationElement> aggregatedVendorElements = new HashSet<>();
mVendorElements.forEach((k, v) -> aggregatedVendorElements.addAll(v));
@@ -6710,6 +7486,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
} else if (scanType == WifiP2pManager.WIFI_P2P_SCAN_SINGLE_FREQ
&& freq != WifiP2pManager.WIFI_P2P_SCAN_FREQ_UNSPECIFIED) {
return mWifiNative.p2pFind(scanType, freq, timeout);
+ } else if (scanType == WifiP2pManager.WIFI_P2P_SCAN_WITH_CONFIG_PARAMS
+ && discoveryConfig != null) {
+ return mWifiNative.p2pFindWithParams(discoveryConfig, timeout);
}
return false;
}
@@ -6903,6 +7682,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return false;
}
+ if (TextUtils.isEmpty(mSavedPeerConfig.deviceAddress)) {
+ logd("Saved peer address is empty");
+ return false;
+ }
+
if (!devAddr.equals(MacAddress.fromString(mSavedPeerConfig.deviceAddress))) {
logd("Saved peer address is different from " + devAddr);
return false;
diff --git a/service/java/com/android/server/wifi/rtt/RttServiceImpl.java b/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
index 99899c3f3b..85e5e65c50 100644
--- a/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
+++ b/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
@@ -19,6 +19,7 @@ package com.android.server.wifi.rtt;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
import static android.net.wifi.rtt.WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_LCI;
import static android.net.wifi.rtt.WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_LCR;
+import static android.net.wifi.rtt.WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR;
import static android.net.wifi.rtt.WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_ONE_SIDED_RTT;
import static android.net.wifi.rtt.WifiRttManager.CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER;
@@ -237,6 +238,8 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
j.put("lcrSupported", mCapabilities.lcrSupported);
j.put("responderSupported", mCapabilities.responderSupported);
j.put("mcVersion", mCapabilities.mcVersion);
+ j.put("ntbInitiatorSupported", mCapabilities.ntbInitiatorSupported);
+ j.put("ntbResponderSupported", mCapabilities.ntbResponderSupported);
} catch (JSONException e) {
Log.e(TAG, "onCommand: get_capabilities e=" + e);
}
@@ -478,10 +481,30 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
characteristics.putBoolean(CHARACTERISTICS_KEY_BOOLEAN_LCR, capabilities.lcrSupported);
characteristics.putBoolean(CHARACTERISTICS_KEY_BOOLEAN_STA_RESPONDER,
capabilities.responderSupported);
+ characteristics.putBoolean(CHARACTERISTICS_KEY_BOOLEAN_NTB_INITIATOR,
+ capabilities.ntbInitiatorSupported);
return characteristics;
}
/**
+ * Override IEEE 802.11az parameters with overlay values.
+ */
+ private void override11azOverlays(RangingRequest rangingRequest) {
+ int minNtbTime = mContext.getResources().getInteger(
+ R.integer.config_wifi80211azMinTimeBetweenNtbMeasurementsMicros);
+ int maxNtbTime = mContext.getResources().getInteger(
+ R.integer.config_wifi80211azMaxTimeBetweenNtbMeasurementsMicros);
+ if (minNtbTime > 0 || maxNtbTime > 0) {
+ for (ResponderConfig peer : rangingRequest.mRttPeers) {
+ if (peer.is80211azNtbSupported()) {
+ if (maxNtbTime > 0) peer.setNtbMaxTimeBetweenMeasurementsMicros(maxNtbTime);
+ if (minNtbTime > 0) peer.setNtbMinTimeBetweenMeasurementsMicros(minNtbTime);
+ }
+ }
+ }
+ }
+
+ /**
* Binder interface API to start a ranging operation. Called on binder thread, operations needs
* to be posted to handler thread.
*/
@@ -584,6 +607,8 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
return;
}
+ override11azOverlays(request);
+
mRttServiceSynchronized.mHandler.post(() -> {
WorkSource sourceToUse = ws;
if (ws == null || ws.isEmpty()) {
@@ -1166,11 +1191,24 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
+ "address for peerId=" + rttPeer.peerHandle.peerId);
continue;
}
- newRequestBuilder.addResponder(new ResponderConfig(
- MacAddress.fromBytes(mac),
- rttPeer.peerHandle, rttPeer.responderType, rttPeer.supports80211mc,
- rttPeer.channelWidth, rttPeer.frequency, rttPeer.centerFreq0,
- rttPeer.centerFreq1, rttPeer.preamble));
+ // To create a ResponderConfig object with both a MAC address and peer
+ // handler, we're bypassing the standard Builder pattern and directly using
+ // the constructor. This is because the SDK's Builder.build() method has a
+ // built-in restriction that prevents setting both properties simultaneously.
+ // To avoid triggering this exception, we're directly invoking the
+ // constructor to accommodate both values.
+ ResponderConfig.Builder responderConfigBuilder = new ResponderConfig.Builder()
+ .setMacAddress(MacAddress.fromBytes(mac))
+ .setPeerHandle(rttPeer.peerHandle)
+ .setResponderType(rttPeer.getResponderType())
+ .set80211mcSupported(rttPeer.is80211mcSupported())
+ .set80211azNtbSupported(rttPeer.is80211azNtbSupported())
+ .setChannelWidth(rttPeer.getChannelWidth())
+ .setFrequencyMhz(rttPeer.getFrequencyMhz())
+ .setCenterFreq1Mhz(rttPeer.getCenterFreq1Mhz())
+ .setCenterFreq0Mhz(rttPeer.getCenterFreq0Mhz())
+ .setPreamble(rttPeer.getPreamble());
+ newRequestBuilder.addResponder(new ResponderConfig(responderConfigBuilder));
} else {
newRequestBuilder.addResponder(rttPeer);
}
@@ -1271,32 +1309,15 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "postProcessResults: missing=" + peer.macAddress);
}
-
- int errorCode = RangingResult.STATUS_FAIL;
-
+ RangingResult.Builder builder = new RangingResult.Builder()
+ .setStatus(RangingResult.STATUS_FAIL);
if (peer.peerHandle == null) {
- finalResults.add(
- new RangingResult(errorCode, peer.macAddress, 0, 0, 0, 0, 0, null,
- null, null, 0, false));
+ builder.setMacAddress(peer.getMacAddress());
} else {
- finalResults.add(
- new RangingResult(
- errorCode,
- peer.peerHandle,
- 0,
- 0,
- 0,
- 0,
- 0,
- null,
- null,
- null,
- 0,
- RangingResult.UNSPECIFIED,
- RangingResult.UNSPECIFIED));
+ builder.setPeerHandle(peer.peerHandle);
}
+ finalResults.add(builder.build());
} else {
- int status = RangingResult.STATUS_SUCCESS;
// Clear LCI and LCR data if the location data should not be retransmitted,
// has a retention expiration time, contains no useful data, or did not parse,
@@ -1309,40 +1330,46 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
lci = null;
lcr = null;
}
- // Create external result with external RangResultStatus, cleared LCI and LCR.
+ RangingResult.Builder builder = new RangingResult.Builder();
+ builder.setStatus(RangingResult.STATUS_SUCCESS)
+ .setDistanceMm(resultForRequest.getDistanceMm())
+ .setDistanceStdDevMm(resultForRequest.getDistanceStdDevMm())
+ .setRssi(resultForRequest.getRssi())
+ .setNumAttemptedMeasurements(
+ resultForRequest.getNumAttemptedMeasurements())
+ .setNumSuccessfulMeasurements(
+ resultForRequest.getNumSuccessfulMeasurements())
+ .setLci(lci)
+ .setLcr(lcr)
+ .setUnverifiedResponderLocation(responderLocation)
+ .setRangingTimestampMillis(resultForRequest.getRangingTimestampMillis())
+ .set80211mcMeasurement(resultForRequest.is80211mcMeasurement())
+ .setMeasurementChannelFrequencyMHz(
+ resultForRequest.getMeasurementChannelFrequencyMHz())
+ .setMeasurementBandwidth(resultForRequest.getMeasurementBandwidth())
+ .set80211azNtbMeasurement(resultForRequest.is80211azNtbMeasurement())
+ .setMinTimeBetweenNtbMeasurementsMicros(
+ resultForRequest.getMinTimeBetweenNtbMeasurementsMicros())
+ .setMaxTimeBetweenNtbMeasurementsMicros(
+ resultForRequest.getMaxTimeBetweenNtbMeasurementsMicros())
+ .set80211azInitiatorTxLtfRepetitionsCount(
+ resultForRequest.get80211azInitiatorTxLtfRepetitionsCount())
+ .set80211azResponderTxLtfRepetitionsCount(
+ resultForRequest.get80211azResponderTxLtfRepetitionsCount())
+ .set80211azNumberOfTxSpatialStreams(
+ resultForRequest.get80211azNumberOfTxSpatialStreams())
+ .set80211azNumberOfRxSpatialStreams(
+ resultForRequest.get80211azNumberOfRxSpatialStreams());
if (peer.peerHandle == null) {
- finalResults.add(new RangingResult(
- status,
- peer.macAddress,
- resultForRequest.mDistanceMm,
- resultForRequest.mDistanceStdDevMm,
- resultForRequest.mRssi,
- resultForRequest.mNumAttemptedMeasurements,
- resultForRequest.mNumSuccessfulMeasurements,
- lci,
- lcr,
- responderLocation,
- resultForRequest.mTimestamp,
- resultForRequest.mIs80211mcMeasurement,
- resultForRequest.mFrequencyMHz,
- resultForRequest.mPacketBw));
+ builder.setMacAddress(peer.getMacAddress());
} else {
- finalResults.add(
- new RangingResult(
- status,
- peer.peerHandle,
- resultForRequest.mDistanceMm,
- resultForRequest.mDistanceStdDevMm,
- resultForRequest.mRssi,
- resultForRequest.mNumAttemptedMeasurements,
- resultForRequest.mNumSuccessfulMeasurements,
- lci,
- lcr,
- responderLocation,
- resultForRequest.mTimestamp,
- resultForRequest.mFrequencyMHz,
- resultForRequest.mPacketBw));
+ builder.setPeerHandle(peer.peerHandle);
+ }
+ if (SdkLevel.isAtLeastV() && resultForRequest.getVendorData() != null
+ && !resultForRequest.getVendorData().isEmpty()) {
+ builder.setVendorData(resultForRequest.getVendorData());
}
+ finalResults.add(builder.build());
}
}
return finalResults;
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 5a32c57bb8..77383f643b 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -28,6 +28,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.net.wifi.IScanDataListener;
import android.net.wifi.IWifiScanner;
import android.net.wifi.IWifiScannerListener;
import android.net.wifi.ScanResult;
@@ -64,6 +65,7 @@ import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.ClientModeImpl;
import com.android.server.wifi.Clock;
import com.android.server.wifi.DeviceConfigFacade;
+import com.android.server.wifi.WifiGlobals;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiLocalServices;
import com.android.server.wifi.WifiLog;
@@ -87,7 +89,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.NoSuchElementException;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@@ -106,17 +108,17 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private void localLog(String message) {
mLocalLog.log(message);
if (isVerboseLoggingEnabled()) {
- Log.i(TAG, message);
+ Log.i(TAG, message, null);
}
}
private void logw(String message) {
- Log.w(TAG, message);
+ Log.w(TAG, message, null);
mLocalLog.log(message);
}
private void loge(String message) {
- Log.e(TAG, message);
+ Log.e(TAG, message, null);
mLocalLog.log(message);
}
@@ -456,6 +458,28 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
new ArrayList<ScanResult>());
}
+
+ /**
+ * See {@link WifiScanner#getCachedScanData(Executor, Consumer)}.
+ */
+ @Override
+ public void getCachedScanData(String packageName, String featureId,
+ IScanDataListener listener) {
+ localLog("get single scan result: package " + packageName
+ + " AttributionTag " + featureId);
+ final int uid = Binder.getCallingUid();
+ Objects.requireNonNull(listener, "listener cannot be null");
+ enforcePermission(uid, packageName, featureId, false, false, false);
+
+ mWifiThreadRunner.post(() -> {
+ try {
+ listener.onResult(mWifiNative.getCachedScanResultsFromAllClientIfaces());
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage(), e);
+ }
+ });
+ }
+
@Override
public void startPnoScan(IWifiScannerListener listener, WifiScanner.ScanSettings scanSettings,
WifiScanner.PnoSettings pnoSettings, String packageName, String featureId) {
@@ -665,6 +689,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private final WifiManager mWifiManager;
private final LastCallerInfoManager mLastCallerInfoManager;
private final DeviceConfigFacade mDeviceConfigFacade;
+ private final WifiGlobals mWifiGlobals;
private AtomicBoolean mVerboseLoggingEnabled = new AtomicBoolean(false);
@@ -685,6 +710,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
mWifiPermissionsUtil = wifiInjector.getWifiPermissionsUtil();
mWifiNative = wifiInjector.getWifiNative();
mDeviceConfigFacade = wifiInjector.getDeviceConfigFacade();
+ mWifiGlobals = wifiInjector.getWifiGlobals();
// Wifi service is always started before other wifi services. So, there is no problem
// obtaining WifiManager in the constructor here.
mWifiManager = mContext.getSystemService(WifiManager.class);
@@ -1561,7 +1587,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
"reason=" + reason + ", " + description);
try {
entry.clientInfo.mListener.onFailure(reason, description);
- } catch (RemoteException e) {
+ } catch (Exception e) {
loge("Failed to call onFailure: " + entry.clientInfo);
}
entry.clientInfo.unregister();
@@ -1822,6 +1848,10 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
case WifiScanner.CMD_GET_SCAN_RESULTS:
ScanParams scanParams = (ScanParams) msg.obj;
ClientInfo ci = mClients.get(scanParams.listener);
+ if (ci == null) {
+ loge("ClientInfo is null");
+ break;
+ }
ci.replyFailed(WifiScanner.REASON_UNSPECIFIED, "not available");
break;
@@ -1873,6 +1903,10 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
ScanParams scanParams = (ScanParams) msg.obj;
mWifiMetrics.incrementBackgroundScanCount();
ClientInfo ci = mClients.get(scanParams.listener);
+ if (ci == null) {
+ loge("ClientInfo is null");
+ return HANDLED;
+ }
if (scanParams.settings == null) {
loge("params null");
return HANDLED;
@@ -2422,8 +2456,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
scanParams.pnoSettings.isConnected)) {
deferMessage(msg);
transitionTo(mHwPnoScanState);
- } else if (mContext.getResources().getBoolean(
- R.bool.config_wifiSwPnoEnabled)
+ } else if (mWifiGlobals.isSwPnoEnabled()
&& mDeviceConfigFacade.isSoftwarePnoEnabled()) {
deferMessage(msg);
transitionTo(mSwPnoScanState);
@@ -3082,7 +3115,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
try {
mListener.asBinder().unlinkToDeath(mDeathRecipient, 0);
- } catch (NoSuchElementException e) {
+ } catch (Exception e) {
Log.e(TAG, "Failed to unregister death recipient! " + mListener);
}
@@ -3154,7 +3187,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
try {
mListener.onSuccess();
mLog.trace("onSuccess").flush();
- } catch (RemoteException e) {
+ } catch (Exception e) {
// There's not much we can do if reply can't be sent!
}
} else {
@@ -3170,7 +3203,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
.c(reason)
.c(description)
.flush();
- } catch (RemoteException e) {
+ } catch (Exception e) {
// There's not much we can do if reply can't be sent!
}
} else {
diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
index 96c2984873..799e530986 100644
--- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
+++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
@@ -440,12 +440,14 @@ public class ApConfigUtil {
// If HAL doesn't support getUsableChannels then return null
return null;
}
- List<Integer> regulatoryList = usableChannelList.stream()
- .map(ch -> inFrequencyMHz
- ? ch.getFrequencyMhz()
- : ScanResult.convertFrequencyMhzToChannelIfSupported(
- ch.getFrequencyMhz()))
- .collect(Collectors.toList());
+ List<Integer> regulatoryList = new ArrayList<>();
+ if (inFrequencyMHz) {
+ usableChannelList.forEach(a -> regulatoryList.add(a.getFrequencyMhz()));
+ } else {
+ usableChannelList.forEach(a -> regulatoryList.add(ScanResult
+ .convertFrequencyMhzToChannelIfSupported(a.getFrequencyMhz())));
+
+ }
return addDfsChannelsIfNeeded(regulatoryList, scannerBand, wifiNative, resources,
inFrequencyMHz);
}
@@ -1086,6 +1088,19 @@ public class ApConfigUtil {
}});
}
+ /**
+ * Helper function to get whether or not device claim support bridged AP.
+ * (i.e. In resource file)
+ *
+ * @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(
+ R.bool.config_wifiBridgedSoftApSupported);
+ }
+
+
/**
* Helper function to get HAL support STA + bridged AP or not.
*
@@ -1521,20 +1536,31 @@ public class ApConfigUtil {
return deepCopyMap;
}
-
/**
* Observer the available channel from native layer (vendor HAL if getUsableChannels is
* supported, or wificond if not supported) and update the SoftApCapability
*
* @param softApCapability the current softap capability
* @param context the caller context used to get value from resource file
- * @param wifiNative reference used to collect regulatory restrictions. *
+ * @param wifiNative reference used to collect regulatory restrictions.
+ * @param channelMap the channel for each band
* @return updated soft AP capability
*/
public static SoftApCapability updateSoftApCapabilityWithAvailableChannelList(
@NonNull SoftApCapability softApCapability, @NonNull Context context,
- @NonNull WifiNative wifiNative) {
+ @NonNull WifiNative wifiNative, @NonNull SparseArray<int[]> channelMap) {
SoftApCapability newSoftApCapability = new SoftApCapability(softApCapability);
+ if (channelMap != null) {
+ for (int band : SoftApConfiguration.BAND_TYPES) {
+ if (isSoftApBandSupported(context, band)) {
+ int[] supportedChannelList = channelMap.get(band);
+ if (supportedChannelList != null) {
+ newSoftApCapability.setSupportedChannelList(band, supportedChannelList);
+ }
+ }
+ }
+ return newSoftApCapability;
+ }
List<Integer> supportedChannelList = null;
for (int band : SoftApConfiguration.BAND_TYPES) {
diff --git a/service/java/com/android/server/wifi/util/HalAidlUtil.java b/service/java/com/android/server/wifi/util/HalAidlUtil.java
index e845446858..500a3d862d 100644
--- a/service/java/com/android/server/wifi/util/HalAidlUtil.java
+++ b/service/java/com/android/server/wifi/util/HalAidlUtil.java
@@ -16,8 +16,12 @@
package com.android.server.wifi.util;
+import android.annotation.NonNull;
+import android.hardware.wifi.WifiChannelWidthInMhz;
import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.KeyMgmtMask;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiAnnotations;
import android.net.wifi.WifiConfiguration;
import android.util.Log;
@@ -118,4 +122,47 @@ public class HalAidlUtil {
}
return halList.toArray(new OuiKeyedData[halList.size()]);
}
+
+ /**
+ * Convert a list of HAL OuiKeyedData its framework equivalent.
+ */
+ public static List<android.net.wifi.OuiKeyedData> halToFrameworkOuiKeyedDataList(
+ @NonNull OuiKeyedData[] halList) {
+ if (halList == null) {
+ return new ArrayList<>();
+ }
+ List<android.net.wifi.OuiKeyedData> frameworkList = new ArrayList<>();
+ for (OuiKeyedData halData : halList) {
+ try {
+ android.net.wifi.OuiKeyedData frameworkData =
+ new android.net.wifi.OuiKeyedData.Builder(
+ halData.oui, halData.vendorData).build();
+ frameworkList.add(frameworkData);
+ } catch (Exception e) {
+ Log.e(TAG, "Invalid HAL OuiKeyedData: " + e);
+ }
+ }
+ return frameworkList;
+ }
+
+ /**
+ * Convert HAL channelBandwidth to framework enum
+ */
+ @WifiAnnotations.ChannelWidth
+ public static int getChannelBandwidthFromHal(int channelBandwidth) {
+ switch (channelBandwidth) {
+ case WifiChannelWidthInMhz.WIDTH_40:
+ return ScanResult.CHANNEL_WIDTH_40MHZ;
+ case WifiChannelWidthInMhz.WIDTH_80:
+ return ScanResult.CHANNEL_WIDTH_80MHZ;
+ case WifiChannelWidthInMhz.WIDTH_160:
+ return ScanResult.CHANNEL_WIDTH_160MHZ;
+ case WifiChannelWidthInMhz.WIDTH_80P80:
+ return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
+ case WifiChannelWidthInMhz.WIDTH_320:
+ return ScanResult.CHANNEL_WIDTH_320MHZ;
+ default:
+ return ScanResult.CHANNEL_WIDTH_20MHZ;
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/util/InformationElementUtil.java b/service/java/com/android/server/wifi/util/InformationElementUtil.java
index b6e991c146..57643b9c01 100644
--- a/service/java/com/android/server/wifi/util/InformationElementUtil.java
+++ b/service/java/com/android/server/wifi/util/InformationElementUtil.java
@@ -15,6 +15,7 @@
*/
package com.android.server.wifi.util;
+import android.hardware.wifi.WifiBand;
import android.net.MacAddress;
import android.net.wifi.MloLink;
import android.net.wifi.ScanResult;
@@ -27,6 +28,7 @@ import android.net.wifi.nl80211.NativeScanResult;
import android.net.wifi.nl80211.WifiNl80211Manager;
import android.net.wifi.util.HexEncoding;
import android.util.Log;
+import android.util.SparseIntArray;
import com.android.server.wifi.ByteBufferReader;
import com.android.server.wifi.MboOceConstants;
@@ -833,10 +835,21 @@ public class InformationElementUtil {
private static final int EHT_OPERATION_INFO_START_INDEX = EHT_OPERATION_BASIC_LENGTH;
private static final int DISABLED_SUBCHANNEL_BITMAP_START_INDEX =
EHT_OPERATION_INFO_START_INDEX + 3;
+ private static final int CHANNEL_WIDTH_INDEX = EHT_OPERATION_INFO_START_INDEX + 0;
+ private static final int CHANNEL_WIDTH_MASK = 0xF;
+ private static final int CHANNEL_CENTER_FREQ_SEG0_INDEX =
+ EHT_OPERATION_INFO_START_INDEX + 1;
+ private static final int CHANNEL_CENTER_FREQ_SEG_MASK = 0xFF;
+ private static final int CHANNEL_CENTER_FREQ_SEG1_INDEX =
+ EHT_OPERATION_INFO_START_INDEX + 2;
+
private boolean mPresent = false;
private boolean mEhtOperationInfoPresent = false;
private boolean mDisabledSubchannelBitmapPresent = false;
private byte[] mDisabledSubchannelBitmap;
+ private int mChannelWidth;
+ private int mCenterFreqSeg0;
+ private int mCenterFreqSeg1;
/**
* Returns whether the EHT Information Element is present.
@@ -868,6 +881,69 @@ public class InformationElementUtil {
}
/**
+ * @return Channel width if EHT Operation Information Present.
+ */
+ public int getChannelWidth() {
+ /*
+ * Channel width in EHT operation Info is set,
+ * 0 for 20 MHz EHT BSS bandwidth.
+ * 1 for 40 MHz EHT BSS bandwidth.
+ * 2 for 80 MHz EHT BSS bandwidth.
+ * 3 for 160 MHz EHT BSS bandwidth.
+ * 4 for 320 MHz EHT BSS bandwidth.
+ * Values in the ranges 5 to 7 are reserved.
+ */
+ switch(mChannelWidth) {
+ case 0: return ScanResult.CHANNEL_WIDTH_20MHZ;
+ case 1: return ScanResult.CHANNEL_WIDTH_40MHZ;
+ case 2: return ScanResult.CHANNEL_WIDTH_80MHZ;
+ case 3: return ScanResult.CHANNEL_WIDTH_160MHZ;
+ case 4: return ScanResult.CHANNEL_WIDTH_320MHZ;
+ default:
+ return ScanResult.UNSPECIFIED;
+ }
+ }
+
+ /**
+ * Returns Channel Center Frequency Segment 0 (CCFS0).
+ *
+ * - For 20, 40 or 80 MHz BSS bandwidth, indicates the channel center frequency for the
+ * 20, 40 or 80 MHz channel on which the EHT BSS operates.
+ * - For 160 MHz BSS bandwidth, indicates the channel center frequency of the primary 80
+ * MHz channel.
+ * - For 320 MHz BSS bandwidth, indicates the channel center frequency of the primary 160
+ * MHz channel.
+ *
+ * @param band Operating band
+ * @return Center frequency.
+ */
+ public int getCenterFreq0(@ScanResult.WifiBand int band) {
+ if (mCenterFreqSeg0 == 0 || band == WifiBand.BAND_UNSPECIFIED) {
+ return ScanResult.UNSPECIFIED;
+ }
+ return ScanResult.convertChannelToFrequencyMhzIfSupported(mCenterFreqSeg0, band);
+ }
+
+ /**
+ * Returns Channel Center Frequency Segment 1 (CCFS1)
+ *
+ * - For a 20, 40 or 80 MHz BSS bandwidth, returns {@link ScanResult#UNSPECIFIED} .
+ * - For a 160 MHz BSS bandwidth, returns the channel center frequency of the 160 MHz
+ * channel on which the EHT BSS operates.
+ * - For a 320 MHz BSS bandwidth, returns the channel center frequency of the 320 MHz
+ * channel on which the EHT BSS operates
+ *
+ * @param band Operating band
+ * @return Center frequency.
+ */
+ public int getCenterFreq1(@ScanResult.WifiBand int band) {
+ if (mCenterFreqSeg1 == 0 || band == WifiBand.BAND_UNSPECIFIED) {
+ return ScanResult.UNSPECIFIED;
+ }
+ return ScanResult.convertChannelToFrequencyMhzIfSupported(mCenterFreqSeg1, band);
+ }
+
+ /**
* Parse EHT Operation IE
*/
public void from(InformationElement ie) {
@@ -899,6 +975,14 @@ public class InformationElementUtil {
}
mPresent = true;
+ if (mEhtOperationInfoPresent) {
+ mChannelWidth = ie.bytes[CHANNEL_WIDTH_INDEX] & CHANNEL_WIDTH_MASK;
+ mCenterFreqSeg0 =
+ ie.bytes[CHANNEL_CENTER_FREQ_SEG0_INDEX] & CHANNEL_CENTER_FREQ_SEG_MASK;
+ mCenterFreqSeg1 =
+ ie.bytes[CHANNEL_CENTER_FREQ_SEG1_INDEX] & CHANNEL_CENTER_FREQ_SEG_MASK;
+ }
+
if (mDisabledSubchannelBitmapPresent) {
mDisabledSubchannelBitmap = new byte[2];
System.arraycopy(ie.bytes, DISABLED_SUBCHANNEL_BITMAP_START_INDEX,
@@ -1689,7 +1773,7 @@ public class InformationElementUtil {
private static final int FILS_CAPABILITY_BIT = 72;
private static final int TWT_REQUESTER_CAPABILITY_BIT = 77;
private static final int TWT_RESPONDER_CAPABILITY_BIT = 78;
- private static final int NO_TB_RANGING_RESPONDER = 90;
+ private static final int NON_TB_RANGING_RESPONDER = 90;
private static final int TB_RANGING_RESPONDER = 91;
public BitSet capabilitiesBitSet;
@@ -1698,7 +1782,7 @@ public class InformationElementUtil {
* @return true if Trigger based ranging responder supported. Refer P802.11az/D7.0,
* September 2022, section 9.4.2.26 Extended Capabilities element.
*/
- public boolean isTriggerBasedRangingRespSupported() {
+ public boolean is80211azTbResponder() {
return capabilitiesBitSet.get(TB_RANGING_RESPONDER);
}
@@ -1706,8 +1790,8 @@ public class InformationElementUtil {
* @return true if Non trigger based ranging responder supported. Refer P802.11az/D7.0,
* September 2022, section 9.4.2.26 Extended Capabilities element.
*/
- public boolean isNonTriggerBasedRangingRespSupported() {
- return capabilitiesBitSet.get(NO_TB_RANGING_RESPONDER);
+ public boolean is80211azNtbResponder() {
+ return capabilitiesBitSet.get(NON_TB_RANGING_RESPONDER);
}
/**
@@ -1843,7 +1927,7 @@ public class InformationElementUtil {
//
// Note: InformationElement.bytes has 'Element ID' and 'Length'
// stripped off already
- private void parseRsnElement(InformationElement ie) {
+ private void parseRsnElement(InformationElement ie, SparseIntArray unknownAkmMap) {
ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN);
try {
@@ -1924,9 +2008,13 @@ public class InformationElementUtil {
case RSN_AKM_DPP:
rsnKeyManagement.add(ScanResult.KEY_MGMT_DPP);
break;
- default:
- rsnKeyManagement.add(ScanResult.KEY_MGMT_UNKNOWN);
+ default: {
+ int akmScheme =
+ getScanResultAkmSchemeOfUnknownAkmIfConfigured(
+ akm, unknownAkmMap);
+ rsnKeyManagement.add(akmScheme);
break;
+ }
}
}
// Default AKM
@@ -1961,6 +2049,27 @@ public class InformationElementUtil {
}
}
+ /**
+ * Get the ScanResult security key management scheme (ScanResult.KEY_MGMT_XX) corresponding
+ * to the unknown AKMs configured in overlay config item
+ * config_wifiUnknownAkmToKnownAkmMapping
+ *
+ * @param unknownAkm unknown AKM seen in the received beacon or probe response.
+ * @param unknownAkmMap unknownAkmMap Mapping of unknown AKMs configured in overlay config
+ * item config_wifiUnknownAkmToKnownAkmMapping to ScanResult security key management
+ * scheme (ScanResult.KEY_MGMT_XX).
+ * @return A valid ScanResult.KEY_MGMT_XX if unknownAkm is configured in the overlay,
+ * ScanResult.KEY_MGMT_UNKNOWN otherwise
+ */
+ private int getScanResultAkmSchemeOfUnknownAkmIfConfigured(
+ int unknownAkm, SparseIntArray unknownAkmMap) {
+ if (unknownAkmMap != null) {
+ return unknownAkmMap.get(unknownAkm, ScanResult.KEY_MGMT_UNKNOWN);
+ } else {
+ return ScanResult.KEY_MGMT_UNKNOWN;
+ }
+ }
+
private static @Cipher int parseWpaCipher(int cipher) {
switch (cipher) {
case WPA_CIPHER_NONE:
@@ -2040,7 +2149,7 @@ public class InformationElementUtil {
// Note: InformationElement.bytes has 'Element ID' and 'Length'
// stripped off already
//
- private void parseWpaOneElement(InformationElement ie) {
+ private void parseWpaOneElement(InformationElement ie, SparseIntArray unknownAkmMap) {
ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN);
try {
@@ -2085,7 +2194,10 @@ public class InformationElementUtil {
wpaKeyManagement.add(ScanResult.KEY_MGMT_PSK);
break;
default:
- wpaKeyManagement.add(ScanResult.KEY_MGMT_UNKNOWN);
+ int akmScheme =
+ getScanResultAkmSchemeOfUnknownAkmIfConfigured(
+ akm, unknownAkmMap);
+ wpaKeyManagement.add(akmScheme);
break;
}
}
@@ -2100,19 +2212,24 @@ public class InformationElementUtil {
}
/**
- * Parse the Information Element and the 16-bit Capability Information field
- * to build the InformationElemmentUtil.capabilities object.
+ * Parse the Information Element and the 16-bit Capability Information field to build the
+ * InformationElemmentUtil.capabilities object.
*
- * @param ies -- Information Element array
- * @param beaconCap -- 16-bit Beacon Capability Information field
+ * @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 freq -- Frequency on which frame/beacon was transmitted.
- * Some parsing may be affected such as DMG parameters in
- * DMG (60GHz) beacon.
+ * @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
+ * security key management scheme(ScanResult.KEY_MGMT_XX)) configured in overlay config
+ * item config_wifiUnknownAkmToKnownAkmMapping.
*/
-
- public void from(InformationElement[] ies, int beaconCap, boolean isOweSupported,
- int freq) {
+ public void from(
+ InformationElement[] ies,
+ int beaconCap,
+ boolean isOweSupported,
+ int freq,
+ SparseIntArray unknownAkmMap) {
protocol = new ArrayList<>();
keyManagement = new ArrayList<>();
groupCipher = new ArrayList<>();
@@ -2148,12 +2265,12 @@ public class InformationElementUtil {
}
if (ie.id == InformationElement.EID_RSN) {
- parseRsnElement(ie);
+ parseRsnElement(ie, unknownAkmMap);
}
if (ie.id == InformationElement.EID_VSA) {
if (isWpaOneElement(ie)) {
- parseWpaOneElement(ie);
+ parseWpaOneElement(ie, unknownAkmMap);
}
if (isWpsElement(ie)) {
// TODO(b/62134557): parse WPS IE to provide finer granularity information.
@@ -2187,6 +2304,48 @@ public class InformationElementUtil {
}
}
+ /** Convert the AKM suite selector to scan result Security key management scheme */
+ public static int akmToScanResultKeyManagementScheme(int akm) {
+ switch (akm) {
+ case RSN_AKM_EAP:
+ case WPA_AKM_EAP:
+ return ScanResult.KEY_MGMT_EAP;
+ case RSN_AKM_PSK:
+ case WPA_AKM_PSK:
+ return ScanResult.KEY_MGMT_PSK;
+ case RSN_AKM_FT_EAP:
+ return ScanResult.KEY_MGMT_FT_EAP;
+ case RSN_AKM_FT_PSK:
+ return ScanResult.KEY_MGMT_FT_PSK;
+ case RSN_AKM_EAP_SHA256:
+ return ScanResult.KEY_MGMT_EAP_SHA256;
+ case RSN_AKM_PSK_SHA256:
+ return ScanResult.KEY_MGMT_PSK_SHA256;
+ case RSN_AKM_SAE:
+ return ScanResult.KEY_MGMT_SAE;
+ case RSN_AKM_FT_SAE:
+ return ScanResult.KEY_MGMT_FT_SAE;
+ case RSN_AKM_SAE_EXT_KEY:
+ return ScanResult.KEY_MGMT_SAE_EXT_KEY;
+ case RSN_AKM_FT_SAE_EXT_KEY:
+ return ScanResult.KEY_MGMT_FT_SAE_EXT_KEY;
+ case RSN_AKM_OWE:
+ return ScanResult.KEY_MGMT_OWE;
+ case RSN_AKM_EAP_SUITE_B_192:
+ return ScanResult.KEY_MGMT_EAP_SUITE_B_192;
+ case RSN_OSEN:
+ return ScanResult.KEY_MGMT_OSEN;
+ case RSN_AKM_EAP_FILS_SHA256:
+ return ScanResult.KEY_MGMT_FILS_SHA256;
+ case RSN_AKM_EAP_FILS_SHA384:
+ return ScanResult.KEY_MGMT_FILS_SHA384;
+ case RSN_AKM_DPP:
+ return ScanResult.KEY_MGMT_DPP;
+ default:
+ return ScanResult.KEY_MGMT_UNKNOWN;
+ }
+ }
+
private static boolean isOweElement(InformationElement ie) {
ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN);
try {
diff --git a/service/java/com/android/server/wifi/util/IpConfigStore.java b/service/java/com/android/server/wifi/util/IpConfigStore.java
index 2a719c4e28..245bcd028b 100644
--- a/service/java/com/android/server/wifi/util/IpConfigStore.java
+++ b/service/java/com/android/server/wifi/util/IpConfigStore.java
@@ -255,10 +255,10 @@ public class IpConfigStore {
}
protected static void loge(String s) {
- Log.e(TAG, s);
+ Log.e(TAG, s, null);
}
protected static void log(String s) {
- Log.d(TAG, s);
+ Log.d(TAG, s, null);
}
}
diff --git a/service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java b/service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java
index a1501e63a4..f556a300f3 100644
--- a/service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java
@@ -53,6 +53,8 @@ public class WifiConfigStoreEncryptionUtil {
private static final int GCM_TAG_LENGTH = 128;
private static final int KEY_LENGTH = 256;
private static final String KEY_STORE = "AndroidKeyStore";
+ private final SecretKey mSecretKeyReference;
+ private Cipher mEncryptCipher;
private final String mDataFileName;
@@ -69,6 +71,16 @@ public class WifiConfigStoreEncryptionUtil {
+ "string");
}
mDataFileName = dataFileName;
+ mSecretKeyReference = getOrCreateSecretKey(getKeyAlias());
+ try {
+ mEncryptCipher = Cipher.getInstance(CIPHER_ALGORITHM);
+ } catch (NoSuchAlgorithmException e) {
+ reportException(e, "encrypt could not find the algorithm: " + CIPHER_ALGORITHM);
+ } catch (NoSuchPaddingException e) {
+ reportException(e, "encrypt had a padding exception");
+ } catch (Exception e) {
+ reportException(e, "exception caught");
+ }
}
private String getKeyAlias() {
@@ -82,27 +94,25 @@ public class WifiConfigStoreEncryptionUtil {
* @return Instance of {@link EncryptedData} containing the encrypted info.
*/
public @Nullable EncryptedData encrypt(byte[] data) {
+ if (data == null || data.length == 0) {
+ return null;
+ }
EncryptedData encryptedData = null;
try {
- Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
- SecretKey secretKeyReference = getOrCreateSecretKey(getKeyAlias());
- if (secretKeyReference != null) {
- cipher.init(Cipher.ENCRYPT_MODE, secretKeyReference);
- encryptedData = new EncryptedData(cipher.doFinal(data), cipher.getIV());
+ if (mSecretKeyReference != null) {
+ mEncryptCipher.init(Cipher.ENCRYPT_MODE, mSecretKeyReference);
+ encryptedData = new EncryptedData(mEncryptCipher.doFinal(data),
+ mEncryptCipher.getIV());
} else {
reportException(new Exception("secretKeyReference is null."),
"secretKeyReference is null.");
}
- } catch (NoSuchAlgorithmException e) {
- reportException(e, "encrypt could not find the algorithm: " + CIPHER_ALGORITHM);
- } catch (NoSuchPaddingException e) {
- reportException(e, "encrypt had a padding exception");
- } catch (InvalidKeyException e) {
- reportException(e, "encrypt received an invalid key");
} catch (BadPaddingException e) {
reportException(e, "encrypt had a padding problem");
} catch (IllegalBlockSizeException e) {
reportException(e, "encrypt had an illegal block size");
+ } catch (InvalidKeyException e) {
+ reportException(e, "encrypt received an invalid key");
} catch (Exception e) {
reportException(e, "exception caught");
}
@@ -120,9 +130,8 @@ public class WifiConfigStoreEncryptionUtil {
try {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, encryptedData.getIv());
- SecretKey secretKeyReference = getOrCreateSecretKey(getKeyAlias());
- if (secretKeyReference != null) {
- cipher.init(Cipher.DECRYPT_MODE, secretKeyReference, spec);
+ if (mSecretKeyReference != null) {
+ cipher.init(Cipher.DECRYPT_MODE, mSecretKeyReference, spec);
decryptedData = cipher.doFinal(encryptedData.getEncryptedData());
}
} catch (NoSuchAlgorithmException e) {
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
index 7c79fafa9d..c7d97cf6ed 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
@@ -753,7 +753,8 @@ public class WifiPermissionsUtil {
private boolean noteAppOpAllowed(String op, String pkgName, @Nullable String featureId,
int uid, @Nullable String message) {
- return mAppOps.noteOp(op, uid, pkgName, featureId, message) == AppOpsManager.MODE_ALLOWED;
+ return mAppOps.noteOpNoThrow(op, uid, pkgName, featureId, message)
+ == AppOpsManager.MODE_ALLOWED;
}
private boolean checkAppOpAllowed(String op, String pkgName, int uid) {
@@ -913,20 +914,6 @@ public class WifiPermissionsUtil {
}
/**
- * Returns true if the |callingUid|/\callingPackage| holds SYSTEM_ALERT_WINDOW permission.
- */
- public boolean checkSystemAlertWindowPermission(int callingUid, String callingPackage) {
- final int mode = mAppOps.noteOp(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, callingUid,
- callingPackage, null, null);
- if (mode == AppOpsManager.MODE_DEFAULT) {
- return mWifiPermissionsWrapper.getUidPermission(
- Manifest.permission.SYSTEM_ALERT_WINDOW, callingUid)
- == PackageManager.PERMISSION_GRANTED;
- }
- return mode == AppOpsManager.MODE_ALLOWED;
- }
-
- /**
* Returns the DevicePolicyManager from context
*/
public static DevicePolicyManager retrieveDevicePolicyManagerFromContext(Context context) {
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
index 47da81f907..e0bb9e5f28 100644
--- a/service/java/com/android/server/wifi/util/XmlUtil.java
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -29,6 +29,7 @@ import android.net.ProxyInfo;
import android.net.RouteInfo;
import android.net.StaticIpConfiguration;
import android.net.Uri;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.ScanResult;
import android.net.wifi.SecurityParams;
import android.net.wifi.SoftApConfiguration;
@@ -39,6 +40,7 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiMigration;
import android.net.wifi.WifiSsid;
import android.os.ParcelUuid;
+import android.os.PersistableBundle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -50,6 +52,8 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
@@ -86,6 +90,11 @@ import java.util.Locale;
public class XmlUtil {
private static final String TAG = "WifiXmlUtil";
+ public static final String XML_TAG_VENDOR_DATA_LIST = "VendorDataList";
+ public static final String XML_TAG_OUI_KEYED_DATA = "OuiKeyedData";
+ public static final String XML_TAG_VENDOR_DATA_OUI = "VendorDataOui";
+ public static final String XML_TAG_PERSISTABLE_BUNDLE = "PersistableBundle";
+
/**
* Ensure that the XML stream is at a start tag or the end of document.
*
@@ -363,6 +372,7 @@ public class XmlUtil {
public static final String XML_TAG_ROAMING_CONSORTIUM_OIS = "RoamingConsortiumOIs";
public static final String XML_TAG_RANDOMIZED_MAC_ADDRESS = "RandomizedMacAddress";
public static final String XML_TAG_MAC_RANDOMIZATION_SETTING = "MacRandomizationSetting";
+ public static final String XML_TAG_SEND_DHCP_HOSTNAME = "SendDhcpHostname";
public static final String XML_TAG_CARRIER_ID = "CarrierId";
public static final String XML_TAG_SUBSCRIPTION_ID = "SubscriptionId";
public static final String XML_TAG_IS_AUTO_JOIN = "AutoJoinEnabled";
@@ -385,11 +395,12 @@ public class XmlUtil {
private static final String XML_TAG_IS_RESTRICTED = "IsRestricted";
private static final String XML_TAG_SUBSCRIPTION_GROUP = "SubscriptionGroup";
public static final String XML_TAG_BSSID_ALLOW_LIST = "bssidAllowList";
- private static final String XML_TAG_IS_REPEATER_ENABLED = "RepeaterEnabled";
+ public static final String XML_TAG_IS_REPEATER_ENABLED = "RepeaterEnabled";
public static final String XML_TAG_DPP_PRIVATE_EC_KEY = "DppPrivateEcKey";
public static final String XML_TAG_DPP_CONNECTOR = "DppConnector";
public static final String XML_TAG_DPP_CSIGN_KEY = "DppCSignKey";
public static final String XML_TAG_DPP_NET_ACCESS_KEY = "DppNetAccessKey";
+ public static final String XML_TAG_ENABLE_WIFI7 = "EnableWifi7";
/**
* Write Wep Keys to the XML stream.
@@ -424,7 +435,7 @@ public class XmlUtil {
EncryptedData[] encryptedDataArray = new EncryptedData[len];
for (int i = 0; i < len; i++) {
if (wepKeys[i] == null) {
- encryptedDataArray[i] = new EncryptedData(null, null);
+ encryptedDataArray[i] = new EncryptedData(new byte[0], new byte[0]);
} else {
encryptedDataArray[i] = encryptionUtil.encrypt(wepKeys[i].getBytes());
if (encryptedDataArray[i] == null) {
@@ -515,7 +526,7 @@ public class XmlUtil {
EncryptedData encryptedData = null;
if (encryptionUtil != null) {
encryptedData = encryptionUtil.encrypt(data);
- if (encryptedData == null) {
+ if (encryptedData == null && data != null && data.length != 0) {
// We silently fail encryption failures!
Log.wtf(TAG, "Encryption of " + tag + " failed");
}
@@ -601,7 +612,10 @@ public class XmlUtil {
configuration.numRebootsSinceLastUse);
XmlUtil.writeNextValue(out, XML_TAG_IS_REPEATER_ENABLED,
configuration.isRepeaterEnabled());
+ XmlUtil.writeNextValue(out, XML_TAG_ENABLE_WIFI7, configuration.isWifi7Enabled());
writeSecurityParamsListToXml(out, configuration);
+ XmlUtil.writeNextValue(out, XML_TAG_SEND_DHCP_HOSTNAME,
+ configuration.isSendDhcpHostnameEnabled());
}
/**
@@ -683,6 +697,9 @@ public class XmlUtil {
.getBssidAllowlistInternal()));
}
writeDppConfigurationToXml(out, configuration, encryptionUtil);
+ if (SdkLevel.isAtLeastV()) {
+ writeVendorDataListToXml(out, configuration.getVendorData());
+ }
}
private static List<String> covertMacAddressListToStringList(List<MacAddress> macList) {
@@ -735,7 +752,12 @@ public class XmlUtil {
List<String> wepKeyList = new ArrayList<>();
final List<EncryptedData> encryptedDataList =
XmlUtil.EncryptedDataXmlUtil.parseListFromXml(in, outerTagDepth);
+ EncryptedData emptyData = new EncryptedData(new byte[0], new byte[0]);
for (int i = 0; i < encryptedDataList.size(); i++) {
+ if (encryptedDataList.get(i).equals(emptyData)) {
+ wepKeyList.add(null);
+ continue;
+ }
byte[] passphraseBytes = encryptionUtil.decrypt(encryptedDataList.get(i));
if (passphraseBytes == null) {
Log.wtf(TAG, "Decryption of passphraseBytes failed");
@@ -851,6 +873,7 @@ public class XmlUtil {
WifiConfiguration configuration = new WifiConfiguration();
String configKeyInData = null;
boolean macRandomizationSettingExists = false;
+ boolean sendDhcpHostnameExists = false;
byte[] dppConnector = null;
byte[] dppCSign = null;
byte[] dppNetAccessKey = null;
@@ -989,6 +1012,10 @@ public class XmlUtil {
configuration.macRandomizationSetting = (int) value;
macRandomizationSettingExists = true;
break;
+ case XML_TAG_SEND_DHCP_HOSTNAME:
+ configuration.setSendDhcpHostnameEnabled((boolean) value);
+ sendDhcpHostnameExists = true;
+ break;
case XML_TAG_CARRIER_ID:
configuration.carrierId = (int) value;
break;
@@ -1048,6 +1075,9 @@ public class XmlUtil {
case XML_TAG_DPP_NET_ACCESS_KEY:
dppNetAccessKey = (byte[]) value;
break;
+ case XML_TAG_ENABLE_WIFI7:
+ configuration.setWifi7Enabled((boolean) value);
+ break;
default:
Log.w(TAG, "Ignoring unknown value name found: " + valueName[0]);
break;
@@ -1102,6 +1132,12 @@ public class XmlUtil {
dppNetAccessKey = readEncrytepdBytesFromXml(encryptionUtil, in,
outerTagDepth);
break;
+ case XML_TAG_VENDOR_DATA_LIST:
+ if (SdkLevel.isAtLeastV()) {
+ configuration.setVendorData(
+ parseVendorDataListFromXml(in, outerTagDepth + 1));
+ }
+ break;
default:
Log.w(TAG, "Ignoring unknown tag found: " + tagName);
break;
@@ -1115,6 +1151,12 @@ public class XmlUtil {
== WifiConfiguration.RANDOMIZATION_PERSISTENT && !fromSuggestion) {
configuration.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO;
}
+ if (!sendDhcpHostnameExists) {
+ // Update legacy configs to send the DHCP hostname for secure networks only.
+ configuration.setSendDhcpHostnameEnabled(
+ !configuration.isSecurityType(WifiConfiguration.SECURITY_TYPE_OPEN)
+ && !configuration.isSecurityType(WifiConfiguration.SECURITY_TYPE_OWE));
+ }
configuration.convertLegacyFieldsToSecurityParamsIfNeeded();
configuration.setDppConnectionKeys(dppConnector, dppCSign, dppNetAccessKey);
return Pair.create(configKeyInData, configuration);
@@ -2154,6 +2196,9 @@ public class XmlUtil {
softApConfig.getPersistentRandomizedMacAddress().toString());
}
}
+ if (SdkLevel.isAtLeastV()) {
+ writeVendorDataListToXml(out, softApConfig.getVendorData());
+ }
} // End of writeSoftApConfigurationToXml
/**
@@ -2349,6 +2394,12 @@ public class XmlUtil {
passphrase = readSoftApPassphraseFromXml(in, outerTagDepth,
shouldExpectEncryptedCredentials, encryptionUtil);
break;
+ case XML_TAG_VENDOR_DATA_LIST:
+ if (SdkLevel.isAtLeastV()) {
+ softApConfigBuilder.setVendorData(
+ parseVendorDataListFromXml(in, outerTagDepth + 1));
+ }
+ break;
default:
Log.w(TAG, "Ignoring unknown tag found: " + tagName);
break;
@@ -2437,5 +2488,118 @@ public class XmlUtil {
return new String(passphraseBytes);
}
}
-}
+ /**
+ * Write the provided vendor data list to XML.
+ *
+ * @param out XmlSerializer instance pointing to the XML stream
+ * @param vendorDataList Vendor data list
+ */
+ private static void writeVendorDataListToXml(
+ XmlSerializer out, List<OuiKeyedData> vendorDataList)
+ throws XmlPullParserException, IOException {
+ if (vendorDataList == null || vendorDataList.isEmpty()) {
+ return;
+ }
+ XmlUtil.writeNextSectionStart(out, XML_TAG_VENDOR_DATA_LIST);
+ for (OuiKeyedData data : vendorDataList) {
+ writeOuiKeyedDataToXml(out, data);
+ }
+ XmlUtil.writeNextSectionEnd(out, XML_TAG_VENDOR_DATA_LIST);
+ }
+
+ private static void writeOuiKeyedDataToXml(
+ XmlSerializer out, OuiKeyedData ouiKeyedData)
+ throws XmlPullParserException, IOException {
+ // PersistableBundle cannot be written directly to XML
+ // Use byte[] as an intermediate data structure
+ if (ouiKeyedData == null) return;
+ byte[] bundleBytes;
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ouiKeyedData.getData().writeToStream(outputStream);
+ bundleBytes = outputStream.toByteArray();
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to write PersistableBundle to byte[]");
+ return;
+ }
+ XmlUtil.writeNextSectionStart(out, XML_TAG_OUI_KEYED_DATA);
+ XmlUtil.writeNextValue(out, XML_TAG_VENDOR_DATA_OUI, ouiKeyedData.getOui());
+ XmlUtil.writeNextValue(out, XML_TAG_PERSISTABLE_BUNDLE, bundleBytes);
+ XmlUtil.writeNextSectionEnd(out, XML_TAG_OUI_KEYED_DATA);
+ }
+
+ /**
+ * Parses the vendor data list from the provided XML stream .
+ *
+ * @param in XmlPullParser instance pointing to the XML stream
+ * @param outerTagDepth depth of the outer tag in the XML document
+ * @return List of OuiKeyedData if successful, empty list otherwise
+ */
+ private static List<OuiKeyedData> parseVendorDataListFromXml(
+ XmlPullParser in, int outerTagDepth)
+ throws XmlPullParserException, IOException, IllegalArgumentException {
+ List<OuiKeyedData> vendorDataList = new ArrayList<>();
+ while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
+ String tagName = in.getName();
+ if (tagName == null) {
+ throw new XmlPullParserException("Unexpected null tag found");
+ }
+ switch (tagName) {
+ case XML_TAG_OUI_KEYED_DATA:
+ OuiKeyedData data = parseOuiKeyedDataFromXml(in, outerTagDepth + 1);
+ if (data != null) {
+ vendorDataList.add(data);
+ }
+ break;
+ default:
+ Log.w(TAG, "Ignoring unknown tag found: " + tagName);
+ break;
+ }
+ }
+ return vendorDataList;
+ }
+
+ private static PersistableBundle readPersistableBundleFromBytes(byte[] bundleBytes) {
+ try {
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bundleBytes);
+ return PersistableBundle.readFromStream(inputStream);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to read PersistableBundle from byte[]");
+ return null;
+ }
+ }
+
+ private static OuiKeyedData parseOuiKeyedDataFromXml(
+ XmlPullParser in, int outerTagDepth)
+ throws XmlPullParserException, IOException, IllegalArgumentException {
+ int oui = 0;
+ PersistableBundle bundle = null;
+
+ while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
+ String[] valueName = new String[1];
+ Object value = XmlUtil.readCurrentValue(in, valueName);
+ if (valueName[0] == null) {
+ throw new XmlPullParserException("Missing value name");
+ }
+ switch (valueName[0]) {
+ case XML_TAG_VENDOR_DATA_OUI:
+ oui = (int) value;
+ break;
+ case XML_TAG_PERSISTABLE_BUNDLE:
+ bundle = readPersistableBundleFromBytes((byte[]) value);
+ break;
+ default:
+ Log.e(TAG, "Unknown value name found: " + valueName[0]);
+ break;
+ }
+ }
+
+ try {
+ return new OuiKeyedData.Builder(oui, bundle).build();
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to build OuiKeyedData");
+ return null;
+ }
+ }
+}
diff --git a/service/proto/src/metrics.proto b/service/proto/src/metrics.proto
index 944ff6b774..9183dc7b4a 100644
--- a/service/proto/src/metrics.proto
+++ b/service/proto/src/metrics.proto
@@ -1463,6 +1463,9 @@ message StaEvent {
// The network has been marked as untrusted.
DISCONNECT_NETWORK_UNTRUSTED = 16;
+
+ // Wi-Fi 7 support for this network has been enabled or disabled.
+ DISCONNECT_NETWORK_WIFI7_TOGGLED = 17;
}
// Authentication Failure reasons as reported through the API.
@@ -2310,8 +2313,8 @@ message WifiRadioUsage {
}
message ExperimentValues {
- // Indicates if we are logging WifiIsUnusableEvent in metrics
- optional bool wifi_is_unusable_logging_enabled = 1;
+ reserved 1;
+ reserved "wifi_is_unusable_logging_enabled";
// Minimum number of txBad to trigger a data stall
optional int32 wifi_data_stall_min_tx_bad = 2;
diff --git a/service/tests/wifitests/Android.bp b/service/tests/wifitests/Android.bp
index 260393243b..9319822b95 100644
--- a/service/tests/wifitests/Android.bp
+++ b/service/tests/wifitests/Android.bp
@@ -98,9 +98,33 @@ android_test {
"com.android.server.wifi.AdaptiveConnectivityEnabledSettingObserver",
"com.android.server.wifi.AdaptiveConnectivityEnabledSettingObserver$*",
"com.android.server.wifi.AdaptiveConnectivityEnabledSettingObserver.**",
+ "com.android.server.wifi.AfcClient",
+ "com.android.server.wifi.AfcClient$*",
+ "com.android.server.wifi.AfcClient.**",
+ "com.android.server.wifi.AfcEllipseLocation",
+ "com.android.server.wifi.AfcEllipseLocation$*",
+ "com.android.server.wifi.AfcEllipseLocation.**",
+ "com.android.server.wifi.AfcLocation",
+ "com.android.server.wifi.AfcLocation$*",
+ "com.android.server.wifi.AfcLocation.**",
+ "com.android.server.wifi.AfcLocationUtil",
+ "com.android.server.wifi.AfcLocationUtil$*",
+ "com.android.server.wifi.AfcLocationUtil.**",
+ "com.android.server.wifi.AfcManager",
+ "com.android.server.wifi.AfcManager$*",
+ "com.android.server.wifi.AfcManager.**",
+ "com.android.server.wifi.AfcServerResponse",
+ "com.android.server.wifi.AfcServerResponse$*",
+ "com.android.server.wifi.AfcServerResponse.**",
"com.android.server.wifi.AggressiveConnectedScore",
"com.android.server.wifi.AggressiveConnectedScore$*",
"com.android.server.wifi.AggressiveConnectedScore.**",
+ "com.android.server.wifi.ApplicationQosPolicyRequestHandler",
+ "com.android.server.wifi.ApplicationQosPolicyRequestHandler$*",
+ "com.android.server.wifi.ApplicationQosPolicyRequestHandler.**",
+ "com.android.server.wifi.ApplicationQosPolicyTrackingTable",
+ "com.android.server.wifi.ApplicationQosPolicyTrackingTable$*",
+ "com.android.server.wifi.ApplicationQosPolicyTrackingTable.**",
"com.android.server.wifi.AssocRejectEventInfo",
"com.android.server.wifi.AssocRejectEventInfo$*",
"com.android.server.wifi.AssocRejectEventInfo.**",
@@ -113,6 +137,9 @@ android_test {
"com.android.server.wifi.BackupManagerProxy",
"com.android.server.wifi.BackupManagerProxy$*",
"com.android.server.wifi.BackupManagerProxy.**",
+ "com.android.server.wifi.BackupRestoreController",
+ "com.android.server.wifi.BackupRestoreController$*",
+ "com.android.server.wifi.BackupRestoreController.**",
"com.android.server.wifi.BubbleFunScorer",
"com.android.server.wifi.BubbleFunScorer$*",
"com.android.server.wifi.BubbleFunScorer.**",
@@ -123,7 +150,7 @@ android_test {
"com.android.server.wifi.ByteBufferReader$*",
"com.android.server.wifi.ByteBufferReader.**",
"com.android.server.wifi.CertificateEventInfo",
- "com.android.server.wifi.CertificateEventInfo*",
+ "com.android.server.wifi.CertificateEventInfo$*",
"com.android.server.wifi.CertificateEventInfo.**",
"com.android.server.wifi.ClientMode",
"com.android.server.wifi.ClientMode$*",
@@ -188,9 +215,6 @@ android_test {
"com.android.server.wifi.DppMetrics",
"com.android.server.wifi.DppMetrics$*",
"com.android.server.wifi.DppMetrics.**",
- "com.android.server.wifi.DtimMultiplierController",
- "com.android.server.wifi.DtimMultiplierController$*",
- "com.android.server.wifi.DtimMultiplierController.**",
"com.android.server.wifi.EapFailureNotifier",
"com.android.server.wifi.EapFailureNotifier$*",
"com.android.server.wifi.EapFailureNotifier.**",
@@ -455,6 +479,9 @@ android_test {
"com.android.server.wifi.ThroughputScorer",
"com.android.server.wifi.ThroughputScorer$*",
"com.android.server.wifi.ThroughputScorer.**",
+ "com.android.server.wifi.TwtManager",
+ "com.android.server.wifi.TwtManager$*",
+ "com.android.server.wifi.TwtManager.**",
"com.android.server.wifi.UntrustedWifiNetworkFactory",
"com.android.server.wifi.UntrustedWifiNetworkFactory$*",
"com.android.server.wifi.UntrustedWifiNetworkFactory.**",
@@ -527,6 +554,9 @@ android_test {
"com.android.server.wifi.WifiDataStall",
"com.android.server.wifi.WifiDataStall$*",
"com.android.server.wifi.WifiDataStall.**",
+ "com.android.server.wifi.WifiDeviceStateChangeManager",
+ "com.android.server.wifi.WifiDeviceStateChangeManager$*",
+ "com.android.server.wifi.WifiDeviceStateChangeManager.**",
"com.android.server.wifi.WifiDiagnostics",
"com.android.server.wifi.WifiDiagnostics$*",
"com.android.server.wifi.WifiDiagnostics.**",
@@ -599,6 +629,12 @@ android_test {
"com.android.server.wifi.WifiPseudonymManager",
"com.android.server.wifi.WifiPseudonymManager$*",
"com.android.server.wifi.WifiPseudonymManager.**",
+ "com.android.server.wifi.WifiPulledAtomLogger",
+ "com.android.server.wifi.WifiPulledAtomLogger$*",
+ "com.android.server.wifi.WifiPulledAtomLogger.**",
+ "com.android.server.wifi.WifiRoamingConfigStore",
+ "com.android.server.wifi.WifiRoamingConfigStore$*",
+ "com.android.server.wifi.WifiRoamingConfigStore.**",
"com.android.server.wifi.WifiScanAlwaysAvailableSettingsCompatibility",
"com.android.server.wifi.WifiScanAlwaysAvailableSettingsCompatibility$*",
"com.android.server.wifi.WifiScanAlwaysAvailableSettingsCompatibility.**",
@@ -614,6 +650,9 @@ android_test {
"com.android.server.wifi.WifiServiceImpl",
"com.android.server.wifi.WifiServiceImpl$*",
"com.android.server.wifi.WifiServiceImpl.**",
+ "com.android.server.wifi.WifiSettingsBackupRestore",
+ "com.android.server.wifi.WifiSettingsBackupRestore$*",
+ "com.android.server.wifi.WifiSettingsBackupRestore.**",
"com.android.server.wifi.WifiSettingsConfigStore",
"com.android.server.wifi.WifiSettingsConfigStore$*",
"com.android.server.wifi.WifiSettingsConfigStore.**",
@@ -686,6 +725,9 @@ android_test {
"com.android.server.wifi.aware.WifiAwareStateManager",
"com.android.server.wifi.aware.WifiAwareStateManager$*",
"com.android.server.wifi.aware.WifiAwareStateManager.**",
+ "com.android.server.wifi.b2b.WifiRoamingModeManager",
+ "com.android.server.wifi.b2b.WifiRoamingModeManager$*",
+ "com.android.server.wifi.b2b.WifiRoamingModeManager.**",
"com.android.server.wifi.coex.CoexManager",
"com.android.server.wifi.coex.CoexManager$*",
"com.android.server.wifi.coex.CoexManager.**",
@@ -1043,6 +1085,9 @@ android_test {
"com.android.server.wifi.hotspot2.soap.command.SppCommand",
"com.android.server.wifi.hotspot2.soap.command.SppCommand$*",
"com.android.server.wifi.hotspot2.soap.command.SppCommand.**",
+ "com.android.server.wifi.mockwifi.MockSupplicantManager",
+ "com.android.server.wifi.mockwifi.MockSupplicantManager$*",
+ "com.android.server.wifi.mockwifi.MockSupplicantManager.**",
"com.android.server.wifi.mockwifi.MockWifiNl80211Manager",
"com.android.server.wifi.mockwifi.MockWifiNl80211Manager$*",
"com.android.server.wifi.mockwifi.MockWifiNl80211Manager.**",
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 bbe67e1b89..fd98347e3b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
@@ -16,6 +16,8 @@
package com.android.server.wifi;
+import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
+import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
@@ -75,6 +77,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.SoftApState;
import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
@@ -452,7 +455,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
private void enterSoftApActiveMode() throws Exception {
enterSoftApActiveMode(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mSoftApCapability, TEST_COUNTRYCODE));
+ mSoftApCapability, TEST_COUNTRYCODE, null));
}
private int mTimesCreatedSoftApManager = 1;
@@ -1005,10 +1008,12 @@ public class ActiveModeWardenTest extends WifiBaseTest {
enterSoftApActiveMode();
mSoftApListener.onStarted(mSoftApManager);
- mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
+ SoftApState softApState = new SoftApState(
+ WifiManager.WIFI_AP_STATE_ENABLED, 0, null, null);
+ mSoftApManagerCallback.onStateChanged(softApState);
mLooper.dispatchAll();
- verify(mSoftApStateMachineCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
+ verify(mSoftApStateMachineCallback).onStateChanged(softApState);
}
/**
@@ -1018,13 +1023,16 @@ public class ActiveModeWardenTest extends WifiBaseTest {
@Test
public void doesntCallWifiServiceCallbackOnLOHSStateChanged() throws Exception {
enterSoftApActiveMode(new SoftApModeConfiguration(
- WifiManager.IFACE_IP_MODE_LOCAL_ONLY, null, mSoftApCapability, TEST_COUNTRYCODE));
+ WifiManager.IFACE_IP_MODE_LOCAL_ONLY, null, mSoftApCapability, TEST_COUNTRYCODE,
+ null));
mSoftApListener.onStarted(mSoftApManager);
- mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
+ SoftApState softApState = new SoftApState(
+ WifiManager.WIFI_AP_STATE_ENABLED, 0, null, null);
+ mSoftApManagerCallback.onStateChanged(softApState);
mLooper.dispatchAll();
- verify(mSoftApStateMachineCallback, never()).onStateChanged(anyInt(), anyInt());
+ verify(mSoftApStateMachineCallback, never()).onStateChanged(softApState);
verify(mSoftApStateMachineCallback, never()).onConnectedClientsOrInfoChanged(any(),
any(), anyBoolean());
}
@@ -1069,7 +1077,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
configBuilder.setSsid("ThisIsAConfig");
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(), mSoftApCapability,
- TEST_COUNTRYCODE);
+ TEST_COUNTRYCODE, null);
enterSoftApActiveMode(softApConfig);
}
@@ -1096,12 +1104,12 @@ public class ActiveModeWardenTest extends WifiBaseTest {
configBuilder1.setSsid("ThisIsAConfig");
SoftApModeConfiguration softApConfig1 = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder1.build(),
- mSoftApCapability, TEST_COUNTRYCODE);
+ mSoftApCapability, TEST_COUNTRYCODE, null);
Builder configBuilder2 = new SoftApConfiguration.Builder();
configBuilder2.setSsid("ThisIsASecondConfig");
SoftApModeConfiguration softApConfig2 = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder2.build(),
- mSoftApCapability, TEST_COUNTRYCODE);
+ mSoftApCapability, TEST_COUNTRYCODE, null);
doAnswer(new Answer<SoftApManager>() {
public SoftApManager answer(InvocationOnMock invocation) {
@@ -1147,6 +1155,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
verify(mWifiNative).getSupportedFeatureSet(null);
verify(mWifiNative).isStaApConcurrencySupported();
verify(mWifiNative).isStaStaConcurrencySupported();
+ verify(mWifiNative).isP2pStaConcurrencySupported();
verifyZeroInteractions(mWifiNative);
}
@@ -1227,12 +1236,14 @@ public class ActiveModeWardenTest extends WifiBaseTest {
mSoftApListener.onStopped(mSoftApManager);
mLooper.dispatchAll();
- mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+ SoftApState softApState = new SoftApState(
+ WifiManager.WIFI_AP_STATE_DISABLED, 0, null, null);
+ mSoftApManagerCallback.onStateChanged(softApState);
mLooper.dispatchAll();
shutdownWifi();
- verify(mSoftApStateMachineCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+ verify(mSoftApStateMachineCallback).onStateChanged(softApState);
}
/**
@@ -1245,10 +1256,12 @@ public class ActiveModeWardenTest extends WifiBaseTest {
shutdownWifi();
mSoftApListener.onStopped(mSoftApManager);
- mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+ SoftApState softApState = new SoftApState(
+ WifiManager.WIFI_AP_STATE_DISABLED, 0, null, null);
+ mSoftApManagerCallback.onStateChanged(softApState);
mLooper.dispatchAll();
- verify(mSoftApStateMachineCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+ verify(mSoftApStateMachineCallback).onStateChanged(softApState);
verify(mModeChangeCallback).onActiveModeManagerRemoved(mSoftApManager);
}
@@ -1287,12 +1300,12 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore);
SoftApModeConfiguration tetherConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mSoftApCapability, TEST_COUNTRYCODE);
+ mSoftApCapability, TEST_COUNTRYCODE, null);
SoftApConfiguration lohsConfigWC = mWifiApConfigStore.generateLocalOnlyHotspotConfig(
mContext, null, mSoftApCapability);
SoftApModeConfiguration lohsConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_LOCAL_ONLY, lohsConfigWC,
- mSoftApCapability, TEST_COUNTRYCODE);
+ mSoftApCapability, TEST_COUNTRYCODE, null);
// mock SoftAPManagers
when(mSoftApManager.getRole()).thenReturn(ROLE_SOFTAP_TETHERED);
@@ -1592,7 +1605,8 @@ public class ActiveModeWardenTest extends WifiBaseTest {
WifiManager.IFACE_IP_MODE_LOCAL_ONLY,
null,
mSoftApCapability,
- TEST_COUNTRYCODE),
+ TEST_COUNTRYCODE,
+ null),
TEST_WORKSOURCE);
mLooper.dispatchAll();
@@ -2243,7 +2257,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
// try to start Soft AP
mActiveModeWarden.startSoftAp(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mSoftApCapability, TEST_COUNTRYCODE), TEST_WORKSOURCE);
+ mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE);
mLooper.dispatchAll();
verify(mWifiInjector, never())
@@ -2251,13 +2265,19 @@ public class ActiveModeWardenTest extends WifiBaseTest {
assertInDisabledState();
// verify triggered Soft AP failure callback
- verify(mSoftApStateMachineCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ ArgumentCaptor<SoftApState> softApStateCaptor =
+ ArgumentCaptor.forClass(SoftApState.class);
+ verify(mSoftApStateMachineCallback).onStateChanged(softApStateCaptor.capture());
+ assertThat(softApStateCaptor.getValue().getState()).isEqualTo(WIFI_AP_STATE_FAILED);
+ assertThat(softApStateCaptor.getValue().getFailureReason())
+ .isEqualTo(SAP_START_FAILURE_GENERAL);
+ assertThat(softApStateCaptor.getValue().getFailureReasonInternal())
+ .isEqualTo(SAP_START_FAILURE_GENERAL);
// try to start LOHS
mActiveModeWarden.startSoftAp(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_LOCAL_ONLY, null,
- mSoftApCapability, TEST_COUNTRYCODE), TEST_WORKSOURCE);
+ mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE);
mLooper.dispatchAll();
verify(mWifiInjector, never())
@@ -2265,8 +2285,12 @@ public class ActiveModeWardenTest extends WifiBaseTest {
assertInDisabledState();
// verify triggered LOHS failure callback
- verify(mLohsStateMachineCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mLohsStateMachineCallback).onStateChanged(softApStateCaptor.capture());
+ assertThat(softApStateCaptor.getValue().getState()).isEqualTo(WIFI_AP_STATE_FAILED);
+ assertThat(softApStateCaptor.getValue().getFailureReason())
+ .isEqualTo(SAP_START_FAILURE_GENERAL);
+ assertThat(softApStateCaptor.getValue().getFailureReasonInternal())
+ .isEqualTo(SAP_START_FAILURE_GENERAL);
}
/**
@@ -2302,7 +2326,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
// Turn on SoftAp.
mActiveModeWarden.startSoftAp(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mSoftApCapability, TEST_COUNTRYCODE), TEST_WORKSOURCE);
+ mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE);
mLooper.dispatchAll();
verify(mWifiInjector)
.makeSoftApManager(any(), any(), any(), eq(TEST_WORKSOURCE), any(), anyBoolean());
@@ -2380,7 +2404,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
mActiveModeWarden.startSoftAp(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mSoftApCapability, TEST_COUNTRYCODE), TEST_WORKSOURCE);
+ mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE);
// add an "unexpected" sta mode stop to simulate a single interface device
mClientListener.onStopped(mClientModeManager);
mLooper.dispatchAll();
@@ -2416,7 +2440,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
mActiveModeWarden.startSoftAp(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mSoftApCapability, TEST_COUNTRYCODE), TEST_WORKSOURCE);
+ mSoftApCapability, TEST_COUNTRYCODE, null), TEST_WORKSOURCE);
mLooper.dispatchAll();
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
@@ -3074,8 +3098,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
assertEquals(additionalClientModeManager, requestedClientModeManager.getValue());
// the additional CMM never became primary
verify(mPrimaryChangedCallback, never()).onChange(any(), eq(additionalClientModeManager));
- if (additionaClientModeManagerRole == ROLE_CLIENT_LOCAL_ONLY
- || additionaClientModeManagerRole == ROLE_CLIENT_SECONDARY_LONG_LIVED) {
+ if (additionaClientModeManagerRole == ROLE_CLIENT_LOCAL_ONLY) {
assertEquals(Set.of(TEST_WORKSOURCE), mActiveModeWarden.getSecondaryRequestWs());
}
return additionalClientListener.value;
@@ -3122,8 +3145,9 @@ public class ActiveModeWardenTest extends WifiBaseTest {
}
private void requestRemoveAdditionalClientModeManagerWhenNotAllowed(
- ClientConnectivityRole role, boolean clientIsExpected) throws Exception {
- enterClientModeActiveState();
+ ClientConnectivityRole role, boolean clientIsExpected,
+ long featureSet) throws Exception {
+ enterClientModeActiveState(false, featureSet);
// Connected to ssid1/bssid1
WifiConfiguration config1 = new WifiConfiguration();
@@ -3338,7 +3362,8 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(false);
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
- requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, true);
+ requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, true,
+ TEST_FEATURE_SET);
}
@Test
@@ -3349,7 +3374,8 @@ public class ActiveModeWardenTest extends WifiBaseTest {
.thenReturn(false);
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
- requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, true);
+ requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, true,
+ TEST_FEATURE_SET);
}
@Test
@@ -3440,7 +3466,8 @@ public class ActiveModeWardenTest extends WifiBaseTest {
WorkSource workSource = new WorkSource(TEST_WORKSOURCE);
workSource.add(SETTINGS_WORKSOURCE);
verify(mWifiNative).isItPossibleToCreateStaIface(eq(workSource));
- requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, true);
+ requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY,
+ true, TEST_FEATURE_SET);
}
@Test
@@ -3464,6 +3491,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can't create more client ifaces - so will attempt to fallback (which we
// 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))
.thenReturn(true);
@@ -3473,14 +3501,12 @@ public class ActiveModeWardenTest extends WifiBaseTest {
.thenReturn(true);
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
- requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, true);
+ requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY,
+ true, TEST_FEATURE_SET | WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY);
}
- @Test
- public void requestRemoveLoClientModeManagerWhenNotSystemAppAndTargetSdkEqualToSAndCantCreate()
- throws Exception {
- // Ensure that we can't create more client ifaces - so will attempt to fallback (which we
- // can't for >=S apps)
+ 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))
.thenReturn(true);
@@ -3490,7 +3516,30 @@ public class ActiveModeWardenTest extends WifiBaseTest {
.thenReturn(false);
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
- requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY, false);
+ long expectedFeatureSet = TEST_FEATURE_SET;
+ if (isStaStaSupported) {
+ expectedFeatureSet |= WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY;
+ }
+
+ requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_LOCAL_ONLY,
+ !isStaStaSupported,
+ expectedFeatureSet);
+ }
+
+ @Test
+ public void requestRemoveLoClientModeManagerWhenNotSystemAppAndTargetSdkEqualToSAndCantCreate()
+ throws Exception {
+ // Ensure that we can't create more client ifaces - so will attempt to fallback (which we
+ // can't for >=S apps)
+ testLoFallbackAboveAndroidS(true);
+ }
+
+ @Test
+ public void requestRemoveLoClientModeManagerWhenNotSystemAppAndTargetSdkEqualToSAndCantCreate2()
+ throws Exception {
+ // Ensure that we can't create more client ifaces and STA+STA is not supported, we
+ // fallback even for >=S apps
+ testLoFallbackAboveAndroidS(false);
}
@Test
@@ -3513,7 +3562,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false));
requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_SECONDARY_LONG_LIVED,
- true);
+ true, TEST_FEATURE_SET);
}
@Test
@@ -3526,7 +3575,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false));
requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_SECONDARY_LONG_LIVED,
- true);
+ true, TEST_FEATURE_SET);
}
@Test
@@ -3602,7 +3651,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false));
requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_SECONDARY_TRANSIENT,
- true);
+ true, TEST_FEATURE_SET);
}
@Test
@@ -3616,7 +3665,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_TRANSIENT, false));
requestRemoveAdditionalClientModeManagerWhenNotAllowed(ROLE_CLIENT_SECONDARY_TRANSIENT,
- true);
+ true, TEST_FEATURE_SET);
}
@Test
@@ -5239,6 +5288,42 @@ public class ActiveModeWardenTest extends WifiBaseTest {
}
@Test
+ public void testSatelliteModemDisableWifiWhenLocationModeChanged() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
+
+ // Wifi is enabled
+ enterClientModeActiveState();
+ assertInEnabledState();
+
+ // Satellite mode is ON, disable Wifi
+ assertWifiShutDown(() -> {
+ when(mSettingsStore.isSatelliteModeOn()).thenReturn(true);
+ mActiveModeWarden.handleSatelliteModeChange();
+ mLooper.dispatchAll();
+ });
+ mClientListener.onStopped(mClientModeManager);
+ mLooper.dispatchAll();
+ assertInDisabledState();
+
+ // Location state changes
+ ArgumentCaptor<BroadcastReceiver> bcastRxCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext).registerReceiver(
+ bcastRxCaptor.capture(),
+ argThat(filter -> filter.hasAction(LocationManager.MODE_CHANGED_ACTION)));
+ BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue();
+
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION);
+ broadcastReceiver.onReceive(mContext, intent);
+ mLooper.dispatchAll();
+
+ // Ensure Wi-Fi is still disabled
+ assertInDisabledState();
+ }
+
+ @Test
public void testOnIdleModeChanged() throws Exception {
enterClientModeActiveState();
List<ClientModeManager> currentCMMs = mActiveModeWarden.getClientModeManagers();
@@ -5260,4 +5345,14 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mWifiGlobals.isWpaPersonalDeprecated()).thenReturn(false);
enterClientModeActiveState(false, TEST_FEATURE_SET | WifiManager.WIFI_FEATURE_WPA_PERSONAL);
}
+
+ @Test
+ public void testD2dSupportedWhenInfraStaDisabled() throws Exception {
+ when(mWifiNative.isP2pStaConcurrencySupported()).thenReturn(true);
+ when(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled()).thenReturn(true);
+ mActiveModeWarden = createActiveModeWarden();
+ mActiveModeWarden.start();
+ verify(mWifiGlobals).setD2dStaConcurrencySupported(true);
+ verify(mWifiGlobals, atLeastOnce()).isD2dSupportedWhenInfraStaDisabled();
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyRequestHandlerTest.java b/service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyRequestHandlerTest.java
index c1809a95c4..5342efbafd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyRequestHandlerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyRequestHandlerTest.java
@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -33,6 +34,7 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.net.wifi.IListListener;
+import android.net.wifi.QosCharacteristics;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.WifiManager;
import android.os.HandlerThread;
@@ -118,6 +120,14 @@ public class ApplicationQosPolicyRequestHandlerTest {
.build();
}
+ private QosPolicyParams createUplinkPolicy(int policyId) {
+ QosCharacteristics mockQosCharacteristics = mock(QosCharacteristics.class);
+ when(mockQosCharacteristics.validate()).thenReturn(true);
+ return new QosPolicyParams.Builder(policyId, QosPolicyParams.DIRECTION_UPLINK)
+ .setQosCharacteristics(mockQosCharacteristics)
+ .build();
+ }
+
private List<QosPolicyParams> createDownlinkPolicyList(int size, int basePolicyId) {
List<QosPolicyParams> policies = new ArrayList<>();
for (int i = 0; i < size; i++) {
@@ -126,6 +136,14 @@ public class ApplicationQosPolicyRequestHandlerTest {
return policies;
}
+ private List<QosPolicyParams> createUplinkPolicyList(int size, int basePolicyId) {
+ List<QosPolicyParams> policies = new ArrayList<>();
+ for (int i = 0; i < size; i++) {
+ policies.add(createUplinkPolicy(basePolicyId + i));
+ }
+ return policies;
+ }
+
private List<Integer> generateIntegerList(int size, int val) {
List<Integer> integerList = new ArrayList<>();
for (int i = 0; i < size; i++) {
@@ -618,7 +636,7 @@ public class ApplicationQosPolicyRequestHandlerTest {
addPoliciesToTable(policyList);
// Expect that the request is divided into two batches of size 16 and 2, respectively.
- mDut.queueAllPoliciesOnIface(TEST_IFACE_NAME_1);
+ mDut.queueAllPoliciesOnIface(TEST_IFACE_NAME_1, false);
verify(mWifiNative).addQosPolicyRequestForScs(
eq(TEST_IFACE_NAME_1), mPolicyListCaptor.capture());
assertEquals(16, mPolicyListCaptor.getValue().size());
@@ -631,4 +649,46 @@ public class ApplicationQosPolicyRequestHandlerTest {
eq(TEST_IFACE_NAME_1), mPolicyListCaptor.capture());
assertEquals(2, mPolicyListCaptor.getValue().size());
}
+
+ /**
+ * Tests that uplink policies are only included in the queueAllPolicies request
+ * if the current AP supports QosCharacteristics.
+ */
+ @Test
+ public void testQueueAllPoliciesRequest_mixedDirection() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mActiveModeWarden.getInternetConnectivityClientModeManagers())
+ .thenReturn(Arrays.asList(mClientModeManager0));
+ int numDownlinkPolicies = 10;
+ int numUplinkPolicies = 5;
+ addPoliciesToTable(createDownlinkPolicyList(numDownlinkPolicies, TEST_POLICY_ID_START));
+ addPoliciesToTable(createUplinkPolicyList(numUplinkPolicies,
+ TEST_POLICY_ID_START + numDownlinkPolicies));
+
+ // Expect that only the downlink policies are sent to the HAL
+ // if the current AP does not support QosCharacteristics.
+ mDut.queueAllPoliciesOnIface(TEST_IFACE_NAME_0, false);
+ verify(mWifiNative, atLeastOnce()).addQosPolicyRequestForScs(
+ eq(TEST_IFACE_NAME_0), mPolicyListCaptor.capture());
+ assertEquals(numDownlinkPolicies, mPolicyListCaptor.getValue().size());
+
+ // Trigger AP callback to complete the current request.
+ triggerAndVerifyApCallback(TEST_IFACE_NAME_0, mPolicyListCaptor.getValue(),
+ SupplicantStaIfaceHal.QOS_POLICY_SCS_RESPONSE_STATUS_SUCCESS);
+
+ // If the current AP supports QosCharacteristics, expect that both uplink
+ // and downlink policies are sent (albeit in separate transactions).
+ // Downlink policies will be sent first.
+ mDut.queueAllPoliciesOnIface(TEST_IFACE_NAME_0, true);
+ verify(mWifiNative, atLeastOnce()).addQosPolicyRequestForScs(
+ eq(TEST_IFACE_NAME_0), mPolicyListCaptor.capture());
+ assertEquals(numDownlinkPolicies, mPolicyListCaptor.getValue().size());
+
+ // Trigger callback and check that the uplink policies are sent next.
+ triggerAndVerifyApCallback(TEST_IFACE_NAME_0, mPolicyListCaptor.getValue(),
+ SupplicantStaIfaceHal.QOS_POLICY_SCS_RESPONSE_STATUS_SUCCESS);
+ verify(mWifiNative, atLeastOnce()).addQosPolicyRequestForScs(
+ eq(TEST_IFACE_NAME_0), mPolicyListCaptor.capture());
+ assertEquals(numUplinkPolicies, mPolicyListCaptor.getValue().size());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyTrackingTableTest.java b/service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyTrackingTableTest.java
index 49f98d48cb..5a8b75a74a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyTrackingTableTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ApplicationQosPolicyTrackingTableTest.java
@@ -20,7 +20,10 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import android.net.wifi.QosCharacteristics;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.WifiManager;
@@ -59,6 +62,20 @@ public class ApplicationQosPolicyTrackingTableTest {
return policyList;
}
+ private List<QosPolicyParams> generateUplinkPolicyList(int size, int policyIdStart) {
+ QosCharacteristics mockQosCharacteristics = mock(QosCharacteristics.class);
+ when(mockQosCharacteristics.validate()).thenReturn(true);
+
+ List<QosPolicyParams> policyList = new ArrayList<>();
+ for (int i = 0; i < size; i++) {
+ policyList.add(new QosPolicyParams.Builder(
+ policyIdStart + i, QosPolicyParams.DIRECTION_UPLINK)
+ .setQosCharacteristics(mockQosCharacteristics)
+ .build());
+ }
+ return policyList;
+ }
+
private List<Integer> getPolicyIdsFromPolicyList(List<QosPolicyParams> policyList) {
List<Integer> policyIds = new ArrayList<>();
for (QosPolicyParams policy : policyList) {
@@ -264,22 +281,53 @@ public class ApplicationQosPolicyTrackingTableTest {
}
/**
- * Tests the {@link ApplicationQosPolicyTrackingTable#getAllPolicies()} method.
+ * Tests the {@link ApplicationQosPolicyTrackingTable#getAllPolicies(boolean)} method when
+ * no policies contain QosCharacteristics.
*/
@Test
- public void testGetAllPolicies() {
+ public void testGetAllPolicies_noQosChars() {
// Empty table should return an empty list.
- List<QosPolicyParams> retrievedPolicies = mDut.getAllPolicies();
+ List<QosPolicyParams> retrievedPolicies = mDut.getAllPolicies(false);
assertTrue(retrievedPolicies.isEmpty());
- // Fill table with policies from multiple requesters.
+ // Fill table with downlink policies from multiple requesters.
+ // No policies contain QosCharacteristics.
List<QosPolicyParams> policyList = generatePolicyList(
NUM_VIRTUAL_POLICY_IDS / 2, TEST_PHYSICAL_POLICY_ID_START);
mDut.addPolicies(policyList, TEST_UID);
mDut.addPolicies(policyList, TEST_UID + 1);
// getAllPolicies should return all policies across all requesters.
- retrievedPolicies = mDut.getAllPolicies();
+ retrievedPolicies = mDut.getAllPolicies(false);
assertEquals(NUM_VIRTUAL_POLICY_IDS, retrievedPolicies.size());
}
+
+ /**
+ * Tests the {@link ApplicationQosPolicyTrackingTable#getAllPolicies(boolean)} method when
+ * some policies in the table contain QosCharacteristics and others do not.
+ */
+ @Test
+ public void testGetAllPolicies_filteredByQosChars() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ List<QosPolicyParams> policiesWithoutQosChars = generatePolicyList(
+ NUM_VIRTUAL_POLICY_IDS / 2, TEST_PHYSICAL_POLICY_ID_START);
+ mDut.addPolicies(policiesWithoutQosChars, TEST_UID);
+
+ // Table should contain no policies with QosCharacteristics.
+ List<QosPolicyParams> retrievedPolicies = mDut.getAllPolicies(false);
+ assertEquals(policiesWithoutQosChars.size(), retrievedPolicies.size());
+ retrievedPolicies = mDut.getAllPolicies(true);
+ assertEquals(0, retrievedPolicies.size());
+
+ // Uplink policies are guaranteed to contain QosCharacteristics.
+ List<QosPolicyParams> policiesWithQosChars = generateUplinkPolicyList(
+ NUM_VIRTUAL_POLICY_IDS / 2, TEST_PHYSICAL_POLICY_ID_START);
+ mDut.addPolicies(policiesWithQosChars, TEST_UID + 1);
+
+ // Table should contain both policies with and without QosCharacteristics.
+ retrievedPolicies = mDut.getAllPolicies(false);
+ assertEquals(policiesWithoutQosChars.size(), retrievedPolicies.size());
+ retrievedPolicies = mDut.getAllPolicies(true);
+ assertEquals(policiesWithQosChars.size(), retrievedPolicies.size());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/AvailableNetworkNotifierTest.java b/service/tests/wifitests/src/com/android/server/wifi/AvailableNetworkNotifierTest.java
index 3c9ac5b4d7..ceecf9bf9a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/AvailableNetworkNotifierTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/AvailableNetworkNotifierTest.java
@@ -106,9 +106,17 @@ public class AvailableNetworkNotifierTest extends WifiBaseTest {
AvailableNetworkNotifier.STATE_SHOWING_RECOMMENDATION_NOTIFICATION;
final String ssid = "UnknownAkm-Network";
final String caps = "[RSN-?-TKIP+CCMP][ESS][WPS]";
- ScanResult result = new ScanResult(WifiSsid.fromUtf8Text(ssid), ssid,
- "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
- 0, true);
+ ScanResult result = 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();
InformationElement ie = new InformationElement();
ie.id = InformationElement.EID_SSID;
ie.bytes = ssid.getBytes(StandardCharsets.UTF_8);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/BackupRestoreControllerTest.java b/service/tests/wifitests/src/com/android/server/wifi/BackupRestoreControllerTest.java
new file mode 100644
index 0000000000..47c61d620d
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/BackupRestoreControllerTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.BackupRestoreControllerTest}.
+ */
+@SmallTest
+public class BackupRestoreControllerTest extends WifiBaseTest {
+
+ public static final String XML_GENERAL_BEGINNING =
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n";
+
+ public static final String TEST_WIFI_UNION_BACKUP_DATA_WITH_SETTINGS_IN_V =
+ XML_GENERAL_BEGINNING
+ + "<WifiSettingsBackupData>\n"
+ + WifiSettingsBackupRestoreTest.generateTestWifiSettingsTestingXml("")
+ + "</WifiSettingsBackupData>\n";
+
+ @Mock WifiSettingsBackupRestore mWifiSettingsBackupRestore;
+ @Mock Clock mClock;
+
+
+ private BackupRestoreController mBackupRestoreController;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mBackupRestoreController = new BackupRestoreController(
+ mWifiSettingsBackupRestore, mClock);
+ }
+
+ /**
+ * Verify that a data return when retrieve backup data is serialized correctly.
+ */
+ @Test
+ public void testNormalBackupDataSerializedDeserialized() {
+ mBackupRestoreController.retrieveBackupData();
+ verify(mWifiSettingsBackupRestore).retrieveBackupDataFromSettingsConfigStore(any(), any());
+ mBackupRestoreController.parserBackupDataAndDispatch(
+ TEST_WIFI_UNION_BACKUP_DATA_WITH_SETTINGS_IN_V.getBytes());
+ verify(mWifiSettingsBackupRestore).restoreSettingsFromBackupData(any(), eq(1));
+ }
+}
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 d8606f0e3a..68c74f972c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -30,6 +30,9 @@ import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED
import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_UNWANTED_LOW_RSSI;
import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED;
import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE;
+import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OPEN;
+import static android.net.wifi.WifiInfo.SECURITY_TYPE_OWE;
+import static android.net.wifi.WifiInfo.SECURITY_TYPE_PSK;
import static android.net.wifi.WifiManager.AddNetworkResult.STATUS_SUCCESS;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
@@ -135,8 +138,10 @@ import android.net.wifi.WifiNetworkAgentSpecifier;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
+import android.net.wifi.flags.Flags;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
+import android.net.wifi.nl80211.DeviceWiphyCapabilities;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.util.ScanResultUtil;
import android.os.BatteryStatsManager;
@@ -172,6 +177,7 @@ import com.android.server.wifi.ClientModeManagerBroadcastQueue.QueuedBroadcast;
import com.android.server.wifi.WifiNative.ConnectionCapabilities;
import com.android.server.wifi.WifiScoreCard.PerBssid;
import com.android.server.wifi.WifiScoreCard.PerNetwork;
+import com.android.server.wifi.b2b.WifiRoamingModeManager;
import com.android.server.wifi.hotspot2.NetworkDetail;
import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.hotspot2.PasspointProvisioningTestUtil;
@@ -267,6 +273,7 @@ public class ClientModeImplTest extends WifiBaseTest {
private static final long TEST_BSSID = 0x112233445566L;
private static final int TEST_DELAY_IN_SECONDS = 300;
+ private static final String TEST_ATTRIBUTION_TAG = "TEST_ATTRIBUTION_TAG";
private static final int DEFINED_ERROR_CODE = 32764;
private static final String TEST_TERMS_AND_CONDITIONS_URL =
@@ -300,6 +307,9 @@ public class ClientModeImplTest extends WifiBaseTest {
private MockitoSession mSession;
private TestNetworkParams mTestNetworkParams = new TestNetworkParams();
+ // Attribution tag to be used in the mocked connect sequence
+ private String mAttributionTagForConnect = TEST_ATTRIBUTION_TAG;
+
/**
* Helper class for setting the default parameters of the WifiConfiguration that gets used
* in connect().
@@ -512,6 +522,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiConfiguration mConnectedNetwork;
WifiConfiguration mTestConfig;
ExtendedWifiInfo mWifiInfo;
+ WifiRoamingModeManager mWifiRoamingModeManager;
ConnectionCapabilities mConnectionCapabilities = new ConnectionCapabilities();
@Mock ActivityManager mActivityManager;
@@ -588,6 +599,9 @@ public class ClientModeImplTest extends WifiBaseTest {
@Mock LocalLog mLocalLog;
@Mock WifiDeviceStateChangeManager mWifiDeviceStateChangeManager;
@Mock WifiCountryCode mWifiCountryCode;
+ @Mock WifiRoamingConfigStore mWifiRoamingConfigStore;
+
+ @Mock DeviceWiphyCapabilities mDeviceWiphyCapabilities;
@Captor ArgumentCaptor<WifiConfigManager.OnNetworkUpdateListener> mConfigUpdateListenerCaptor;
@Captor ArgumentCaptor<WifiNetworkAgent.Callback> mWifiNetworkAgentCallbackCaptor;
@@ -679,6 +693,8 @@ public class ClientModeImplTest extends WifiBaseTest {
mFrameworkFacade = getFrameworkFacade();
mContext = getContext();
mWifiInfo = new ExtendedWifiInfo(mWifiGlobals, WIFI_IFACE_NAME);
+ mWifiRoamingModeManager = new WifiRoamingModeManager(mWifiNative,
+ mActiveModeWarden, mWifiRoamingConfigStore);
when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(true);
mResources = getMockResources();
@@ -691,6 +707,7 @@ public class ClientModeImplTest extends WifiBaseTest {
when(mWifiGlobals.getPollRssiIntervalMillis()).thenReturn(3000);
when(mWifiGlobals.getIpReachabilityDisconnectEnabled()).thenReturn(true);
+ when(mWifiGlobals.getRepeatedNudFailuresThreshold()).thenReturn(Integer.MAX_VALUE);
when(mFrameworkFacade.getIntegerSetting(mContext,
Settings.Global.WIFI_FREQUENCY_BAND,
@@ -724,7 +741,10 @@ public class ClientModeImplTest extends WifiBaseTest {
when(mWifiInjector.getWifiDeviceStateChangeManager())
.thenReturn(mWifiDeviceStateChangeManager);
when(mWifiHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
- when(mWifiGlobals.isWpa3SaeUpgradeEnabled()).thenReturn(true);
+ when(mWifiNative.getDeviceWiphyCapabilities(any())).thenReturn(mDeviceWiphyCapabilities);
+ if (Flags.getDeviceCrossAkmRoamingSupport() && SdkLevel.isAtLeastV()) {
+ when(mDeviceWiphyCapabilities.getMaxNumberAkms()).thenReturn(2);
+ }
when(mWifiGlobals.isOweUpgradeEnabled()).thenReturn(true);
when(mWifiGlobals.getClientModeImplNumLogRecs()).thenReturn(100);
when(mWifiGlobals.isSaveFactoryMacToConfigStoreEnabled()).thenReturn(true);
@@ -754,6 +774,9 @@ public class ClientModeImplTest extends WifiBaseTest {
initializeCmi();
// Retrieve factory MAC address on first bootup.
verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME);
+ if (Flags.getDeviceCrossAkmRoamingSupport() && SdkLevel.isAtLeastV()) {
+ verify(mWifiGlobals).setWpa3SaeUpgradeOffloadEnabled();
+ }
mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true);
mConnectedNetwork = spy(WifiConfigurationTestUtil.createOpenNetwork());
@@ -773,6 +796,7 @@ public class ClientModeImplTest extends WifiBaseTest {
when(mWifiScoreCard.lookupBssid(any(), any())).thenReturn(mPerBssid);
when(mThroughputPredictor.predictMaxTxThroughput(any())).thenReturn(90);
when(mThroughputPredictor.predictMaxRxThroughput(any())).thenReturn(80);
+ when(mWifiInjector.getWifiRoamingModeManager()).thenReturn(mWifiRoamingModeManager);
doAnswer(new AnswerWithArguments() {
public void answer(boolean shouldReduceNetworkScore) {
@@ -998,7 +1022,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(config.networkId),
new ActionListenerWrapper(connectActionListener),
- Binder.getCallingUid(), OP_PACKAGE_NAME);
+ Binder.getCallingUid(), OP_PACKAGE_NAME, mAttributionTagForConnect);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
}
@@ -1061,8 +1085,17 @@ public class ClientModeImplTest extends WifiBaseTest {
}
}).when(mWifiNetworkSelector).selectNetwork(any());
String caps = "[RSN-OWE_TRANSITION]";
- ScanResult scanResult = new ScanResult(WifiSsid.fromUtf8Text(ssid),
- ssid, TEST_BSSID_STR, 1245, 0, caps, -78, 2412, 1025, 22, 33, 20, 0, 0, true);
+ ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(ssid),
+ TEST_BSSID_STR)
+ .setHessid(1245)
+ .setCaps(caps)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID,
ssid.getBytes(StandardCharsets.UTF_8));
scanResult.informationElements = new ScanResult.InformationElement[]{ie};
@@ -1184,8 +1217,16 @@ public class ClientModeImplTest extends WifiBaseTest {
getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq));
when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn(
getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult());
- ScanResult scanResult = new ScanResult(WifiSsid.fromUtf8Text(sFilsSsid),
- sFilsSsid, TEST_BSSID_STR, 1245, 0, "", -78, 2412, 1025, 22, 33, 20, 0, 0, true);
+ ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(sFilsSsid),
+ TEST_BSSID_STR)
+ .setHessid(1245)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID,
sFilsSsid.getBytes(StandardCharsets.UTF_8));
scanResult.informationElements = new ScanResult.InformationElement[]{ie};
@@ -1323,8 +1364,16 @@ public class ClientModeImplTest extends WifiBaseTest {
getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq));
when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn(
getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult());
- ScanResult scanResult = new ScanResult(WifiSsid.fromUtf8Text(sFilsSsid),
- sFilsSsid, TEST_BSSID_STR, 1245, 0, "", -78, 2412, 1025, 22, 33, 20, 0, 0, true);
+ ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(sFilsSsid),
+ TEST_BSSID_STR)
+ .setHessid(1245)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID,
sFilsSsid.getBytes(StandardCharsets.UTF_8));
scanResult.informationElements = new ScanResult.InformationElement[]{ie};
@@ -1692,7 +1741,7 @@ public class ClientModeImplTest extends WifiBaseTest {
verify(mSimRequiredNotifier).showSimRequiredNotification(any(), any());
verify(mWifiNative, times(2)).removeAllNetworks(WIFI_IFACE_NAME);
verify(mWifiMetrics).startConnectionEvent(
- anyString(), any(), anyString(), anyInt(), eq(true), anyInt());
+ anyString(), any(), anyString(), anyInt(), eq(true), anyInt(), anyInt());
}
/**
@@ -2255,9 +2304,11 @@ public class ClientModeImplTest extends WifiBaseTest {
eq(WifiNative.DISABLE_FIRMWARE_ROAMING));
// Verify firmware roaming is enabled when idle mode exited
+ when(mWifiRoamingConfigStore.getRoamingMode(anyString())).thenReturn(
+ WifiManager.ROAMING_MODE_NORMAL);
mCmi.onIdleModeChanged(false);
- verify(mWifiNative).enableFirmwareRoaming(anyString(),
- eq(WifiNative.ENABLE_FIRMWARE_ROAMING));
+ verify(mWifiNative).setRoamingMode(anyString(),
+ eq(WifiManager.ROAMING_MODE_NORMAL));
}
@Test
@@ -2280,6 +2331,31 @@ public class ClientModeImplTest extends WifiBaseTest {
}
/**
+ * Verify that when the primary connects, roaming mode is set
+ * based on the connected network ssid.
+ */
+ @Test
+ public void testPerSsidRoamingModePrimary() throws Exception {
+ when(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID)).thenReturn(
+ WifiManager.ROAMING_MODE_NORMAL);
+ connect();
+ verify(mWifiRoamingConfigStore).getRoamingMode(TEST_SSID);
+ verify(mWifiNative).setRoamingMode(anyString(),
+ eq(WifiManager.ROAMING_MODE_NORMAL));
+ }
+
+ /**
+ * Verify that when the secondary connects, roaming mode is not set.
+ */
+ @Test
+ public void testPerSsidRoamingModeSecondary() throws Exception {
+ when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_TRANSIENT);
+ connect();
+ verify(mWifiRoamingConfigStore, never()).getRoamingMode(anyString());
+ verify(mWifiNative, never()).setRoamingMode(anyString(), anyInt());
+ }
+
+ /**
* Tests the network connection initiation sequence with no network request pending from
* from WifiNetworkFactory when we're already connected to a different network.
* This simulates the connect sequence using the public
@@ -2353,7 +2429,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(FRAMEWORK_NETWORK_ID),
new ActionListenerWrapper(connectActionListener),
- Binder.getCallingUid(), OP_PACKAGE_NAME);
+ Binder.getCallingUid(), OP_PACKAGE_NAME, TEST_ATTRIBUTION_TAG);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
@@ -2378,7 +2454,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(FRAMEWORK_NETWORK_ID),
new ActionListenerWrapper(connectActionListener),
- callingUid, OP_PACKAGE_NAME);
+ callingUid, OP_PACKAGE_NAME, TEST_ATTRIBUTION_TAG);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
@@ -2403,7 +2479,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(FRAMEWORK_NETWORK_ID),
new ActionListenerWrapper(connectActionListener),
- Binder.getCallingUid(), OP_PACKAGE_NAME);
+ Binder.getCallingUid(), OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
@@ -2436,7 +2512,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
networkUpdateResult,
new ActionListenerWrapper(connectActionListener),
- Binder.getCallingUid(), OP_PACKAGE_NAME);
+ Binder.getCallingUid(), OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
@@ -2466,7 +2542,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(FRAMEWORK_NETWORK_ID),
new ActionListenerWrapper(connectActionListener),
- Binder.getCallingUid(), OP_PACKAGE_NAME);
+ Binder.getCallingUid(), OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
@@ -2496,7 +2572,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(FRAMEWORK_NETWORK_ID),
new ActionListenerWrapper(connectActionListener),
- Binder.getCallingUid(), OP_PACKAGE_NAME);
+ Binder.getCallingUid(), OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
@@ -2516,7 +2592,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(FRAMEWORK_NETWORK_ID),
new ActionListenerWrapper(connectActionListener),
- Binder.getCallingUid(), OP_PACKAGE_NAME);
+ Binder.getCallingUid(), OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
@@ -2639,7 +2715,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(TEST_NETWORK_ID),
new ActionListenerWrapper(connectActionListener),
- Process.SYSTEM_UID, OP_PACKAGE_NAME);
+ Process.SYSTEM_UID, OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
@@ -2656,7 +2732,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(networkId),
new ActionListenerWrapper(connectActionListener),
- Binder.getCallingUid(), OP_PACKAGE_NAME);
+ Binder.getCallingUid(), OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
}
@@ -2892,7 +2968,7 @@ public class ClientModeImplTest extends WifiBaseTest {
@Test
public void testEapSimErrorVendorSpecific() throws Exception {
when(mWifiMetrics.startConnectionEvent(any(), any(), anyString(), anyInt(), anyBoolean(),
- anyInt())).thenReturn(80000);
+ anyInt(), anyInt())).thenReturn(80000);
initializeAndAddNetworkAndVerifySuccess();
startConnectSuccess();
@@ -2923,7 +2999,7 @@ public class ClientModeImplTest extends WifiBaseTest {
@Test
public void testEapAkaRetrieveOobPseudonymTriggeredByAuthenticationFailure() throws Exception {
when(mWifiMetrics.startConnectionEvent(any(), any(), anyString(), anyInt(), anyBoolean(),
- anyInt())).thenReturn(80000);
+ anyInt(), anyInt())).thenReturn(80000);
when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(anyInt())).thenReturn(true);
initializeAndAddNetworkAndVerifySuccess();
@@ -5582,22 +5658,32 @@ public class ClientModeImplTest extends WifiBaseTest {
anyInt());
}
- /**
- * Verify that on the second successful connection to a saved network we set the user connect
- * choice.
- */
- @Test
- public void testConnectionSetUserConnectChoiceOnSecondConnection() throws Exception {
+ private void verifyUserConnectChoice(boolean shouldSetUcc) throws Exception {
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
mTestNetworkParams.hasEverConnected = true;
connect();
verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID);
verify(mWifiConfigManager).updateNetworkAfterConnect(eq(FRAMEWORK_NETWORK_ID),
- eq(true), eq(true),
+ eq(shouldSetUcc), eq(shouldSetUcc),
anyInt());
}
/**
+ * Verify that on the second successful connection to a saved network we set the user connect
+ * choice.
+ */
+ @Test
+ public void testConnectionSetUserConnectChoiceOnSecondConnection() throws Exception {
+ verifyUserConnectChoice(true);
+ }
+
+ @Test
+ public void testDisallowUserConnectChoice() throws Exception {
+ mAttributionTagForConnect = ClientModeImpl.ATTRIBUTION_TAG_DISALLOW_CONNECT_CHOICE;
+ verifyUserConnectChoice(false);
+ }
+
+ /**
* Verify that on the first successful connection to an ephemeral network we set the user
* connect choice.
*/
@@ -6838,8 +6924,17 @@ public class ClientModeImplTest extends WifiBaseTest {
private void setupFilsEnabledApInScanResult() {
String caps = "[WPA2-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA256-CCMP]"
+ "[RSN-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA256-CCMP][ESS]";
- ScanResult scanResult = new ScanResult(WifiSsid.fromUtf8Text(sFilsSsid),
- sFilsSsid, TEST_BSSID_STR, 1245, 0, caps, -78, 2412, 1025, 22, 33, 20, 0, 0, true);
+ ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(sFilsSsid),
+ TEST_BSSID_STR)
+ .setHessid(1245)
+ .setCaps(caps)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID,
sFilsSsid.getBytes(StandardCharsets.UTF_8));
scanResult.informationElements = new ScanResult.InformationElement[]{ie};
@@ -7461,10 +7556,7 @@ public class ClientModeImplTest extends WifiBaseTest {
}
@Test
- public void testIpReachabilityFailureStaticIpOrganicTriggersDisconnection() throws Exception {
- when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(true);
- assumeTrue(SdkLevel.isAtLeastT());
-
+ public void testIpReachabilityMonitorNotStartOnStaticIpConfiguration() throws Exception {
final List<InetAddress> dnsServers = new ArrayList<>();
dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8"));
dnsServers.add(InetAddresses.parseNumericAddress("4.4.4.4"));
@@ -7498,19 +7590,9 @@ public class ClientModeImplTest extends WifiBaseTest {
injectDhcpSuccess(dhcpResults);
mLooper.dispatchAll();
expectRegisterNetworkAgent((agentConfig) -> {}, (cap) -> {});
- reset(mWifiNetworkAgent);
-
- // normal behavior outside specific CC
- when(mWifiGlobals.disableNudDisconnectsForWapiInSpecificCc()).thenReturn(true);
- when(mWifiCountryCode.getCountryCode()).thenReturn("US");
- // Trigger IP reachability failure and ensure we trigger a disconnection due to static IP.
- ReachabilityLossInfoParcelable lossInfo =
- new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ORGANIC);
- mIpClientCallback.onReachabilityFailure(lossInfo);
- mLooper.dispatchAll();
- verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
- verify(mWifiNetworkAgent, never()).unregisterAfterReplacement(anyInt());
+ verify(mIpClient).startProvisioning(mProvisioningConfigurationCaptor.capture());
+ assertFalse(mProvisioningConfigurationCaptor.getValue().usingIpReachabilityMonitor);
}
private void doIpReachabilityFailureTest(int lossReason, boolean shouldWifiDisconnect)
@@ -7573,6 +7655,57 @@ public class ClientModeImplTest extends WifiBaseTest {
verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
}
+ /**
+ * Verify that when HandleRssiOrganicKernelFailuresEnabled, multiple IP reachability failures
+ * within a specified time window will lead to disconnect and network disabled.
+ */
+ @Test
+ public void testRepeatedIpReachabilityFailureDisableNetwork() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastU());
+ when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(true);
+ int failureThreshold = 5;
+ int failureWindowMs = 60000;
+ when(mWifiGlobals.getRepeatedNudFailuresThreshold()).thenReturn(failureThreshold);
+ when(mWifiGlobals.getRepeatedNudFailuresWindowMs()).thenReturn(failureWindowMs);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+
+ connect();
+ expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { });
+ reset(mWifiNetworkAgent);
+
+ for (int i = 0; i < failureThreshold; i++) {
+ // increment time outside the failure window. Failure counter should never add up and
+ // thus not trigger blocking.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(
+ (long) (i + 1) * (failureWindowMs + 1));
+ verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME);
+ verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(anyInt(),
+ eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES));
+ ReachabilityLossInfoParcelable lossInfo =
+ new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ORGANIC);
+ mIpClientCallback.onReachabilityFailure(lossInfo);
+ mLooper.dispatchAll();
+ }
+
+ // Now trigger NUD failure within the failure window and verify the network is blocked.
+ for (int i = 0; i < failureThreshold - 1; i++) {
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(
+ (long) (i + failureThreshold + 1) * (failureWindowMs));
+ verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME);
+ verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(anyInt(),
+ eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES));
+ ReachabilityLossInfoParcelable lossInfo =
+ new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ORGANIC);
+ mIpClientCallback.onReachabilityFailure(lossInfo);
+ mLooper.dispatchAll();
+ }
+
+ // Should disconnect and block network after the last iteration.
+ verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(),
+ eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES));
+ verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
+ }
+
@Test
public void testIpReachabilityFailureOrganic_enableHandleRssiOrganicKernelFailuresFlag()
throws Exception {
@@ -8250,8 +8383,17 @@ public class ClientModeImplTest extends WifiBaseTest {
private void verifyTransitionDisableEvent(String caps, int indication, boolean shouldUpdate)
throws Exception {
final int networkId = FRAMEWORK_NETWORK_ID;
- ScanResult scanResult = new ScanResult(WifiSsid.fromUtf8Text(sFilsSsid),
- sFilsSsid, TEST_BSSID_STR, 1245, 0, caps, -78, 2412, 1025, 22, 33, 20, 0, 0, true);
+ ScanResult scanResult = new ScanResult.Builder(WifiSsid.fromUtf8Text(sFilsSsid),
+ TEST_BSSID_STR)
+ .setHessid(1245)
+ .setCaps(caps)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID,
sFilsSsid.getBytes(StandardCharsets.UTF_8));
scanResult.informationElements = new ScanResult.InformationElement[]{ie};
@@ -8998,7 +9140,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(config.networkId),
new ActionListenerWrapper(connectActionListener),
- Binder.getCallingUid(), OP_PACKAGE_NAME);
+ Binder.getCallingUid(), OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
verify(mWifiConfigManager, never())
@@ -9502,7 +9644,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(TEST_NETWORK_ID),
new ActionListenerWrapper(connectActionListener),
- Process.SYSTEM_UID, OP_PACKAGE_NAME);
+ Process.SYSTEM_UID, OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
if (shouldBeUpdated) {
@@ -9719,7 +9861,7 @@ public class ClientModeImplTest extends WifiBaseTest {
anyInt(), anyInt());
}
- /**
+ /**
* Verify Trust On First Use support.
* - this network is automatically connected.
* - Tap the notification.
@@ -9878,22 +10020,24 @@ public class ClientModeImplTest extends WifiBaseTest {
link1.setChannel(TEST_CHANNEL);
link1.setApMacAddress(MacAddress.fromString(TEST_BSSID_STR));
link1.setLinkId(TEST_MLO_LINK_ID);
+ link1.setRssi(TEST_RSSI);
MloLink link2 = new MloLink();
link2.setBand(WifiScanner.WIFI_BAND_5_GHZ);
link2.setChannel(TEST_CHANNEL_1);
link2.setApMacAddress(MacAddress.fromString(TEST_BSSID_STR1));
link2.setLinkId(TEST_MLO_LINK_ID_1);
+ link2.setRssi(TEST_RSSI);
mloLinks.add(link1);
mloLinks.add(link2);
when(mScanResult.getApMldMacAddress()).thenReturn(TEST_AP_MLD_MAC_ADDRESS);
when(mScanResult.getApMloLinkId()).thenReturn(TEST_MLO_LINK_ID);
when(mScanResult.getAffiliatedMloLinks()).thenReturn(mloLinks);
+ mScanResult.level = TEST_RSSI;
when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID))
.thenReturn(mScanDetailCache);
when(mScanDetailCache.getScanResult(any())).thenReturn(mScanResult);
-
}
private void setScanResultWithoutMloInfo() {
@@ -9942,6 +10086,33 @@ public class ClientModeImplTest extends WifiBaseTest {
assertFalse(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR2)));
}
+ @Test
+ public void testAffiliatedLinkBssidMatchWithNullLinkMacAddress() throws Exception {
+ setConnection();
+ List<MloLink> mloLinks = new ArrayList<>();
+ // Build MLO link with null link mac address
+ MloLink link1 = new MloLink();
+ link1.setBand(WifiScanner.WIFI_BAND_24_GHZ);
+ link1.setChannel(TEST_CHANNEL);
+ link1.setLinkId(TEST_MLO_LINK_ID);
+ link1.setRssi(TEST_RSSI);
+ mloLinks.add(link1);
+ when(mScanResult.getApMldMacAddress()).thenReturn(TEST_AP_MLD_MAC_ADDRESS);
+ when(mScanResult.getApMloLinkId()).thenReturn(TEST_MLO_LINK_ID);
+ when(mScanResult.getAffiliatedMloLinks()).thenReturn(mloLinks);
+ mScanResult.level = TEST_RSSI;
+ when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID))
+ .thenReturn(mScanDetailCache);
+ when(mScanDetailCache.getScanResult(any())).thenReturn(mScanResult);
+ // Associate
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq,
+ SupplicantState.ASSOCIATED));
+ mLooper.dispatchAll();
+ // Test isAffiliatedLinkBssid match fails with no NPE
+ assertFalse(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR)));
+ }
+
/**
* Verify MLO parameters update from ScanResult at association
*/
@@ -10264,7 +10435,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.connectNetwork(
new NetworkUpdateResult(TEST_NETWORK_ID),
new ActionListenerWrapper(connectActionListener),
- Process.SYSTEM_UID, OP_PACKAGE_NAME);
+ Process.SYSTEM_UID, OP_PACKAGE_NAME, null);
mLooper.dispatchAll();
verify(connectActionListener).onSuccess();
if (shouldDropRequest) {
@@ -10277,13 +10448,22 @@ public class ClientModeImplTest extends WifiBaseTest {
}
private ScanResult makeScanResult(String ssid, String caps) {
- ScanResult scanResult = new ScanResult(WifiSsid.fromUtf8Text(ssid.replace("\"", "")),
- ssid, TEST_BSSID_STR, 1245, 0, caps, -78, 2412, 1025, 22, 33, 20, 0, 0, true);
+ ScanResult scanResult = new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(ssid.replace("\"", "")),
+ TEST_BSSID_STR)
+ .setHessid(1245)
+ .setCaps(caps)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID,
ssid.getBytes(StandardCharsets.UTF_8));
scanResult.informationElements = new ScanResult.InformationElement[]{ie};
return scanResult;
-
}
private void verifyConnectWithDisabledPskType(
@@ -10734,6 +10914,28 @@ public class ClientModeImplTest extends WifiBaseTest {
assertEquals(links.get(1).getBand(), WifiScanner.WIFI_BAND_5_GHZ);
assertEquals(links.get(1).getChannel(), TEST_CHANNEL_1);
assertEquals(links.get(1).getLinkId(), TEST_MLO_LINK_ID_1);
+
+ // Make sure the dynamic attributes (Tx link speed, Rx link speed and RSSI) are matching
+ // with poll results for associated links.
+ assertEquals(65, links.get(0).getTxLinkSpeedMbps());
+ assertEquals(54, links.get(0).getRxLinkSpeedMbps());
+ assertEquals(-42, links.get(0).getRssi());
+
+ // Make sure the RSSI is matching with scan cache for un-associated links
+ assertEquals(TEST_RSSI, links.get(1).getRssi());
+
+ // Send signal poll for un-associated link
+ signalPollResults = new WifiSignalPollResults();
+ signalPollResults.addEntry(TEST_MLO_LINK_ID_1, -42, 65, 54, sFreq);
+ when(mWifiNative.signalPoll(any())).thenReturn(signalPollResults);
+ mCmi.enableRssiPolling(true);
+ mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1);
+ mLooper.dispatchAll();
+ links = mWifiInfo.getAffiliatedMloLinks();
+
+ // Make sure the RSSI is matching with scan result for associated link
+ assertEquals(TEST_RSSI, links.get(0).getRssi());
+
}
/**
@@ -10831,4 +11033,71 @@ public class ClientModeImplTest extends WifiBaseTest {
assertEquals(53, links.get(0).getChannel());
assertEquals(WifiScanner.WIFI_BAND_6_GHZ, links.get(0).getBand());
}
+
+ /**
+ * Verify that we disconnect Wi-Fi 7 is toggled.
+ */
+ @Test
+ public void verifyDisconnectOnTogglingWifi7() throws Exception {
+ connect();
+
+ WifiConfiguration oldConfig = new WifiConfiguration(mConnectedNetwork);
+ mConnectedNetwork.setWifi7Enabled(false);
+
+ for (WifiConfigManager.OnNetworkUpdateListener listener : mConfigUpdateListenerCaptor
+ .getAllValues()) {
+ listener.onNetworkUpdated(mConnectedNetwork, oldConfig, false);
+ }
+ mLooper.dispatchAll();
+ verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
+ verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT),
+ eq(StaEvent.DISCONNECT_NETWORK_WIFI7_TOGGLED));
+ }
+
+ private void testDhcpHostnameSetting(
+ boolean configEnabled,
+ @WifiManager.SendDhcpHostnameRestriction int restriction,
+ int security,
+ int expectedHostnameSetting) throws Exception {
+ if (!SdkLevel.isAtLeastV()) {
+ expectedHostnameSetting = IIpClient.HOSTNAME_SETTING_UNSET;
+ }
+ when(mWifiGlobals.getSendDhcpHostnameRestriction()).thenReturn(restriction);
+ mConnectedNetwork.setSecurityParams(security);
+ mConnectedNetwork.setSendDhcpHostnameEnabled(configEnabled);
+ connect();
+
+ verify(mIpClient).startProvisioning(mProvisioningConfigurationCaptor.capture());
+ assertEquals(expectedHostnameSetting,
+ mProvisioningConfigurationCaptor.getValue().hostnameSetting);
+ }
+
+ @Test
+ public void testSendDhcpHostnameEnabled() throws Exception {
+ testDhcpHostnameSetting(true, 0, SECURITY_TYPE_OPEN, IIpClient.HOSTNAME_SETTING_SEND);
+ }
+
+ @Test
+ public void testSendDhcpHostnameDisabled() throws Exception {
+ testDhcpHostnameSetting(false, 0,
+ SECURITY_TYPE_OPEN, IIpClient.HOSTNAME_SETTING_DO_NOT_SEND);
+ }
+
+ @Test
+ public void testSendDhcpHostnameEnabledWithOpenRestriction() throws Exception {
+ testDhcpHostnameSetting(true, WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN,
+ SECURITY_TYPE_OPEN, IIpClient.HOSTNAME_SETTING_DO_NOT_SEND);
+ }
+
+ @Test
+ public void testSendDhcpHostnameEnabledWithOpenRestrictionOwe() throws Exception {
+ testDhcpHostnameSetting(true, WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN,
+ SECURITY_TYPE_OWE, IIpClient.HOSTNAME_SETTING_DO_NOT_SEND);
+ }
+
+ @Test
+ public void testSendDhcpHostnameEnabledWithSecureRestriction() throws Exception {
+ testDhcpHostnameSetting(true, WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_SECURE,
+ SECURITY_TYPE_PSK, IIpClient.HOSTNAME_SETTING_DO_NOT_SEND);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
index a823f64c08..e30e8f8262 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
@@ -61,10 +61,11 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.RegistrationManager;
-import android.test.suitebuilder.annotation.SmallTest;
import android.util.LocalLog;
import android.util.Log;
+import androidx.test.filters.SmallTest;
+
import com.android.server.wifi.ClientModeManagerBroadcastQueue.QueuedBroadcast;
import com.android.wifi.resources.R;
@@ -779,6 +780,33 @@ public class ConcreteClientModeManagerTest extends WifiBaseTest {
}
/**
+ * Secondary CMM will stop without deferring.
+ */
+ @Test
+ public void clientModeStopWithWifiOffDeferringTimeWithWifiCallingOnSecondaryTransient()
+ throws Exception {
+ setUpVoWifiTest(true,
+ TEST_WIFI_OFF_DEFERRING_TIME_MS);
+ startClientInConnectModeAndVerifyEnabled();
+ reset(mContext, mListener);
+ setUpSystemServiceForContext();
+
+ // Make sure CMM is not primary
+ mClientModeManager.setRole(ROLE_CLIENT_SECONDARY_TRANSIENT, TEST_WORKSOURCE);
+ mLooper.dispatchAll();
+
+ // Stop CMM and verify the Defer stop code is skipped
+ mClientModeManager.stop();
+ mLooper.dispatchAll();
+ when(mClientModeImpl.hasQuit()).thenReturn(true);
+ mClientModeManager.onClientModeImplQuit();
+ verify(mListener).onStopped(mClientModeManager);
+ verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any());
+ verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
+ verify(mWifiMetrics).noteWifiOff(eq(false), eq(false), anyInt());
+ }
+
+ /**
* ClientMode stop properly with IMS deferring time without WifiCalling.
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ConnectHelperTest.java b/service/tests/wifitests/src/com/android/server/wifi/ConnectHelperTest.java
index dc4e2b7091..bdf82a75b2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ConnectHelperTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ConnectHelperTest.java
@@ -17,6 +17,7 @@
package com.android.server.wifi;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -44,6 +45,7 @@ public class ConnectHelperTest extends WifiBaseTest {
private static final int TEST_NETWORK_ID = 42;
private static final String TEST_SSID = "TestSSID";
private static final String TEST_PACKAGE_NAME = "com.test.xxx";
+ private static final String TEST_ATTRIBUTION_TAG = "TEST_ATTRIBUTION_TAG";
private ConnectHelper mConnectHelper;
@@ -68,33 +70,42 @@ public class ConnectHelperTest extends WifiBaseTest {
mWifiConfig.networkId = TEST_NETWORK_ID;
}
- @Test
- public void connectToNetwork_success() throws Exception {
+ private void verifyConnectNetworkSuccess(String attributionTag, boolean expectDisableOthers) {
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(mWifiConfig);
NetworkUpdateResult result = new NetworkUpdateResult(TEST_NETWORK_ID);
mConnectHelper.connectToNetwork(result, mActionListener, TEST_CALLING_UID,
- TEST_PACKAGE_NAME);
+ TEST_PACKAGE_NAME, attributionTag);
verify(mWifiConfigManager).updateBeforeConnect(TEST_NETWORK_ID, TEST_CALLING_UID,
- TEST_PACKAGE_NAME);
+ TEST_PACKAGE_NAME, expectDisableOthers);
verify(mClientModeManager).connectNetwork(eq(result), any(), eq(TEST_CALLING_UID),
- eq(TEST_PACKAGE_NAME));
+ eq(TEST_PACKAGE_NAME), eq(attributionTag));
// success is sent by ClientModeManager, not sent by ConnectHelper
verify(mActionListener, never()).sendSuccess();
verify(mActionListener, never()).sendFailure(anyInt());
}
@Test
+ public void connectToNetwork_success() throws Exception {
+ verifyConnectNetworkSuccess(TEST_ATTRIBUTION_TAG, true);
+ }
+
+ @Test
+ public void connectToNetwork_successDisallowUserConnectChoice() throws Exception {
+ verifyConnectNetworkSuccess(ClientModeImpl.ATTRIBUTION_TAG_DISALLOW_CONNECT_CHOICE, false);
+ }
+
+ @Test
public void connectToNetwork_invalidNetId_failure() throws Exception {
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(null);
mConnectHelper.connectToNetwork(new NetworkUpdateResult(TEST_NETWORK_ID), mActionListener,
- TEST_CALLING_UID, TEST_PACKAGE_NAME);
+ TEST_CALLING_UID, TEST_PACKAGE_NAME, TEST_ATTRIBUTION_TAG);
- verify(mWifiConfigManager, never()).updateBeforeConnect(TEST_NETWORK_ID, TEST_CALLING_UID,
- TEST_PACKAGE_NAME);
- verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any());
+ verify(mWifiConfigManager, never()).updateBeforeConnect(anyInt(), anyInt(),
+ any(), anyBoolean());
+ verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any(), any());
verify(mActionListener).sendFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
verify(mActionListener, never()).sendSuccess();
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java
index f060cddac4..1870690353 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java
@@ -79,7 +79,8 @@ import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.test.TestLooper;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
import com.android.internal.util.WakeupMessage;
import com.android.modules.utils.build.SdkLevel;
@@ -855,9 +856,18 @@ public class DppManagerTest extends WifiBaseTest {
*/
private void addTestNetworkInScanResult(int frequency) {
String caps = "[WPA2-FT/SAE+SAE][ESS][WPS]";
- ScanResult scanResult = new ScanResult(WifiSsid.fromUtf8Text(TEST_SSID_NO_QUOTE),
- TEST_SSID_NO_QUOTE, TEST_BSSID, 1245, 0, caps, -78, frequency,
- 1025, 22, 33, 20, 0, 0, true);
+ ScanResult scanResult = new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(TEST_SSID_NO_QUOTE),
+ TEST_BSSID)
+ .setHessid(1245)
+ .setCaps(caps)
+ .setRssi(-78)
+ .setFrequency(frequency)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
List<ScanResult> scanResults = new ArrayList<>();
scanResults.add(scanResult);
when(mScanRequestProxy.getScanResults()).thenReturn(scanResults);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java b/service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java
index d0e4cbc793..40d4694fdd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java
@@ -39,7 +39,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
-import android.test.suitebuilder.annotation.SmallTest;
+import androidx.test.filters.SmallTest;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
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 8fd5c3e7e9..8328dd3618 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalAidlImpTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalAidlImpTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -165,7 +166,7 @@ public class HostapdHalAidlImpTest extends WifiBaseTest {
verify(mockSoftApHalCallback).onInfoChanged(eq(TEST_AP_INSTANCE), eq(TEST_FREQ_24G),
eq(mHostapdHal.mapHalChannelBandwidthToSoftApInfo(TEST_BANDWIDTH)),
eq(mHostapdHal.mapHalGenerationToWifiStandard(TEST_GENERATION)),
- eq(MacAddress.fromString(TEST_CLIENT_MAC)));
+ eq(MacAddress.fromString(TEST_CLIENT_MAC)), anyList());
} else if (numOfApInfo == 2) {
apInfo.apIfaceInstance = TEST_AP_INSTANCE_2;
apInfo.freqMhz = TEST_FREQ_5G;
@@ -173,7 +174,7 @@ public class HostapdHalAidlImpTest extends WifiBaseTest {
verify(mockSoftApHalCallback).onInfoChanged(eq(TEST_AP_INSTANCE_2), eq(TEST_FREQ_5G),
eq(mHostapdHal.mapHalChannelBandwidthToSoftApInfo(TEST_BANDWIDTH)),
eq(mHostapdHal.mapHalGenerationToWifiStandard(TEST_GENERATION)),
- eq(MacAddress.fromString(TEST_CLIENT_MAC)));
+ eq(MacAddress.fromString(TEST_CLIENT_MAC)), anyList());
}
}
@@ -893,7 +894,7 @@ public class HostapdHalAidlImpTest extends WifiBaseTest {
// Trigger on info changed and verify.
mockApInfoChangedAndVerify(IFACE_NAME, 1, mIHostapdCallback, mSoftApHalCallback);
verify(mSoftApHalCallback1, never()).onInfoChanged(anyString(), anyInt(), anyInt(),
- anyInt(), any());
+ anyInt(), any(), anyList());
// Trigger on client connected.
ClientInfo clientInfo = new ClientInfo();
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 44dc1512f9..f1a3c312d7 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalHidlImpTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalHidlImpTest.java
@@ -1321,9 +1321,9 @@ public class HostapdHalHidlImpTest extends WifiBaseTest {
verify(mSoftApHalCallback).onInfoChanged(eq(TEST_AP_INSTANCE), eq(testFreq),
eq(mHostapdHal.mapHalBandwidthToSoftApInfo(testBandwidth)),
eq(mHostapdHal.mapHalGenerationToWifiStandard(testGeneration)),
- eq(MacAddress.fromString(TEST_CLIENT_MAC)));
+ eq(MacAddress.fromString(TEST_CLIENT_MAC)), anyList());
verify(mSoftApHalCallback1, never()).onInfoChanged(anyString(), anyInt(), anyInt(),
- anyInt(), any());
+ anyInt(), any(), anyList());
// Trigger on client connected.
mIHostapdCallback13.onConnectedClientsChanged(IFACE_NAME, TEST_AP_INSTANCE,
diff --git a/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java b/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java
index af60b424e6..3addabb430 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/InsecureEapNetworkHandlerTest.java
@@ -99,6 +99,7 @@ public class InsecureEapNetworkHandlerTest extends WifiBaseTest {
private static final int TEST_GEN_SERVER_CERT = 2;
private static final int TEST_GEN_SELF_SIGNED_CERT = 3;
private static final int TEST_GEN_FAKE_CA_CERT = 4;
+ private static final int TEST_GEN_SERVER_CERTIFICATE_WITHOUT_COMMON_NAME = 5;
private static final String TEST_SERVER_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n"
+ "MIIGPjCCBCagAwIBAgIUN2Ss1JmvjveRe97iWoNh4V+Y5LYwDQYJKoZIhvcNAQEM\n"
@@ -279,6 +280,42 @@ public class InsecureEapNetworkHandlerTest extends WifiBaseTest {
+ "jUR49A==\n"
+ "-----END CERTIFICATE-----";
+ private static final String TEST_SERVER_CERTIFICATE_WITHOUT_COMMON_NAME =
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIIF+zCCA+OgAwIBAgIUCvmbTyLRy+5/Tt8iSpBB+xmZTfUwDQYJKoZIhvcNAQEM\n"
+ + "BQAwgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRswGQYDVQQK\n"
+ + "DBJBbmRyb2lkIFdpLUZpIFRlc3QxGDAWBgNVBAsMD2FuZHJvaWR3aWZpLm9lbTE8\n"
+ + "MDoGA1UEAwwzQW5kcm9pZCBQYXJ0bmVyIFJvb3QgQ0EgZm9yIHRlc3RpbmcgYW5k\n"
+ + "IGRldmVsb3BtZW50MB4XDTI0MDMxMzE3NTIwMFoXDTI2MDMxMzE3NTIwMFowQTEL\n"
+ + "MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExHTAbBgNVBAoMFEFuZHJv\n"
+ + "aWQgV2ktRmkgVGVzdGVyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA\n"
+ + "uVNdRG1M/DVcfqi1Cl1FRXxZ2eeKe/IM6OA4KhkR0aymZtjmsoTO52JFVoTykCrj\n"
+ + "bnDp6wOTDaglwbClip/Be5Oj//6LS+A5J3PqUfQsOI+s8ZeAu6s4Kur4g0oPhfNz\n"
+ + "msRyQvhIUkwYCXEum+uQ3INLpy38JggEbTRR4nnn2UUh4+Shv9xYA/SiYrV/sd/f\n"
+ + "Vj++lAmOUQu/CLCWtpfBFTeiyg/DhypbHQVPnr+k1QBy7DKZlBXQb7POjE4M6Ed/\n"
+ + "/st11tB8qHZnM8Xe4CdM3xSJj9qs2BQyT228z7SCmA3r3P1CMvSRYqWu1mn4iMO1\n"
+ + "t0sShF/OfUkihE1ADA0q6GRHDLQ3T/TSnuYWyH4/iMMygHl+yfDeECaLOn/KEQM9\n"
+ + "hOBlXo5iKB/GMkFKeoGQQePwWllHK7HjNEAOOPyXS4nzRA1VUq0gVvhFpQX7ZK9X\n"
+ + "OWdNdcnof4wzOEJse96I7v3A1C0FYg57f1HKOnx195hb1wQfi0MOyE/mgqvtVWbP\n"
+ + "90Vd2nFMlNSVc38DUT7jyYTygUAl5eQDRZo/npNs32nf8YW4cWmN1r+LCHUkK22v\n"
+ + "y8bmSVTts7WHzx9K1kg5+XvaTxpgmmFneuh0XIFvTcGFwMPrHzwaa5pOCYjUvlSy\n"
+ + "GXOmRuSqFipufxxlRKM0cJhMUqI/vmYJ5byx5Wb1N+MCAwEAAaOBkzCBkDAdBgNV\n"
+ + "HQ4EFgQUz4BlPUEPOANhQ74NbClj0CrdiHswHwYDVR0jBBgwFoAUyWVsWmPxPCB6\n"
+ + "D7hRF7K2vyVzKOMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYI\n"
+ + "KwYBBQUHAwEwIQYDVR0RBBowGIIWc2VydmVyLmFuZHJvaWR3aWZpLm9lbTANBgkq\n"
+ + "hkiG9w0BAQwFAAOCAgEAkf5CHaqzDsQKn8udsA9/fIKSOEqr0LUfwP20JzFe0HBA\n"
+ + "F3cWoMrEVoAJFfi5NFQJOjlEib7kvu2MI92lL6ch3D3iW5mnY5Ncnm2eyqi1kvii\n"
+ + "uueKnH4a9jsolWgcsGiw5vUhsodgxWzFr/yDURYZEWkzP4uiW3+0K6eoc11DPiDr\n"
+ + "16LS4xAINHVeEDhhkuZG2Bqo1ctbcQWR7Leb5JGpfkC7xNGyVNUwJYjI5vow5GzR\n"
+ + "Af2SvJuG3mMxBfM+8TMx4wf4Sgq80FmaJLNAOlfKlYIN0u/NV/pq6nWb0B4u3K0u\n"
+ + "ytH3BRJsuKg35fZEy4qRpBZL1Us9FzwPkRaUK+Sgtz9BLRPL5my3xUwnZaqw+ZRp\n"
+ + "Gw+vwErnSc3md9DhYMeGc0JdA141/pxc/P20hoLG7cDK/tO4PwBzNrF57XLEFC7v\n"
+ + "bww0rQoADGCIk48n2gZX/wh1XeHWJhk7C+lGGbA/qrs5zZbzDaMi/N3C74eiQJOH\n"
+ + "KdQk10pt2nU8xwC/RsfL7W+2K4c4/mZvaroxQvIxs8tRB3glbpwQe4HntpE0LdvH\n"
+ + "7hotzbIt0YtGtzIdOwpR277a73qT09pmYL97+rwPGWMviCkb9QNvFHBKc0MsgxXz\n"
+ + "15THXfttbGruZySMyj9kMox0NbhsVKiSEEiqMMHvJMbn4FDI1O9U5IDZdUplI0A=\n"
+ + "-----END CERTIFICATE-----";
+
@Mock WifiContext mContext;
@Mock WifiConfigManager mWifiConfigManager;
@Mock WifiNative mWifiNative;
@@ -660,6 +697,8 @@ public class InsecureEapNetworkHandlerTest extends WifiBaseTest {
certString = TEST_SELF_SIGNED_CERTIFICATE;
} else if (type == TEST_GEN_FAKE_CA_CERT) {
certString = TEST_FAKE_CA_CERTIFICATE;
+ } else if (type == TEST_GEN_SERVER_CERTIFICATE_WITHOUT_COMMON_NAME) {
+ certString = TEST_SERVER_CERTIFICATE_WITHOUT_COMMON_NAME;
} else {
throw (new Exception());
}
@@ -921,6 +960,31 @@ public class InsecureEapNetworkHandlerTest extends WifiBaseTest {
}
/**
+ * Verify that is reports errors if the server certificate doesn't contain the common name
+ */
+ @Test
+ public void verifyOnErrorWithServerCertificateWithoutCommonName() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true;
+
+ WifiConfiguration config = prepareWifiConfiguration(isAtLeastT);
+ setupTest(config, isAtLeastT, isTrustOnFirstUseSupported);
+
+ CertificateEventInfo mockCaCert = generateMockCertEventInfo(TEST_GEN_CA2_CERT);
+ // Server certificate without common name
+ CertificateEventInfo mockServerCert =
+ generateMockCertEventInfo(TEST_GEN_SERVER_CERTIFICATE_WITHOUT_COMMON_NAME);
+ mInsecureEapNetworkHandler.addPendingCertificate(config.networkId, 1, mockCaCert);
+ mInsecureEapNetworkHandler.addPendingCertificate(config.networkId, 0, mockServerCert);
+
+ mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected);
+ verify(mCallbacks).onError(eq(config.SSID));
+ verify(mWifiConfigManager, atLeastOnce()).updateNetworkSelectionStatus(eq(config.networkId),
+ eq(WifiConfiguration.NetworkSelectionStatus
+ .DISABLED_BY_WIFI_MANAGER));
+ }
+
+ /**
* Verify that setting pending certificate won't crash with no current configuration.
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/MultiInternetWifiNetworkFactoryTest.java b/service/tests/wifitests/src/com/android/server/wifi/MultiInternetWifiNetworkFactoryTest.java
index 70412573f0..fa1dc98e00 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/MultiInternetWifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/MultiInternetWifiNetworkFactoryTest.java
@@ -39,9 +39,10 @@ import android.net.wifi.WifiNetworkSpecifier;
import android.os.PatternMatcher;
import android.os.WorkSource;
import android.os.test.TestLooper;
-import android.test.suitebuilder.annotation.SmallTest;
import android.util.LocalLog;
+import androidx.test.filters.SmallTest;
+
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -50,6 +51,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+
/**
* Unit tests for {@link com.android.server.wifi.MultiInternetWifiNetworkFactory}.
*/
diff --git a/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
index 3598cf128e..06384c3138 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
@@ -103,6 +103,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
+ "<int name=\"DeletionPriority\" value=\"0\" />\n"
+ "<int name=\"NumRebootsSinceLastUse\" value=\"0\" />\n"
+ "<boolean name=\"RepeaterEnabled\" value=\"false\" />\n"
+ + "<boolean name=\"EnableWifi7\" value=\"true\" />\n"
+ "<SecurityParamsList>\n"
+ "<SecurityParams>\n"
+ "<int name=\"SecurityType\" value=\"0\" />\n"
@@ -121,6 +122,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
+ "<byte-array name=\"AllowedSuiteBCiphers\" num=\"0\"></byte-array>\n"
+ "</SecurityParams>\n"
+ "</SecurityParamsList>\n"
+ + "<boolean name=\"SendDhcpHostname\" value=\"true\" />\n"
+ "<boolean name=\"Trusted\" value=\"true\" />\n"
+ "<boolean name=\"IsRestricted\" value=\"false\" />\n"
+ "<boolean name=\"OemPaid\" value=\"false\" />\n"
@@ -192,6 +194,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
+ "<int name=\"DeletionPriority\" value=\"0\" />\n"
+ "<int name=\"NumRebootsSinceLastUse\" value=\"0\" />\n"
+ "<boolean name=\"RepeaterEnabled\" value=\"false\" />\n"
+ + "<boolean name=\"EnableWifi7\" value=\"true\" />\n"
+ "<SecurityParamsList>\n"
+ "<SecurityParams>\n"
+ "<int name=\"SecurityType\" value=\"3\" />\n"
@@ -210,6 +213,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
+ "<byte-array name=\"AllowedSuiteBCiphers\" num=\"0\"></byte-array>\n"
+ "</SecurityParams>\n"
+ "</SecurityParamsList>\n"
+ + "<boolean name=\"SendDhcpHostname\" value=\"true\" />\n"
+ "<boolean name=\"Trusted\" value=\"true\" />\n"
+ "<boolean name=\"IsRestricted\" value=\"false\" />\n"
+ "<boolean name=\"OemPaid\" value=\"false\" />\n"
@@ -315,6 +319,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
+ "<int name=\"DeletionPriority\" value=\"0\" />\n"
+ "<int name=\"NumRebootsSinceLastUse\" value=\"0\" />\n"
+ "<boolean name=\"RepeaterEnabled\" value=\"false\" />\n"
+ + "<boolean name=\"EnableWifi7\" value=\"true\" />\n"
+ "<SecurityParamsList>\n"
+ "<SecurityParams>\n"
+ "<int name=\"SecurityType\" value=\"4\" />\n"
@@ -325,6 +330,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
+ "<byte-array name=\"AllowedSuiteBCiphers\" num=\"0\"></byte-array>\n"
+ "</SecurityParams>\n"
+ "</SecurityParamsList>\n"
+ + "<boolean name=\"SendDhcpHostname\" value=\"true\" />\n"
+ "<boolean name=\"Trusted\" value=\"true\" />\n"
+ "<boolean name=\"IsRestricted\" value=\"false\" />\n"
+ "<boolean name=\"OemPaid\" value=\"false\" />\n"
@@ -396,6 +402,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
+ "<int name=\"DeletionPriority\" value=\"0\" />\n"
+ "<int name=\"NumRebootsSinceLastUse\" value=\"0\" />\n"
+ "<boolean name=\"RepeaterEnabled\" value=\"false\" />\n"
+ + "<boolean name=\"EnableWifi7\" value=\"true\" />\n"
+ "<SecurityParamsList>\n"
+ "<SecurityParams>\n"
+ "<int name=\"SecurityType\" value=\"3\" />\n"
@@ -414,6 +421,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
+ "<byte-array name=\"AllowedSuiteBCiphers\" num=\"0\"></byte-array>\n"
+ "</SecurityParams>\n"
+ "</SecurityParamsList>\n"
+ + "<boolean name=\"SendDhcpHostname\" value=\"true\" />\n"
+ "<boolean name=\"Trusted\" value=\"true\" />\n"
+ "<boolean name=\"OemPaid\" value=\"false\" />\n"
+ "<boolean name=\"OemPrivate\" value=\"false\" />\n"
@@ -521,6 +529,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
+ "<int name=\"DeletionPriority\" value=\"0\" />\n"
+ "<int name=\"NumRebootsSinceLastUse\" value=\"0\" />\n"
+ "<boolean name=\"RepeaterEnabled\" value=\"false\" />\n"
+ + "<boolean name=\"EnableWifi7\" value=\"true\" />\n"
+ "<boolean name=\"Trusted\" value=\"true\" />\n"
+ "<null name=\"BSSID\" />\n"
+ "<int name=\"Status\" value=\"2\" />\n"
diff --git a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java
index b89a150738..7d65e3f78f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java
@@ -42,6 +42,7 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiSsid;
+import android.os.Process;
import android.telephony.SubscriptionManager;
import android.util.LocalLog;
import android.util.Pair;
@@ -1820,6 +1821,53 @@ public class NetworkSuggestionNominatorTest extends WifiBaseTest {
.incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
}
+ /**
+ * Ensure that we nominate the one matching network suggestion.
+ * Because the only matched suggestion is restricted and suggested by the SYSTEM_SERVER
+ * Expected connectable Networks: {suggestionSsids[0]}
+ */
+ @Test
+ public void testSelectNetworkSuggestionForOneMatchRestrictedAllowBySystemServer() {
+ String[] scanSsids = {"test1", "test2"};
+ String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
+ int[] freqs = {2470, 2437};
+ String[] caps = {"[WPA2-EAP/SHA1-CCMP][ESS]", "[WPA2-EAP/SHA1-CCMP][ESS]"};
+ int[] levels = {-67, -76};
+ String[] suggestionSsids = {"\"" + scanSsids[0] + "\""};
+ int[] securities = {SECURITY_PSK};
+ boolean[] appInteractions = {true};
+ boolean[] meteredness = {true};
+ int[] priorities = {-1};
+ int[] uids = {Process.SYSTEM_UID};
+ String[] packageNames = {TEST_PACKAGE};
+ boolean[] autojoin = {true};
+ boolean[] shareWithUser = {true};
+ int[] priorityGroup = {0};
+
+ ScanDetail[] scanDetails =
+ buildScanDetails(scanSsids, bssids, freqs, caps, levels, mClock);
+ ExtendedWifiNetworkSuggestion[] suggestions = buildNetworkSuggestions(suggestionSsids,
+ securities, appInteractions, meteredness, priorities, uids,
+ packageNames, autojoin, shareWithUser, priorityGroup);
+ suggestions[0].wns.wifiConfiguration.restricted = true;
+ // Link the scan result with suggestions.
+ linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
+
+ setupAddToWifiConfigManager(suggestions[0]);
+
+ List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks = new ArrayList<>();
+ mNetworkSuggestionNominator.nominateNetworks(
+ Arrays.asList(scanDetails), mPasspointCandidates, true, false, false,
+ Collections.emptySet(), // restrictedNetworkAllowedUids is empty
+ (ScanDetail scanDetail, WifiConfiguration configuration) -> {
+ connectableNetworks.add(Pair.create(scanDetail, configuration));
+ });
+
+ validateConnectableNetworks(connectableNetworks, scanSsids[0]);
+ verify(mWifiMetrics, never())
+ .incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
+ }
+
private void setupAddToWifiConfigManager(ExtendedWifiNetworkSuggestion...candidates) {
for (int i = 0; i < candidates.length; i++) {
WifiConfiguration candidate = candidates[i].createInternalWifiConfiguration(
diff --git a/service/tests/wifitests/src/com/android/server/wifi/OemWifiNetworkFactoryTest.java b/service/tests/wifitests/src/com/android/server/wifi/OemWifiNetworkFactoryTest.java
index 63e811dbc7..45439e0ed6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/OemWifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/OemWifiNetworkFactoryTest.java
@@ -25,7 +25,8 @@ import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.WorkSource;
import android.os.test.TestLooper;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
import com.android.modules.utils.build.SdkLevel;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java b/service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
index 533c5b95a3..e061ea5e3f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
@@ -554,7 +554,7 @@ public class OpenNetworkNotifierTest extends WifiBaseTest {
@Test
public void actionConnectToNetwork_notificationNotShowing_doesNothing() {
mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
- verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
+ verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any(), any());
}
/**
@@ -575,7 +575,7 @@ public class OpenNetworkNotifierTest extends WifiBaseTest {
mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
verify(mConnectHelper).connectToNetwork(eq(new NetworkUpdateResult(TEST_NETWORK_ID)),
- any(ActionListenerWrapper.class), eq(Process.SYSTEM_UID), any());
+ any(ActionListenerWrapper.class), eq(Process.SYSTEM_UID), any(), any());
// Connecting Notification
verify(mNotificationBuilder).createNetworkConnectingNotification(OPEN_NET_NOTIFIER_TAG,
mTestNetwork);
@@ -759,7 +759,7 @@ public class OpenNetworkNotifierTest extends WifiBaseTest {
ArgumentCaptor<ActionListenerWrapper> connectListenerCaptor =
ArgumentCaptor.forClass(ActionListenerWrapper.class);
verify(mConnectHelper).connectToNetwork(eq(new NetworkUpdateResult(TEST_NETWORK_ID)),
- connectListenerCaptor.capture(), eq(Process.SYSTEM_UID), any());
+ connectListenerCaptor.capture(), eq(Process.SYSTEM_UID), any(), any());
ActionListenerWrapper connectListener = connectListenerCaptor.getValue();
// Connecting Notification
diff --git a/service/tests/wifitests/src/com/android/server/wifi/OuiKeyedDataUtil.java b/service/tests/wifitests/src/com/android/server/wifi/OuiKeyedDataUtil.java
new file mode 100644
index 0000000000..3be43596a2
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/OuiKeyedDataUtil.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import android.net.wifi.OuiKeyedData;
+import android.os.PersistableBundle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test utils for {@link OuiKeyedData}. Implementation is the same as
+ * {@link android.net.wifi.OuiKeyedDataUtil}
+ */
+public class OuiKeyedDataUtil {
+ private static final String STRING_FIELD_KEY = "stringField";
+ private static final String ARRAY_FIELD_KEY = "arrayField";
+
+ private static final String STRING_FIELD_VALUE = "someString";
+ private static final int[] ARRAY_FIELD_VALUE = new int[] {1, 2, 3};
+
+ /**
+ * Generate a single OuiKeyedData object containing several test fields.
+ */
+ public static OuiKeyedData createTestOuiKeyedData(int oui) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putString(STRING_FIELD_KEY, STRING_FIELD_VALUE);
+ bundle.putIntArray(ARRAY_FIELD_KEY, ARRAY_FIELD_VALUE);
+ return new OuiKeyedData.Builder(oui, bundle).build();
+ }
+
+ /**
+ * Generate a list of OuiKeyedData objects, each containing several test fields.
+ */
+ public static List<OuiKeyedData> createTestOuiKeyedDataList(int size) {
+ List<OuiKeyedData> ouiKeyedDataList = new ArrayList<>();
+ for (int i = 0; i < size; i++) {
+ ouiKeyedDataList.add(createTestOuiKeyedData(i + 1));
+ }
+ return ouiKeyedDataList;
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/RestrictedWifiNetworkFactoryTest.java b/service/tests/wifitests/src/com/android/server/wifi/RestrictedWifiNetworkFactoryTest.java
index eca0a01e0a..12cac6ece4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/RestrictedWifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/RestrictedWifiNetworkFactoryTest.java
@@ -27,7 +27,8 @@ import android.content.Context;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.test.TestLooper;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
import org.junit.After;
import org.junit.Before;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java b/service/tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java
index 025973cabc..850f8a7a82 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SavedNetworkNominatorTest.java
@@ -26,10 +26,11 @@ import static org.mockito.Mockito.*;
import android.net.MacAddress;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
-import android.test.suitebuilder.annotation.SmallTest;
import android.util.LocalLog;
import android.util.Pair;
+import androidx.test.filters.SmallTest;
+
import com.android.server.wifi.WifiNetworkSelector.NetworkNominator.OnConnectableListener;
import com.android.server.wifi.WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs;
import com.android.server.wifi.entitlement.PseudonymInfo;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java b/service/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java
index ccbc456203..7c690e7856 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java
@@ -311,9 +311,11 @@ public class ScanTestUtil {
}
public static ScanResult createScanResult(int freq) {
- return new ScanResult(WifiSsid.fromUtf8Text("AN SSID"),
- MacAddressUtils.createRandomUnicastAddress().toString(), 0L,
- -1, null, "", 0, freq, 0);
+ return new ScanResult.Builder(WifiSsid.fromUtf8Text("AN SSID"),
+ MacAddressUtils.createRandomUnicastAddress().toString())
+ .setCaps("")
+ .setFrequency(freq)
+ .build();
}
private static ScanData createScanData(int[] freqs, int bucketsScanned, int bandScanned) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java b/service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java
index cc9080fdb6..b8759d84df 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java
@@ -18,6 +18,8 @@ package com.android.server.wifi;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -276,6 +278,10 @@ public class SelfRecoveryTest extends WifiBaseTest {
@Test
public void testUnsolicitedSystemRestart() {
mRestartListenerCaptor.getValue().onSubsystemRestart();
+ ExtendedMockito.verify(() -> WifiStatsLog.write(eq(WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED),
+ eq(WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__REASON__REASON_SUBSYSTEM_RESTART),
+ eq(WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__RESULT__RES_RESTART_STARTED_INTERNAL_RECOVERY_BY_NATIVE_CALLBACK),
+ anyLong()));
verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_SUBSYSTEM_RESTART,
true);
assertTrue(mSelfRecovery.isRecoveryInProgress());
@@ -369,15 +375,20 @@ public class SelfRecoveryTest extends WifiBaseTest {
10000L));
when(mClock.getWallClockMillis()).thenReturn(100000L);
- when(mWifiNative.startSubsystemRestart()).thenReturn(false);
+ doAnswer((invocation) -> {
+ return false;
+ }).when(mWifiNative).startSubsystemRestart();
mSelfRecovery.trigger(SelfRecovery.REASON_API_CALL);
ExtendedMockito.verify(() -> WifiStatsLog.write(WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED,
WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__REASON__REASON_API_CALL,
- WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__RESULT__RES_RESTART_FAILURE,
+ WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__RESULT__RES_RESTART_STARTED_INTERNAL_RECOVERY,
20000L));
when(mClock.getWallClockMillis()).thenReturn(160000L);
- when(mWifiNative.startSubsystemRestart()).thenReturn(true);
+ doAnswer((invocation) -> {
+ mRestartListenerCaptor.getValue().onSubsystemRestart();
+ return true;
+ }).when(mWifiNative).startSubsystemRestart();
mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
ExtendedMockito.verify(() -> WifiStatsLog.write(WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED,
WifiStatsLog.WIFI_SELF_RECOVERY_TRIGGERED__REASON__REASON_LAST_RESORT_WDOG,
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 8cfd632061..03ca47d3fb 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -63,17 +63,21 @@ 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;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.ScanResult;
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.SoftApState;
import android.net.wifi.WifiClient;
import android.net.wifi.WifiContext;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
+import android.net.wifi.nl80211.DeviceWiphyCapabilities;
import android.net.wifi.nl80211.NativeWifiClient;
import android.os.BatteryManager;
import android.os.Message;
@@ -105,6 +109,7 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -125,6 +130,7 @@ public class SoftApManagerTest extends WifiBaseTest {
private static final String TEST_FIRST_INSTANCE_NAME = "testif1";
private static final String TEST_SECOND_INSTANCE_NAME = "testif2";
private static final String OTHER_INTERFACE_NAME = "otherif";
+ private static final String TEST_STA_INTERFACE_NAME = "testif0sta";
private static final long TEST_DEFAULT_SHUTDOWN_TIMEOUT_MILLIS = 600_000;
private static final long TEST_DEFAULT_SHUTDOWN_IDLE_INSTANCE_IN_BRIDGED_MODE_TIMEOUT_MILLIS =
300_000;
@@ -160,6 +166,10 @@ public class SoftApManagerTest extends WifiBaseTest {
private static final int[] ALLOWED_60G_FREQS = {58320, 60480}; // ch# 1, 2
private static final WorkSource TEST_WORKSOURCE = new WorkSource();
private SoftApConfiguration mDefaultApConfig = createDefaultApConfig();
+
+ private static final TetheringManager.TetheringRequest TEST_TETHERING_REQUEST =
+ new TetheringManager.TetheringRequest.Builder(TetheringManager.TETHERING_WIFI).build();
+
private final int mBand256G = SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
| SoftApConfiguration.BAND_6GHZ;
private static final int[] TEST_SUPPORTED_24G_CHANNELS = new int[] {1, 2};
@@ -207,6 +217,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Mock WifiInjector mWifiInjector;
@Mock WifiCountryCode mWifiCountryCode;
@Mock LocalLog mLocalLog;
+ @Mock DeviceWiphyCapabilities mDeviceWiphyCapabilities;
final ArgumentCaptor<WifiNative.InterfaceCallback> mWifiNativeInterfaceCallbackCaptor =
ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
@@ -229,14 +240,16 @@ public class SoftApManagerTest extends WifiBaseTest {
/** Old callback event from wificond */
private void mockChannelSwitchEvent(int frequency, int bandwidth) {
mSoftApHalCallbackCaptor.getValue().onInfoChanged(
- TEST_INTERFACE_NAME, frequency, bandwidth, 0, null);
+ TEST_INTERFACE_NAME, frequency, bandwidth, 0, null, Collections.emptyList());
}
/** New callback event from hostapd */
private void mockApInfoChangedEvent(SoftApInfo apInfo) {
+ List<OuiKeyedData> vendorData = SdkLevel.isAtLeastV()
+ ? apInfo.getVendorData() : Collections.emptyList();
mSoftApHalCallbackCaptor.getValue().onInfoChanged(
apInfo.getApInstanceIdentifier(), apInfo.getFrequency(), apInfo.getBandwidth(),
- apInfo.getWifiStandardInternal(), apInfo.getBssidInternal());
+ apInfo.getWifiStandardInternal(), apInfo.getBssidInternal(), vendorData);
mTestSoftApInfoMap.put(apInfo.getApInstanceIdentifier(), apInfo);
mTestWifiClientsMap.put(apInfo.getApInstanceIdentifier(), new ArrayList<WifiClient>());
}
@@ -387,9 +400,15 @@ public class SoftApManagerTest extends WifiBaseTest {
.thenReturn(mPrimaryWifiInfo);
when(mConcreteClientModeManager.getConnectionInfo())
.thenReturn(mPrimaryWifiInfo);
+ when(mConcreteClientModeManager.getInterfaceName())
+ .thenReturn(TEST_STA_INTERFACE_NAME);
when(mWifiNative.forceClientDisconnect(any(), any(), anyInt())).thenReturn(true);
when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog);
when(mWifiInjector.getWifiCountryCode()).thenReturn(mWifiCountryCode);
+ when(mWifiNative.getDeviceWiphyCapabilities(any(), anyBoolean())).thenReturn(
+ mDeviceWiphyCapabilities);
+ when(mDeviceWiphyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE))
+ .thenReturn(true);
// Init Test SoftAp infos
mTestSoftApInfo = new SoftApInfo();
@@ -467,7 +486,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void startSoftApWithoutConfig() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
}
@@ -479,7 +498,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
}
@@ -491,7 +510,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabledWithUserApproval(apConfig);
}
@@ -503,15 +522,15 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
when(mInterfaceConflictManager.manageInterfaceConflictForStateMachine(any(), any(),
any(), any(), any(), anyInt(), any(), anyBoolean()))
.thenReturn(InterfaceConflictManager.ICM_ABORT_COMMAND);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_TETHERED);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_USER_REJECTED);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_USER_REJECTED, TEST_TETHERING_REQUEST, null)));
verify(mListener).onStartFailure(mSoftApManager);
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_INTERFACE_CONFLICT_USER_REJECTED),
@@ -527,7 +546,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
verify(mInterfaceConflictManager).manageInterfaceConflictForStateMachine(any(),
any(), any(), any(), any(), anyInt(), any(), eq(true));
@@ -545,7 +564,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setHiddenSsid(true);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
}
@@ -562,7 +581,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
}
@@ -572,10 +591,10 @@ public class SoftApManagerTest extends WifiBaseTest {
when(mWifiApConfigStore.getApConfiguration()).thenReturn(null);
SoftApModeConfiguration nullApConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(nullApConfig, ROLE_SOFTAP_TETHERED);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_GENERAL, TEST_TETHERING_REQUEST, null)));
verify(mListener).onStartFailure(mSoftApManager);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
if (SdkLevel.isAtLeastSv2()) {
@@ -608,10 +627,10 @@ public class SoftApManagerTest extends WifiBaseTest {
when(mWifiApConfigStore.getApConfiguration()).thenReturn(null);
SoftApModeConfiguration nullApConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(nullApConfig, ROLE_SOFTAP_TETHERED);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_GENERAL, TEST_TETHERING_REQUEST, null)));
verify(mListener).onStartFailure(mSoftApManager);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
if (SdkLevel.isAtLeastSv2()) {
@@ -641,16 +660,19 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testStartSoftApNotPossibleToCreateApInterfaceIncrementsMetrics()
throws Exception {
+ when(mWifiNative.setupInterfaceForSoftApMode(
+ any(), any(), anyInt(), anyBoolean(), any(), anyList())).thenReturn(null);
when(mWifiNative.isItPossibleToCreateApIface(any())).thenReturn(false);
Builder configBuilder = new SoftApConfiguration.Builder();
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ);
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_TETHERED);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mWifiNative).isItPossibleToCreateApIface(any());
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_GENERAL, TEST_TETHERING_REQUEST, null)));
verify(mListener).onStartFailure(mSoftApManager);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
if (SdkLevel.isAtLeastSv2()) {
@@ -684,10 +706,12 @@ public class SoftApManagerTest extends WifiBaseTest {
any(), any(), anyInt(), anyBoolean(), any(), anyList())).thenReturn("");
SoftApModeConfiguration nullApConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(nullApConfig, ROLE_SOFTAP_TETHERED);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mCallback).onStateChanged(eq(new SoftApState(
+ WifiManager.WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL,
+ TEST_TETHERING_REQUEST, "")));
+ verify(mWifiNative).isItPossibleToCreateApIface(any());
verify(mListener).onStartFailure(mSoftApManager);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
if (SdkLevel.isAtLeastSv2()) {
@@ -721,7 +745,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, null);
+ mTestSoftApCapability, null, null);
mSoftApManager = createSoftApManager(softApConfig, ROLE_SOFTAP_TETHERED);
@@ -760,7 +784,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setPassphrase("somepassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, null);
+ mTestSoftApCapability, null, null);
mSoftApManager = createSoftApManager(softApConfig, ROLE_SOFTAP_TETHERED);
@@ -795,7 +819,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
when(mWifiNative.setApCountryCode(
TEST_INTERFACE_NAME, TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT)))
@@ -836,7 +860,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setPassphrase("somepassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
when(mWifiNative.setApCountryCode(
TEST_INTERFACE_NAME, TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT)))
@@ -876,7 +900,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, null);
+ mTestSoftApCapability, null, null);
startSoftApAndVerifyEnabled(softApConfig);
verify(mWifiNative, never()).setApCountryCode(eq(TEST_INTERFACE_NAME), any());
@@ -894,7 +918,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setPassphrase("somepassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, null);
+ mTestSoftApCapability, null, null);
startSoftApAndVerifyEnabled(softApConfig);
verify(mWifiNative, never()).setApCountryCode(eq(TEST_INTERFACE_NAME), any());
@@ -911,7 +935,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
when(mWifiNative.setApCountryCode(eq(TEST_INTERFACE_NAME), any())).thenReturn(false);
@@ -932,7 +956,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setPassphrase("somepassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
when(mWifiNative.setApCountryCode(eq(TEST_INTERFACE_NAME), any())).thenReturn(false);
@@ -954,7 +978,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setSsid(TEST_SSID);
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- noAcsCapability, TEST_COUNTRY_CODE);
+ noAcsCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ))
.thenReturn(EMPTY_CHANNEL_ARRAY);
@@ -977,7 +1001,8 @@ public class SoftApManagerTest extends WifiBaseTest {
softApConfig.getTargetMode());
checkApStateChangedBroadcast(capturedIntents.get(1), WIFI_AP_STATE_FAILED,
WIFI_AP_STATE_ENABLING, WifiManager.SAP_START_FAILURE_NO_CHANNEL,
- TEST_INTERFACE_NAME, softApConfig.getTargetMode());
+ TEST_INTERFACE_NAME, softApConfig.getTargetMode()
+ );
}
/**
@@ -991,13 +1016,14 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration softApModeConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, mDefaultApConfig,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(
softApModeConfig, ROLE_SOFTAP_TETHERED);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mCallback).onStateChanged(eq(new SoftApState(
+ WifiManager.WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
verify(mListener).onStartFailure(mSoftApManager);
verify(mWifiNative).teardownInterface(TEST_INTERFACE_NAME);
verify(mWifiMetrics).writeSoftApStartedEvent(
@@ -1013,7 +1039,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void stopWhenStarted() throws Exception {
SoftApModeConfiguration softApModeConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(softApModeConfig);
// reset to clear verified Intents for ap state change updates
@@ -1025,7 +1051,9 @@ public class SoftApManagerTest extends WifiBaseTest {
mLooper.dispatchAll();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
+ order.verify(mCallback).onStateChanged(eq(new SoftApState(
+ WifiManager.WIFI_AP_STATE_DISABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
if (SdkLevel.isAtLeastSv2()) {
order.verify(mContext).sendBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL), eq(android.Manifest.permission.ACCESS_WIFI_STATE));
@@ -1037,7 +1065,9 @@ public class SoftApManagerTest extends WifiBaseTest {
WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME,
softApModeConfig.getTargetMode());
- order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+ order.verify(mCallback).onStateChanged(eq(new SoftApState(
+ WIFI_AP_STATE_DISABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
verify(mSarManager).setSapWifiState(WifiManager.WIFI_AP_STATE_DISABLED);
verify(mWifiDiagnostics).stopLogging(TEST_INTERFACE_NAME);
if (SdkLevel.isAtLeastSv2()) {
@@ -1061,7 +1091,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void cleanStopOnInterfaceDestroyed() throws Exception {
SoftApModeConfiguration softApModeConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(softApModeConfig);
// reset to clear verified Intents for ap state change updates
@@ -1074,7 +1104,9 @@ public class SoftApManagerTest extends WifiBaseTest {
mLooper.dispatchAll();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
+ order.verify(mCallback).onStateChanged(eq(new SoftApState(
+ WifiManager.WIFI_AP_STATE_DISABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
if (SdkLevel.isAtLeastSv2()) {
order.verify(mContext).sendBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL), eq(android.Manifest.permission.ACCESS_WIFI_STATE));
@@ -1086,7 +1118,9 @@ public class SoftApManagerTest extends WifiBaseTest {
WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME,
softApModeConfig.getTargetMode());
- order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+ order.verify(mCallback).onStateChanged(eq(new SoftApState(
+ WifiManager.WIFI_AP_STATE_DISABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
if (SdkLevel.isAtLeastSv2()) {
order.verify(mContext).sendBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL), eq(android.Manifest.permission.ACCESS_WIFI_STATE));
@@ -1107,15 +1141,17 @@ public class SoftApManagerTest extends WifiBaseTest {
public void noCallbackOnInterfaceDestroyedWhenAlreadyStopped() throws Exception {
SoftApModeConfiguration softApModeConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(softApModeConfig);
verify(mListener, never()).onStopped(mSoftApManager);
mSoftApManager.stop();
mLooper.dispatchAll();
verify(mListener).onStopped(mSoftApManager);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_DISABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_DISABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
reset(mCallback);
@@ -1133,7 +1169,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testInterfaceOnDownHandled() throws Exception {
SoftApModeConfiguration softApModeConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(softApModeConfig);
// reset to clear verified Intents for ap state change updates
@@ -1146,8 +1182,9 @@ public class SoftApManagerTest extends WifiBaseTest {
mLooper.dispatchAll();
- order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ order.verify(mCallback).onStateChanged(eq(new SoftApState(
+ WifiManager.WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
order.verify(mListener).onStopped(mSoftApManager);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
if (SdkLevel.isAtLeastSv2()) {
@@ -1180,7 +1217,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testInterfaceOnDownForDifferentInterfaceDoesNotTriggerStop() throws Exception {
SoftApModeConfiguration softApModeConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(softApModeConfig);
// reset to clear verified Intents for ap state change updates
@@ -1200,7 +1237,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testHostapdOnFailureHandled() throws Exception {
SoftApModeConfiguration softApModeConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(softApModeConfig);
// reset to clear verified Intents for ap state change updates
@@ -1211,8 +1248,9 @@ public class SoftApManagerTest extends WifiBaseTest {
mSoftApHalCallbackCaptor.getValue().onFailure();
mLooper.dispatchAll();
- order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ order.verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_GENERAL,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
order.verify(mListener).onStopped(mSoftApManager);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
if (SdkLevel.isAtLeastSv2()) {
@@ -1246,7 +1284,7 @@ public class SoftApManagerTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastS());
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, generateBridgedModeSoftApConfig(null),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mCallback);
// SoftApInfo updated
@@ -1283,7 +1321,7 @@ public class SoftApManagerTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastS());
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, generateBridgedModeSoftApConfig(null),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
// SoftApInfo updated
mockSoftApInfoUpdateAndVerifyAfterSapStarted(true /* bridged mode*/, true);
@@ -1327,7 +1365,7 @@ public class SoftApManagerTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastS());
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, generateBridgedModeSoftApConfig(null),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
// SoftApInfo updated
mockSoftApInfoUpdateAndVerifyAfterSapStarted(true /* bridged mode*/, true);
@@ -1365,7 +1403,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void updatesMetricsOnChannelSwitchedEvent() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -1383,7 +1421,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
SoftApInfo testSoftApInfo = new SoftApInfo(mTestSoftApInfo);
testSoftApInfo.setFrequency(5220);
@@ -1407,7 +1445,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -1428,7 +1466,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -1447,7 +1485,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testOnSoftApChannelSwitchedEventTriggerSoftApInfoUpdate() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -1465,7 +1503,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testDoesNotTriggerCallbackForSameChannelInfoUpdate() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -1489,7 +1527,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testHandlesInvalidChannelFrequency() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mCallback);
mockChannelSwitchEvent(-1, TEST_AP_BANDWIDTH_FROM_IFACE_CALLBACK);
@@ -1508,7 +1546,7 @@ public class SoftApManagerTest extends WifiBaseTest {
InOrder order = inOrder(mCallback, mWifiMetrics);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
order.verify(mWifiMetrics).addSoftApChannelSwitchedEvent(
@@ -1530,7 +1568,7 @@ public class SoftApManagerTest extends WifiBaseTest {
InOrder order = inOrder(mCallback, mWifiMetrics);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
reset(mCallback);
@@ -1552,7 +1590,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testDoesNotTriggerCallbackForSameClients() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -1589,7 +1627,7 @@ public class SoftApManagerTest extends WifiBaseTest {
InOrder order = inOrder(mCallback, mWifiMetrics);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
mockClientConnectedEvent(TEST_CLIENT_MAC_ADDRESS, true, TEST_INTERFACE_NAME, true);
@@ -1610,7 +1648,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void handlesInvalidConnectedClients() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
reset(mCallback);
@@ -1628,7 +1666,7 @@ public class SoftApManagerTest extends WifiBaseTest {
InOrder order = inOrder(mCallback, mWifiMetrics);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -1671,7 +1709,8 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setBlockedClientList(blockedClientList);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE);
+ configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
reset(mCallback);
@@ -1700,7 +1739,8 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setClientControlByUserEnabled(false);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE);
+ configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
mockClientConnectedEvent(TEST_CLIENT_MAC_ADDRESS, true, TEST_INTERFACE_NAME, true);
@@ -1742,7 +1782,8 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setClientControlByUserEnabled(true);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE);
+ configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
reset(mCallback);
@@ -1771,7 +1812,8 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setClientControlByUserEnabled(true);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE);
+ configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
reset(mWifiMetrics);
@@ -1821,7 +1863,8 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setClientControlByUserEnabled(true);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE);
+ configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
reset(mWifiMetrics);
@@ -1877,7 +1920,8 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setAllowedClientList(allowedClientList);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE);
+ configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
mockClientConnectedEvent(TEST_CLIENT_MAC_ADDRESS, true, TEST_INTERFACE_NAME, true);
@@ -1924,7 +1968,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void schedulesTimeoutTimerOnStart() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
verify(mResources)
.getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds);
@@ -1951,7 +1995,8 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setShutdownTimeoutMillis(50000);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE);
+ configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mCallback);
@@ -1972,7 +2017,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void cancelsTimeoutTimerOnStop() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -1990,7 +2035,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void cancelsTimeoutTimerOnNewClientsConnect() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -2008,7 +2053,7 @@ public class SoftApManagerTest extends WifiBaseTest {
InOrder order = inOrder(mCallback, mWifiMetrics);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -2031,7 +2076,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void stopsSoftApOnTimeoutMessage() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -2053,7 +2098,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void cancelsTimeoutTimerOnTimeoutToggleChangeWhenNoClients() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -2077,7 +2122,7 @@ public class SoftApManagerTest extends WifiBaseTest {
.build();
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mCallback);
@@ -2114,7 +2159,7 @@ public class SoftApManagerTest extends WifiBaseTest {
.build();
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mCallback);
SoftApInfo expectedInfo = new SoftApInfo(mTestSoftApInfo);
@@ -2137,7 +2182,7 @@ public class SoftApManagerTest extends WifiBaseTest {
.build();
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mCallback);
@@ -2169,7 +2214,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(), mTestSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
startSoftApAndVerifyEnabled(apConfig);
@@ -2182,6 +2227,8 @@ public class SoftApManagerTest extends WifiBaseTest {
| SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
| SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD
| SoftApCapability.SOFTAP_FEATURE_WPA3_SAE;
+ when(mDeviceWiphyCapabilities.isWifiStandardSupported(
+ ScanResult.WIFI_STANDARD_11BE)).thenReturn(false);
SoftApCapability testSoftApCapability = new SoftApCapability(testSoftApFeature);
testSoftApCapability.setCountryCode(TEST_COUNTRY_CODE);
Builder configBuilder = new SoftApConfiguration.Builder();
@@ -2194,7 +2241,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(), testSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
startSoftApAndVerifyEnabled(apConfig);
@@ -2213,7 +2260,7 @@ public class SoftApManagerTest extends WifiBaseTest {
}
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(), mTestSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
when(mWifiNative.setApMacAddress(eq(TEST_INTERFACE_NAME), mac.capture())).thenReturn(true);
@@ -2234,14 +2281,16 @@ public class SoftApManagerTest extends WifiBaseTest {
}
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(), mTestSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_LOCAL_ONLY);
mLooper.dispatchAll();
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_ENABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
verify(mWifiNative, never()).setApMacAddress(any(), any());
}
@@ -2256,15 +2305,17 @@ public class SoftApManagerTest extends WifiBaseTest {
}
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(), mTestSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
when(mWifiNative.setApMacAddress(eq(TEST_INTERFACE_NAME), mac.capture())).thenReturn(false);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_LOCAL_ONLY);
mLooper.dispatchAll();
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_ENABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_GENERAL,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
assertThat(mac.getValue()).isEqualTo(TEST_CLIENT_MAC_ADDRESS);
}
@@ -2281,21 +2332,25 @@ public class SoftApManagerTest extends WifiBaseTest {
when(mWifiApConfigStore.randomizeBssidIfUnset(any(), any())).thenReturn(
randomizedBssidConfig);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
- IFACE_IP_MODE_LOCAL_ONLY, null, mTestSoftApCapability, TEST_COUNTRY_CODE);
+ IFACE_IP_MODE_LOCAL_ONLY, null, mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
when(mWifiNative.setApMacAddress(eq(TEST_INTERFACE_NAME), mac.capture())).thenReturn(false);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_LOCAL_ONLY);
mLooper.dispatchAll();
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_ENABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_GENERAL,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
}
@Test
public void setRandomMacWhenSetMacNotsupport() throws Exception {
when(mWifiNative.isApSetMacAddressSupported(any())).thenReturn(false);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
- IFACE_IP_MODE_LOCAL_ONLY, null, mTestSoftApCapability, TEST_COUNTRY_CODE);
+ IFACE_IP_MODE_LOCAL_ONLY, null, mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
verify(mWifiNative, never()).setApMacAddress(any(), any());
}
@@ -2305,7 +2360,7 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability.setMaxSupportedClients(1);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
mockClientConnectedEvent(TEST_CLIENT_MAC_ADDRESS, true, TEST_INTERFACE_NAME, true);
@@ -2340,7 +2395,7 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability.setMaxSupportedClients(2);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
verify(mCallback).onConnectedClientsOrInfoChanged(mTestSoftApInfoMap,
@@ -2463,7 +2518,6 @@ public class SoftApManagerTest extends WifiBaseTest {
mWifiNativeInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE),
eq(expectedConfig.getBand()), eq(expectedConfig.getBands().length > 1),
eq(mSoftApManager), anyList());
-
// Simulate user approval
ArgumentCaptor<StateMachine> stateMachineCaptor =
ArgumentCaptor.forClass(StateMachine.class);
@@ -2477,6 +2531,9 @@ public class SoftApManagerTest extends WifiBaseTest {
stateMachineCaptor.getValue().sendMessage(Message.obtain(messageCaptor.getValue()));
mLooper.dispatchAll();
}
+ // isItPossibleToCreateApIface should never happen in normal case since it may fail in
+ // normal use case
+ verify(mWifiNative, never()).isItPossibleToCreateApIface(any());
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mFakeSoftApNotifier).dismissSoftApShutdownTimeoutExpiredNotification();
order.verify(mWifiNative).setupInterfaceForSoftApMode(
@@ -2485,7 +2542,9 @@ public class SoftApManagerTest extends WifiBaseTest {
eq(mSoftApManager), anyList());
ArgumentCaptor<SoftApConfiguration> configCaptor =
ArgumentCaptor.forClass(SoftApConfiguration.class);
- order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
+ order.verify(mCallback).onStateChanged(eq(new SoftApState(
+ WifiManager.WIFI_AP_STATE_ENABLING, 0,
+ softApConfig.getTetheringRequest(), TEST_INTERFACE_NAME)));
if (!TextUtils.isEmpty(softApConfig.getCountryCode())
&& !TextUtils.equals(
softApConfig.getCountryCode(),
@@ -2519,7 +2578,9 @@ public class SoftApManagerTest extends WifiBaseTest {
? expectedConfigWithFrameworkACS : expectedConfig);
mWifiNativeInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
- order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
+ order.verify(mCallback).onStateChanged(eq(new SoftApState(
+ WifiManager.WIFI_AP_STATE_ENABLED, 0,
+ softApConfig.getTetheringRequest(), TEST_INTERFACE_NAME)));
order.verify(mCallback).onConnectedClientsOrInfoChanged(eq(mTestSoftApInfoMap),
eq(mTestWifiClientsMap), eq(expectedConfig.getBands().length > 1));
verify(mSarManager).setSapWifiState(WifiManager.WIFI_AP_STATE_ENABLED);
@@ -2590,12 +2651,14 @@ public class SoftApManagerTest extends WifiBaseTest {
| SoftApCapability.SOFTAP_FEATURE_WPA3_SAE
| SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD
| SoftApCapability.SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION;
+ when(mDeviceWiphyCapabilities.isWifiStandardSupported(
+ ScanResult.WIFI_STANDARD_11BE)).thenReturn(false);
SoftApCapability noClientControlCapability = new SoftApCapability(testSoftApFeature);
noClientControlCapability.setMaxSupportedClients(1);
noClientControlCapability.setCountryCode(TEST_COUNTRY_CODE);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- noClientControlCapability, TEST_COUNTRY_CODE);
+ noClientControlCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
mockClientConnectedEvent(TEST_CLIENT_MAC_ADDRESS, true, TEST_INTERFACE_NAME, true);
@@ -2633,12 +2696,14 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
- noClientControlCapability, TEST_COUNTRY_CODE);
+ noClientControlCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_TETHERED);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_ENABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
verify(mWifiMetrics).incrementSoftApStartResult(false,
WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION);
verify(mListener).onStartFailure(mSoftApManager);
@@ -2661,12 +2726,14 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
- noSaeCapability, TEST_COUNTRY_CODE);
+ noSaeCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_TETHERED);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_ENABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
verify(mListener).onStartFailure(mSoftApManager);
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_UNSUPPORTED_CONFIG),
@@ -2683,6 +2750,8 @@ public class SoftApManagerTest extends WifiBaseTest {
| SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
| SoftApCapability.SOFTAP_FEATURE_WPA3_SAE
| SoftApCapability.SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION;
+ when(mDeviceWiphyCapabilities.isWifiStandardSupported(
+ ScanResult.WIFI_STANDARD_11BE)).thenReturn(false);
SoftApCapability testCapability = new SoftApCapability(testSoftApFeature);
testCapability.setSupportedChannelList(
SoftApConfiguration.BAND_2GHZ, TEST_SUPPORTED_24G_CHANNELS);
@@ -2692,13 +2761,15 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApConfiguration softApConfig = generateBridgedModeSoftApConfig(null);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
- testCapability, TEST_COUNTRY_CODE);
+ testCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_TETHERED);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
- verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION);
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_ENABLING, 0,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
+ verify(mCallback).onStateChanged(eq(new SoftApState(WifiManager.WIFI_AP_STATE_FAILED,
+ WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION,
+ TEST_TETHERING_REQUEST, TEST_INTERFACE_NAME)));
verify(mWifiMetrics).incrementSoftApStartResult(false,
WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION);
verify(mListener).onStartFailure(mSoftApManager);
@@ -2717,6 +2788,8 @@ public class SoftApManagerTest extends WifiBaseTest {
| SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
| SoftApCapability.SOFTAP_FEATURE_WPA3_SAE
| SoftApCapability.SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION;
+ when(mDeviceWiphyCapabilities.isWifiStandardSupported(
+ ScanResult.WIFI_STANDARD_11BE)).thenReturn(false);
SparseIntArray dual_channels = new SparseIntArray(2);
dual_channels.put(SoftApConfiguration.BAND_5GHZ, 149);
dual_channels.put(SoftApConfiguration.BAND_2GHZ, 2);
@@ -2730,7 +2803,7 @@ public class SoftApManagerTest extends WifiBaseTest {
.build();
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, softApConfig,
- testCapability, TEST_COUNTRY_CODE);
+ testCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, null, false);
}
@@ -2743,7 +2816,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(), mTestSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
verify(mCallback).onConnectedClientsOrInfoChanged(mTestSoftApInfoMap,
@@ -2783,7 +2856,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(), mTestSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
@@ -2806,7 +2879,8 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setMaxNumberOfClients(2);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE);
+ configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
mockClientConnectedEvent(TEST_CLIENT_MAC_ADDRESS, true, TEST_INTERFACE_NAME, true);
@@ -2847,7 +2921,8 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setMaxNumberOfClients(1);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE);
+ configBuilder.build(), mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
mockClientConnectedEvent(TEST_CLIENT_MAC_ADDRESS, true, TEST_INTERFACE_NAME, true);
@@ -2917,7 +2992,8 @@ public class SoftApManagerTest extends WifiBaseTest {
InOrder order = inOrder(mCallback, mWifiMetrics);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED,
- customizedBssidConfig, mTestSoftApCapability, TEST_COUNTRY_CODE);
+ customizedBssidConfig, mTestSoftApCapability, TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
order.verify(mWifiMetrics).addSoftApChannelSwitchedEvent(
@@ -2943,7 +3019,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testHandleCallbackFromWificond() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mCallback);
mockChannelSwitchEvent(mTestSoftApInfo.getFrequency(), mTestSoftApInfo.getBandwidth());
@@ -2970,7 +3046,7 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability.setMaxSupportedClients(1);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
mockClientConnectedEvent(TEST_CLIENT_MAC_ADDRESS, true, TEST_INTERFACE_NAME, true);
@@ -3017,7 +3093,7 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability.setMaxSupportedClients(1);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
mockSoftApInfoUpdateAndVerifyAfterSapStarted(false, true);
reset(mCallback);
@@ -3060,7 +3136,7 @@ public class SoftApManagerTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastS());
SoftApModeConfiguration dualBandConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, generateBridgedModeSoftApConfig(null),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(dualBandConfig, ROLE_SOFTAP_TETHERED);
verify(mWifiNative).setupInterfaceForSoftApMode(
any(), any(), eq(SoftApConfiguration.BAND_2GHZ), eq(true), eq(mSoftApManager),
@@ -3071,7 +3147,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testOnInfoChangedFromDifferentInstancesTriggerSoftApInfoUpdate() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mCallback);
mockApInfoChangedEvent(mTestSoftApInfoOnFirstInstance);
@@ -3090,7 +3166,7 @@ public class SoftApManagerTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastS());
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, generateBridgedModeSoftApConfig(null),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
verify(mResources)
@@ -3126,7 +3202,7 @@ public class SoftApManagerTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastS());
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, generateBridgedModeSoftApConfig(null),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
verify(mResources)
@@ -3237,7 +3313,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED,
configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
verify(mResources)
@@ -3271,7 +3347,7 @@ public class SoftApManagerTest extends WifiBaseTest {
configBuilder.setBridgedModeOpportunisticShutdownEnabled(false);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
verify(mResources)
@@ -3324,7 +3400,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- testCapability, TEST_COUNTRY_CODE);
+ testCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
// Reset band to 2.4G | 6G to generate expected configuration
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_6GHZ);
startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
@@ -3344,7 +3420,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- testCapability, TEST_COUNTRY_CODE);
+ testCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
// Reset band array to {2.4G, 5G} to generate expected configuration
int[] expected_dual_bands = {SoftApConfiguration.BAND_2GHZ,
SoftApConfiguration.BAND_5GHZ};
@@ -3363,7 +3439,7 @@ public class SoftApManagerTest extends WifiBaseTest {
generateBridgedModeSoftApConfig(null));
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- testCapability, TEST_COUNTRY_CODE);
+ testCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
// Reset band to 2.4G | 5G to generate expected configuration
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ);
startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
@@ -3387,7 +3463,7 @@ public class SoftApManagerTest extends WifiBaseTest {
generateBridgedModeSoftApConfig(null));
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- testCapability, TEST_COUNTRY_CODE);
+ testCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
// Reset band to 2.4G | 5G to generate expected configuration
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ);
startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
@@ -3402,7 +3478,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApConfiguration bridgedConfig = generateBridgedModeSoftApConfig(null);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, bridgedConfig,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, bridgedConfig, false);
}
@@ -3421,7 +3497,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, bridgedConfig,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, bridgedConfig, false);
}
@@ -3440,7 +3516,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
// Reset band to 2.4G to generate expected configuration
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ);
startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
@@ -3459,7 +3535,7 @@ public class SoftApManagerTest extends WifiBaseTest {
generateBridgedModeSoftApConfig(null));
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- testCapability, worldModeCC);
+ testCapability, worldModeCC, TEST_TETHERING_REQUEST);
// Reset band to 2.4G | 5G to generate expected configuration
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ);
startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
@@ -3474,7 +3550,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApConfiguration bridgedConfig = generateBridgedModeSoftApConfig(null);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, bridgedConfig, mTestSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, bridgedConfig, false);
reset(mCallback);
@@ -3506,7 +3582,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApConfiguration bridgedConfig = generateBridgedModeSoftApConfig(null);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, bridgedConfig,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, bridgedConfig, false);
reset(mCallback);
@@ -3550,7 +3626,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApConfiguration bridgedConfig = generateBridgedModeSoftApConfig(null);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, bridgedConfig,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, bridgedConfig, false);
reset(mCallback);
@@ -3576,7 +3652,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApConfiguration bridgedConfig = generateBridgedModeSoftApConfig(null);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, bridgedConfig, mTestSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, bridgedConfig, false);
reset(mCallback);
@@ -3600,7 +3676,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApConfiguration bridgedConfig = generateBridgedModeSoftApConfig(null);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, bridgedConfig, mTestSoftApCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, bridgedConfig, false);
reset(mCallback);
@@ -3609,6 +3685,9 @@ public class SoftApManagerTest extends WifiBaseTest {
// TEST_SUPPORTED_5G_CHANNELS = 36, 149, mark to unsafe. Let Wifi connect to 5945 (6G)
when(mPrimaryWifiInfo.getFrequency()).thenReturn(5945);
+ // Device doesn't support three band combination.
+ when(mWifiNative.isBandCombinationSupported(eq(TEST_STA_INTERFACE_NAME), any()))
+ .thenReturn(false);
reset(mCallback);
// Trigger wifi connected
@@ -3631,11 +3710,40 @@ public class SoftApManagerTest extends WifiBaseTest {
}
@Test
+ public void testBridgedModeNotShutDownForWifiUnavailableChannelWhenBandCombinationSupported()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ SoftApConfiguration bridgedConfig = generateBridgedModeSoftApConfig(null);
+ SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, bridgedConfig, mTestSoftApCapability,
+ TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
+ startSoftApAndVerifyEnabled(apConfig, bridgedConfig, false);
+
+ reset(mCallback);
+ // SoftApInfo updated
+ mockSoftApInfoUpdateAndVerifyAfterSapStarted(true /* bridged mode*/, true);
+
+ // TEST_SUPPORTED_5G_CHANNELS = 36, 149, mark to unsafe. Let Wifi connect to 5945 (6G)
+ when(mPrimaryWifiInfo.getFrequency()).thenReturn(5945);
+ // Device supports three band combination
+ when(mWifiNative.isBandCombinationSupported(eq(TEST_STA_INTERFACE_NAME), any()))
+ .thenReturn(true);
+
+ reset(mCallback);
+ // Trigger wifi connected
+ mCmiListenerCaptor.getValue().onL2Connected(mConcreteClientModeManager);
+ mLooper.dispatchAll();
+ // Verify instance not removed
+ verify(mWifiNative, never()).removeIfaceInstanceFromBridgedApIface(eq(TEST_INTERFACE_NAME),
+ eq(TEST_SECOND_INSTANCE_NAME));
+ }
+
+ @Test
public void testBridgedModeDowngradeIfaceInstanceForRemoval() throws Exception {
assumeTrue(SdkLevel.isAtLeastS());
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, generateBridgedModeSoftApConfig(null),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
// SoftApInfo updated
@@ -3673,7 +3781,8 @@ public class SoftApManagerTest extends WifiBaseTest {
WifiManager.IFACE_IP_MODE_TETHERED,
configBuilder.build(),
staleCapability,
- TEST_COUNTRY_CODE);
+ TEST_COUNTRY_CODE,
+ TEST_TETHERING_REQUEST);
// Started bands should include both 2.4GHz and 5GHz since we get the updated capabilities
// after waiting for the driver CC event.
startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
@@ -3685,7 +3794,7 @@ public class SoftApManagerTest extends WifiBaseTest {
R.bool.config_wifiDriverSupportedNl80211RegChangedEvent)).thenReturn(true);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, "Not " + TEST_COUNTRY_CODE);
+ mTestSoftApCapability, "Not " + TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
}
@@ -3695,7 +3804,7 @@ public class SoftApManagerTest extends WifiBaseTest {
R.bool.config_wifiDriverSupportedNl80211RegChangedEvent)).thenReturn(true);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, "Not" + TEST_COUNTRY_CODE);
+ mTestSoftApCapability, "Not" + TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_TETHERED);
ArgumentCaptor<WifiCountryCode.ChangeListener> changeListenerCaptor =
ArgumentCaptor.forClass(WifiCountryCode.ChangeListener.class);
@@ -3716,7 +3825,7 @@ public class SoftApManagerTest extends WifiBaseTest {
.thenReturn(false);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mWifiNative);
mSoftApManager.updateCountryCode(TEST_COUNTRY_CODE + "TW");
@@ -3730,7 +3839,7 @@ public class SoftApManagerTest extends WifiBaseTest {
.thenReturn(true);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mWifiNative);
mSoftApManager.updateCountryCode(TEST_COUNTRY_CODE + "TW");
@@ -3744,7 +3853,7 @@ public class SoftApManagerTest extends WifiBaseTest {
.thenReturn(true);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
reset(mWifiNative);
mSoftApManager.updateCountryCode(TEST_COUNTRY_CODE);
@@ -3763,7 +3872,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
// Reset band to 2.4G | 5G to generate expected configuration since it should fallback to
// single AP mode
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ);
@@ -3782,7 +3891,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
// Reset band to 2.4G | 5G to generate expected configuration since it should fallback to
// single AP mode
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ);
@@ -3798,7 +3907,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
// Reset band to 2.4G | 5G to generate expected configuration since it should fallback to
// single AP mode
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ);
@@ -3816,7 +3925,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
// Reset band to 2.4G | 5G to generate expected configuration since it should fallback to
// single AP mode
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ);
@@ -3836,7 +3945,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, bridgedConfig,
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, bridgedConfig, false);
}
@@ -3849,7 +3958,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, generateBridgedModeSoftApConfig(null),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
verify(mResources)
@@ -3912,7 +4021,7 @@ public class SoftApManagerTest extends WifiBaseTest {
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- testCapability, TEST_COUNTRY_CODE);
+ testCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
}
@@ -3923,17 +4032,16 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testStartSoftApRemoves11BEIfNotSupported() throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
- mTestSoftApCapability.setSupportedFeatures(false,
- SoftApCapability.SOFTAP_FEATURE_IEEE80211_BE);
+ when(mDeviceWiphyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE))
+ .thenReturn(false);
Builder configBuilder = new SoftApConfiguration.Builder();
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ);
configBuilder.setSsid(TEST_SSID);
configBuilder.setIeee80211beEnabled(true);
SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
- mTestSoftApCapability, TEST_COUNTRY_CODE);
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
SoftApConfiguration expectedConfig = configBuilder.setIeee80211beEnabled(false).build();
startSoftApAndVerifyEnabled(apConfig, expectedConfig, false);
}
}
-
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
index e3f0695609..65bee6e0be 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
@@ -35,6 +35,7 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
@@ -77,10 +78,13 @@ import android.hardware.wifi.supplicant.KeyMgmtMask;
import android.hardware.wifi.supplicant.LegacyMode;
import android.hardware.wifi.supplicant.MloLink;
import android.hardware.wifi.supplicant.MloLinksInfo;
+import android.hardware.wifi.supplicant.MscsParams.FrameClassifierFields;
+import android.hardware.wifi.supplicant.MsduDeliveryInfo;
import android.hardware.wifi.supplicant.OceRssiBasedAssocRejectAttr;
import android.hardware.wifi.supplicant.OsuMethod;
import android.hardware.wifi.supplicant.PmkSaCacheData;
import android.hardware.wifi.supplicant.PortRange;
+import android.hardware.wifi.supplicant.QosCharacteristics.QosCharacteristicsMask;
import android.hardware.wifi.supplicant.QosPolicyClassifierParams;
import android.hardware.wifi.supplicant.QosPolicyClassifierParamsMask;
import android.hardware.wifi.supplicant.QosPolicyData;
@@ -101,6 +105,8 @@ import android.hardware.wifi.supplicant.WpsErrorIndication;
import android.net.DscpPolicy;
import android.net.MacAddress;
import android.net.NetworkAgent;
+import android.net.wifi.MscsParams;
+import android.net.wifi.QosCharacteristics;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.ScanResult;
import android.net.wifi.SecurityParams;
@@ -120,6 +126,7 @@ import androidx.test.filters.SmallTest;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.MboOceController.BtmFrameData;
+import com.android.server.wifi.hal.HalTestUtils;
import com.android.server.wifi.hotspot2.AnqpEvent;
import com.android.server.wifi.hotspot2.IconEvent;
import com.android.server.wifi.hotspot2.WnmData;
@@ -1262,6 +1269,74 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
}
/**
+ * Tests that association rejection due to timeout doesn't broadcast authentication failure
+ * with reason code ERROR_AUTH_FAILURE_WRONG_PSWD.
+ * Driver/Supplicant sets the timedOut field when there is no ACK or response frame for
+ * Authentication request or Association request frame.
+ */
+ @Test
+ public void testAssociationRejectionDueToTimedOutDoesntNotifyWrongPassword() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+
+ executeAndValidateConnectSequenceWithKeyMgmt(
+ SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
+ WifiConfiguration.SECURITY_TYPE_SAE, null, true);
+ mISupplicantStaIfaceCallback.onStateChanged(
+ StaIfaceCallbackState.ASSOCIATING,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(SUPPLICANT_SSID)), false);
+ AssociationRejectionData rejectionData = createAssocRejectData(SUPPLICANT_SSID, BSSID,
+ StaIfaceStatusCode.UNSPECIFIED_FAILURE, true);
+ mISupplicantStaIfaceCallback.onAssociationRejected(rejectionData);
+ verify(mWifiMonitor, never()).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
+ anyInt(), anyInt(), any(), any());
+ ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
+ ArgumentCaptor.forClass(AssocRejectEventInfo.class);
+ verify(mWifiMonitor).broadcastAssociationRejectionEvent(
+ eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
+ AssocRejectEventInfo assocRejectEventInfo = assocRejectEventInfoCaptor.getValue();
+ assertNotNull(assocRejectEventInfo);
+ assertTrue(assocRejectEventInfo.timedOut);
+ }
+
+ /**
+ * Tests the handling of authentication failure for WPA3-Personal networks with
+ * status code = 15 (CHALLENGE_FAIL)
+ */
+ @Test
+ public void testWpa3AuthRejectionDueToChallengeFail() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+
+ executeAndValidateConnectSequenceWithKeyMgmt(
+ SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
+ WifiConfiguration.SECURITY_TYPE_SAE, null, true);
+ mISupplicantStaIfaceCallback.onStateChanged(
+ StaIfaceCallbackState.ASSOCIATING,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(SUPPLICANT_SSID)), false);
+ int statusCode = StaIfaceStatusCode.CHALLENGE_FAIL;
+ AssociationRejectionData rejectionData = createAssocRejectData(SUPPLICANT_SSID, BSSID,
+ statusCode, false);
+ mISupplicantStaIfaceCallback.onAssociationRejected(rejectionData);
+ verify(mWifiMonitor).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
+ eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1),
+ eq(TRANSLATED_SUPPLICANT_SSID.toString()),
+ eq(MacAddress.fromString(BSSID)));
+ ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
+ ArgumentCaptor.forClass(AssocRejectEventInfo.class);
+ verify(mWifiMonitor).broadcastAssociationRejectionEvent(
+ eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
+ AssocRejectEventInfo assocRejectEventInfo = assocRejectEventInfoCaptor.getValue();
+ assertNotNull(assocRejectEventInfo);
+ assertEquals(SupplicantStaIfaceCallbackAidlImpl.halToFrameworkStatusCode(
+ statusCode), assocRejectEventInfo.statusCode);
+ }
+
+ /**
* Tests the handling of incorrect network passwords for WEP networks.
*/
@Test
@@ -1349,6 +1424,30 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
}
/**
+ * Tests the handling of incorrect network password for AP_BUSY error code
+ *
+ * If the disconnect reason is "NO_MORE_STAS - Disassociated because AP is unable
+ * to handle all currently associated STAs", do not call it a password mismatch.
+ */
+ @Test
+ public void testApBusy() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+
+ int reasonCode = StaIfaceReasonCode.DISASSOC_AP_BUSY;
+
+ mISupplicantStaIfaceCallback.onStateChanged(
+ StaIfaceCallbackState.FOURWAY_HANDSHAKE,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(SUPPLICANT_SSID)), false);
+ mISupplicantStaIfaceCallback.onDisconnected(
+ NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
+ verify(mWifiMonitor, never()).broadcastAuthenticationFailureEvent(any(), anyInt(),
+ anyInt(), any(), any());
+ }
+
+ /**
* Tests the handling of eap failure during disconnect.
*/
@Test
@@ -2006,6 +2105,9 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
halCap.channelBandwidth = WifiChannelWidthInMhz.WIDTH_20;
halCap.maxNumberTxSpatialStreams = 1;
halCap.maxNumberRxSpatialStreams = 1;
+ if (SdkLevel.isAtLeastV()) {
+ halCap.vendorData = HalTestUtils.createHalOuiKeyedDataList(5);
+ }
doReturn(halCap).when(mISupplicantStaIfaceMock).getConnectionCapabilities();
WifiNative.ConnectionCapabilities expectedCap =
@@ -2015,6 +2117,12 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
assertEquals(testChannelBandwidth, expectedCap.channelBandwidth);
assertEquals(maxNumberTxSpatialStreams, expectedCap.maxNumberTxSpatialStreams);
assertEquals(maxNumberRxSpatialStreams, expectedCap.maxNumberRxSpatialStreams);
+ if (SdkLevel.isAtLeastV()) {
+ assertTrue(HalTestUtils.ouiKeyedDataListEquals(
+ halCap.vendorData, expectedCap.vendorData));
+ } else {
+ assertTrue(expectedCap.vendorData.isEmpty());
+ }
}
/**
@@ -2428,8 +2536,35 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
.setDestinationPort(10)
.build();
frameworkPolicy.setTranslatedPolicyId(translatedPolicyId);
- QosPolicyScsData halPolicy = SupplicantStaIfaceHalAidlImpl
- .frameworkToHalQosPolicyScsData(frameworkPolicy);
+ QosPolicyScsData halPolicy = mDut.frameworkToHalQosPolicyScsData(frameworkPolicy);
+ compareQosPolicyParamsToHal(frameworkPolicy, halPolicy);
+ }
+
+ /**
+ * Tests the conversion method
+ * {@link SupplicantStaIfaceHalAidlImpl#frameworkToHalQosPolicyScsData(QosPolicyParams)}
+ * when the instance contains QosCharacteristics.
+ */
+ @Test
+ public void testFrameworkToHalQosPolicyScsDataWithCharacteristics() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mISupplicantMock.getInterfaceVersion()).thenReturn(3);
+ assertTrue(mDut.startDaemon()); // retrieves and caches the interface version
+
+ QosCharacteristics frameworkChars = new QosCharacteristics.Builder(
+ 2000, 5000, 500, 2)
+ .setMaxMsduSizeOctets(4)
+ .setServiceStartTimeInfo(250, 0x5)
+ .setMeanDataRateKbps(1500)
+ .setMsduLifetimeMillis(400)
+ .setMsduDeliveryInfo(QosCharacteristics.DELIVERY_RATIO_99, 5)
+ .build();
+ QosPolicyParams frameworkPolicy = new QosPolicyParams.Builder(
+ 5 /* policyId */, QosPolicyParams.DIRECTION_UPLINK)
+ .setQosCharacteristics(frameworkChars)
+ .build();
+ frameworkPolicy.setTranslatedPolicyId(15);
+ QosPolicyScsData halPolicy = mDut.frameworkToHalQosPolicyScsData(frameworkPolicy);
compareQosPolicyParamsToHal(frameworkPolicy, halPolicy);
}
@@ -2540,6 +2675,55 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
return qosPolicyData;
}
+ private static void compareFrameworkQosCharacteristicsToHal(
+ android.net.wifi.QosCharacteristics frameworkChars,
+ android.hardware.wifi.supplicant.QosCharacteristics halChars) {
+ assertEquals(frameworkChars.getMinServiceIntervalMicros(), halChars.minServiceIntervalUs);
+ assertEquals(frameworkChars.getMaxServiceIntervalMicros(), halChars.maxServiceIntervalUs);
+ assertEquals(frameworkChars.getMinDataRateKbps(), halChars.minDataRateKbps);
+ assertEquals(frameworkChars.getDelayBoundMicros(), halChars.delayBoundUs);
+
+ int paramsMask = halChars.optionalFieldMask;
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.MAX_MSDU_SIZE)) {
+ assertNotEquals(0, paramsMask & QosCharacteristicsMask.MAX_MSDU_SIZE);
+ assertEquals((char) frameworkChars.getMaxMsduSizeOctets(), halChars.maxMsduSizeOctets);
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.SERVICE_START_TIME)) {
+ assertNotEquals(0, paramsMask & QosCharacteristicsMask.SERVICE_START_TIME);
+ assertNotEquals(0, paramsMask & QosCharacteristicsMask.SERVICE_START_TIME_LINK_ID);
+ assertEquals(frameworkChars.getServiceStartTimeMicros(), halChars.serviceStartTimeUs);
+ assertEquals((byte) frameworkChars.getServiceStartTimeLinkId(),
+ halChars.serviceStartTimeLinkId);
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.MEAN_DATA_RATE)) {
+ assertNotEquals(0, paramsMask & QosCharacteristicsMask.MEAN_DATA_RATE);
+ assertEquals(frameworkChars.getMeanDataRateKbps(), halChars.meanDataRateKbps);
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.BURST_SIZE)) {
+ assertNotEquals(0, paramsMask & QosCharacteristicsMask.BURST_SIZE);
+ assertEquals(frameworkChars.getBurstSizeOctets(), halChars.burstSizeOctets);
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.MSDU_LIFETIME)) {
+ assertNotEquals(0, paramsMask & QosCharacteristicsMask.MSDU_LIFETIME);
+ assertEquals((char) frameworkChars.getMsduLifetimeMillis(), halChars.msduLifetimeMs);
+ }
+ if (frameworkChars.containsOptionalField(
+ android.net.wifi.QosCharacteristics.MSDU_DELIVERY_INFO)) {
+ assertNotEquals(0, paramsMask & QosCharacteristicsMask.MSDU_DELIVERY_INFO);
+ MsduDeliveryInfo halDeliveryInfo = halChars.msduDeliveryInfo;
+ int convertedFrameworkRatio =
+ SupplicantStaIfaceHalAidlImpl.frameworkToHalDeliveryRatio(
+ frameworkChars.getDeliveryRatio());
+ assertEquals(convertedFrameworkRatio, halDeliveryInfo.deliveryRatio);
+ assertEquals((byte) frameworkChars.getCountExponent(), halDeliveryInfo.countExponent);
+ }
+ }
+
private void compareQosPolicyParamsToHal(QosPolicyParams frameworkPolicy,
QosPolicyScsData halPolicy) {
assertEquals((byte) frameworkPolicy.getTranslatedPolicyId(), halPolicy.policyId);
@@ -2576,6 +2760,17 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
assertNotEquals(0, paramsMask & QosPolicyClassifierParamsMask.DSCP);
assertEquals((byte) frameworkPolicy.getDscp(), classifierParams.dscp);
}
+
+ if (mDut.isServiceVersionAtLeast(3)) {
+ int convertedFrameworkDirection =
+ SupplicantStaIfaceHalAidlImpl.frameworkToHalPolicyDirection(
+ frameworkPolicy.getDirection());
+ assertEquals(convertedFrameworkDirection, halPolicy.direction);
+ if (frameworkPolicy.getQosCharacteristics() != null) {
+ compareFrameworkQosCharacteristicsToHal(
+ frameworkPolicy.getQosCharacteristics(), halPolicy.QosCharacteristics);
+ }
+ }
}
/**
@@ -3122,4 +3317,74 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
assertTrue(mDut.startDaemon());
verify(mISupplicantMock, never()).getInterfaceVersion();
}
+
+ /**
+ * Test {@link SupplicantStaIfaceHalAidlImpl#enableMscs(MscsParams, String)} and verify the
+ * conversion from {@link MscsParams} to its HAL equivalent.
+ */
+ @Test
+ public void testEnableMscs() throws Exception {
+ int userPriorityBitmap = (1 << 6) | (1 << 7);
+ int userPriorityLimit = 5;
+ int streamTimeoutUs = 1500;
+ int frameworkFrameClassifierMask =
+ MscsParams.FRAME_CLASSIFIER_IP_VERSION | MscsParams.FRAME_CLASSIFIER_DSCP;
+ byte halFrameClassifierMask =
+ FrameClassifierFields.IP_VERSION | FrameClassifierFields.DSCP;
+
+ ArgumentCaptor<android.hardware.wifi.supplicant.MscsParams> halParamsCaptor =
+ ArgumentCaptor.forClass(android.hardware.wifi.supplicant.MscsParams.class);
+ doNothing().when(mISupplicantStaIfaceMock).configureMscs(any());
+ executeAndValidateInitializationSequence();
+
+ MscsParams frameworkParams = new MscsParams.Builder()
+ .setUserPriorityBitmap(userPriorityBitmap)
+ .setUserPriorityLimit(userPriorityLimit)
+ .setStreamTimeoutUs(streamTimeoutUs)
+ .setFrameClassifierFields(frameworkFrameClassifierMask)
+ .build();
+ mDut.setupIface(WLAN0_IFACE_NAME);
+ mDut.enableMscs(frameworkParams, WLAN0_IFACE_NAME);
+
+ verify(mISupplicantStaIfaceMock).configureMscs(halParamsCaptor.capture());
+ android.hardware.wifi.supplicant.MscsParams halParams = halParamsCaptor.getValue();
+ assertEquals((byte) userPriorityBitmap, halParams.upBitmap);
+ assertEquals((byte) userPriorityLimit, halParams.upLimit);
+ assertEquals(streamTimeoutUs, halParams.streamTimeoutUs);
+ assertEquals(halFrameClassifierMask, halParams.frameClassifierMask);
+ }
+
+ /**
+ * Test that MSCS params set through {@link SupplicantStaIfaceHalAidlImpl#enableMscs(
+ * MscsParams, String)} are cached for later resends.
+ */
+ @Test
+ public void testEnableAndResendMscs() throws Exception {
+ executeAndValidateInitializationSequence();
+ mDut.setupIface(WLAN0_IFACE_NAME);
+
+ doNothing().when(mISupplicantStaIfaceMock).configureMscs(any());
+ MscsParams defaultParams = new MscsParams.Builder().build();
+
+ ArgumentCaptor<android.hardware.wifi.supplicant.MscsParams> halParamsCaptor =
+ ArgumentCaptor.forClass(android.hardware.wifi.supplicant.MscsParams.class);
+ mDut.enableMscs(defaultParams, WLAN0_IFACE_NAME);
+ verify(mISupplicantStaIfaceMock).configureMscs(halParamsCaptor.capture());
+ android.hardware.wifi.supplicant.MscsParams initialParams = halParamsCaptor.getValue();
+
+ // Resend should use the params cached during the initial send.
+ mDut.resendMscs(WLAN0_IFACE_NAME);
+ verify(mISupplicantStaIfaceMock, times(2)).configureMscs(halParamsCaptor.capture());
+ android.hardware.wifi.supplicant.MscsParams resendParams = halParamsCaptor.getValue();
+
+ assertEquals(initialParams.upBitmap, resendParams.upBitmap);
+ assertEquals(initialParams.upLimit, resendParams.upLimit);
+ assertEquals(initialParams.streamTimeoutUs, resendParams.streamTimeoutUs);
+ assertEquals(initialParams.frameClassifierMask, resendParams.frameClassifierMask);
+
+ // Disabling MSCS should clear the cached params and prevent future resends.
+ mDut.disableMscs(WLAN0_IFACE_NAME);
+ mDut.resendMscs(WLAN0_IFACE_NAME);
+ verify(mISupplicantStaIfaceMock, times(2)).configureMscs(halParamsCaptor.capture());
+ }
}
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 7f01d7b563..be19bc53d1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
@@ -1501,6 +1501,73 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
}
/**
+ * Tests that association rejection due to timeout doesn't broadcast authentication failure
+ * with reason code ERROR_AUTH_FAILURE_WRONG_PSWD.
+ * Driver/Supplicant sets the timedOut field when there is no ACK or response frame for
+ * Authentication request or Association request frame.
+ */
+ @Test
+ public void testAssociationRejectionDueToTimedOutDoesntNotifyWrongPassword() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+
+ executeAndValidateConnectSequenceWithKeyMgmt(
+ SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
+ WifiConfiguration.SECURITY_TYPE_SAE, null, true);
+ mISupplicantStaIfaceCallback.onStateChanged(
+ ISupplicantStaIfaceCallback.State.ASSOCIATING,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID));
+ mISupplicantStaIfaceCallback.onAssociationRejected(
+ NativeUtil.macAddressToByteArray(BSSID),
+ ISupplicantStaIfaceCallback.StatusCode.UNSPECIFIED_FAILURE, true);
+ verify(mWifiMonitor, never()).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
+ anyInt(), anyInt(), any(), any());
+ ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
+ ArgumentCaptor.forClass(AssocRejectEventInfo.class);
+ verify(mWifiMonitor).broadcastAssociationRejectionEvent(
+ eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
+ AssocRejectEventInfo assocRejectEventInfo =
+ (AssocRejectEventInfo) assocRejectEventInfoCaptor.getValue();
+ assertNotNull(assocRejectEventInfo);
+ assertTrue(assocRejectEventInfo.timedOut);
+ }
+
+ /**
+ * Tests the handling of authentication failure for WPA3-Personal networks with
+ * status code = 15 (CHALLENGE_FAIL)
+ */
+ @Test
+ public void testWpa3AuthRejectionDueToChallengeFail() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+
+ executeAndValidateConnectSequenceWithKeyMgmt(
+ SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
+ WifiConfiguration.SECURITY_TYPE_SAE, null, true);
+ mISupplicantStaIfaceCallback.onStateChanged(
+ ISupplicantStaIfaceCallback.State.ASSOCIATING,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID));
+ int statusCode = ISupplicantStaIfaceCallback.StatusCode.CHALLENGE_FAIL;
+ mISupplicantStaIfaceCallback.onAssociationRejected(
+ NativeUtil.macAddressToByteArray(BSSID), statusCode, false);
+ verify(mWifiMonitor).broadcastAuthenticationFailureEvent(eq(WLAN0_IFACE_NAME),
+ eq(WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD), eq(-1),
+ eq(TRANSLATED_SUPPLICANT_SSID.toString()), eq(MacAddress.fromString(BSSID)));
+ ArgumentCaptor<AssocRejectEventInfo> assocRejectEventInfoCaptor =
+ ArgumentCaptor.forClass(AssocRejectEventInfo.class);
+ verify(mWifiMonitor).broadcastAssociationRejectionEvent(
+ eq(WLAN0_IFACE_NAME), assocRejectEventInfoCaptor.capture());
+ AssocRejectEventInfo assocRejectEventInfo =
+ (AssocRejectEventInfo) assocRejectEventInfoCaptor.getValue();
+ assertNotNull(assocRejectEventInfo);
+ assertEquals(statusCode, assocRejectEventInfo.statusCode);
+ }
+
+ /**
* Tests the handling of incorrect network passwords for WEP networks.
*/
@Test
@@ -1586,6 +1653,30 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
}
/**
+ * Tests the handling of incorrect network password for AP_BUSY error code
+ *
+ * If the disconnect reason is "NO_MORE_STAS - Disassociated because AP is unable
+ * to handle all currently associated STAs", do not call it a password mismatch.
+ */
+ @Test
+ public void testApBusy() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+
+ int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.DISASSOC_AP_BUSY;
+
+ mISupplicantStaIfaceCallback.onStateChanged(
+ ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID));
+ mISupplicantStaIfaceCallback.onDisconnected(
+ NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
+ verify(mWifiMonitor, never()).broadcastAuthenticationFailureEvent(any(), anyInt(),
+ anyInt(), any(), any());
+ }
+
+ /**
* Tests the handling of eap failure during disconnect.
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java
index 8d77125a0b..fbd03da9c8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java
@@ -35,6 +35,7 @@ import static org.mockito.Mockito.when;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.Context;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.GroupCipherMask;
import android.hardware.wifi.supplicant.GsmRand;
import android.hardware.wifi.supplicant.ISupplicantStaNetwork;
@@ -53,6 +54,7 @@ import android.net.wifi.SecurityParams;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiManager;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.text.TextUtils;
@@ -74,6 +76,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Random;
@@ -1359,6 +1362,34 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
}
/**
+ * Tests that vendor data is sent to the HAL if included in the WifiConfiguration.
+ */
+ @Test
+ public void testSetVendorData() throws Exception {
+ // Re-initialize DUT to HAL service version 3
+ assumeTrue(SdkLevel.isAtLeastV());
+ mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(3,
+ mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor,
+ mWifiGlobals, mAdvanceKeyMgmtFeatures, mWpaDriverFeatures);
+
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putInt("intFieldKey", 1337);
+ android.net.wifi.OuiKeyedData ouiKeyedData =
+ new android.net.wifi.OuiKeyedData.Builder(0x00aabbcc, bundle).build();
+ List<android.net.wifi.OuiKeyedData> frameworkVendorData = Arrays.asList(ouiKeyedData);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
+ config.setVendorData(frameworkVendorData);
+ testWifiConfigurationSaveLoad(config);
+
+ verify(mISupplicantStaNetworkMock).setVendorData(any(OuiKeyedData[].class));
+ OuiKeyedData[] halVendorData = mSupplicantVariables.vendorData;
+ assertEquals(frameworkVendorData.size(), halVendorData.length);
+ assertEquals(frameworkVendorData.get(0).getOui(), halVendorData[0].oui);
+ assertTrue(frameworkVendorData.get(0).getData().equals(halVendorData[0].vendorData));
+ }
+
+ /**
* Sets up the AIDL interface mock with all the setters/getter values.
* Note: This only sets up the mock to return success on all methods.
*/
@@ -1818,6 +1849,13 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
mSupplicantVariables.selectedRcoi = selectedRcoi;
}
}).when(mISupplicantStaNetworkMock).setRoamingConsortiumSelection(any(byte[].class));
+
+ /** Vendor data */
+ doAnswer(new AnswerWithArguments() {
+ public void answer(OuiKeyedData[] vendorData) throws RemoteException {
+ mSupplicantVariables.vendorData = vendorData;
+ }
+ }).when(mISupplicantStaNetworkMock).setVendorData(any(OuiKeyedData[].class));
}
// Private class to to store/inspect values set via the AIDL mock.
@@ -1860,5 +1898,6 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
public boolean eapErp;
public byte saeH2eMode;
public byte[] selectedRcoi;
+ public OuiKeyedData[] vendorData;
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/TwtManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/TwtManagerTest.java
new file mode 100644
index 0000000000..6bcc9c59cf
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/TwtManagerTest.java
@@ -0,0 +1,361 @@
+/*
+ * 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;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.app.AlarmManager;
+import android.app.test.TestAlarmManager;
+import android.content.res.Resources;
+import android.net.wifi.ITwtCallback;
+import android.net.wifi.ITwtCapabilitiesListener;
+import android.net.wifi.ITwtStatsListener;
+import android.net.wifi.WifiContext;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiTwtSession;
+import android.net.wifi.twt.TwtRequest;
+import android.net.wifi.twt.TwtSession;
+import android.net.wifi.twt.TwtSessionCallback;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.test.TestLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wifi.resources.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+
+/**
+ * Unit test for {@link TwtManager}
+ */
+@SmallTest
+public class TwtManagerTest extends WifiBaseTest {
+ private static final int TWT_CALLBACKS_ID_START_OFFSET = 1;
+ private static final String WIFI_IFACE_NAME = "wlan0";
+ private static final String WIFI_IFACE_NAME_1 = "wlan1";
+
+ private static final int TEST_TWT_SESSION_ID = 10;
+ private static final int TEST_TWT_CMD_ID = 1;
+ private static final String TEST_BSSID = "00:11:22:33:44:55";
+ private static final String TEST_BLOCKED_BSSID_1 = "AA:BB:CC:DD:EE:FF";
+ private static final int TEST_BLOCKED_OUI_1 = 0xAABBCC;
+ private static final int TEST_BLOCKED_OUI_2 = 0xAABBCD;
+ private static final int TEST_BLOCKED_OUI_3 = 0xAABBCE;
+ private static final int TEST_BLOCKED_OUI_4 = 0xAABBCF;
+
+ @Mock
+ Clock mClock;
+ private TestAlarmManager mTestAlarmManager;
+ private final TestLooper mLooper = new TestLooper();
+ @Mock
+ private WifiInjector mWifiInjector;
+ private TwtManager mTwtManager;
+ @Mock
+ WifiNative mWifiNative;
+ @Mock
+ private ClientModeImplMonitor mCmiMonitor;
+ @Captor
+ private ArgumentCaptor<ClientModeImplListener> mCmiListenerCaptor;
+ @Mock
+ private IBinder mAppBinder;
+ private Handler mHandler;
+ private AlarmManager mAlarmManager;
+ @Mock
+ ConcreteClientModeManager mClientModeManager;
+ @Captor
+ private ArgumentCaptor<TwtManager.WifiNativeTwtEvents> mWifiNativeTwtEventsArgumentCaptor;
+ @Mock
+ Resources mResources;
+ @Mock
+ WifiContext mContext;
+
+ /**
+ * Test setup.
+ */
+ @Before
+ public void setUp() throws Exception {
+ initMocks(this);
+ mHandler = new Handler(mLooper.getLooper());
+ mTestAlarmManager = new TestAlarmManager();
+ mAlarmManager = mTestAlarmManager.getAlarmManager();
+ when(mWifiInjector.getAlarmManager()).thenReturn(mAlarmManager);
+ when(mWifiInjector.getContext()).thenReturn(mContext);
+ when(mContext.getResources()).thenReturn(mResources);
+ int[] blockedOuiList =
+ {TEST_BLOCKED_OUI_4, TEST_BLOCKED_OUI_3, TEST_BLOCKED_OUI_2, TEST_BLOCKED_OUI_1};
+ when(mResources.getIntArray(R.array.config_wifiTwtBlockedOuiList)).thenReturn(
+ blockedOuiList);
+ mTwtManager = new TwtManager(mWifiInjector, mCmiMonitor, mWifiNative, mHandler, mClock,
+ WifiTwtSession.MAX_TWT_SESSIONS, TWT_CALLBACKS_ID_START_OFFSET);
+ verify(mCmiMonitor).registerListener(mCmiListenerCaptor.capture());
+ mTwtManager.registerWifiNativeTwtEvents();
+ verify(mWifiNative).registerTwtCallbacks(mWifiNativeTwtEventsArgumentCaptor.capture());
+ }
+
+ private Bundle getDefaultTwtCapabilities() {
+ Bundle twtCapabilities = new Bundle();
+ twtCapabilities.putBoolean(WifiManager.TWT_CAPABILITIES_KEY_BOOLEAN_TWT_REQUESTER, false);
+ twtCapabilities.putInt(WifiManager.TWT_CAPABILITIES_KEY_INT_MIN_WAKE_DURATION_MICROS, -1);
+ twtCapabilities.putInt(WifiManager.TWT_CAPABILITIES_KEY_INT_MAX_WAKE_DURATION_MICROS, -1);
+ twtCapabilities.putLong(WifiManager.TWT_CAPABILITIES_KEY_LONG_MIN_WAKE_INTERVAL_MICROS, -1);
+ twtCapabilities.putLong(WifiManager.TWT_CAPABILITIES_KEY_LONG_MAX_WAKE_INTERVAL_MICROS, -1);
+ return twtCapabilities;
+ }
+
+ private Bundle getMockTwtCapabilities() {
+ Bundle twtCapabilities = new Bundle();
+ twtCapabilities.putBoolean(WifiManager.TWT_CAPABILITIES_KEY_BOOLEAN_TWT_REQUESTER, true);
+ twtCapabilities.putInt(WifiManager.TWT_CAPABILITIES_KEY_INT_MIN_WAKE_DURATION_MICROS, 100);
+ twtCapabilities.putInt(WifiManager.TWT_CAPABILITIES_KEY_INT_MAX_WAKE_DURATION_MICROS, 1000);
+ twtCapabilities.putLong(WifiManager.TWT_CAPABILITIES_KEY_LONG_MIN_WAKE_INTERVAL_MICROS,
+ 1000);
+ twtCapabilities.putLong(WifiManager.TWT_CAPABILITIES_KEY_LONG_MAX_WAKE_INTERVAL_MICROS,
+ 10000);
+ return twtCapabilities;
+ }
+
+ private static Bundle getMockTwtStats() {
+ Bundle twtStats = new Bundle();
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_COUNT, 200);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_COUNT, 300);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_SIZE, 400);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_SIZE, 200);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS, 1000);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_EOSP_COUNT, 10);
+ return twtStats;
+ }
+
+ private static Bundle getDefaultTwtStats() {
+ Bundle twtStats = new Bundle();
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_COUNT, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_COUNT, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_SIZE, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_SIZE, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS, -1);
+ twtStats.putInt(TwtSession.TWT_STATS_KEY_INT_EOSP_COUNT, -1);
+ return twtStats;
+ }
+
+ private boolean isBundleContentEqual(Bundle expected, Bundle actual) {
+ if (expected == actual) return true;
+ for (String key : expected.keySet()) {
+ if (!actual.containsKey(key) || !actual.get(key).equals(expected.get(key))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Test
+ public void testGetTwtCapabilities() throws RemoteException {
+ ITwtCapabilitiesListener iTwtCapabilitiesListener = mock(ITwtCapabilitiesListener.class);
+ InOrder inorder = inOrder(iTwtCapabilitiesListener);
+ // Test with null interface name
+ final Bundle defaultTwtCapabilities = getDefaultTwtCapabilities();
+ mTwtManager.getTwtCapabilities(null, iTwtCapabilitiesListener);
+ inorder.verify(iTwtCapabilitiesListener).onResult(
+ argThat(argument -> isBundleContentEqual(defaultTwtCapabilities, argument)));
+ // Test getTwtCapabilities when WifiNative return null
+ when(mWifiNative.getTwtCapabilities(eq(WIFI_IFACE_NAME))).thenReturn(null);
+ mTwtManager.getTwtCapabilities(null, iTwtCapabilitiesListener);
+ inorder.verify(iTwtCapabilitiesListener).onResult(
+ argThat(argument -> isBundleContentEqual(defaultTwtCapabilities, argument)));
+ // Test getTwtCapabilities
+ final Bundle mockTwtCapabilities = getMockTwtCapabilities();
+ when(mWifiNative.getTwtCapabilities(eq(WIFI_IFACE_NAME))).thenReturn(mockTwtCapabilities);
+ mTwtManager.getTwtCapabilities(WIFI_IFACE_NAME, iTwtCapabilitiesListener);
+ inorder.verify(iTwtCapabilitiesListener).onResult(
+ argThat(argument -> isBundleContentEqual(mockTwtCapabilities, argument)));
+ }
+
+ @Test
+ public void testOuiBlockListing() throws RemoteException {
+ ITwtCallback iTwtCallback = mock(ITwtCallback.class);
+ TwtRequest twtRequest = mock(TwtRequest.class);
+ InOrder inOrderCallback = inOrder(iTwtCallback);
+ when(iTwtCallback.asBinder()).thenReturn(mAppBinder);
+ when(mWifiNative.setupTwtSession(eq(1), eq(WIFI_IFACE_NAME), eq(twtRequest))).thenReturn(
+ true);
+ mTwtManager.setupTwtSession(WIFI_IFACE_NAME, twtRequest, iTwtCallback,
+ Binder.getCallingUid(), TEST_BLOCKED_BSSID_1);
+ inOrderCallback.verify(iTwtCallback).onFailure(
+ TwtSessionCallback.TWT_ERROR_CODE_AP_OUI_BLOCKLISTED);
+ }
+
+ @Test
+ public void testSetupTwtSession() throws RemoteException {
+ ITwtCallback iTwtCallback = mock(ITwtCallback.class);
+ TwtRequest twtRequest = mock(TwtRequest.class);
+ when(iTwtCallback.asBinder()).thenReturn(mAppBinder);
+ InOrder inOrderCallback = inOrder(iTwtCallback);
+ InOrder inOrderBinder = inOrder(mAppBinder);
+ InOrder inOrderAlarm = inOrder(mAlarmManager);
+ // Test with null interface
+ mTwtManager.setupTwtSession(null, twtRequest, iTwtCallback, Binder.getCallingUid(),
+ TEST_BSSID);
+ inOrderCallback.verify(iTwtCallback).onFailure(
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ // Test when wifiNative.setupTwtSession return false
+ when(mWifiNative.setupTwtSession(eq(1), eq(WIFI_IFACE_NAME), eq(twtRequest))).thenReturn(
+ false);
+ mTwtManager.setupTwtSession(WIFI_IFACE_NAME, twtRequest, iTwtCallback,
+ Binder.getCallingUid(), TEST_BSSID);
+ inOrderBinder.verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+ inOrderAlarm.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
+ anyString(), any(AlarmManager.OnAlarmListener.class), eq(mHandler));
+ inOrderBinder.verify(mAppBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+ inOrderCallback.verify(iTwtCallback).onFailure(
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ inOrderAlarm.verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
+ // Test when wifiNative.setupTwtSession return true
+ when(mWifiNative.setupTwtSession(eq(1), eq(WIFI_IFACE_NAME), eq(twtRequest))).thenReturn(
+ true);
+ mTwtManager.setupTwtSession(WIFI_IFACE_NAME, twtRequest, iTwtCallback,
+ Binder.getCallingUid(), TEST_BSSID);
+ inOrderBinder.verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+ inOrderAlarm.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
+ anyString(), any(AlarmManager.OnAlarmListener.class), eq(mHandler));
+ }
+
+ @Test
+ public void testTeardownTwtSession() throws RemoteException {
+ ITwtCallback iTwtCallback = mock(ITwtCallback.class);
+ TwtRequest twtRequest = mock(TwtRequest.class);
+ when(iTwtCallback.asBinder()).thenReturn(mAppBinder);
+ InOrder inOrderCallback = inOrder(iTwtCallback);
+ InOrder inOrderBinder = inOrder(mAppBinder);
+ InOrder inOrderAlarm = inOrder(mAlarmManager);
+ when(mWifiNative.tearDownTwtSession(eq(TEST_TWT_CMD_ID), eq(WIFI_IFACE_NAME),
+ eq(TEST_TWT_SESSION_ID))).thenReturn(true);
+ when(mWifiNative.setupTwtSession(eq(TEST_TWT_CMD_ID), eq(WIFI_IFACE_NAME),
+ eq(twtRequest))).thenReturn(true);
+ // Test when session is not setup
+ mTwtManager.tearDownTwtSession(WIFI_IFACE_NAME, TEST_TWT_SESSION_ID);
+ inOrderCallback.verifyNoMoreInteractions();
+ inOrderBinder.verifyNoMoreInteractions();
+ inOrderAlarm.verifyNoMoreInteractions();
+ // Make a session
+ mTwtManager.setupTwtSession(WIFI_IFACE_NAME, twtRequest, iTwtCallback,
+ Binder.getCallingUid(), TEST_BSSID);
+ inOrderBinder.verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+ inOrderAlarm.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
+ anyString(), any(AlarmManager.OnAlarmListener.class), eq(mHandler));
+ mWifiNativeTwtEventsArgumentCaptor.getValue().onTwtSessionCreate(TEST_TWT_CMD_ID, 100, 1000,
+ 1, TEST_TWT_SESSION_ID);
+ inOrderCallback.verify(iTwtCallback).onCreate(eq(100), eq(1000L), eq(1),
+ eq(Binder.getCallingUid()), eq(TEST_TWT_SESSION_ID));
+ // Test teardown with null interface
+ mTwtManager.tearDownTwtSession(null, TEST_TWT_SESSION_ID);
+ inOrderCallback.verify(iTwtCallback).onFailure(
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ // Test teardown with wrong interface
+ mTwtManager.tearDownTwtSession(WIFI_IFACE_NAME_1, TEST_TWT_SESSION_ID);
+ inOrderCallback.verify(iTwtCallback).onFailure(
+ TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE);
+ // Test teardown the session
+ mTwtManager.tearDownTwtSession(WIFI_IFACE_NAME, TEST_TWT_SESSION_ID);
+ inOrderBinder.verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+ inOrderAlarm.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
+ anyString(), any(AlarmManager.OnAlarmListener.class), eq(mHandler));
+ }
+
+ @Test
+ public void testGetStatsSession() throws RemoteException {
+ final Bundle defaultTwtStats = getDefaultTwtStats();
+ ITwtCallback iTwtCallback = mock(ITwtCallback.class);
+ ITwtStatsListener iTwtStatsListener = mock(ITwtStatsListener.class);
+ TwtRequest twtRequest = mock(TwtRequest.class);
+ when(iTwtStatsListener.asBinder()).thenReturn(mAppBinder);
+ when(iTwtCallback.asBinder()).thenReturn(mAppBinder);
+ InOrder inOrderListener = inOrder(iTwtStatsListener);
+ InOrder inOrderBinder = inOrder(mAppBinder);
+ InOrder inOrderAlarm = inOrder(mAlarmManager);
+ when(mWifiNative.getStatsTwtSession(eq(TEST_TWT_CMD_ID), eq(WIFI_IFACE_NAME),
+ eq(TEST_TWT_SESSION_ID))).thenReturn(true);
+ when(mWifiNative.setupTwtSession(eq(TEST_TWT_CMD_ID), eq(WIFI_IFACE_NAME),
+ eq(twtRequest))).thenReturn(true);
+ // Test when interface is not registered
+ mTwtManager.getStatsTwtSession(WIFI_IFACE_NAME_1, iTwtStatsListener, TEST_TWT_SESSION_ID);
+ inOrderListener.verify(iTwtStatsListener).onResult(
+ argThat(argument -> isBundleContentEqual(defaultTwtStats, argument)));
+ // Test when session is not setup
+ mTwtManager.getStatsTwtSession(WIFI_IFACE_NAME, iTwtStatsListener, TEST_TWT_SESSION_ID);
+ inOrderListener.verify(iTwtStatsListener).onResult(
+ argThat(argument -> isBundleContentEqual(defaultTwtStats, argument)));
+ // Make a session
+ mTwtManager.setupTwtSession(WIFI_IFACE_NAME, twtRequest, iTwtCallback,
+ Binder.getCallingUid(), TEST_BSSID);
+ inOrderBinder.verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+ inOrderAlarm.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
+ anyString(), any(AlarmManager.OnAlarmListener.class), eq(mHandler));
+ mWifiNativeTwtEventsArgumentCaptor.getValue().onTwtSessionCreate(TEST_TWT_CMD_ID, 100, 1000,
+ 1, TEST_TWT_SESSION_ID);
+ verify(iTwtCallback).onCreate(eq(100), eq(1000L), eq(1), eq(Binder.getCallingUid()),
+ eq(TEST_TWT_SESSION_ID));
+ // Test get stats on the session
+ mTwtManager.getStatsTwtSession(WIFI_IFACE_NAME, iTwtStatsListener, TEST_TWT_SESSION_ID);
+ Bundle twtStats = getMockTwtStats();
+ mWifiNativeTwtEventsArgumentCaptor.getValue().onTwtSessionStats(TEST_TWT_CMD_ID,
+ TEST_TWT_SESSION_ID, twtStats);
+ inOrderListener.verify(iTwtStatsListener).onResult(
+ argThat(argument -> isBundleContentEqual(twtStats, argument)));
+ }
+
+ @Test
+ public void testDisconnect() throws RemoteException {
+ ITwtCallback iTwtCallback = mock(ITwtCallback.class);
+ TwtRequest twtRequest = mock(TwtRequest.class);
+ when(iTwtCallback.asBinder()).thenReturn(mAppBinder);
+ InOrder inOrderCallback = inOrder(iTwtCallback);
+ InOrder inOrderBinder = inOrder(mAppBinder);
+ InOrder inOrderAlarm = inOrder(mAlarmManager);
+ when(mClientModeManager.getInterfaceName()).thenReturn("wlan0");
+ when(mClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
+ // Setup TWT session
+ when(mWifiNative.setupTwtSession(eq(1), eq(WIFI_IFACE_NAME), eq(twtRequest))).thenReturn(
+ true);
+ mTwtManager.setupTwtSession(WIFI_IFACE_NAME, twtRequest, iTwtCallback,
+ Binder.getCallingUid(), TEST_BSSID);
+ inOrderBinder.verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+ inOrderAlarm.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
+ anyString(), any(AlarmManager.OnAlarmListener.class), eq(mHandler));
+ // Disconnect and check the cleanup
+ mCmiListenerCaptor.getValue().onConnectionEnd(mClientModeManager);
+ inOrderCallback.verify(iTwtCallback).onFailure(TwtSessionCallback.TWT_ERROR_CODE_FAIL);
+ inOrderBinder.verify(mAppBinder).unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+ inOrderAlarm.verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java b/service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java
index f28628a517..51fe0fecff 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java
@@ -23,7 +23,8 @@ import android.content.Context;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.test.TestLooper;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
import org.junit.After;
import org.junit.Before;
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 644d022cdd..cd4a3fe773 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.android.server.wifi;
import static android.net.wifi.SoftApConfiguration.RANDOMIZATION_NON_PERSISTENT;
@@ -23,6 +22,7 @@ import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE;
import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
+import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO;
import static com.google.common.truth.Truth.assertThat;
@@ -33,9 +33,11 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
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;
@@ -110,6 +112,8 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
@Mock private ActiveModeWarden mActiveModeWarden;
@Mock private PackageManager mPackageManager;
@Mock private SoftApCapability mSoftApCapability;
+ @Mock private HalDeviceManager mHalDeviceManager;
+ @Mock private WifiSettingsConfigStore mWifiSettingsConfigStore;
private Random mRandom;
private MockResources mResources;
@@ -118,6 +122,10 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
private SoftApStoreData.DataSource mDataStoreSource;
private ArrayList<Integer> mKnownGood2GChannelList;
+ final ArgumentCaptor<WifiSettingsConfigStore.OnSettingsChangedListener>
+ mStaticChipInfoListenerCaptor =
+ ArgumentCaptor.forClass(WifiSettingsConfigStore.OnSettingsChangedListener.class);
+
@Before
public void setUp() throws Exception {
mLooper = new TestLooper();
@@ -125,7 +133,10 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
MockitoAnnotations.initMocks(this);
mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.P;
when(mContext.getApplicationInfo()).thenReturn(mMockApplInfo);
-
+ when(mWifiInjector.getSettingsConfigStore()).thenReturn(mWifiSettingsConfigStore);
+ when(mWifiInjector.getHalDeviceManager()).thenReturn(mHalDeviceManager);
+ // 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.setString(R.string.config_wifiSoftap2gChannelList,
@@ -187,7 +198,10 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
ArgumentCaptor.forClass(SoftApStoreData.DataSource.class);
verify(mWifiInjector).makeSoftApStoreData(dataStoreSourceArgumentCaptor.capture());
mDataStoreSource = dataStoreSourceArgumentCaptor.getValue();
-
+ verify(mWifiSettingsConfigStore).registerChangeListener(
+ eq(WIFI_STATIC_CHIP_INFO),
+ mStaticChipInfoListenerCaptor.capture(),
+ any(Handler.class));
return store;
}
@@ -223,7 +237,6 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
verifyDefaultApConfig(config, expectedSsid, isSaeSupport, true, false);
}
-
private void verifyDefaultApConfig(SoftApConfiguration config, String expectedSsid,
boolean isSaeSupport, boolean isMacRandomizationSupport, boolean isBridgedApSupport) {
String[] splitSsid = config.getWifiSsid().getUtf8Text().toString().split("_");
@@ -1472,4 +1485,43 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
.setSsid(TEST_DEFAULT_HOTSPOT_SSID).build());
assertEquals(lastPassphrase, store.getLastConfiguredTetheredApPassphraseSinceBoot());
}
+
+ @Test
+ public void testChipSupportBridgedButStaticChipUpdatedAfterGeneratingDefaultConfig()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mHalDeviceManager.isConcurrencyComboLoadedFromDriver()).thenReturn(false);
+ mResources.setBoolean(R.bool.config_wifiBridgedSoftApSupported, true);
+ WifiApConfigStore store = createWifiApConfigStore();
+ verifyDefaultApConfig(store.getApConfiguration(),
+ TEST_DEFAULT_AP_SSID, false, true, true);
+ mLooper.dispatchAll();
+ mStaticChipInfoListenerCaptor.getValue()
+ .onSettingsChanged(WIFI_STATIC_CHIP_INFO, "new static chip info");
+ mLooper.dispatchAll();
+ // Chip supports bridged mode, so no extra saveToStore when chip info is updated.
+ verify(mWifiConfigManager).saveToStore(true);
+ }
+
+ @Test
+ public void testChipNotSupportButStaticChipUpdatedAfterGeneratingDefaultConfig()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ reset(mWifiNative);
+ when(mWifiNative.canDeviceSupportCreateTypeCombo(any())).thenReturn(false);
+ when(mHalDeviceManager.isConcurrencyComboLoadedFromDriver()).thenReturn(false);
+ mResources.setBoolean(R.bool.config_wifiBridgedSoftApSupported, true);
+ WifiApConfigStore store = createWifiApConfigStore();
+ // Verify default band is bridged mode
+ verifyDefaultApConfig(store.getApConfiguration(),
+ TEST_DEFAULT_AP_SSID, false, true, true);
+ mLooper.dispatchAll();
+ mStaticChipInfoListenerCaptor.getValue()
+ .onSettingsChanged(WIFI_STATIC_CHIP_INFO, "new static chip info");
+ mLooper.dispatchAll();
+ // Chip didn't support bridged mode, so extra saveToStore for update to default band.
+ verify(mWifiConfigManager, times(2)).saveToStore(true);
+ // Verify it changes to default band.
+ verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID, false, true, false);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
index c500a4243e..481c8a5a4c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
@@ -257,6 +257,7 @@ public class WifiBackupRestoreTest extends WifiBaseTest {
+ "<int name=\"DeletionPriority\" value=\"0\" />\n"
+ "<int name=\"NumRebootsSinceLastUse\" value=\"0\" />\n"
+ "<boolean name=\"RepeaterEnabled\" value=\"false\" />\n"
+ + "<boolean name=\"EnableWifi7\" value=\"true\" />\n"
+ "<SecurityParamsList>\n"
+ "<SecurityParams>\n"
+ "<int name=\"SecurityType\" value=\"2\" />\n"
@@ -267,6 +268,7 @@ public class WifiBackupRestoreTest extends WifiBaseTest {
+ "<byte-array name=\"AllowedSuiteBCiphers\" num=\"0\"></byte-array>\n"
+ "</SecurityParams>\n"
+ "</SecurityParamsList>\n"
+ + "<boolean name=\"SendDhcpHostname\" value=\"true\" />\n"
+ "<int name=\"MeteredOverride\" value=\"1\" />\n"
+ "</WifiConfiguration>\n"
+ "<IpConfiguration>\n"
@@ -277,6 +279,58 @@ public class WifiBackupRestoreTest extends WifiBaseTest {
+ "</NetworkList>\n"
+ "</WifiBackupData>\n";
+ private static final String WIFI_BACKUP_DATA_V1_4 =
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<WifiBackupData>\n"
+ + "<float name=\"Version\" value=\"1.4\" />\n"
+ + "<NetworkList>\n"
+ + "<Network>\n"
+ + "<WifiConfiguration>\n"
+ + "<string name=\"ConfigKey\">&quot;"
+ + WifiConfigurationTestUtil.TEST_SSID
+ + "&quot;WPA_PSK</string>\n"
+ + "<string name=\"SSID\">&quot;"
+ + WifiConfigurationTestUtil.TEST_SSID
+ + "&quot;</string>\n"
+ + "<null name=\"PreSharedKey\" />\n"
+ + "<null name=\"WEPKeys\" />\n"
+ + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+ + "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
+ + "<boolean name=\"RequirePMF\" value=\"false\" />\n"
+ + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">02</byte-array>\n"
+ + "<byte-array name=\"AllowedProtocols\" num=\"1\">03</byte-array>\n"
+ + "<byte-array name=\"AllowedAuthAlgos\" num=\"0\"></byte-array>\n"
+ + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>\n"
+ + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>\n"
+ + "<byte-array name=\"AllowedGroupMgmtCiphers\" num=\"0\"></byte-array>\n"
+ + "<byte-array name=\"AllowedSuiteBCiphers\" num=\"0\"></byte-array>\n"
+ + "<boolean name=\"Shared\" value=\"true\" />\n"
+ + "<boolean name=\"AutoJoinEnabled\" value=\"false\" />\n"
+ + "<int name=\"Priority\" value=\"0\" />\n"
+ + "<int name=\"DeletionPriority\" value=\"0\" />\n"
+ + "<int name=\"NumRebootsSinceLastUse\" value=\"0\" />\n"
+ + "<boolean name=\"RepeaterEnabled\" value=\"true\" />\n"
+ + "<boolean name=\"EnableWifi7\" value=\"false\" />\n"
+ + "<SecurityParamsList>\n"
+ + "<SecurityParams>\n"
+ + "<int name=\"SecurityType\" value=\"2\" />\n"
+ + "<boolean name=\"IsEnabled\" value=\"true\" />\n"
+ + "<boolean name=\"SaeIsH2eOnlyMode\" value=\"false\" />\n"
+ + "<boolean name=\"SaeIsPkOnlyMode\" value=\"false\" />\n"
+ + "<boolean name=\"IsAddedByAutoUpgrade\" value=\"false\" />\n"
+ + "<byte-array name=\"AllowedSuiteBCiphers\" num=\"0\"></byte-array>\n"
+ + "</SecurityParams>\n"
+ + "</SecurityParamsList>\n"
+ + "<boolean name=\"SendDhcpHostname\" value=\"false\" />\n"
+ + "<int name=\"MeteredOverride\" value=\"1\" />\n"
+ + "</WifiConfiguration>\n"
+ + "<IpConfiguration>\n"
+ + "<string name=\"IpAssignment\">DHCP</string>\n"
+ + "<string name=\"ProxySettings\">NONE</string>\n"
+ + "</IpConfiguration>\n"
+ + "</Network>\n"
+ + "</NetworkList>\n"
+ + "</WifiBackupData>\n";
@Mock WifiPermissionsUtil mWifiPermissionsUtil;
private WifiBackupRestore mWifiBackupRestore;
private boolean mCheckDump = true;
@@ -1151,11 +1205,27 @@ public class WifiBackupRestoreTest extends WifiBaseTest {
WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
configurations, retrievedConfigurations);
+ }
+
+ /**
+ * Verify that restoring of configuration from a 1.4 version backup data.
+ */
+ @Test
+ public void testRestoreFromV1_4BackupData() {
+ List<WifiConfiguration> configurations = new ArrayList<>();
+ configurations.add(createNetworkForConfigurationWithV1_4Data());
+
+ byte[] backupData = WIFI_BACKUP_DATA_V1_4.getBytes();
+ List<WifiConfiguration> retrievedConfigurations =
+ mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+
+ WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+ configurations, retrievedConfigurations);
// Also, assert in the reverse direction to ensure the serialization logic matches.
// Note: This will stop working when we bump up the version. Then we'll need to copy
// the below assert to the test for the latest version.
- assertEquals(WIFI_BACKUP_DATA_V1_3,
+ assertEquals(WIFI_BACKUP_DATA_V1_4,
new String(mWifiBackupRestore.retrieveBackupDataFromConfigurations(
retrievedConfigurations)));
}
@@ -1222,6 +1292,19 @@ public class WifiBackupRestoreTest extends WifiBaseTest {
}
/**
+ * Creates correct WiFiConfiguration that should be parsed out of
+ * {@link #WIFI_BACKUP_DATA_V1_4} configuration which contains 1.4 version backup.
+ */
+ private static WifiConfiguration createNetworkForConfigurationWithV1_4Data() {
+ final WifiConfiguration config = createNetworkForConfigurationWithV1_3Data();
+ // Use non-default value for testing.
+ config.setRepeaterEnabled(true);
+ config.setWifi7Enabled(false);
+ config.setSendDhcpHostnameEnabled(false);
+ return config;
+ }
+
+ /**
* Helper method to write a list of networks in wpa_supplicant.conf format to the output stream.
*/
private byte[] createWpaSupplicantConfBackupData(List<WifiConfiguration> configurations) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java
index c44bcad857..f4efd0a4e2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java
@@ -80,6 +80,8 @@ public class WifiBlocklistMonitorTest extends WifiBaseTest {
private static final int TEST_DHCP_FAILURE = WifiBlocklistMonitor.REASON_DHCP_FAILURE;
private static final long TEST_MAX_DISABLE_DURATION_MILLIS =
TimeUnit.HOURS.toMillis(18); // 18 hours
+ private static final long TEST_SHORT_MAX_DISABLE_DURATION_MILLIS =
+ TimeUnit.SECONDS.toMillis(10); // 10 seconds
private static final long BASE_BLOCKLIST_DURATION = TimeUnit.MINUTES.toMillis(5); // 5 minutes
private static final long BASE_CONNECTED_SCORE_BLOCKLIST_DURATION =
TimeUnit.SECONDS.toMillis(30);
@@ -88,6 +90,7 @@ public class WifiBlocklistMonitorTest extends WifiBaseTest {
private static final long ABNORMAL_DISCONNECT_TIME_WINDOW_MS = TimeUnit.SECONDS.toMillis(30);
private static final long ABNORMAL_DISCONNECT_RESET_TIME_MS = TimeUnit.HOURS.toMillis(3);
private static final int FAILURE_STREAK_CAP = 7;
+ private static final int FAILURE_STREAK_CAP_LONG = 20;
private static final Map<Integer, Integer> BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP =
Map.ofEntries(
Map.entry(WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA, 1),
@@ -440,7 +443,7 @@ public class WifiBlocklistMonitorTest extends WifiBaseTest {
* streak), we are setting the blocklist duration using an exponential backoff technique.
*/
@Test
- public void testBssidIsRemoveFromBlocklistAfterTimoutExponentialBackoff() {
+ public void testBssidIsRemoveFromBlocklistAfterTimeoutExponentialBackoff() {
verifyAddTestBssidToBlocklist();
int multiplier = 2;
long duration = 0;
@@ -461,7 +464,7 @@ public class WifiBlocklistMonitorTest extends WifiBaseTest {
multiplier *= 2;
}
- // finally verify that the timout is capped by the FAILURE_STREAK_CAP
+ // finally verify that the timeout is capped by the FAILURE_STREAK_CAP
when(mWifiScoreCard.getBssidBlocklistStreak(anyString(), anyString(), anyInt()))
.thenReturn(FAILURE_STREAK_CAP + 1);
when(mClock.getWallClockMillis()).thenReturn(0L);
@@ -473,6 +476,26 @@ public class WifiBlocklistMonitorTest extends WifiBaseTest {
}
/**
+ * Verify that when adding a AP that had already been failing (therefore has a blocklist
+ * streak), we are setting the blocklist duration using an exponential backoff technique,
+ * and the disable duration for a network is capped at WifiConfigMaxDisableDurationMs.
+ */
+ @Test
+ public void testBssidIsRemoveFromBlocklistAfterTimeoutExponentialBackoffCapped() {
+ mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorFailureStreakCap,
+ FAILURE_STREAK_CAP_LONG);
+ when(mWifiScoreCard.getBssidBlocklistStreak(anyString(), anyString(), anyInt()))
+ .thenReturn(FAILURE_STREAK_CAP_LONG);
+ // verify that the timeout is capped at WifiConfigMaxDisableDurationMs
+ when(mClock.getWallClockMillis()).thenReturn(0L);
+ verifyAddTestBssidToBlocklist();
+ when(mClock.getWallClockMillis()).thenReturn(TEST_MAX_DISABLE_DURATION_MILLIS);
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_1));
+ when(mClock.getWallClockMillis()).thenReturn(TEST_MAX_DISABLE_DURATION_MILLIS + 1);
+ assertEquals(0, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+ }
+
+ /**
* Verify that consecutive failures will add a BSSID to blocklist.
*/
@Test
@@ -1622,6 +1645,24 @@ public class WifiBlocklistMonitorTest extends WifiBaseTest {
}
/**
+ * Verify the disable duration for a network is capped at
+ * a short WifiConfigMaxDisableDurationMs.
+ */
+ @Test
+ public void testTryEnableNetworkCappedByShortMaxDisableDuration() {
+ WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+ int disableReason = NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION;
+ when(mWifiGlobals.getWifiConfigMaxDisableDurationMs())
+ .thenReturn(TEST_SHORT_MAX_DISABLE_DURATION_MILLIS);
+ verifyDisableNetwork(openNetwork, disableReason);
+
+ // verify the exponential backoff is capped at WifiConfigMaxDisableDurationMs
+ verifyNetworkIsEnabledAfter(openNetwork,
+ TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS
+ + TEST_SHORT_MAX_DISABLE_DURATION_MILLIS);
+ }
+
+ /**
* Verifies that a network is disabled for the base duration even when there are no BSSIDs
* blocked.
*/
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 24c5898a40..3fd252d03e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
@@ -28,6 +28,8 @@ import static com.android.server.wifi.WifiCarrierInfoManager.NOTIFICATION_USER_C
import static com.android.server.wifi.WifiCarrierInfoManager.NOTIFICATION_USER_DISALLOWED_CARRIER_INTENT_ACTION;
import static com.android.server.wifi.WifiCarrierInfoManager.NOTIFICATION_USER_DISMISSED_INTENT_ACTION;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -110,6 +112,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
import java.util.function.Consumer;
import javax.crypto.BadPaddingException;
@@ -156,6 +159,9 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
@Mock SubscriptionInfo mNonDataSubscriptionInfo;
@Mock WifiConfigStore mWifiConfigStore;
@Mock WifiInjector mWifiInjector;
+ @Mock WifiNetworkFactory mWifiNetworkFactory;
+ @Mock UntrustedWifiNetworkFactory mUntrustedWifiNetworkFactory;
+ @Mock RestrictedWifiNetworkFactory mRestrictedWifiNetworkFactory;
@Mock WifiConfigManager mWifiConfigManager;
@Mock
WifiCarrierInfoStoreManagerData mWifiCarrierInfoStoreManagerData;
@@ -224,6 +230,11 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
when(mWifiInjector.getWifiNetworkSuggestionsManager())
.thenReturn(mWifiNetworkSuggestionsManager);
when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade);
+ when(mWifiInjector.getWifiNetworkFactory()).thenReturn(mWifiNetworkFactory);
+ when(mWifiInjector.getUntrustedWifiNetworkFactory())
+ .thenReturn(mUntrustedWifiNetworkFactory);
+ when(mWifiInjector.getRestrictedWifiNetworkFactory())
+ .thenReturn(mRestrictedWifiNetworkFactory);
when(mContext.getStringResourceWrapper(anyInt(), anyInt()))
.thenReturn(mWifiStringResourceWrapper);
mWifiCarrierInfoManager = new WifiCarrierInfoManager(mTelephonyManager,
@@ -2496,4 +2507,28 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
assertTrue(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(1));
}
+
+ @Test
+ public void testActiveSubsChangeUpdateWifiNetworkFactory() {
+ SubscriptionInfo subInfo1 = mock(SubscriptionInfo.class);
+ when(subInfo1.getSubscriptionId()).thenReturn(DATA_SUBID);
+ SubscriptionInfo subInfo2 = mock(SubscriptionInfo.class);
+ when(subInfo2.getSubscriptionId()).thenReturn(NON_DATA_SUBID);
+ when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(subInfo1, subInfo2));
+ mListenerArgumentCaptor.getValue().onSubscriptionsChanged();
+ mLooper.dispatchAll();
+ ArgumentCaptor<Set<Integer>> restrictedWifiCaptor = ArgumentCaptor.forClass(Set.class);
+ ArgumentCaptor<Set<Integer>> untrustedWifiCaptor = ArgumentCaptor.forClass(Set.class);
+ ArgumentCaptor<Set<Integer>> wifiCaptor = ArgumentCaptor.forClass(Set.class);
+ verify(mRestrictedWifiNetworkFactory, times(2)).updateSubIdsInCapabilitiesFilter(
+ restrictedWifiCaptor.capture());
+ assertThat(restrictedWifiCaptor.getValue()).containsExactly(DATA_SUBID, NON_DATA_SUBID);
+ verify(mUntrustedWifiNetworkFactory, times(2)).updateSubIdsInCapabilitiesFilter(
+ untrustedWifiCaptor.capture());
+ assertThat(restrictedWifiCaptor.getValue()).containsExactly(DATA_SUBID, NON_DATA_SUBID);
+ verify(mWifiNetworkFactory, times(2)).updateSubIdsInCapabilitiesFilter(
+ wifiCaptor.capture());
+ assertThat(wifiCaptor.getValue()).containsExactly(DATA_SUBID, NON_DATA_SUBID);
+ }
}
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 84e12e6018..7d12e157b0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -63,6 +63,7 @@ import android.content.pm.PackageManager;
import android.net.DhcpOption;
import android.net.IpConfiguration;
import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.ScanResult;
import android.net.wifi.SecurityParams;
import android.net.wifi.WifiConfiguration;
@@ -319,6 +320,8 @@ public class WifiConfigManagerTest extends WifiBaseTest {
when(mWifiPermissionsUtil.isProfileOwner(anyInt(), any())).thenReturn(false);
when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
.thenReturn(true);
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(false);
when(mWifiPermissionsUtil.isDeviceInDemoMode(any())).thenReturn(false);
when(mWifiPermissionsUtil.isSystem(any(), anyInt())).thenReturn(true);
when(mWifiLastResortWatchdog.shouldIgnoreSsidUpdate()).thenReturn(false);
@@ -1291,6 +1294,29 @@ public class WifiConfigManagerTest extends WifiBaseTest {
}
/**
+ * Test that configs containing vendor data can only be added/updated if the
+ * caller has the proper permissions.
+ */
+ @Test
+ public void testAddNetworkWithVendorDataPermissionCheck() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ WifiConfiguration configuration = WifiConfigurationTestUtil.createOpenNetwork();
+ configuration.setVendorData(Arrays.asList(mock(OuiKeyedData.class)));
+
+ // Expect failure if the caller does not have the permission.
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(false);
+ NetworkUpdateResult result = addNetworkToWifiConfigManager(configuration,
+ configuration.creatorUid);
+ assertEquals(WifiConfiguration.INVALID_NETWORK_ID, result.getNetworkId());
+
+ // Expect success if the caller has the permission.
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(true);
+ verifyAddNetworkToWifiConfigManager(configuration);
+ }
+
+ /**
* Verifies that the modification of a single open network using
* {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} with the creator UID
* should always succeed.
@@ -1818,7 +1844,8 @@ public class WifiConfigManagerTest extends WifiBaseTest {
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
mWifiConfigManager
- .updateBeforeConnect(result.getNetworkId(), TEST_CREATOR_UID, TEST_PACKAGE_NAME);
+ .updateBeforeConnect(result.getNetworkId(), TEST_CREATOR_UID, TEST_PACKAGE_NAME,
+ true);
WifiConfiguration retrievedNetwork =
mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
@@ -6657,7 +6684,7 @@ public class WifiConfigManagerTest extends WifiBaseTest {
.thenReturn(true);
mWifiConfigManager.updateBeforeConnect(config.networkId, TEST_CREATOR_UID,
- TEST_PACKAGE_NAME);
+ TEST_PACKAGE_NAME, true);
config = mWifiConfigManager.getConfiguredNetwork(config.networkId);
// network became enabled
@@ -6695,7 +6722,7 @@ public class WifiConfigManagerTest extends WifiBaseTest {
.thenReturn(false);
mWifiConfigManager.updateBeforeConnect(config.networkId, TEST_CREATOR_UID,
- TEST_PACKAGE_NAME);
+ TEST_PACKAGE_NAME, true);
config = mWifiConfigManager.getConfiguredNetwork(config.networkId);
// network became enabled
@@ -6730,7 +6757,7 @@ public class WifiConfigManagerTest extends WifiBaseTest {
when(mUserManager.isSameProfileGroup(any(), any())).thenReturn(false);
mWifiConfigManager.updateBeforeConnect(config.networkId, TEST_OTHER_USER_UID,
- TEST_PACKAGE_NAME);
+ TEST_PACKAGE_NAME, true);
// network still disabled
assertFalse(config.getNetworkSelectionStatus().isNetworkEnabled());
@@ -8218,7 +8245,7 @@ public class WifiConfigManagerTest extends WifiBaseTest {
WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(eapPeapNetId);
assertFalse(config.enterpriseConfig.isTrustOnFirstUseEnabled());
assertFalse(config.enterpriseConfig.isUserApproveNoCaCert());
- assertEquals("", config.enterpriseConfig.getDomainSuffixMatch());
+ assertEquals("mockServerCert", config.enterpriseConfig.getDomainSuffixMatch());
assertEquals("DNS:wifi.android;EMAIL:test@wifi.com;DNS:network.android;"
+ "URI:http://test.android.com",
config.enterpriseConfig.getAltSubjectMatch());
@@ -8444,4 +8471,60 @@ public class WifiConfigManagerTest extends WifiBaseTest {
// Verify operation still fails
assertFalse(addNetworkToWifiConfigManager(config).isSuccess());
}
+
+ /**
+ * Verify that the send DHCP hostname setting is correctly updated
+ */
+ @Test
+ public void testAddNetworkUpdatesSendDhcpHostname() {
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ config.setSendDhcpHostnameEnabled(false);
+
+ NetworkUpdateResult result = addNetworkToWifiConfigManager(config);
+
+ assertTrue(result.isSuccess());
+ config = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+ assertFalse(config.isSendDhcpHostnameEnabled());
+
+ config.setSendDhcpHostnameEnabled(true);
+ result = updateNetworkToWifiConfigManager(config);
+
+ assertTrue(result.isSuccess());
+ config = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+ assertTrue(config.isSendDhcpHostnameEnabled());
+ }
+
+ /**
+ * Verify that changing the DHCP hostname setting fails without NETWORK_SETTINGS or
+ * NETWORK_SETUP_WIZARD permissions.
+ */
+ @Test
+ public void testUpdateSendDhcpHostnameFailsWithoutSettingsOrSuwPermission() {
+ when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_CREATOR_UID))
+ .thenReturn(false);
+ when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(TEST_CREATOR_UID))
+ .thenReturn(false);
+ when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UPDATE_UID))
+ .thenReturn(false);
+ when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(TEST_UPDATE_UID))
+ .thenReturn(false);
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+
+ // Fail to add if dhcp hostname setting is set to DO_NOT_SEND
+ config.setSendDhcpHostnameEnabled(false);
+ NetworkUpdateResult result = addNetworkToWifiConfigManager(config);
+ assertFalse(result.isSuccess());
+
+ // Can add if dhcp hostname setting is reset to default SEND
+ config.setSendDhcpHostnameEnabled(true);
+ result = addNetworkToWifiConfigManager(config);
+ assertTrue(result.isSuccess());
+ config = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+ assertTrue(config.isSendDhcpHostnameEnabled());
+
+ // Fail to update if dchp hostname setting is set to DO_NOT_SEND
+ config.setSendDhcpHostnameEnabled(false);
+ result = updateNetworkToWifiConfigManager(config);
+ assertFalse(result.isSuccess());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
index c7fa102633..dd930430fd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
@@ -106,6 +106,7 @@ public class WifiConfigStoreTest extends WifiBaseTest {
+ "<int name=\"DeletionPriority\" value=\"0\" />\n"
+ "<int name=\"NumRebootsSinceLastUse\" value=\"0\" />\n"
+ "<boolean name=\"RepeaterEnabled\" value=\"false\" />\n"
+ + "<boolean name=\"EnableWifi7\" value=\"true\" />\n"
+ "<SecurityParamsList>\n"
+ "<SecurityParams>\n"
+ "<int name=\"SecurityType\" value=\"0\" />\n"
@@ -124,6 +125,7 @@ public class WifiConfigStoreTest extends WifiBaseTest {
+ "<byte-array name=\"AllowedSuiteBCiphers\" num=\"0\"></byte-array>\n"
+ "</SecurityParams>\n"
+ "</SecurityParamsList>\n"
+ + "<boolean name=\"SendDhcpHostname\" value=\"true\" />\n"
+ "<boolean name=\"Trusted\" value=\"true\" />\n"
+ "<boolean name=\"IsRestricted\" value=\"false\" />\n"
+ "<boolean name=\"OemPaid\" value=\"false\" />\n"
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
index 42f9c6ae38..8d29edb679 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
@@ -77,6 +77,9 @@ public class WifiConfigurationTestUtil {
public static final String[] TEST_WEP_KEYS =
{"\"WifiTestWep12\"", "\"WifiTestWep34\"",
"45342312ab", "45342312ab45342312ab34ac12"};
+ public static final String[] TEST_WEP_KEYS_WITH_NULL = {
+ "\"WifiTestWep12\"", "\"WifiTestWep34\"", "45342312ab45342312ab34ac12", null
+ };
public static final String TEST_EAP_PASSWORD = "WifiConfigurationTestUtilEapPassword";
public static final int TEST_WEP_TX_KEY_INDEX = 1;
public static final String TEST_FQDN = "WifiConfigurationTestUtilFQDN";
@@ -797,6 +800,9 @@ public class WifiConfigurationTestUtil {
expected.getNetworkSelectionStatus(), actual.getNetworkSelectionStatus());
assertWifiEnterpriseConfigEqualForConfigStore(
expected.enterpriseConfig, actual.enterpriseConfig);
+ if (SdkLevel.isAtLeastV()) {
+ assertEquals(expected.getVendorData(), actual.getVendorData());
+ }
}
/**
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 ece4ea1ebd..f2461fee37 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -503,9 +503,17 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// This unfortunately needs to be a somewhat valid scan result, otherwise
// |ScanDetailUtil.toScanDetail| raises exceptions.
final ScanResult[] scanResults = new ScanResult[1];
- scanResults[0] = new ScanResult(WifiSsid.fromUtf8Text(CANDIDATE_SSID),
- CANDIDATE_SSID, CANDIDATE_BSSID, 1245, 0, "some caps",
- -78, 2450, 1025, 22, 33, 20, 0, 0, true);
+ scanResults[0] = new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(CANDIDATE_SSID), CANDIDATE_BSSID)
+ .setHessid(1245)
+ .setCaps("some caps")
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
scanResults[0].informationElements = new InformationElement[1];
scanResults[0].informationElements[0] = new InformationElement();
scanResults[0].informationElements[0].id = InformationElement.EID_SSID;
@@ -1341,9 +1349,16 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(candidate.isOemPrivate()).thenReturn(false);
// Set up the scan candidates
- ScanResult result = new ScanResult(WifiSsid.fromString(ssid),
- ssid, bssid, 1245, 0, "some caps", rssi, frequency,
- 1025, 22, 33, 20, 0, 0, true);
+ ScanResult result = new ScanResult.Builder(WifiSsid.fromString(ssid), bssid)
+ .setHessid(1245)
+ .setCaps("some caps")
+ .setRssi(rssi)
+ .setFrequency(frequency)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
ScanResultMatchInfo matchInfo = ScanResultMatchInfo.fromScanResult(result);
WifiCandidates.Key key = new WifiCandidates.Key(matchInfo, MacAddress.fromString(bssid),
networkId, WifiConfiguration.SECURITY_TYPE_PSK);
@@ -1408,10 +1423,17 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
private void setupMockPrimaryNetworkSelect(int networkId, String bssid, int rssi,
int frequency) {
WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(networkId);
- config.getNetworkSelectionStatus().setCandidate(
- new ScanResult(WifiSsid.fromUtf8Text(config.SSID),
- config.SSID, bssid, 1245, 0, "some caps", rssi, frequency,
- 1025, 22, 33, 20, 0, 0, true));
+ config.getNetworkSelectionStatus().setCandidate(new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(config.SSID), bssid)
+ .setHessid(1245)
+ .setCaps("some caps")
+ .setRssi(rssi)
+ .setFrequency(frequency)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build());
// Selection for primary
when(mWifiNS.selectNetwork(any()))
.then(new AnswerWithArguments() {
@@ -1443,11 +1465,18 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Will return the first candidate matching networkId
if (networkId == candidate.getKey().networkId) {
config.getNetworkSelectionStatus().setCandidate(
- new ScanResult(WifiSsid.fromUtf8Text(config.SSID),
- config.SSID, candidate.getKey().bssid
- .toString(), 1245, 0, "some caps", rssi,
- candidate.getFrequency(), 1025, 22, 33,
- 20, 0, 0, true));
+ new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(config.SSID),
+ candidate.getKey().bssid.toString())
+ .setHessid(1245)
+ .setCaps("some caps")
+ .setRssi(rssi)
+ .setFrequency(candidate.getFrequency())
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build());
return config;
}
}
@@ -2666,10 +2695,18 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
List<ScanDetail> expectedOpenNetworks = new ArrayList<>();
expectedOpenNetworks.add(
- new ScanDetail(
- new ScanResult(WifiSsid.fromUtf8Text(CANDIDATE_SSID),
- CANDIDATE_SSID, CANDIDATE_BSSID, 1245, 0, "some caps", -78, 2450,
- 1025, 22, 33, 20, 0, 0, true)));
+ new ScanDetail(new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(CANDIDATE_SSID),
+ CANDIDATE_BSSID)
+ .setHessid(1245)
+ .setCaps("some caps")
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build()));
when(mWifiNS.getFilteredScanDetailsForOpenUnsavedNetworks())
.thenReturn(expectedOpenNetworks);
@@ -2696,9 +2733,18 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
List<ScanDetail> expectedOpenNetworks = new ArrayList<>();
expectedOpenNetworks.add(
new ScanDetail(
- new ScanResult(WifiSsid.fromUtf8Text(CANDIDATE_SSID),
- CANDIDATE_SSID, CANDIDATE_BSSID, 1245, 0, "some caps", -78, 2450,
- 1025, 22, 33, 20, 0, 0, true)));
+ new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(CANDIDATE_SSID),
+ CANDIDATE_BSSID)
+ .setHessid(1245)
+ .setCaps("some caps")
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build()));
when(mWifiNS.getFilteredScanDetailsForOpenUnsavedNetworks())
.thenReturn(expectedOpenNetworks);
@@ -2959,8 +3005,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// The actual interval should be same as scheduled.
final long delta = Math.abs(expectedInterval * 1000L - intervals.get(0));
- assertTrue("Interval " + " (" + delta + ") not in 1ms error margin",
- delta < 2);
+ assertTrue("Interval " + " (" + delta + ") not in 2ms error margin",
+ delta <= 2);
}
/**
@@ -4730,9 +4776,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null,
WifiConfigurationTestUtil.SECURITY_NONE);
candidate.BSSID = CANDIDATE_BSSID; // config specified
- ScanResult candidateScanResult = new ScanResult();
- candidateScanResult.SSID = CANDIDATE_SSID;
- candidateScanResult.BSSID = CANDIDATE_BSSID;
+ ScanResult candidateScanResult = new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(CANDIDATE_SSID), CANDIDATE_BSSID).build();
candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
when(mWifiNS.selectNetwork(any())).thenReturn(candidate);
@@ -4788,9 +4833,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null,
WifiConfigurationTestUtil.SECURITY_NONE);
candidate.BSSID = CANDIDATE_BSSID; // config specified
- ScanResult candidateScanResult = new ScanResult();
- candidateScanResult.SSID = CANDIDATE_SSID;
- candidateScanResult.BSSID = CANDIDATE_BSSID;
+ ScanResult candidateScanResult = new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(CANDIDATE_SSID), CANDIDATE_BSSID).build();
candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
when(mWifiNS.selectNetwork(any())).thenReturn(candidate);
@@ -4867,10 +4911,9 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null,
WifiConfigurationTestUtil.SECURITY_NONE);
candidate.BSSID = CANDIDATE_BSSID; // config specified
- ScanResult candidateScanResult = new ScanResult();
- candidateScanResult.SSID = CANDIDATE_SSID;
// Set up the scan result BSSID to be different from the config specified one.
- candidateScanResult.BSSID = INVALID_SCAN_RESULT_BSSID;
+ ScanResult candidateScanResult = new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(CANDIDATE_SSID), INVALID_SCAN_RESULT_BSSID).build();
candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
when(mWifiNS.selectNetwork(any())).thenReturn(candidate);
@@ -4908,10 +4951,9 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
TEST_CONNECTED_NETWORK_ID, 0, CANDIDATE_SSID, false, true, null, null,
WifiConfigurationTestUtil.SECURITY_NONE);
candidate.BSSID = CANDIDATE_BSSID; // config specified
- ScanResult candidateScanResult = new ScanResult();
- candidateScanResult.SSID = CANDIDATE_SSID;
// Set up the scan result BSSID to be different from the config specified one.
- candidateScanResult.BSSID = INVALID_SCAN_RESULT_BSSID;
+ ScanResult candidateScanResult = new ScanResult.Builder(
+ WifiSsid.fromUtf8Text(CANDIDATE_SSID), INVALID_SCAN_RESULT_BSSID).build();
candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
when(mWifiNS.selectNetwork(any())).thenReturn(candidate);
@@ -6060,12 +6102,13 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mLooper.dispatchAll();
List<WifiNetworkSelector.ClientModeManagerState> expectedCmmStates =
Arrays.asList(new WifiNetworkSelector.ClientModeManagerState(
- "wlan0", false, true, wifiInfo1, false),
+ "wlan0", false, true, wifiInfo1, false, ROLE_CLIENT_PRIMARY),
new WifiNetworkSelector.ClientModeManagerState(
- "wlan1", false, true, wifiInfo2, false));
+ "wlan1", false, true, wifiInfo2, false,
+ ROLE_CLIENT_SECONDARY_LONG_LIVED));
verify(mWifiNS).getCandidatesFromScan(any(), any(),
eq(expectedCmmStates), anyBoolean(), anyBoolean(), anyBoolean(), any(),
- anyBoolean());
+ eq(false));
}
@Test
@@ -6095,14 +6138,42 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
primaryCmm,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
mLooper.dispatchAll();
- List<WifiNetworkSelector.ClientModeManagerState> expectedCmmStates =
- Arrays.asList(new WifiNetworkSelector.ClientModeManagerState(
- "wlan0", false, true, wifiInfo1, false),
- new WifiNetworkSelector.ClientModeManagerState(
- "unknown", false, true, new WifiInfo(), false));
verify(mWifiNS).getCandidatesFromScan(any(), any(),
- eq(expectedCmmStates), anyBoolean(), anyBoolean(), anyBoolean(), any(),
- anyBoolean());
+ any(), anyBoolean(), anyBoolean(), anyBoolean(), any(),
+ eq(true));
+ }
+
+ @Test
+ public void testMbbAvailableWillSkipSufficiencyCheck() {
+ // Set screen to on
+ setScreenState(true);
+ // set OEM paid connection allowed.
+ WorkSource oemPaidWs = new WorkSource();
+ mWifiConnectivityManager.setOemPaidConnectionAllowed(true, oemPaidWs);
+
+ ConcreteClientModeManager primaryCmm = mock(ConcreteClientModeManager.class);
+ WifiInfo wifiInfo1 = mock(WifiInfo.class);
+ when(primaryCmm.getInterfaceName()).thenReturn("wlan0");
+ when(primaryCmm.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
+ when(primaryCmm.isConnected()).thenReturn(false);
+ when(primaryCmm.isDisconnected()).thenReturn(true);
+ when(primaryCmm.getConnectionInfo()).thenReturn(wifiInfo1);
+
+ when(mActiveModeWarden.getInternetConnectivityClientModeManagers())
+ .thenReturn(Arrays.asList(primaryCmm));
+ // Second STA creation is allowed.
+ when(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
+ eq(ActiveModeWarden.INTERNAL_REQUESTOR_WS), eq(ROLE_CLIENT_SECONDARY_TRANSIENT),
+ eq(false))).thenReturn(true);
+
+ // Set WiFi to disconnected state to trigger scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ primaryCmm,
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
+ verify(mWifiNS).getCandidatesFromScan(any(), any(),
+ any(), anyBoolean(), anyBoolean(), anyBoolean(), any(),
+ eq(true));
}
/**
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 5212b0ffd1..e9ba8d3b68 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
@@ -41,6 +41,7 @@ import static org.mockito.Mockito.when;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -79,6 +80,9 @@ import java.util.Locale;
public class WifiCountryCodeTest extends WifiBaseTest {
private static final String TAG = "WifiCountryCodeTest";
+ /* TODO: replace with PackageManager.FEATURE_TELEPHONY_CALLING once
+ * wifi-module-sdk-version-defaults min_sdk_version bumps to API 33. */
+ private static final String FEATURE_TELEPHONY_CALLING = "android.hardware.telephony.calling";
private static final String TEST_COUNTRY_CODE = "JP";
private static final String TEST_COUNTRY_CODE_2 = "CN";
private static final int TEST_ACTIVE_SUBSCRIPTION_ID = 1;
@@ -92,9 +96,11 @@ public class WifiCountryCodeTest extends WifiBaseTest {
// Default assume true since it was a design before R
private boolean mDriverSupportedNl80211RegChangedEvent = false;
private boolean mForcedSoftApRestateWhenCountryCodeChanged = false;
+ private boolean mCallingSupported;
@Mock Context mContext;
MockResources mResources = new MockResources();
@Mock TelephonyManager mTelephonyManager;
+ @Mock PackageManager mPackageManager;
@Mock ActiveModeWarden mActiveModeWarden;
@Mock ConcreteClientModeManager mClientModeManager;
@Mock SoftApManager mSoftApManager;
@@ -153,6 +159,9 @@ public class WifiCountryCodeTest extends WifiBaseTest {
when(mWifiInfo.getSuccessfulRxPacketsPerSecond()).thenReturn(5.0);
when(mContext.getSystemService(Context.TELEPHONY_SERVICE))
.thenReturn(mTelephonyManager);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+
+ setCallingSupported(true);
doAnswer(new AnswerWithArguments() {
public void answer(WifiSettingsConfigStore.Key<String> key, Object countryCode) {
@@ -180,6 +189,11 @@ public class WifiCountryCodeTest extends WifiBaseTest {
mScanDetails = setupScanDetails(TEST_COUNTRY_CODE);
}
+ private void setCallingSupported(boolean supported) {
+ mCallingSupported = supported;
+ when(mPackageManager.hasSystemFeature(FEATURE_TELEPHONY_CALLING)).thenReturn(supported);
+ }
+
@After
public void cleanUp() throws Exception {
mStaticMockSession.finishMocking();
@@ -293,7 +307,7 @@ public class WifiCountryCodeTest extends WifiBaseTest {
// Wifi get L2 connected.
mClientModeImplListenerCaptor.getValue().onConnectionStart(mClientModeManager);
- verify(mClientModeManager, times(3)).setCountryCode(anyString());
+ verify(mClientModeManager, times(2)).setCountryCode(anyString());
assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
}
@@ -318,15 +332,16 @@ public class WifiCountryCodeTest extends WifiBaseTest {
// Wifi get L2 connected.
mClientModeImplListenerCaptor.getValue().onConnectionStart(mClientModeManager);
- verify(mClientModeManager, times(3)).setCountryCode(anyString());
+ // Set twice, one is mDefaultCountryCode and another on is mTelephonyCountryCode
+ verify(mClientModeManager, times(2)).setCountryCode(anyString());
assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
// Remove mode manager.
mModeChangeCallbackCaptor.getValue().onActiveModeManagerRemoved(mClientModeManager);
- // Send Telephony country code again - should be ignored.
+ // Send Telephony country code again - should be ignored, times keep 2.
mWifiCountryCode.setTelephonyCountryCodeAndUpdate(mTelephonyCountryCode);
- verify(mClientModeManager, times(3)).setCountryCode(anyString());
+ verify(mClientModeManager, times(2)).setCountryCode(anyString());
assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCountryCode());
// Now try removing the mode manager again - should not crash.
@@ -375,8 +390,10 @@ public class WifiCountryCodeTest extends WifiBaseTest {
}
// Telephony country code still won't be applied.
assertEquals("00", mWifiCountryCode.getCurrentDriverCountryCode());
- // Wifi is forced to disconnect
- verify(mClientModeManager, times(1)).disconnect();
+ if (mCallingSupported) {
+ // Wifi is forced to disconnect
+ verify(mClientModeManager, times(1)).disconnect();
+ }
mClientModeImplListenerCaptor.getValue().onConnectionEnd(mClientModeManager);
// Telephony country is applied after supplicant is ready.
@@ -384,6 +401,12 @@ public class WifiCountryCodeTest extends WifiBaseTest {
assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
}
+ @Test
+ public void telephonyCountryCodeChangeAfterL2ConnectedWithoutCalling() throws Exception {
+ setCallingSupported(false);
+ telephonyCountryCodeChangeAfterL2Connected();
+ }
+
/**
* Test if we receive country code from Telephony after we get L2 connected on 2 STA interfaces.
* @throws Exception
@@ -643,7 +666,8 @@ public class WifiCountryCodeTest extends WifiBaseTest {
mModeChangeCallbackCaptor.getValue().onActiveModeManagerAdded(mClientModeManager);
// Verify the SoftApManager doesn't impact when client mode changed
verify(mSoftApManager, never()).updateCountryCode(anyString());
- verify(mClientModeManager, times(2)).setCountryCode(anyString());
+ // The mode change should not set country code again
+ verify(mClientModeManager).setCountryCode(anyString());
// Override the mClientModeManager.setCountryCode mock in setUp, do not update driver
// country code, so both client mode manager and ap mode manager will update country code.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java
index bf347639f7..257e7b9e70 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java
@@ -60,6 +60,7 @@ import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -82,6 +83,9 @@ public class WifiDialogManagerTest extends WifiBaseTest {
@Mock FrameworkFacade mFrameworkFacade;
@Mock Resources mResources;
@Mock ActivityManager mActivityManager;
+ @Mock WifiInjector mWifiInjector;
+ @Mock WifiDeviceStateChangeManager mWifiDeviceStateChangeManager;
+ @Captor ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor;
private WifiDialogManager mDialogManager;
@Before
@@ -90,11 +94,15 @@ public class WifiDialogManagerTest extends WifiBaseTest {
when(mWifiContext.getWifiDialogApkPkgName()).thenReturn(WIFI_DIALOG_APK_PKG_NAME);
when(mWifiContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
when(mWifiContext.getResources()).thenReturn(mResources);
+ when(mWifiInjector.getWifiDeviceStateChangeManager())
+ .thenReturn(mWifiDeviceStateChangeManager);
doThrow(SecurityException.class).when(mWifiContext).startActivityAsUser(any(), any(),
any());
- mDialogManager =
- new WifiDialogManager(mWifiContext, mWifiThreadRunner, mFrameworkFacade);
+ mDialogManager = new WifiDialogManager(mWifiContext, mWifiThreadRunner, mFrameworkFacade,
+ mWifiInjector);
mDialogManager.enableVerboseLogging(true);
+ verify(mWifiContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(),
+ eq(SdkLevel.isAtLeastT() ? Context.RECEIVER_EXPORTED : 0));
}
private void dispatchMockWifiThreadRunner(WifiThreadRunner wifiThreadRunner) {
@@ -750,11 +758,7 @@ public class WifiDialogManagerTest extends WifiBaseTest {
// ACTION_CLOSE_SYSTEM_DIALOGS with EXTRA_CLOSE_SYSTEM_DIALOGS_EXCEPT_WIFI should be
// ignored.
- ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- verify(mWifiContext).registerReceiver(broadcastReceiverCaptor.capture(), any(),
- eq(SdkLevel.isAtLeastT() ? Context.RECEIVER_EXPORTED : 0));
- broadcastReceiverCaptor.getValue().onReceive(mWifiContext,
+ mBroadcastReceiverArgumentCaptor.getValue().onReceive(mWifiContext,
new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
.putExtra(WifiManager.EXTRA_CLOSE_SYSTEM_DIALOGS_EXCEPT_WIFI, true));
dispatchMockWifiThreadRunner(mWifiThreadRunner);
@@ -762,7 +766,7 @@ public class WifiDialogManagerTest extends WifiBaseTest {
verify(dialog, never()).cancel();
// ACTION_CLOSE_SYSTEM_DIALOGS without the extra should cancel the dialog.
- broadcastReceiverCaptor
+ mBroadcastReceiverArgumentCaptor
.getValue()
.onReceive(mWifiContext, new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
dispatchMockWifiThreadRunner(mWifiThreadRunner);
@@ -799,15 +803,13 @@ public class WifiDialogManagerTest extends WifiBaseTest {
launchDialogSynchronous(dialogHandle, TIMEOUT_MILLIS, mWifiThreadRunner);
verify(window).setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
- // Receive ACTION_SCREEN_OFF.
+ // Receive screen off event.
when(dialog.isShowing()).thenReturn(true);
- ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- verify(mWifiContext).registerReceiver(broadcastReceiverCaptor.capture(), any(),
- eq(SdkLevel.isAtLeastT() ? Context.RECEIVER_EXPORTED : 0));
- broadcastReceiverCaptor.getValue().onReceive(mWifiContext,
- new Intent(Intent.ACTION_SCREEN_OFF));
- dispatchMockWifiThreadRunner(mWifiThreadRunner);
+ ArgumentCaptor<WifiDeviceStateChangeManager.StateChangeCallback> callbackArgumentCaptor =
+ ArgumentCaptor.forClass(WifiDeviceStateChangeManager.StateChangeCallback.class);
+ verify(mWifiDeviceStateChangeManager).registerStateChangeCallback(
+ callbackArgumentCaptor.capture());
+ callbackArgumentCaptor.getValue().onScreenStateChanged(false);
// Verify dialog was dismissed and relaunched with window type TYPE_APPLICATION_OVERLAY.
verify(dialog, never()).cancel();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java
index 919a7a2940..3a29bbf1bc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java
@@ -290,6 +290,17 @@ public class WifiGlobalsTest extends WifiBaseTest {
assertFalse(mWifiGlobals.isWepAllowed());
}
+
+ @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);
+ assertFalse(mWifiGlobals.isSwPnoEnabled());
+ }
+
/**
* Verify Force Overlay Config Value
*/
@@ -340,4 +351,23 @@ public class WifiGlobalsTest extends WifiBaseTest {
"true", true));
assertTrue(mWifiGlobals.isBackgroundScanSupported());
}
+
+ @Test
+ public void testIsD2dSupportedWhenInfraStaDisabled() {
+ mResources.setBoolean(R.bool.config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled,
+ false);
+ mWifiGlobals = new WifiGlobals(mContext);
+ mWifiGlobals.setD2dStaConcurrencySupported(true);
+ assertFalse(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled());
+ mWifiGlobals.setD2dStaConcurrencySupported(false);
+ assertFalse(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled());
+
+ mResources.setBoolean(R.bool.config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled,
+ true);
+ mWifiGlobals = new WifiGlobals(mContext);
+ mWifiGlobals.setD2dStaConcurrencySupported(true);
+ assertFalse(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled());
+ mWifiGlobals.setD2dStaConcurrencySupported(false);
+ assertTrue(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled());
+ }
}
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 4736dfbd32..f6192bd1c8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -291,7 +291,7 @@ public class WifiMetricsTest extends WifiBaseTest {
//Start and end Connection event
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
WifiMetricsProto.ConnectionEvent.HLF_DHCP,
@@ -306,10 +306,10 @@ public class WifiMetricsTest extends WifiBaseTest {
//start two ConnectionEvents in a row
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"BLUE", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"GREEN", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
}
private static final long TEST_RECORD_DURATION_SEC = 12 * 60 * 60;
@@ -523,7 +523,6 @@ public class WifiMetricsTest extends WifiBaseTest {
private static final long NUM_WATCHDOG_SUCCESS_DURATION_MS = 65;
private static final long WIFI_POWER_METRICS_LOGGING_DURATION = 280;
private static final long WIFI_POWER_METRICS_SCAN_TIME = 33;
- private static final boolean WIFI_IS_UNUSABLE_EVENT_LOGGING_SETTING = true;
private static final boolean LINK_SPEED_COUNTS_LOGGING_SETTING = true;
private static final int DATA_STALL_MIN_TX_BAD_SETTING = 5;
private static final int DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX_SETTING = 75;
@@ -1088,8 +1087,6 @@ public class WifiMetricsTest extends WifiBaseTest {
addWifiHealthMetrics();
- mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled,
- WIFI_IS_UNUSABLE_EVENT_LOGGING_SETTING);
mResources.setBoolean(R.bool.config_wifiLinkSpeedMetricsEnabled,
LINK_SPEED_COUNTS_LOGGING_SETTING);
mResources.setInteger(R.integer.config_wifiDataStallMinTxBad,
@@ -1596,8 +1593,6 @@ public class WifiMetricsTest extends WifiBaseTest {
mDecodedProto.wifiRadioUsage.loggingDurationMs);
assertEquals(WIFI_POWER_METRICS_SCAN_TIME,
mDecodedProto.wifiRadioUsage.scanTimeMs);
- assertEquals(WIFI_IS_UNUSABLE_EVENT_LOGGING_SETTING,
- mDecodedProto.experimentValues.wifiIsUnusableLoggingEnabled);
assertEquals(LINK_SPEED_COUNTS_LOGGING_SETTING,
mDecodedProto.experimentValues.linkSpeedCountsLoggingEnabled);
assertEquals(DATA_STALL_MIN_TX_BAD_SETTING,
@@ -1873,7 +1868,7 @@ public class WifiMetricsTest extends WifiBaseTest {
//Create a connection event using only the config
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"Red", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -1887,7 +1882,7 @@ public class WifiMetricsTest extends WifiBaseTest {
//Create a connection event using the config and a scan detail
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"Green", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME, scanDetail);
mWifiMetrics.logBugReport();
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
@@ -1975,7 +1970,7 @@ public class WifiMetricsTest extends WifiBaseTest {
// Create a connection event using only the config
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"Red", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -1995,7 +1990,7 @@ public class WifiMetricsTest extends WifiBaseTest {
public void testMetricsAssociationTimedOut() throws Exception {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2031,7 +2026,7 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2059,7 +2054,7 @@ public class WifiMetricsTest extends WifiBaseTest {
when(securityParams.isEnterpriseSecurityType()).thenReturn(false);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2079,11 +2074,11 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiConfiguration config1 = WifiConfigurationTestUtil.createPskNetwork();
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config1, "RED",
WifiMetricsProto.ConnectionEvent.ROAM_DBDC, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
WifiConfiguration config2 = WifiConfigurationTestUtil.createOpenNetwork();
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME2, config2, "BLUE",
WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME, mock(ScanDetail.class));
mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME, false);
@@ -2135,11 +2130,11 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiConfiguration config1 = WifiConfigurationTestUtil.createPskNetwork();
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config1, "RED",
WifiMetricsProto.ConnectionEvent.ROAM_DBDC, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
WifiConfiguration config2 = WifiConfigurationTestUtil.createOpenNetwork();
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME2, config2, "BLUE",
WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME, mock(ScanDetail.class));
mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME, false);
@@ -2189,7 +2184,7 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiConfiguration config1 = WifiConfigurationTestUtil.createPskNetwork();
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config1, "RED",
WifiMetricsProto.ConnectionEvent.ROAM_DBDC, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME, mock(ScanDetail.class));
mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME, false);
mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME, 100, 50);
@@ -2202,7 +2197,7 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiConfiguration config2 = WifiConfigurationTestUtil.createOpenNetwork();
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME2, config2, "BLUE",
WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME2, mock(ScanDetail.class));
mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME2, true);
mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME2, 400, 200);
@@ -2240,6 +2235,7 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.setConnectionScanDetail("nonexistentIface", mock(ScanDetail.class));
mWifiMetrics.setConnectionPmkCache("nonexistentIface", false);
mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps("nonexistentIface", 100, 50);
+ mWifiMetrics.setConnectionChannelWidth("nonexistentIface", ScanResult.CHANNEL_WIDTH_160MHZ);
mWifiMetrics.endConnectionEvent("nonexistentIface",
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION,
WifiMetricsProto.ConnectionEvent.HLF_DHCP,
@@ -2256,7 +2252,7 @@ public class WifiMetricsTest extends WifiBaseTest {
config.carrierMerged = true;
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2289,7 +2285,7 @@ public class WifiMetricsTest extends WifiBaseTest {
config.fromWifiNetworkSuggestion = false;
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2301,7 +2297,7 @@ public class WifiMetricsTest extends WifiBaseTest {
config.carrierId = 123;
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2313,7 +2309,7 @@ public class WifiMetricsTest extends WifiBaseTest {
config.carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2338,7 +2334,7 @@ public class WifiMetricsTest extends WifiBaseTest {
public void testMetricsAuthenticationFailureReason() throws Exception {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2414,7 +2410,7 @@ public class WifiMetricsTest extends WifiBaseTest {
// Create 3 ConnectionEvents
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2422,7 +2418,7 @@ public class WifiMetricsTest extends WifiBaseTest {
TEST_CONNECTION_FAILURE_STATUS_CODE);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"YELLOW", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2430,7 +2426,7 @@ public class WifiMetricsTest extends WifiBaseTest {
TEST_CONNECTION_FAILURE_STATUS_CODE);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"GREEN", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2438,7 +2434,7 @@ public class WifiMetricsTest extends WifiBaseTest {
TEST_CONNECTION_FAILURE_STATUS_CODE);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"ORANGE", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2456,7 +2452,7 @@ public class WifiMetricsTest extends WifiBaseTest {
// Create 2 ConnectionEvents
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"BLUE", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2464,7 +2460,7 @@ public class WifiMetricsTest extends WifiBaseTest {
TEST_CONNECTION_FAILURE_STATUS_CODE);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2485,7 +2481,7 @@ public class WifiMetricsTest extends WifiBaseTest {
// Start and end Connection event
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
WifiMetricsProto.ConnectionEvent.HLF_DHCP,
@@ -2504,7 +2500,7 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(true),
eq(false),
eq(1), eq(TEST_CONNECTION_FAILURE_STATUS_CODE), anyInt(), anyInt(), anyInt(),
- anyInt(), anyInt()));
+ anyInt(), anyInt(), eq(TEST_UID)));
}
/**
@@ -2516,7 +2512,7 @@ public class WifiMetricsTest extends WifiBaseTest {
// Create 2 complete ConnectionEvents and 1 ongoing un-ended ConnectionEvent
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2524,7 +2520,7 @@ public class WifiMetricsTest extends WifiBaseTest {
TEST_CONNECTION_FAILURE_STATUS_CODE);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"YELLOW", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -2532,7 +2528,7 @@ public class WifiMetricsTest extends WifiBaseTest {
TEST_CONNECTION_FAILURE_STATUS_CODE);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
"GREEN", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
// Dump proto and deserialize
// This should clear the metrics in mWifiMetrics,
@@ -3393,7 +3389,7 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.setNetworkSelectorExperimentId(id);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
"TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -3410,7 +3406,7 @@ public class WifiMetricsTest extends WifiBaseTest {
public void testConnectionWithPmkCache() throws Exception {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
"TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME, true);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
@@ -3431,7 +3427,7 @@ public class WifiMetricsTest extends WifiBaseTest {
.thenReturn(2);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
"TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME,
MAX_SUPPORTED_TX_LINK_SPEED_MBPS, MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
@@ -3515,7 +3511,7 @@ public class WifiMetricsTest extends WifiBaseTest {
when(securityParams.isEnterpriseSecurityType()).thenReturn(true);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
if (completeConnectionEvent) {
if (successfulConnectionEvent) {
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
@@ -3716,22 +3712,10 @@ public class WifiMetricsTest extends WifiBaseTest {
}
/**
- * Verify that no WifiIsUnusableEvent is generated when it is disabled in the settings
- */
- @Test
- public void testNoUnusableEventLogWhenDisabled() throws Exception {
- mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, false);
- generateAllUnusableEvents(mWifiMetrics);
- dumpProtoAndDeserialize();
- assertEquals(0, mDecodedProto.wifiIsUnusableEventList.length);
- }
-
- /**
* Generate WifiIsUnusableEvent and verify that they are logged correctly
*/
@Test
public void testUnusableEventLogSerializeDeserialize() throws Exception {
- mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, true);
generateAllUnusableEvents(mWifiMetrics);
dumpProtoAndDeserialize();
verifyDeserializedUnusableEvents(mDecodedProto);
@@ -3743,7 +3727,6 @@ public class WifiMetricsTest extends WifiBaseTest {
*/
@Test
public void testWifiIsUnUsableReportedWithNoExternalScorer() throws Exception {
- mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, true);
generateAllUnusableEvents(mWifiMetrics);
for (int i = 0; i < mTestUnusableEvents.length; i++) {
int index = i;
@@ -3759,7 +3742,6 @@ public class WifiMetricsTest extends WifiBaseTest {
*/
@Test
public void testWifiIsUnUsableReportedWithExternalScorer() throws Exception {
- mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, true);
mWifiMetrics.setIsExternalWifiScorerOn(true, TEST_UID);
mWifiMetrics.setScorerPredictedWifiUsabilityState(TEST_IFACE_NAME,
WifiMetrics.WifiUsabilityState.USABLE);
@@ -3777,7 +3759,6 @@ public class WifiMetricsTest extends WifiBaseTest {
*/
@Test
public void testUnusableEventBounding() throws Exception {
- mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, true);
for (int i = 0; i < (WifiMetrics.MAX_UNUSABLE_EVENTS + 2); i++) {
generateAllUnusableEvents(mWifiMetrics);
}
@@ -3791,7 +3772,6 @@ public class WifiMetricsTest extends WifiBaseTest {
*/
@Test
public void testUnusableEventTimeThrottleForDataStall() throws Exception {
- mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, true);
generateUnusableEventAtGivenTime(0, 0);
// should be time throttled
generateUnusableEventAtGivenTime(1, 1);
@@ -6270,12 +6250,12 @@ public class WifiMetricsTest extends WifiBaseTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
"TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 1000);
// Connection event 2 overlaps with 1
assertEquals(1000, mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
"TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY));
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID));
// Connection event 2 ends
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
@@ -6287,7 +6267,7 @@ public class WifiMetricsTest extends WifiBaseTest {
// Connection event 3 doesn't overlap with 2
assertEquals(0, mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
"TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY));
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID));
}
@Test
@@ -6317,7 +6297,7 @@ public class WifiMetricsTest extends WifiBaseTest {
config.updateIdentifier = "7";
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -6419,12 +6399,13 @@ public class WifiMetricsTest extends WifiBaseTest {
public void testWifiConnectionResultAtomNotEmittedWithNoConnectionEndEvent() {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
ExtendedMockito.verify(() -> WifiStatsLog.write(
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED), anyBoolean(), anyInt(), anyInt(),
anyInt(), anyInt(), anyInt(), anyInt(), anyBoolean(), anyInt(), anyBoolean(),
- anyBoolean(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()),
+ anyBoolean(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
+ eq(TEST_UID)),
times(0));
}
@@ -6439,7 +6420,8 @@ public class WifiMetricsTest extends WifiBaseTest {
ExtendedMockito.verify(() -> WifiStatsLog.write(
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED), anyBoolean(), anyInt(), anyInt(),
anyInt(), anyInt(), anyInt(), anyInt(), anyBoolean(), anyInt(), anyBoolean(),
- anyBoolean(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()),
+ anyBoolean(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
+ eq(TEST_UID)),
times(0));
}
@@ -6447,7 +6429,7 @@ public class WifiMetricsTest extends WifiBaseTest {
public void testWifiConnectionResultAtomEmittedOnlyOnceWithMultipleConnectionEndEvents() {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
for (int i = 0; i < 5; i++) {
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
@@ -6466,7 +6448,7 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_BOOT),
eq(true),
eq(0), eq(true), eq(false), eq(1), eq(TEST_CONNECTION_FAILURE_STATUS_CODE),
- anyInt(), anyInt(), anyInt(), anyInt(), anyInt()),
+ anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), eq(TEST_UID)),
times(1));
}
@@ -6481,11 +6463,11 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config1,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config2,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, true,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
@@ -6502,7 +6484,7 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_BOOT),
eq(true),
eq(0), eq(true), eq(true), eq(1), eq(TEST_CONNECTION_FAILURE_STATUS_CODE),
- anyInt(), anyInt(), anyInt(), anyInt(), anyInt()),
+ anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), eq(TEST_UID)),
times(1));
}
@@ -6510,7 +6492,7 @@ public class WifiMetricsTest extends WifiBaseTest {
public void testWifiConnectionResultAtomHasCorrectTriggers() {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
@@ -6526,11 +6508,11 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_BOOT),
anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), anyInt(),
eq(TEST_CONNECTION_FAILURE_STATUS_CODE), anyInt(), anyInt(), anyInt(), anyInt(),
- anyInt()));
+ anyInt(), eq(TEST_UID)));
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
@@ -6546,7 +6528,7 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__RECONNECT_SAME_NETWORK),
anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), anyInt(),
eq(TEST_CONNECTION_FAILURE_STATUS_CODE), anyInt(), anyInt(), anyInt(), anyInt(),
- anyInt()));
+ anyInt(), eq(TEST_UID)));
WifiConfiguration configOtherNetwork = createComplexWifiConfig();
configOtherNetwork.networkId = 21;
@@ -6556,7 +6538,7 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, configOtherNetwork,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
@@ -6572,7 +6554,7 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_CONFIGURED_NETWORK),
anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), anyInt(),
eq(TEST_CONNECTION_FAILURE_STATUS_CODE), anyInt(), anyInt(), anyInt(), anyInt(),
- anyInt()));
+ anyInt(), eq(TEST_UID)));
WifiConfiguration config = createComplexWifiConfig();
config.networkId = 42;
@@ -6581,7 +6563,7 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"GREEN", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
@@ -6595,14 +6577,14 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__MANUAL),
anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), anyInt(),
eq(TEST_CONNECTION_FAILURE_STATUS_CODE), anyInt(), anyInt(), anyInt(), anyInt(),
- anyInt()));
+ anyInt(), eq(TEST_UID)));
}
@Test
public void testWifiDisconnectAtomEmittedOnDisconnectFromSuccessfulSession() {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
long connectionEndTimeMs = 1000;
when(mClock.getElapsedSinceBootMillis()).thenReturn(connectionEndTimeMs);
@@ -6637,7 +6619,7 @@ public class WifiMetricsTest extends WifiBaseTest {
public void testWifiDisconnectAtomNotEmittedOnDisconnectFromNotConnectedSession() {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
long connectionEndTimeMs = 1000;
when(mClock.getElapsedSinceBootMillis()).thenReturn(connectionEndTimeMs);
@@ -6677,7 +6659,7 @@ public class WifiMetricsTest extends WifiBaseTest {
public void testWifiStateChangedAtomEmittedOnSuccessfulConnectAndDisconnect() {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
@@ -6709,7 +6691,7 @@ public class WifiMetricsTest extends WifiBaseTest {
public void testWifiStateChangedAtomNotEmittedOnNotSuccessfulConnectAndDisconnect() {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
@@ -6728,12 +6710,12 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, reason, TEST_CANDIDATE_LEVEL,
linkSpeed, 0);
- // But we still expect FALSE to be emitted
+ // FALSE should not be emitted since wifi was never connected
ExtendedMockito.verify(() -> WifiStatsLog.write(
- WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED,
- false,
- 0,
- 0));
+ eq(WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED),
+ eq(false),
+ anyInt(),
+ anyInt()), times(0));
}
@Test
@@ -6742,7 +6724,7 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
@@ -6756,7 +6738,7 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_BOOT),
anyBoolean(), eq(10), anyBoolean(), anyBoolean(), anyInt(),
eq(TEST_CONNECTION_FAILURE_STATUS_CODE), anyInt(), anyInt(), anyInt(), anyInt(),
- anyInt()));
+ anyInt(), eq(TEST_UID)));
mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, 0, 0, 0, 0);
@@ -6764,7 +6746,7 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
"RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
@@ -6778,7 +6760,7 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__RECONNECT_SAME_NETWORK),
anyBoolean(), eq(20), anyBoolean(), anyBoolean(), anyInt(),
eq(TEST_CONNECTION_FAILURE_STATUS_CODE), anyInt(), anyInt(), anyInt(), anyInt(),
- anyInt()));
+ anyInt(), eq(TEST_UID)));
mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, 0, 0, 0, 0);
}
@@ -7134,7 +7116,7 @@ public class WifiMetricsTest extends WifiBaseTest {
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -7275,7 +7257,8 @@ public class WifiMetricsTest extends WifiBaseTest {
when(networkDetail.isIndividualTwtSupported()).thenReturn(true);
when(networkDetail.isTwtRequired()).thenReturn(true);
when(networkDetail.isFilsCapable()).thenReturn(true);
- when(networkDetail.is11azSupported()).thenReturn(true);
+ when(networkDetail.is80211azNtbResponder()).thenReturn(true);
+ when(networkDetail.is80211azTbResponder()).thenReturn(false);
when(networkDetail.is80211McResponderSupport()).thenReturn(true);
when(networkDetail.isEpcsPriorityAccessSupported()).thenReturn(true);
when(networkDetail.getHSRelease()).thenReturn(NetworkDetail.HSRelease.Unknown);
@@ -7291,11 +7274,12 @@ public class WifiMetricsTest extends WifiBaseTest {
//Create a connection event using only the config
mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
"Red", WifiMetricsProto.ConnectionEvent.ROAM_NONE, false,
- WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY);
+ WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY, TEST_UID);
mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME, scanDetail);
mWifiMetrics.logBugReport();
mWifiMetrics.logStaEvent(TEST_IFACE_NAME, StaEvent.TYPE_CMD_START_ROAM,
StaEvent.DISCONNECT_UNKNOWN, null);
+ mWifiMetrics.setConnectionChannelWidth(TEST_IFACE_NAME, ScanResult.CHANNEL_WIDTH_160MHZ);
mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -7329,6 +7313,7 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__PASSPOINT_RELEASE__PASSPOINT_RELEASE_UNKNOWN),
eq(false), // isPasspointHomeProvider
eq(WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__AP_TYPE_6GHZ__AP_TYPE_6GHZ_STANDARD_POWER),
- eq(true))); // mIsEcpsPriorityAccessSupported
+ eq(true), // mIsEcpsPriorityAccessSupported
+ eq(WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__CHANNEL_WIDTH_MHZ__CHANNEL_WIDTH_160MHZ))); // mChannelWidth
}
}
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 0d48157005..2481f066e6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
@@ -16,8 +16,12 @@
package com.android.server.wifi;
+import static com.android.server.wifi.p2p.WifiP2pNative.P2P_IFACE_NAME;
+import static com.android.server.wifi.p2p.WifiP2pNative.P2P_INTERFACE_PROPERTY;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -53,6 +57,7 @@ import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
import com.android.server.wifi.WifiNative.SupplicantDeathEventHandler;
import com.android.server.wifi.WifiNative.VendorHalDeathEventHandler;
+import com.android.server.wifi.p2p.WifiP2pNative;
import com.android.server.wifi.util.NetdWrapper;
import com.android.server.wifi.util.NetdWrapper.NetdEventObserver;
import com.android.wifi.resources.R;
@@ -88,6 +93,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
private static final int SOFTAP_FAILURE_CODE_START_DAEMON = 2;
private static final int SOFTAP_FAILURE_CODE_CREATE_IFACE = 3;
private static final int SOFTAP_FAILURE_CODE_BRIDGED_AP_INSTANCES = 4;
+ private static final int P2P_FAILURE_CODE_CREATE_INTERFACE = 1;
private static final int TEST_SUPPORTED_BANDS = 15;
MockResources mResources;
@@ -103,11 +109,15 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
@Mock BuildProperties mBuildProperties;
@Mock private WifiInjector mWifiInjector;
@Mock private WifiContext mContext;
+ @Mock private HalDeviceManager mHalDeviceManager;
+ @Mock private WifiP2pNative mWifiP2pNative;
@Mock private WifiNative.StatusListener mStatusListener;
@Mock private WifiNative.InterfaceCallback mIfaceCallback0;
@Mock private WifiNative.InterfaceCallback mIfaceCallback1;
@Mock private WifiNative.InterfaceEventCallback mIfaceEventCallback0;
+ @Mock private HalDeviceManager.InterfaceDestroyedListener mP2pInterfaceDestroyedListener;
+ @Mock private Handler mP2pEventHandler;
@Mock private WifiSettingsConfigStore mWifiSettingsConfigStore;
@Mock private WifiGlobals mWifiGlobals;
@@ -116,6 +126,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
@Mock DeviceConfigFacade mDeviceConfigFacade;
private TestLooper mLooper;
+ private WifiNative.Iface mActiveP2pIface;
private ArgumentCaptor<VendorHalDeathEventHandler> mWifiVendorHalDeathHandlerCaptor =
ArgumentCaptor.forClass(VendorHalDeathEventHandler.class);
@@ -206,6 +217,8 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
when(mWifiInjector.getSettingsConfigStore()).thenReturn(mWifiSettingsConfigStore);
when(mWifiInjector.getContext()).thenReturn(mContext);
when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals);
+ when(mWifiInjector.getHalDeviceManager()).thenReturn(mHalDeviceManager);
+ when(mWifiInjector.getWifiP2pNative()).thenReturn(mWifiP2pNative);
mResources = getMockResources();
mResources.setBoolean(R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled, false);
mResources.setString(
@@ -223,7 +236,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder = inOrder(mWifiVendorHal, mWificondControl, mSupplicantStaIfaceHal, mHostapdHal,
mWifiMonitor, mNetdWrapper, mIfaceCallback0, mIfaceCallback1, mIfaceEventCallback0,
- mWifiMetrics);
+ mWifiMetrics, mWifiP2pNative);
mWifiNative = new WifiNative(
mWifiVendorHal, mSupplicantStaIfaceHal, mHostapdHal, mWificondControl,
@@ -237,6 +250,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mWificondDeathHandlerCaptor.capture());
mInOrder.verify(mWificondControl).tearDownInterfaces();
mInOrder.verify(mWifiVendorHal).registerRadioModeChangeHandler(any());
+ mActiveP2pIface = null;
}
@After
@@ -269,6 +283,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
@Test
public void testSetupClientInterfaceWithQosPolicyFeatureEnabled() throws Exception {
mResources.setBoolean(R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled, true);
+ when(mSupplicantStaIfaceHal.isAidlService()).thenReturn(true);
when(mSupplicantStaIfaceHal
.setNetworkCentricQosPolicyFeatureEnabled(anyString(), anyBoolean()))
.thenReturn(true);
@@ -276,6 +291,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
assertEquals(Set.of(IFACE_NAME_0), mWifiNative.getClientInterfaceNames());
+ verify(mSupplicantStaIfaceHal).isAidlService();
verify(mSupplicantStaIfaceHal)
.setNetworkCentricQosPolicyFeatureEnabled(IFACE_NAME_0, true);
}
@@ -491,6 +507,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
verify(mNetdWrapper).unregisterObserver(mNetworkObserverCaptor1.getValue());
verify(mSupplicantStaIfaceHal).teardownIface(IFACE_NAME_1);
verify(mWificondControl).tearDownClientInterface(IFACE_NAME_1);
+ verify(mSupplicantStaIfaceHal, atLeastOnce()).isInitializationStarted();
verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
verify(mSupplicantStaIfaceHal).terminate();
verify(mIfaceCallback1).onDestroyed(IFACE_NAME_1);
@@ -555,11 +572,14 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).replaceStaIfaceRequestorWs(ifaceName, workSource);
mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(ifaceName);
+ mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
+ 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).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
@@ -587,6 +607,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
mInOrder.verify(mWifiVendorHal).enableStaChannelForPeerNetwork(anyBoolean(), anyBoolean());
}
@@ -599,6 +620,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
@@ -1338,6 +1360,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
}
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
+ when(mSupplicantStaIfaceHal.isInitializationStarted()).thenReturn(true);
}
mInOrder.verify(mSupplicantStaIfaceHal).setupIface(ifaceName);
if (failureCode == STA_FAILURE_CODE_SETUP_INTERFACE) {
@@ -1348,6 +1371,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
}
@@ -1393,6 +1417,88 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
assertEquals(Set.of(IFACE_NAME_0, IFACE_NAME_1), mWifiNative.getClientInterfaceNames());
}
+ @Test
+ public void testSetupP2pInterfaceAndTeardownP2p() throws Exception {
+ executeAndValidateCreateP2pInterface(false, false, false, P2P_IFACE_NAME, true, 0);
+ executeAndValidateTeardownP2pInterface(false, false, false, false, false,
+ mActiveP2pIface, true);
+ }
+
+ @Test
+ public void testSetupP2pInterfaceAndTeardownP2pWhenClientInterfaceExist() throws Exception {
+ // Start client interface
+ executeAndValidateSetupClientInterface(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0);
+ assertEquals(Set.of(IFACE_NAME_0), mWifiNative.getClientInterfaceNames());
+ executeAndValidateCreateP2pInterface(true, false, false, P2P_IFACE_NAME, true, 0);
+ assertTrue(mWifiNative.hasAnyP2pIface());
+ executeAndValidateTeardownP2pInterface(true, true, true, false, false,
+ mActiveP2pIface, true);
+ assertFalse(mWifiNative.hasAnyP2pIface());
+ verify(mWifiVendorHal, never()).stopVendorHal();
+ }
+
+ /**
+ * Verifies the setup of a single client interface and teardown by P2P on.
+ */
+ @Test
+ public void testSetupClientInterfaceAndTeardownP2p() throws Exception {
+ executeAndValidateCreateP2pInterface(false, false, false, P2P_IFACE_NAME, true, 0);
+ // Trigger the P2P interface teardown when STA interface is created.
+ // The iface name will remain the same.
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public String answer(InterfaceDestroyedListener destroyedListener, WorkSource ws,
+ ConcreteClientModeManager concreteClientModeManager) {
+ mWifiNative.teardownP2pIface(mActiveP2pIface.id);
+ return IFACE_NAME_0;
+ }
+ }).when(mWifiVendorHal).createStaIface(any(), any(), eq(mConcreteClientModeManager));
+
+ assertEquals(IFACE_NAME_0,
+ mWifiNative.setupInterfaceForClientInScanMode(mIfaceCallback0, TEST_WORKSOURCE,
+ mConcreteClientModeManager));
+ assertEquals(Set.of(IFACE_NAME_0), mWifiNative.getClientInterfaceNames());
+ validateSetupClientInterfaceForScan(
+ false, false, true, IFACE_NAME_0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0, true, 0);
+ verify(mSupplicantStaIfaceHal, atLeastOnce()).isInitializationStarted();
+ verify(mWifiVendorHal, never()).stopVendorHal();
+ verify(mWifiP2pNative).stopP2pSupplicantIfNecessary();
+ }
+
+ /**
+ * Verifies the setup of a single client interface (for scan) and teardown by P2P on.
+ */
+ @Test
+ public void testCreateP2pIfaceAndTeardownClientIface() throws Exception {
+ executeAndValidateSetupClientInterface(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0);
+ assertEquals(Set.of(IFACE_NAME_0), mWifiNative.getClientInterfaceNames());
+ // Trigger the STA interface teardown when P2p interface is created.
+ // The iface name will remain the same.
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public String answer(
+ HalDeviceManager.InterfaceDestroyedListener p2pInterfaceDestroyedListener,
+ Handler handler, WorkSource requestorWs) {
+ mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
+ return P2P_IFACE_NAME;
+ }
+ }).when(mHalDeviceManager).createP2pIface(any(), any(), any());
+ mActiveP2pIface = mWifiNative.createP2pIface(mP2pInterfaceDestroyedListener,
+ mP2pEventHandler, TEST_WORKSOURCE);
+ assertEquals(P2P_IFACE_NAME, mActiveP2pIface.name);
+ // Creation of P2P interface should trigger the STA interface destroy
+ verify(mWifiVendorHal, atLeastOnce()).isVendorHalSupported();
+ verify(mWifiVendorHal, atLeastOnce()).isVendorHalReady();
+ validateOnDestroyedClientInterface(false, false, true,
+ IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue());
+ validateCreateP2pInterface(true, false, false, P2P_IFACE_NAME, true, 0);
+ executeAndValidateTeardownP2pInterface(false, false, false, false, false,
+ mActiveP2pIface, true);
+ }
+
private void executeAndValidateSetupClientInterface(
boolean hasStaIface, boolean hasApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
@@ -1409,10 +1515,21 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported,
int failureCode) throws Exception {
+ executeAndValidateSetupClientInterface(hasStaIface, hasApIface, false, ifaceName, callback,
+ destroyedListenerCaptor,
+ networkObserverCaptor, vendorHalSupported, failureCode);
+ }
+
+ private void executeAndValidateSetupClientInterface(
+ boolean hasStaIface, boolean hasApIface, boolean hasP2pIface,
+ String ifaceName, @Mock WifiNative.InterfaceCallback callback,
+ ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported,
+ int failureCode) throws Exception {
when(mWifiVendorHal.createStaIface(any(), any(), eq(mConcreteClientModeManager)))
.thenReturn(ifaceName);
executeAndValidateSetupClientInterfaceForScan(
- hasStaIface, hasApIface, ifaceName, callback, destroyedListenerCaptor,
+ hasStaIface, hasApIface, hasP2pIface, ifaceName, callback, destroyedListenerCaptor,
networkObserverCaptor, vendorHalSupported, failureCode);
executeAndValidateSwitchClientInterfaceToConnectivityMode(hasStaIface, hasApIface,
ifaceName, TEST_WORKSOURCE, vendorHalSupported, failureCode);
@@ -1423,6 +1540,16 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
InterfaceDestroyedListener destroyedListener,
NetdEventObserver networkObserver) throws Exception {
+ executeAndValidateTeardownClientInterface(anyOtherStaIface, anyOtherApIface,
+ false /* anyOtherP2pIface */, ifaceName, callback, destroyedListener,
+ networkObserver);
+ }
+
+ private void executeAndValidateTeardownClientInterface(
+ boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface,
+ String ifaceName, @Mock WifiNative.InterfaceCallback callback,
+ InterfaceDestroyedListener destroyedListener,
+ NetdEventObserver networkObserver) throws Exception {
mWifiNative.teardownInterface(ifaceName);
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
@@ -1432,13 +1559,23 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
destroyedListener.onDestroyed(ifaceName);
validateOnDestroyedClientInterface(
- anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver);
+ anyOtherStaIface, anyOtherApIface, anyOtherP2pIface,
+ ifaceName, callback, networkObserver);
}
private void validateOnDestroyedClientInterface(
boolean anyOtherStaIface, boolean anyOtherApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
NetdEventObserver networkObserver) throws Exception {
+ validateOnDestroyedClientInterface(
+ anyOtherStaIface, anyOtherApIface, false /* anyOtherP2pIface */,
+ ifaceName, callback, networkObserver);
+ }
+
+ private void validateOnDestroyedClientInterface(
+ boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface,
+ String ifaceName, @Mock WifiNative.InterfaceCallback callback,
+ NetdEventObserver networkObserver) throws Exception {
mInOrder.verify(mWifiMonitor).stopMonitoring(ifaceName);
if (networkObserver != null) {
mInOrder.verify(mNetdWrapper).unregisterObserver(networkObserver);
@@ -1447,10 +1584,15 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mWificondControl).tearDownClientInterface(ifaceName);
if (!anyOtherStaIface) {
+ mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
- mInOrder.verify(mSupplicantStaIfaceHal).terminate();
+ if (!anyOtherP2pIface) {
+ mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
+ mInOrder.verify(mSupplicantStaIfaceHal).terminate();
+ }
+ when(mSupplicantStaIfaceHal.isInitializationStarted()).thenReturn(false);
}
- if (!anyOtherStaIface && !anyOtherApIface) {
+ if (!anyOtherStaIface && !anyOtherApIface && !anyOtherP2pIface) {
mInOrder.verify(mWificondControl).tearDownInterfaces();
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).stopVendorHal();
@@ -1474,6 +1616,17 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<NetdEventObserver> networkObserverCaptor,
boolean vendorHalSupported, int failureCode) throws Exception {
+ executeAndValidateSetupClientInterfaceForScan(hasStaIface, hasApIface,
+ false /* hasP2pIface */, ifaceName, callback,
+ destroyedListenerCaptor, networkObserverCaptor, vendorHalSupported, failureCode);
+ }
+
+ private void executeAndValidateSetupClientInterfaceForScan(
+ boolean hasStaIface, boolean hasApIface, boolean hasP2pIface,
+ String ifaceName, @Mock WifiNative.InterfaceCallback callback,
+ ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor,
+ boolean vendorHalSupported, int failureCode) throws Exception {
if (failureCode != STA_FAILURE_CODE_CREAT_IFACE) {
when(mWifiVendorHal.createStaIface(any(), any(), eq(mConcreteClientModeManager)))
.thenReturn(ifaceName);
@@ -1483,7 +1636,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mConcreteClientModeManager));
validateSetupClientInterfaceForScan(
- hasStaIface, hasApIface, ifaceName, destroyedListenerCaptor,
+ hasStaIface, hasApIface, hasP2pIface, ifaceName, destroyedListenerCaptor,
networkObserverCaptor, vendorHalSupported, failureCode);
}
@@ -1508,7 +1661,17 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported,
int failureCode) throws Exception {
- validateStartHal(hasStaIface || hasApIface, vendorHalSupported);
+ validateSetupClientInterfaceForScan(hasStaIface, hasApIface, false /* hasP2pIfacd */,
+ ifaceName, destroyedListenerCaptor, networkObserverCaptor, vendorHalSupported,
+ failureCode);
+ }
+
+ private void validateSetupClientInterfaceForScan(
+ boolean hasStaIface, boolean hasApIface, boolean hasP2pIface,
+ String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported,
+ int failureCode) throws Exception {
+ validateStartHal(hasStaIface || hasApIface || hasP2pIface, vendorHalSupported);
if (vendorHalSupported) {
mInOrder.verify(mWifiVendorHal).createStaIface(
destroyedListenerCaptor.capture(), eq(TEST_WORKSOURCE),
@@ -1546,6 +1709,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
mInOrder.verify(mWifiVendorHal).enableStaChannelForPeerNetwork(anyBoolean(), anyBoolean());
}
@@ -1555,6 +1719,16 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
InterfaceDestroyedListener destroyedListener,
NetdEventObserver networkObserver) throws Exception {
+ executeAndValidateTeardownClientInterfaceForScan(anyOtherStaIface, anyOtherApIface,
+ false /* anyOtherP2pIface */, ifaceName, callback, destroyedListener,
+ networkObserver);
+ }
+
+ private void executeAndValidateTeardownClientInterfaceForScan(
+ boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface,
+ String ifaceName, @Mock WifiNative.InterfaceCallback callback,
+ InterfaceDestroyedListener destroyedListener,
+ NetdEventObserver networkObserver) throws Exception {
mWifiNative.teardownInterface(ifaceName);
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
@@ -1564,20 +1738,30 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
destroyedListener.onDestroyed(ifaceName);
validateOnDestroyedClientInterfaceForScan(
- anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver);
+ anyOtherStaIface, anyOtherApIface, anyOtherP2pIface,
+ ifaceName, callback, networkObserver);
}
private void validateOnDestroyedClientInterfaceForScan(
boolean anyOtherStaIface, boolean anyOtherApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
NetdEventObserver networkObserver) throws Exception {
+ validateOnDestroyedClientInterfaceForScan(
+ anyOtherStaIface, anyOtherApIface, false /* anyOtherP2pIface */,
+ ifaceName, callback, networkObserver);
+ }
+
+ private void validateOnDestroyedClientInterfaceForScan(
+ boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface,
+ String ifaceName, @Mock WifiNative.InterfaceCallback callback,
+ NetdEventObserver networkObserver) throws Exception {
mInOrder.verify(mWifiMonitor).stopMonitoring(ifaceName);
if (networkObserver != null) {
mInOrder.verify(mNetdWrapper).unregisterObserver(networkObserver);
}
mInOrder.verify(mWificondControl).tearDownClientInterface(ifaceName);
- if (!anyOtherStaIface && !anyOtherApIface) {
+ if (!anyOtherStaIface && !anyOtherApIface && !anyOtherP2pIface) {
mInOrder.verify(mWificondControl).tearDownInterfaces();
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).stopVendorHal();
@@ -1601,6 +1785,17 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged,
boolean vendorHalSupported, int failureCode) throws Exception {
+ executeAndValidateSetupSoftApInterface(hasStaIface, hasApIface, false /* hasP2pIface */,
+ ifaceName, callback, destroyedListenerCaptor, networkObserverCaptor,
+ isBridged, vendorHalSupported, failureCode);
+ }
+
+ private void executeAndValidateSetupSoftApInterface(
+ boolean hasStaIface, boolean hasApIface, boolean hasP2pIface,
+ String ifaceName, @Mock WifiNative.InterfaceCallback callback,
+ ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged,
+ boolean vendorHalSupported, int failureCode) throws Exception {
when(mWifiVendorHal.createApIface(any(), any(), anyInt(), eq(isBridged), any(), anyList()))
.thenReturn(ifaceName);
assertEquals(failureCode == 0 ? ifaceName : null, mWifiNative.setupInterfaceForSoftApMode(
@@ -1617,7 +1812,17 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged,
boolean vendorHalSupported, int failureCode) throws Exception {
- validateStartHal(hasStaIface || hasApIface, vendorHalSupported);
+ validateSetupSoftApInterface(hasStaIface, hasApIface, false /* hasP2pIface */,
+ ifaceName, destroyedListenerCaptor,
+ networkObserverCaptor, isBridged, vendorHalSupported, failureCode);
+ }
+
+ private void validateSetupSoftApInterface(
+ boolean hasStaIface, boolean hasApIface, boolean hasP2pIface,
+ String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged,
+ boolean vendorHalSupported, int failureCode) throws Exception {
+ validateStartHal(hasStaIface || hasApIface || hasP2pIface, vendorHalSupported);
if (!hasApIface) {
mInOrder.verify(mHostapdHal).isInitializationStarted();
mInOrder.verify(mHostapdHal).initialize();
@@ -1649,8 +1854,11 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
}
mInOrder.verify(mWificondControl).tearDownClientInterface(ifaceName);
if (mWifiNative.hasAnyStaIfaceForConnectivity()) {
+ mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
+ mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).terminate();
+ when(mSupplicantStaIfaceHal.isInitializationStarted()).thenReturn(false);
}
mInOrder.verify(mWifiVendorHal).isVendorHalReady();
mInOrder.verify(mIfaceCallback0).onDestroyed(ifaceName);
@@ -1676,6 +1884,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
@@ -1693,13 +1902,23 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
destroyedListener.onDestroyed(ifaceName);
validateOnDestroyedSoftApInterface(
- anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver);
+ anyOtherStaIface, anyOtherApIface, false /* anyOtherP2pIface */,
+ ifaceName, callback, networkObserver);
}
private void validateOnDestroyedSoftApInterface(
boolean anyOtherStaIface, boolean anyOtherApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
NetdEventObserver networkObserver) throws Exception {
+ validateOnDestroyedSoftApInterface(
+ anyOtherStaIface, anyOtherApIface, false /* anyOtherP2pIface */,
+ ifaceName, callback, networkObserver);
+ }
+
+ private void validateOnDestroyedSoftApInterface(
+ boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface,
+ String ifaceName, @Mock WifiNative.InterfaceCallback callback,
+ NetdEventObserver networkObserver) throws Exception {
if (networkObserver != null) {
mInOrder.verify(mNetdWrapper).unregisterObserver(networkObserver);
}
@@ -1710,7 +1929,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mHostapdHal).deregisterDeathHandler();
mInOrder.verify(mHostapdHal).terminate();
}
- if (!anyOtherStaIface && !anyOtherApIface) {
+ if (!anyOtherStaIface && !anyOtherApIface && !anyOtherP2pIface) {
mInOrder.verify(mWificondControl).tearDownInterfaces();
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).stopVendorHal();
@@ -1733,4 +1952,77 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mLooper.dispatchAll();
mInOrder.verify(mIfaceEventCallback0).onInterfaceAdded(ifaceName);
}
+
+ private void executeAndValidateCreateP2pInterface(
+ boolean hasStaIface, boolean hasApIface, boolean hasP2pIface,
+ String ifaceName, boolean vendorHalSupported, int failureCode) throws Exception {
+ if (failureCode != P2P_FAILURE_CODE_CREATE_INTERFACE) {
+ if (vendorHalSupported) {
+ when(mHalDeviceManager.createP2pIface(any(), any(), any()))
+ .thenReturn(ifaceName);
+ } else {
+ when(mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME))
+ .thenReturn(ifaceName);
+ }
+ }
+ mActiveP2pIface = mWifiNative.createP2pIface(mP2pInterfaceDestroyedListener,
+ mP2pEventHandler, TEST_WORKSOURCE);
+ if (failureCode == 0) {
+ assertNotNull(mActiveP2pIface);
+ assertEquals(mActiveP2pIface.name, ifaceName);
+ } else {
+ assertNull(mActiveP2pIface);
+ }
+ validateCreateP2pInterface(hasStaIface, hasApIface, hasP2pIface,
+ ifaceName, vendorHalSupported, failureCode);
+ }
+
+ private void validateCreateP2pInterface(
+ boolean hasStaIface, boolean hasApIface, boolean hasP2pIface,
+ String ifaceName, boolean vendorHalSupported, int failureCode) throws Exception {
+ validateStartHal(hasStaIface || hasApIface || hasP2pIface, vendorHalSupported);
+ if (vendorHalSupported) {
+ verify(mHalDeviceManager).createP2pIface(eq(mP2pInterfaceDestroyedListener),
+ eq(mP2pEventHandler), eq(TEST_WORKSOURCE));
+ if (failureCode == P2P_FAILURE_CODE_CREATE_INTERFACE) {
+ verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToHal();
+ }
+ } else {
+ verify(mPropertyService).getString(eq(P2P_INTERFACE_PROPERTY), eq(P2P_IFACE_NAME));
+ }
+ }
+
+ private void executeAndValidateTeardownP2pInterface(
+ boolean anyOtherStaIface, boolean anyOtherConnectivityStaIface,
+ boolean isSupplicantStartedBefore, boolean anyOtherApIface,
+ boolean anyOtherP2pIface, WifiNative.Iface iface, boolean vendorHalSupported)
+ throws Exception {
+ mWifiNative.teardownP2pIface(iface.id);
+
+ validateOnDestroyedP2pInterface(anyOtherStaIface, anyOtherConnectivityStaIface,
+ isSupplicantStartedBefore, anyOtherApIface,
+ anyOtherP2pIface, vendorHalSupported);
+ }
+
+ private void validateOnDestroyedP2pInterface(
+ boolean anyOtherStaIface, boolean anyOtherConnectivityStaIface,
+ boolean isSupplicantStartedBefore, boolean anyOtherApIface,
+ boolean anyOtherP2pIface, boolean vendorHalSupported) throws Exception {
+ if (vendorHalSupported && !anyOtherStaIface && !anyOtherApIface && !anyOtherP2pIface) {
+ mInOrder.verify(mWificondControl).tearDownInterfaces();
+ mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
+ mInOrder.verify(mWifiVendorHal).stopVendorHal();
+ }
+ if (!anyOtherConnectivityStaIface) {
+ mInOrder.verify(mSupplicantStaIfaceHal, atLeastOnce()).isInitializationStarted();
+ if (isSupplicantStartedBefore) {
+ mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
+ mInOrder.verify(mSupplicantStaIfaceHal).terminate();
+ } else {
+ if (!anyOtherP2pIface) {
+ mInOrder.verify(mWifiP2pNative).stopP2pSupplicantIfNecessary();
+ }
+ }
+ }
+ }
}
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 63389f8dbc..492770024d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
@@ -51,7 +51,9 @@ import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiContext;
+import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
+import android.net.wifi.WifiScanner.ScanData;
import android.net.wifi.WifiSsid;
import android.net.wifi.nl80211.NativeScanResult;
import android.net.wifi.nl80211.RadioChainInfo;
@@ -350,6 +352,7 @@ public class WifiNativeTest extends WifiBaseTest {
mHandler, mRandom, mBuildProperties, mWifiInjector);
mWifiNative.enableVerboseLogging(true, true);
mWifiNative.initialize();
+ assertNull(mWifiNative.mUnknownAkmMap);
}
@After
@@ -1643,6 +1646,48 @@ public class WifiNativeTest extends WifiBaseTest {
}
@Test
+ public void testGetCachedScanResultsLocationDisabledOrInvalidTimestamp() throws Exception {
+ ScanResult[] scanResults = new ScanResult[2];
+ for (int i = 0; i < 2; i++) {
+ ScanResult scanResult = new ScanResult();
+ scanResult.timestamp = 0;
+ scanResults[i] = scanResult;
+ }
+ ScanData testScanData = new ScanData(0, 0,
+ 0, WifiScanner.WIFI_BAND_UNSPECIFIED, scanResults);
+ when(mWifiVendorHal.getCachedScanData(any())).thenReturn(testScanData);
+
+ mWifiNative.setLocationModeEnabled(false);
+ ScanData scanData = mWifiNative.getCachedScanResults(WIFI_IFACE_NAME);
+ // Get no scan result because the location mode is disabled
+ assertEquals(0, scanData.getResults().length);
+
+ mWifiNative.setLocationModeEnabled(true);
+ scanData = mWifiNative.getCachedScanResults(WIFI_IFACE_NAME);
+ // Get no scan result because the scan timestamp is too new
+ assertEquals(0, scanData.getResults().length);
+ }
+
+ @Test
+ public void testGetCachedScanResultsLocationEnabledValidTimestamp() throws Exception {
+ ScanResult[] scanResults = new ScanResult[3];
+ for (int i = 0; i < 3; i++) {
+ ScanResult scanResult = new ScanResult();
+ // 1st ScanResult has invalid timestamp
+ scanResult.timestamp = (i > 0) ? Long.MAX_VALUE : 0;
+ scanResults[i] = scanResult;
+ }
+ ScanData testScanData = new ScanData(0, 0,
+ 0, WifiScanner.WIFI_BAND_UNSPECIFIED, scanResults);
+ when(mWifiVendorHal.getCachedScanData(any())).thenReturn(testScanData);
+
+ mWifiNative.setLocationModeEnabled(true);
+ ScanData scanData = mWifiNative.getCachedScanResults(WIFI_IFACE_NAME);
+ // Get the last two scan results which has the valid timestamp
+ assertEquals(2, scanData.getResults().length);
+ }
+
+ @Test
public void testEnableStaChannelForPeerNetworkWithOverride() throws Exception {
mResources.setBoolean(R.bool.config_wifiEnableStaIndoorChannelForPeerNetwork, true);
mResources.setBoolean(R.bool.config_wifiEnableStaDfsChannelForPeerNetwork, true);
@@ -1659,4 +1704,118 @@ public class WifiNativeTest extends WifiBaseTest {
mWifiNative.setAfcChannelAllowance(mAfcChannelAllowance);
verify(mWifiVendorHal).setAfcChannelAllowance(mAfcChannelAllowance);
}
+
+ /**
+ * Verifies that overlay config item config_wifiUnknownAkmToKnownAkmMapping is parsed correctly
+ * and an expected value is set in unknown AKM map.
+ */
+ @Test
+ public void testConfigWifiUnknownAkmToKnownAkmMapping() throws Exception {
+ // Test that UnknownAkmMap is not set if two values are not added in the config.
+ mResources.setStringArray(
+ R.array.config_wifiUnknownAkmToKnownAkmMapping, new String[] {"1234"});
+ WifiNative wifiNativeInstance =
+ new WifiNative(
+ mWifiVendorHal,
+ mStaIfaceHal,
+ mHostapdHal,
+ mWificondControl,
+ mWifiMonitor,
+ mPropertyService,
+ mWifiMetrics,
+ mHandler,
+ mRandom,
+ mBuildProperties,
+ mWifiInjector);
+ assertNull(wifiNativeInstance.mUnknownAkmMap);
+
+ // Test that UnknownAkmMap is not set if non-integer values are added in the config.
+ mResources.setStringArray(
+ R.array.config_wifiUnknownAkmToKnownAkmMapping, new String[] {"1234, bad"});
+ wifiNativeInstance =
+ new WifiNative(
+ mWifiVendorHal,
+ mStaIfaceHal,
+ mHostapdHal,
+ mWificondControl,
+ mWifiMonitor,
+ mPropertyService,
+ mWifiMetrics,
+ mHandler,
+ mRandom,
+ mBuildProperties,
+ mWifiInjector);
+ assertNull(wifiNativeInstance.mUnknownAkmMap);
+
+ // Test that UnknownAkmMap is not set when an invalid AKM is set in the known AKM field
+ // known AKM - 555 (which is not a valid AKM suite specifier)
+ mResources.setStringArray(
+ R.array.config_wifiUnknownAkmToKnownAkmMapping, new String[] {"9846784, 555"});
+ wifiNativeInstance =
+ new WifiNative(
+ mWifiVendorHal,
+ mStaIfaceHal,
+ mHostapdHal,
+ mWificondControl,
+ mWifiMonitor,
+ mPropertyService,
+ mWifiMetrics,
+ mHandler,
+ mRandom,
+ mBuildProperties,
+ mWifiInjector);
+ assertNull(wifiNativeInstance.mUnknownAkmMap);
+
+ // Test that UnknownAkmMap is set for a valid configuration
+ // known AKM - 28053248 (which corresponds to ScanResult.KEY_MGMT_EAP)
+ mResources.setStringArray(
+ R.array.config_wifiUnknownAkmToKnownAkmMapping, new String[] {"9846784, 28053248"});
+ wifiNativeInstance =
+ new WifiNative(
+ mWifiVendorHal,
+ mStaIfaceHal,
+ mHostapdHal,
+ mWificondControl,
+ mWifiMonitor,
+ mPropertyService,
+ mWifiMetrics,
+ mHandler,
+ mRandom,
+ mBuildProperties,
+ mWifiInjector);
+ assertEquals(1, wifiNativeInstance.mUnknownAkmMap.size());
+ assertEquals(ScanResult.KEY_MGMT_EAP, wifiNativeInstance.mUnknownAkmMap.get(9846784));
+
+ // Test that UnknownAkmMap is set for multiple valid configuration entries
+ // known AKM - 28053248 (which corresponds to ScanResult.KEY_MGMT_EAP)
+ // known AKM - 413929216 (which corresponds to ScanResult.KEY_MGMT_SAE_EXT_KEY)
+ mResources.setStringArray(
+ R.array.config_wifiUnknownAkmToKnownAkmMapping,
+ new String[] {"9846784, 28053248", "1234, 413929216"});
+ wifiNativeInstance =
+ new WifiNative(
+ mWifiVendorHal,
+ mStaIfaceHal,
+ mHostapdHal,
+ mWificondControl,
+ mWifiMonitor,
+ mPropertyService,
+ mWifiMetrics,
+ mHandler,
+ mRandom,
+ mBuildProperties,
+ mWifiInjector);
+ assertEquals(2, wifiNativeInstance.mUnknownAkmMap.size());
+ assertEquals(ScanResult.KEY_MGMT_EAP, wifiNativeInstance.mUnknownAkmMap.get(9846784));
+ assertEquals(ScanResult.KEY_MGMT_SAE_EXT_KEY, wifiNativeInstance.mUnknownAkmMap.get(1234));
+ }
+
+ @Test
+ public void testSetRoamingMode() throws Exception {
+ int status = 0;
+ when(mWifiVendorHal.setRoamingMode(eq(WIFI_IFACE_NAME), anyInt())).thenReturn(status);
+ assertEquals(status, mWifiNative.setRoamingMode(WIFI_IFACE_NAME,
+ WifiManager.ROAMING_MODE_NORMAL));
+ verify(mWifiVendorHal).setRoamingMode(WIFI_IFACE_NAME, WifiManager.ROAMING_MODE_NORMAL);
+ }
}
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 d4db3789a2..d2e20cdfc7 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -93,10 +93,11 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.WorkSource;
import android.os.test.TestLooper;
-import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
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.WifiNetworkFactory.AccessPoint;
@@ -1339,7 +1340,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mClientModeManager).disconnect();
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
- mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
+ mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1), any());
}
/**
@@ -1444,7 +1445,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mClientModeManager).disconnect();
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
- mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
+ mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1), any());
}
/**
@@ -1494,7 +1495,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mClientModeManager).disconnect();
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
- mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
+ mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1), any());
}
/**
@@ -1545,7 +1546,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mClientModeManager).disconnect();
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
- mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
+ mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1), any());
}
/**
@@ -1606,7 +1607,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mClientModeManager).disconnect();
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
- mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
+ mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1), any());
}
/**
@@ -1673,7 +1674,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mClientModeManager).disconnect();
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
- mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1));
+ mConnectListenerArgumentCaptor.capture(), anyInt(), eq(TEST_PACKAGE_NAME_1), any());
}
/**
@@ -2468,7 +2469,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mConnectHelper).connectToNetwork(
eq(mClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
}
/**
@@ -2957,7 +2958,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ModeImplProxy.
verify(mConnectHelper, never()).connectToNetwork(any(), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
}
/**
@@ -3001,7 +3002,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ClientModeManager.
verify(mConnectHelper, never()).connectToNetwork(any(), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
}
/**
@@ -3042,7 +3043,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ClientModeManager.
verify(mConnectHelper, never()).connectToNetwork(any(), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
}
/**
@@ -3080,7 +3081,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Connection does not happen yet since it is waiting for scan results.
verify(mConnectHelper, never()).connectToNetwork(any(), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
// simulate scan results coming in and verify we auto connect to the network
when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
@@ -3100,7 +3101,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
if (bypassActivated) {
assertNotNull(configurationArgumentCaptor.getAllValues().get(1).BSSID);
verify(mConnectHelper).connectToNetwork(any(), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
}
}
@@ -3161,7 +3162,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ClientModeManager.
verify(mConnectHelper, never()).connectToNetwork(any(), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
}
/**
@@ -3205,7 +3206,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ClientModeManager.
verify(mConnectHelper, never()).connectToNetwork(any(), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
}
/**
@@ -3239,9 +3240,17 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
@Test
public void testNetworkSpecifierUserApprovalConfigStoreLoad()
throws Exception {
+ // Setup scan data for WPA-PSK networks.
+ setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
+ TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
+
+ // Choose the matching scan result.
+ ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
+ when(mWifiScanner.getSingleScanResults())
+ .thenReturn(Arrays.asList(mTestScanDatas[0].getResults()));
Map<String, Set<AccessPoint>> approvedAccessPointsMapToRead = new HashMap<>();
Set<AccessPoint> approvedAccessPoints = Set.of(
- new AccessPoint(TEST_SSID_1, MacAddress.fromString(TEST_BSSID_1),
+ new AccessPoint(TEST_SSID_1, MacAddress.fromString(matchingScanResult.BSSID),
WifiConfiguration.SECURITY_TYPE_PSK));
approvedAccessPointsMapToRead.put(TEST_PACKAGE_NAME_1, approvedAccessPoints);
mDataSource.fromDeserialized(approvedAccessPointsMapToRead);
@@ -3250,7 +3259,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
PatternMatcher ssidPatternMatch =
new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
Pair<MacAddress, MacAddress> bssidPatternMatch =
- Pair.create(MacAddress.fromString(TEST_BSSID_1),
+ Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
MacAddress.BROADCAST_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
@@ -3264,7 +3273,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
// Verify that we sent a connection attempt to ClientModeManager
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
}
/**
@@ -3312,6 +3321,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// 2. Second request for the same access point (user approval bypass).
ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
+ when(mWifiScanner.getSingleScanResults())
+ .thenReturn(Arrays.asList(mTestScanDatas[0].getResults()));
PatternMatcher ssidPatternMatch =
new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
@@ -3334,7 +3345,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Verify that we sent a connection attempt to ClientModeManager
if (bypassActivated) {
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
}
@@ -3368,6 +3379,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Choose the matching scan result.
ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
+ when(mWifiScanner.getSingleScanResults())
+ .thenReturn(Arrays.asList(mTestScanDatas[0].getResults()));
// Setup CDM approval for the scan result.
when(mCompanionDeviceManager.isDeviceAssociatedForWifiConnection(
@@ -3394,7 +3407,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
// Verify that we sent a connection attempt to ClientModeManager
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
}
@@ -3431,6 +3444,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Choose the matching scan result.
ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
+ when(mWifiScanner.getSingleScanResults())
+ .thenReturn(Arrays.asList(mTestScanDatas[0].getResults()));
// Setup shell approval for the scan result.
mWifiNetworkFactory.setUserApprovedApp(TEST_PACKAGE_NAME_1, true);
@@ -3454,7 +3469,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
// Verify that we sent a connection attempt to ClientModeManager
verify(mConnectHelper).connectToNetwork(eq(mClientModeManager), any(),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
}
@@ -3563,7 +3578,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Verify no reconnection
verify(mWifiConnectivityManager, never()).setSpecificNetworkRequestInProgress(true);
verify(mClientModeManager, never()).disconnect();
- verify(mConnectHelper, never()).connectToNetwork(any(), any(), any(), anyInt(), any());
+ verify(mConnectHelper, never()).connectToNetwork(any(), any(), any(), anyInt(), any(),
+ any());
// Verify the network will be shared with new request.
assertEquals(2, mWifiNetworkFactory
@@ -3630,7 +3646,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Verify disconnect and reconnect
verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(true);
verify(mClientModeManager).disconnect();
- verify(mConnectHelper).connectToNetwork(any(), any(), any(), anyInt(), any());
+ verify(mConnectHelper).connectToNetwork(any(), any(), any(), anyInt(), any(), any());
// Verify the network will be only available to car mode app.
assertEquals(1, mWifiNetworkFactory
@@ -3687,7 +3703,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mConnectHelper, atLeastOnce()).connectToNetwork(
eq(mPrimaryClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
verify(mWifiMetrics, atLeastOnce()).incrementNetworkRequestApiNumConnectOnPrimaryIface();
// Start the connection timeout alarm.
@@ -3751,7 +3767,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mConnectHelper, atLeastOnce()).connectToNetwork(
eq(mClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
- mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any(), any());
if (mClientModeManager.getRole() == ActiveModeManager.ROLE_CLIENT_PRIMARY) {
verify(mWifiMetrics, atLeastOnce())
.incrementNetworkRequestApiNumConnectOnPrimaryIface();
@@ -3993,7 +4009,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
eq(mClientModeManager),
eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
mConnectListenerArgumentCaptor.capture(),
- anyInt(), any());
+ anyInt(), any(), any());
// Start the new connection timeout alarm.
mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
index 7d819b94ef..47b105f948 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
@@ -19,6 +19,8 @@ package com.android.server.wifi;
import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
+import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
+import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LONG_LIVED;
import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_EAP;
import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_NONE;
import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_OWE;
@@ -552,7 +554,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
@@ -586,12 +588,12 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
- verify(mPasspointNetworkNominateHelper).updatePasspointConfig(any());
+ verify(mPasspointNetworkNominateHelper, never()).updatePasspointConfig(any());
verify(mPasspointNetworkNominateHelper, never()).getPasspointNetworkCandidates(any());
}
@@ -623,9 +625,10 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
+ assertNotNull(candidate);
when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
+ WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS - 2000);
@@ -634,16 +637,16 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, true, false, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
- assertEquals("Expect null configuration", null, candidate);
+ assertNull("Expect null configuration", candidate);
assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
verify(mWifiConfigManager, atLeast(2))
.updateScanDetailCacheFromScanDetailForSavedNetwork(any());
- verify(mPasspointNetworkNominateHelper, times(2)).updatePasspointConfig(any());
+ verify(mPasspointNetworkNominateHelper).updatePasspointConfig(any());
verify(mPasspointNetworkNominateHelper).getPasspointNetworkCandidates(any());
}
@@ -676,7 +679,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
@@ -688,7 +691,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -728,7 +731,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
when(mWifiInfo.getSupplicantState()).thenReturn(SupplicantState.COMPLETED);
@@ -746,7 +749,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, true, false, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -788,7 +791,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
when(mWifiInfo.getSupplicantState()).thenReturn(SupplicantState.COMPLETED);
@@ -814,7 +817,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, true, false, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -850,7 +853,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
verify(mWifiMetrics).incrementNetworkSelectionFilteredBssidCount(0);
@@ -891,7 +894,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
verify(mWifiMetrics).incrementNetworkSelectionFilteredBssidCount(1);
@@ -931,7 +934,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
@@ -969,7 +972,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
@@ -1009,7 +1012,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
@@ -1052,7 +1055,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
@@ -1101,7 +1104,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
}
@@ -1135,7 +1138,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
@@ -1170,7 +1173,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect null configuration", null, candidate);
@@ -1205,7 +1208,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals(ssids[0], candidate.SSID);
@@ -1239,7 +1242,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -1265,7 +1268,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, true, false, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -1304,7 +1307,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -1335,7 +1338,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, true, false, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertEquals(2, candidates.size());
assertEquals(100, candidates.get(0).getPredictedThroughputMbps());
@@ -1375,7 +1378,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -1401,7 +1404,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -1454,7 +1457,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
WifiConfigurationTestUtil.assertConfigurationEqual(userChoice, candidate);
@@ -1469,7 +1472,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
WifiConfigurationTestUtil.assertConfigurationEqual(networkSelectorChoice, candidate);
@@ -1510,7 +1513,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
WifiConfigurationTestUtil.assertConfigurationEqual(userChoice, candidate);
@@ -1523,7 +1526,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -1565,7 +1568,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
WifiConfigurationTestUtil.assertConfigurationEqual(userChoice, candidate);
@@ -1576,7 +1579,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
WifiConfigurationTestUtil.assertConfigurationEqual(networkSelectorChoice, candidate);
@@ -1611,7 +1614,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertFalse(candidates.isEmpty());
@@ -1628,7 +1631,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertFalse(candidates.isEmpty());
@@ -1678,7 +1681,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -1894,7 +1897,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
//WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals(1, candidates.size());
@@ -1906,7 +1909,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
//WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals(1, candidates.size());
@@ -2022,7 +2025,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
true, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertNotNull("Result should be not null", candidate);
@@ -2064,7 +2067,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, true, false, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
true, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -2102,7 +2105,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
@@ -2137,7 +2140,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
unSavedScanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertEquals("Expect open unsaved networks",
@@ -2152,7 +2155,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
candidates = mWifiNetworkSelector.getCandidatesFromScan(
savedScanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
candidate = mWifiNetworkSelector.selectNetwork(candidates);
// Saved networks are filtered out.
@@ -2182,7 +2185,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
@@ -2214,7 +2217,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks().isEmpty());
@@ -2256,7 +2259,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
@@ -2292,7 +2295,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
@@ -2323,7 +2326,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
setUpTwoNetworks(-35, -40),
EMPTY_BLOCKLIST,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
true, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -2461,7 +2464,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
true, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
// Check if the wifiConfig is updated with the latest
@@ -2492,7 +2495,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
// Expect one privileged and one regular candidate.
assertEquals(2, candidates.size());
@@ -2542,7 +2545,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
verify(mWifiMetrics, times(1))
@@ -2666,10 +2669,10 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(
- TEST_IFACE_NAME, true, false, mWifiInfo, false),
+ TEST_IFACE_NAME, true, false, mWifiInfo, false, ROLE_CLIENT_PRIMARY),
new ClientModeManagerState(
TEST_IFACE_NAME_SECONDARY, true, false, mSecondaryWifiInfo,
- false)),
+ false, ROLE_CLIENT_SECONDARY_LONG_LIVED)),
false, true, true, Collections.emptySet(), false);
WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
@@ -2730,16 +2733,33 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
+ WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000);
- // Do network selection.
- List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
- scanDetails, blocklist,
+ List<ClientModeManagerState> cmmStates =
Arrays.asList(new ClientModeManagerState(
- TEST_IFACE_NAME, true, false, mWifiInfo, false),
+ TEST_IFACE_NAME, true, false, mWifiInfo, false, ROLE_CLIENT_PRIMARY),
new ClientModeManagerState(
- TEST_IFACE_NAME_SECONDARY, true, false, mSecondaryWifiInfo,
- false)),
- false, true, true, Collections.emptySet(), false);
- assertNull(mWifiNetworkSelector.selectNetwork(candidates));
+ TEST_IFACE_NAME_SECONDARY, true, false, mSecondaryWifiInfo, false,
+ ROLE_CLIENT_SECONDARY_LONG_LIVED));
+
+ // Do network selection.
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blocklist, cmmStates, false, true, true, Collections.emptySet(),
+ false);
+ assertNull(candidates);
+
+ // Mock that the primary connection has a user connect choice pointing something
+ // Verify candidate return is not null in this case
+ WifiConfiguration primaryConfig = mock(WifiConfiguration.class);
+ WifiConfiguration.NetworkSelectionStatus networkSelectionStatus = mock(
+ WifiConfiguration.NetworkSelectionStatus.class);
+ when(networkSelectionStatus.getConnectChoice()).thenReturn("\"ConnectChoiceTest\"NONE");
+ when(primaryConfig.getNetworkSelectionStatus()).thenReturn(networkSelectionStatus);
+ when(mWifiConfigManager.getConfiguredNetwork(mWifiInfo.getNetworkId())).thenReturn(
+ primaryConfig);
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blocklist, cmmStates, false, true, true, Collections.emptySet(),
+ false);
+ // Candidate should not be null
+ assertNotNull(candidates);
}
private void runNetworkSelectionWith(ScanDetailsAndWifiConfigs scanDetailsAndConfigs) {
@@ -2747,7 +2767,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
scanDetailsAndConfigs.getScanDetails(),
new HashSet<>(), // blocklist
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
true, // untrustedNetworkAllowed
true, // oemPaid
true, // oemPrivate
@@ -2806,7 +2826,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertEquals(2, candidates.size());
@@ -2862,7 +2882,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
// PSK type is disabled, PSK network is not matched.
assertEquals(1, candidates.size());
@@ -2896,7 +2916,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertEquals(2, candidates.size());
@@ -2929,7 +2949,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
// The SAE-only network should be filtered.
assertEquals(1, candidates.size());
@@ -2964,7 +2984,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertEquals(2, candidates.size());
@@ -3008,7 +3028,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
// OPEN type is disabled, OPEN network is not matched.
assertEquals(1, candidates.size());
@@ -3041,7 +3061,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertEquals(2, candidates.size());
@@ -3074,7 +3094,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
// The OWE-only network should be filtered.
assertEquals(1, candidates.size());
@@ -3107,7 +3127,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertEquals(2, candidates.size());
@@ -3151,7 +3171,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
// WPA2 Enterprise type is disabled, WPA2 Enterprise network is not matched.
assertEquals(1, candidates.size());
@@ -3223,7 +3243,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertNotNull(candidates);
if (expectedSecurityParamType == -1) {
@@ -3262,7 +3282,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, new HashSet<>(),
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
assertEquals(2, candidates.size());
@@ -3306,10 +3326,11 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
*
* @param maxMloStrLinkCount - Maximum STR link count supported for the test.
* @param bandMatrix - Simultaneous band combination matrix for the test.
+ * @param enableWifi7 - Enable Wi-Fi 7 or not
* @return A list of Wi-Fi candidates.
*/
private List<WifiCandidates.Candidate> getWifiCandidates(final int maxMloStrLinkCount,
- Set<List<Integer>> bandMatrix) {
+ Set<List<Integer>> bandMatrix, boolean enableWifi7) {
// Static configuration for the test.
String[] ssids = {"\"mlo\"", "\"mlo\"", "\"mlo\"", "\"legacy\""};
String[] bssids =
@@ -3361,11 +3382,15 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
when(mWifiNative.getSupportedBandCombinations(anyString())).thenReturn(bandMatrix);
// Mock interface name
when(mClientModeManager.getInterfaceName()).thenReturn(TEST_IFACE_NAME);
+ // Enable Wi-Fi 7
+ for (WifiConfiguration config : scanDetailsAndConfigs.getWifiConfigs()) {
+ when(mWifiConfigManager.isWifi7Enabled(config.networkId)).thenReturn(enableWifi7);
+ }
// Select network.
List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
scanDetails, blocklist,
Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo,
- false)),
+ false, ROLE_CLIENT_PRIMARY)),
false, true, true, Collections.emptySet(), false);
return candidates;
}
@@ -3417,19 +3442,19 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
// Scenario: Chip doesn't support Simultaneous Transmit and Receive (STR).
// Expectation: no change in multi-link attributes.
- for (WifiCandidates.Candidate c : getWifiCandidates(-1, bandMatrix)) {
+ for (WifiCandidates.Candidate c : getWifiCandidates(-1, bandMatrix, true)) {
validateDefaultMultiLinkAttributes(c);
}
// Scenario: STR link count = 1.
// Expectation: no change in multi-link attributes.
- for (WifiCandidates.Candidate c : getWifiCandidates(1, bandMatrix)) {
+ for (WifiCandidates.Candidate c : getWifiCandidates(1, bandMatrix, true)) {
validateDefaultMultiLinkAttributes(c);
}
// Scenario: No band combination info.
// Expectation: no change in multi-link attributes.
- for (WifiCandidates.Candidate c : getWifiCandidates(2, null)) {
+ for (WifiCandidates.Candidate c : getWifiCandidates(2, null, true)) {
validateDefaultMultiLinkAttributes(c);
}
}
@@ -3456,7 +3481,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
Arrays.asList(WifiScanner.WIFI_BAND_5_GHZ, WifiScanner.WIFI_BAND_6_GHZ)));
// Validate multi-link candidates are grouped and predicted multi-link throughput is
// updated properly for each group.
- for (WifiCandidates.Candidate c : getWifiCandidates(2, bandMatrix)) {
+ for (WifiCandidates.Candidate c : getWifiCandidates(2, bandMatrix, true)) {
switch (c.getKey().bssid.toString()) {
case CandidateParams.BSSID_1:
assertTrue(c.isMultiLinkCapable());
@@ -3504,7 +3529,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
WifiScanner.WIFI_BAND_6_GHZ)));
// Validate multi-link candidates are grouped and predicted multi-link throughput is
// updated properly for each group.
- for (WifiCandidates.Candidate c : getWifiCandidates(3, bandMatrix)) {
+ for (WifiCandidates.Candidate c : getWifiCandidates(3, bandMatrix, true)) {
switch (c.getKey().bssid.toString()) {
case CandidateParams.BSSID_1:
// fall through
@@ -3541,20 +3566,20 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
// STR not supported.
WifiConfiguration candidate;
- candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(-1, bandMatrix));
+ candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(-1, bandMatrix, true));
assertEquals("\"legacy\"", candidate.SSID);
// Max STR link count = 1.
- candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(1, bandMatrix));
+ candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(1, bandMatrix, true));
assertEquals("\"legacy\"", candidate.SSID);
// No band matrix.
- candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(2, null));
+ candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(2, null, true));
assertEquals("\"legacy\"", candidate.SSID);
// Legacy AP is better than MLO.
CandidateParams.throughput_4 = 300;
- candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(2, bandMatrix));
+ candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(2, bandMatrix, true));
assertEquals("\"legacy\"", candidate.SSID);
// Revert the throughput change.
CandidateParams.throughput_4 = 150;
@@ -3581,7 +3606,7 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
Arrays.asList(WifiScanner.WIFI_BAND_5_GHZ, WifiScanner.WIFI_BAND_6_GHZ)));
WifiConfiguration candidate;
- candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(2, bandMatrix));
+ candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(2, bandMatrix, true));
assertEquals("\"mlo\"", candidate.SSID);
}
@@ -3609,7 +3634,34 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
Arrays.asList(WifiScanner.WIFI_BAND_24_GHZ, WifiScanner.WIFI_BAND_5_GHZ,
WifiScanner.WIFI_BAND_6_GHZ)));
WifiConfiguration candidate;
- candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(3, bandMatrix));
+ candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(3, bandMatrix, true));
assertEquals("\"mlo\"", candidate.SSID);
}
+
+ /**
+ * Test Network selection with Wi-Fi7 disabled.
+ *
+ * Test scenario:
+ * Band Supported: {{2.4}, {5}, {6}, {2.4, 5}, {2.4, 6}, {5, 6}, {2.4, 5, 6}}
+ * APs: AP1 - {2.4 Ghz, 5 Ghz, 6 Ghz} , AP2 - 5 Ghz
+ * Max STR link count: 3 (tri-band)
+ */
+ @Test
+ public void testNetworkSelectionDisableWifi7() {
+ Set<List<Integer>> bandMatrix = Set.of(
+ new ArrayList(Arrays.asList(WifiScanner.WIFI_BAND_24_GHZ)),
+ new ArrayList(Arrays.asList(WifiScanner.WIFI_BAND_5_GHZ)),
+ new ArrayList(Arrays.asList(WifiScanner.WIFI_BAND_6_GHZ)), new ArrayList(
+ Arrays.asList(WifiScanner.WIFI_BAND_24_GHZ, WifiScanner.WIFI_BAND_5_GHZ)),
+ new ArrayList(
+ Arrays.asList(WifiScanner.WIFI_BAND_24_GHZ, WifiScanner.WIFI_BAND_6_GHZ)),
+ new ArrayList(
+ Arrays.asList(WifiScanner.WIFI_BAND_5_GHZ, WifiScanner.WIFI_BAND_6_GHZ)),
+ new ArrayList(
+ Arrays.asList(WifiScanner.WIFI_BAND_24_GHZ, WifiScanner.WIFI_BAND_5_GHZ,
+ WifiScanner.WIFI_BAND_6_GHZ)));
+ WifiConfiguration candidate;
+ candidate = mWifiNetworkSelector.selectNetwork(getWifiCandidates(3, bandMatrix, false));
+ assertEquals("\"legacy\"", candidate.SSID);
+ }
}
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 cbf3c06297..ade054a6c2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -87,10 +87,11 @@ import android.os.UserHandle;
import android.os.test.TestLooper;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.SmallTest;
import android.util.LocalLog;
import android.view.LayoutInflater;
+import androidx.test.filters.SmallTest;
+
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.modules.utils.build.SdkLevel;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiPseudonymManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiPseudonymManagerTest.java
index 7257f5246a..6915f62853 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiPseudonymManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiPseudonymManagerTest.java
@@ -36,7 +36,8 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiContext;
import android.net.wifi.WifiEnterpriseConfig;
import android.os.Looper;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
import com.android.server.wifi.entitlement.CarrierSpecificServiceEntitlement;
import com.android.server.wifi.entitlement.PseudonymInfo;
@@ -338,7 +339,8 @@ public class WifiPseudonymManagerTest extends WifiBaseTest {
any());
assertEquals(AlarmManager.RTC_WAKEUP, mAlarmTypeCaptor.getValue().intValue());
long maxStartTime = Instant.now().toEpochMilli();
- assertTrue(mWindowStartCaptor.getValue().longValue() <= maxStartTime);
+ assertTrue("The difference is:" + (mWindowStartCaptor.getValue() - maxStartTime),
+ mWindowStartCaptor.getValue() <= maxStartTime);
assertEquals(CARRIER_ID, mRetrieveListenerArgumentCaptor.getValue().mCarrierId);
}
@@ -362,7 +364,8 @@ public class WifiPseudonymManagerTest extends WifiBaseTest {
.getValidPseudonymInfo(CARRIER_ID)
.get()
.getLttrInMillis();
- assertTrue(mWindowStartCaptor.getValue().longValue() <= maxStartTime);
+ assertTrue("The difference is:" + (mWindowStartCaptor.getValue() - maxStartTime),
+ mWindowStartCaptor.getValue() <= maxStartTime + 2);
assertEquals(CARRIER_ID, mRetrieveListenerArgumentCaptor.getValue().mCarrierId);
}
@@ -383,7 +386,8 @@ public class WifiPseudonymManagerTest extends WifiBaseTest {
any());
assertEquals(AlarmManager.RTC_WAKEUP, mAlarmTypeCaptor.getValue().intValue());
long maxStartTime = Instant.now().toEpochMilli();
- assertTrue(mWindowStartCaptor.getValue().longValue() <= maxStartTime);
+ assertTrue("The difference is:" + (mWindowStartCaptor.getValue() - maxStartTime),
+ mWindowStartCaptor.getValue() <= maxStartTime);
assertEquals(CARRIER_ID, mRetrieveListenerArgumentCaptor.getValue().mCarrierId);
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiRoamingConfigStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiRoamingConfigStoreTest.java
new file mode 100644
index 0000000000..e59bd4c37a
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiRoamingConfigStoreTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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;
+
+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;
+
+import android.net.wifi.WifiManager;
+import android.util.ArrayMap;
+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;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.WifiRoamingConfigStoreTest}.
+ */
+@SmallTest
+public class WifiRoamingConfigStoreTest extends WifiBaseTest {
+ @Mock
+ private WifiConfigStore mWifiConfigStore;
+ @Mock
+ private WifiConfigManager mWifiConfigManager;
+ private WifiRoamingConfigStore mWifiRoamingConfigStore;
+ private static final String TEST_SSID = "SSID1";
+ private static final int TEST_ROAMING_MODE = WifiManager.ROAMING_MODE_AGGRESSIVE;
+ private static final int TEST_DEFAULT_ROAMING_MODE = WifiManager.ROAMING_MODE_NORMAL;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mWifiRoamingConfigStore =
+ new WifiRoamingConfigStore(mWifiConfigManager, mWifiConfigStore);
+ }
+
+ /**
+ * Called after each test
+ */
+ @After
+ public void cleanup() {
+ validateMockitoUsage();
+ }
+
+ @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);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(true).get(TEST_SSID)
+ == TEST_ROAMING_MODE);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(false).isEmpty());
+
+ mWifiRoamingConfigStore.removeRoamingMode(TEST_SSID, true);
+ assertTrue(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID) == TEST_DEFAULT_ROAMING_MODE);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(true).isEmpty());
+
+ verify(mWifiConfigManager, times(2)).saveToStore(true);
+ }
+
+ @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);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(false).get(TEST_SSID)
+ == TEST_ROAMING_MODE);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(true).isEmpty());
+
+ mWifiRoamingConfigStore.removeRoamingMode(TEST_SSID, false);
+ assertTrue(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID) == TEST_DEFAULT_ROAMING_MODE);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(false).isEmpty());
+
+ verify(mWifiConfigManager, times(2)).saveToStore(true);
+ }
+
+ @Test
+ public void testSaveAndLoadFromStore() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ ArgumentCaptor<WifiConfigStore.StoreData> storeDataCaptor = ArgumentCaptor.forClass(
+ WifiConfigStore.StoreData.class);
+ verify(mWifiConfigStore).registerStoreData(storeDataCaptor.capture());
+ assertNotNull(storeDataCaptor.getValue());
+
+ XmlPullParser in = createRoamingPolicyTestXmlForParsing(
+ TEST_SSID, TEST_ROAMING_MODE, true);
+ storeDataCaptor.getValue().resetData();
+ storeDataCaptor.getValue().deserializeData(in, in.getDepth(), -1, null);
+ assertTrue(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID) == TEST_ROAMING_MODE);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(true).get(TEST_SSID)
+ == TEST_ROAMING_MODE);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(false).isEmpty());
+
+ in = createRoamingPolicyTestXmlForParsing(
+ TEST_SSID, TEST_ROAMING_MODE, false);
+ storeDataCaptor.getValue().resetData();
+ storeDataCaptor.getValue().deserializeData(in, in.getDepth(), -1, null);
+ assertTrue(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID) == TEST_ROAMING_MODE);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(false).get(TEST_SSID)
+ == TEST_ROAMING_MODE);
+ assertTrue(mWifiRoamingConfigStore.getPerSsidRoamingModes(true).isEmpty());
+ }
+
+ 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);
+ final XmlSerializer out = new FastXmlSerializer();
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+ XmlUtil.writeDocumentStart(out, "RoamingPolicies");
+ XmlUtil.writeNextValue(out, isDeviceOwner ? "DeviceAdminPolicies" : "NonAdminPolicies",
+ roamingPolicies);
+ XmlUtil.writeDocumentEnd(out, "RoamingPolicies");
+
+ // Start Deserializing
+ final XmlPullParser in = Xml.newPullParser();
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+ in.setInput(inputStream, StandardCharsets.UTF_8.name());
+ XmlUtil.gotoDocumentStart(in, "RoamingPolicies");
+ return in;
+ }
+}
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 15001919e2..d06ed9f2fc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -67,6 +67,7 @@ import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TR
import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
import static com.android.server.wifi.SelfRecovery.REASON_API_CALL;
import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_NONE;
+import static com.android.server.wifi.WifiSettingsConfigStore.D2D_ALLOWED_WHEN_INFRA_STA_DISABLED;
import static com.android.server.wifi.WifiSettingsConfigStore.SHOW_DIALOG_WHEN_THIRD_PARTY_APPS_ENABLE_WIFI;
import static com.android.server.wifi.WifiSettingsConfigStore.SHOW_DIALOG_WHEN_THIRD_PARTY_APPS_ENABLE_WIFI_SET_BY_API;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STA_FACTORY_MAC_ADDRESS;
@@ -145,10 +146,12 @@ import android.net.DhcpResultsParcelable;
import android.net.MacAddress;
import android.net.Network;
import android.net.NetworkStack;
+import android.net.TetheringManager;
import android.net.Uri;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.IActionListener;
import android.net.wifi.IBooleanListener;
+import android.net.wifi.IByteArrayListener;
import android.net.wifi.ICoexCallback;
import android.net.wifi.IDppCallback;
import android.net.wifi.IIntegerListener;
@@ -157,6 +160,7 @@ import android.net.wifi.ILastCallerListener;
import android.net.wifi.IListListener;
import android.net.wifi.ILocalOnlyConnectionStatusListener;
import android.net.wifi.ILocalOnlyHotspotCallback;
+import android.net.wifi.IMapListener;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.IOnWifiActivityEnergyInfoListener;
import android.net.wifi.IOnWifiDriverCountryCodeChangedListener;
@@ -169,18 +173,24 @@ import android.net.wifi.ISubsystemRestartCallback;
import android.net.wifi.ISuggestionConnectionStatusListener;
import android.net.wifi.ISuggestionUserApprovalStatusListener;
import android.net.wifi.ITrafficStateCallback;
+import android.net.wifi.ITwtCallback;
+import android.net.wifi.ITwtCapabilitiesListener;
+import android.net.wifi.ITwtStatsListener;
import android.net.wifi.IWifiBandsListener;
import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.IWifiLowLatencyLockListener;
import android.net.wifi.IWifiNetworkSelectionConfigListener;
import android.net.wifi.IWifiNetworkStateChangedListener;
import android.net.wifi.IWifiVerboseLoggingStatusChangedListener;
+import android.net.wifi.MscsParams;
+import android.net.wifi.QosCharacteristics;
import android.net.wifi.QosPolicyParams;
import android.net.wifi.ScanResult;
import android.net.wifi.SecurityParams;
import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApInfo;
+import android.net.wifi.SoftApState;
import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiBands;
import android.net.wifi.WifiClient;
@@ -200,6 +210,8 @@ import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
+import android.net.wifi.twt.TwtRequest;
+import android.net.wifi.twt.TwtSessionCallback;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -222,6 +234,7 @@ import android.telephony.CarrierConfigManager;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.util.ArrayMap;
import android.util.Pair;
import androidx.test.filters.SmallTest;
@@ -231,6 +244,7 @@ import com.android.modules.utils.ParceledListSlice;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.WifiServiceImpl.LocalOnlyRequestorCallback;
import com.android.server.wifi.WifiServiceImpl.SoftApCallbackInternal;
+import com.android.server.wifi.b2b.WifiRoamingModeManager;
import com.android.server.wifi.coex.CoexManager;
import com.android.server.wifi.entitlement.PseudonymInfo;
import com.android.server.wifi.hotspot2.PasspointManager;
@@ -288,6 +302,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
private static final String TEST_PACKAGE_NAME = "TestPackage";
private static final String TEST_PACKAGE_NAME_OTHER = "TestPackageOther";
private static final String TEST_FEATURE_ID = "TestFeature";
+ private static final String TEST_FEATURE_ID_OTHER = "TestFeatureOther";
private static final String SYSUI_PACKAGE_NAME = "com.android.systemui";
private static final String CERT_INSTALLER_PACKAGE_NAME = "com.android.certinstaller";
private static final int TEST_PID = 6789;
@@ -325,6 +340,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
SECURITY_NONE));
private static final int TEST_AP_FREQUENCY = 2412;
private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ;
+ private static final TetheringManager.TetheringRequest TEST_TETHERING_REQUEST =
+ new TetheringManager.TetheringRequest.Builder(TetheringManager.TETHERING_WIFI).build();
+ private static final String TEST_IFACE_NAME = "test-wlan0";
private static final int NETWORK_CALLBACK_ID = 1100;
private static final String TEST_CAP = "[RSN-PSK-CCMP]";
private static final String TEST_SSID = "Sid's Place";
@@ -368,6 +386,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
final ArgumentCaptor<SoftApModeConfiguration> mSoftApModeConfigCaptor =
ArgumentCaptor.forClass(SoftApModeConfiguration.class);
+ final ArgumentCaptor<WifiSettingsConfigStore.OnSettingsChangedListener>
+ mWepAllowedSettingChangedListenerCaptor =
+ ArgumentCaptor.forClass(WifiSettingsConfigStore.OnSettingsChangedListener.class);
+
@Mock Bundle mBundle;
@Mock WifiContext mContext;
@Mock Context mContextAsUser;
@@ -475,9 +497,12 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Mock Location mLocation;
@Mock WifiDeviceStateChangeManager mWifiDeviceStateChangeManager;
@Mock PasspointNetworkNominateHelper mPasspointNetworkNominateHelper;
+ @Mock WifiRoamingModeManager mWifiRoamingModeManager;
+ @Mock BackupRestoreController mBackupRestoreController;
+ @Mock WifiSettingsBackupRestore mWifiSettingsBackupRestore;
@Captor ArgumentCaptor<Intent> mIntentCaptor;
@Captor ArgumentCaptor<List> mListCaptor;
-
+ @Mock TwtManager mTwtManager;
@Rule
// For frameworks
public TestRule compatChangeRule = new PlatformCompatChangeRule();
@@ -533,6 +558,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
.thenReturn(mock(HandlerThread.class));
when(mWifiInjector.getWifiDeviceStateChangeManager())
.thenReturn(mWifiDeviceStateChangeManager);
+ when(mWifiInjector.getWifiSettingsBackupRestore()).thenReturn(mWifiSettingsBackupRestore);
+ when(mWifiInjector.getBackupRestoreController()).thenReturn(mBackupRestoreController);
when(mHandlerThread.getThreadHandler()).thenReturn(new Handler(mLooper.getLooper()));
when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
when(mContext.getResources()).thenReturn(mResources);
@@ -657,9 +684,12 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiInjector.getScoringParams()).thenReturn(mScoringParams);
when(mWifiInjector.getApplicationQosPolicyRequestHandler())
.thenReturn(mApplicationQosPolicyRequestHandler);
+ when(mWifiInjector.getWifiRoamingModeManager()).thenReturn(mWifiRoamingModeManager);
when(mLocationManager.getProviders(anyBoolean())).thenReturn(List.of(
LocationManager.FUSED_PROVIDER, LocationManager.PASSIVE_PROVIDER,
LocationManager.NETWORK_PROVIDER, LocationManager.GPS_PROVIDER));
+ when(mWifiInjector.getWifiRoamingModeManager()).thenReturn(mWifiRoamingModeManager);
+ when(mWifiInjector.getTwtManager()).thenReturn(mTwtManager);
doAnswer(new AnswerWithArguments() {
public void answer(Runnable onStoppedListener) throws Throwable {
@@ -1353,7 +1383,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
private void changeLohsState(int apState, int previousState, int error) {
// TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
// apState, previousState, error, WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
- mLohsApCallback.onStateChanged(apState, error);
+ mLohsApCallback.onStateChanged(new SoftApState(apState, error,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME));
}
/**
@@ -1367,7 +1398,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.dispatchAll();
verifyApRegistration();
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ mStateMachineSoftApCallback.onStateChanged(
+ new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME));
when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
when(mContext.checkPermission(
@@ -1393,7 +1426,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.dispatchAll();
verifyApRegistration();
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ mStateMachineSoftApCallback.onStateChanged(
+ new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME));
when(mContext.checkPermission(
eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
@@ -1869,8 +1904,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
// send an ap state change to verify WifiServiceImpl is updated
verifyApRegistration();
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
+ mStateMachineSoftApCallback.onStateChanged(
+ new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME));
+ mStateMachineSoftApCallback.onStateChanged(
+ new SoftApState(
+ WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME));
mLooper.dispatchAll();
assertEquals(WifiManager.WIFI_AP_STATE_FAILED, mWifiServiceImpl.getWifiApEnabledState());
@@ -1903,7 +1943,6 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mWifiConfigManager).loadFromStore();
verify(mActiveModeWarden).start();
verify(mActiveModeWarden, never()).wifiToggled(any());
- verify(mWifiDeviceStateChangeManager).handleBootCompleted();
}
@Test
@@ -1935,7 +1974,6 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mWifiConfigManager).loadFromStore();
verify(mActiveModeWarden).start();
- verify(mWifiDeviceStateChangeManager).handleBootCompleted();
}
@Test
@@ -1959,6 +1997,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testSetPulledAtomCallbacks() {
mWifiServiceImpl.checkAndStartWifi();
+ mWifiServiceImpl.handleBootCompleted();
mLooper.dispatchAll();
verify(mWifiPulledAtomLogger).setPullAtomCallback(WifiStatsLog.WIFI_MODULE_INFO);
verify(mWifiPulledAtomLogger).setPullAtomCallback(WifiStatsLog.WIFI_SETTING_INFO);
@@ -2093,6 +2132,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertNull(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -2124,6 +2164,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
config,
mSoftApModeConfigCaptor.getValue().getSoftApConfiguration().toWifiConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
verify(mLastCallerInfoManager).put(eq(WifiManager.API_SOFT_AP), anyInt(),
anyInt(), anyInt(), anyString(), eq(true));
}
@@ -2161,6 +2202,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
config,
mSoftApModeConfigCaptor.getValue().getSoftApConfiguration().toWifiConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
verify(mContext).enforceCallingOrSelfPermission(
eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
}
@@ -2186,6 +2228,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
config,
mSoftApModeConfigCaptor.getValue().getSoftApConfiguration().toWifiConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -2198,6 +2241,73 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertNull(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_TETHERED_HOTSPOT), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
+ }
+
+ /**
+ * Verify a SecurityException is thrown when a caller without the correct permission attempts to
+ * call startTetheredHotspotRequest().
+ */
+ @Test(expected = SecurityException.class)
+ public void testStartTetheredHotspotRequestWithoutPermissionThrowsException() throws Exception {
+ when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+ doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+ eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
+ mLooper.startAutoDispatch();
+ TetheringManager.TetheringRequest request = new TetheringManager.TetheringRequest.Builder(
+ TetheringManager.TETHERING_WIFI).build();
+ mWifiServiceImpl.startTetheredHotspotRequest(request, TEST_PACKAGE_NAME);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ }
+
+ /**
+ * Verify that startTetheredHotspotRequest() succeeds if the caller does not have the
+ * NETWORK_STACK permission but does have the MAINLINE_NETWORK_STACK permission.
+ */
+ @Test
+ public void testStartTetheredHotspotRequestNetworkStackWithMainlineNetworkStackSucceeds() {
+ when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+ mLooper.startAutoDispatch();
+ TetheringManager.TetheringRequest request = new TetheringManager.TetheringRequest.Builder(
+ TetheringManager.TETHERING_WIFI).build();
+ boolean result = mWifiServiceImpl.startTetheredHotspotRequest(request, TEST_PACKAGE_NAME);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ assertTrue(result);
+ verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
+ eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
+ assertThat(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration()).isNull();
+ assertThat(mSoftApModeConfigCaptor.getValue().getTetheringRequest()).isEqualTo(request);
+ verify(mContext).enforceCallingOrSelfPermission(
+ eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
+ }
+
+ /**
+ * Verify startTetheredHotspot fails with a null request.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testStartTetheredHotspotNullRequestFails() {
+ mLooper.startAutoDispatch();
+ mWifiServiceImpl.startTetheredHotspotRequest(null, TEST_PACKAGE_NAME);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ }
+
+ /**
+ * Verify caller with proper permission can call startTetheredHotspot from a TetheringRequest.
+ */
+ @Test
+ public void testStartTetheredHotspotRequestWithPermissions() {
+ TetheringManager.TetheringRequest request = new TetheringManager.TetheringRequest.Builder(
+ TetheringManager.TETHERING_WIFI).build();
+ boolean result = mWifiServiceImpl.startTetheredHotspotRequest(request, TEST_PACKAGE_NAME);
+ assertTrue(result);
+ verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
+ eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
+ assertNull(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertThat(mSoftApModeConfigCaptor.getValue().getTetheringRequest()).isEqualTo(request);
verify(mLastCallerInfoManager).put(eq(WifiManager.API_TETHERED_HOTSPOT), anyInt(),
anyInt(), anyInt(), anyString(), eq(true));
}
@@ -2224,6 +2334,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -2426,6 +2537,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -2484,6 +2596,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -2543,6 +2656,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -2601,6 +2715,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -2635,6 +2750,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
.setBand(SoftApConfiguration.BAND_60GHZ)
.build();
boolean result = mWifiServiceImpl.startTetheredHotspot(config, TEST_PACKAGE_NAME);
+
assertFalse(result);
verify(mActiveModeWarden, never()).startSoftAp(any(), any());
}
@@ -2657,6 +2773,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -2688,6 +2805,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
verify(mContext).enforceCallingOrSelfPermission(
eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -2704,6 +2822,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertNull(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -3360,6 +3479,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testStartLocalOnlyHotspotSingleRegistrationReturnsRequestRegistered() {
registerLOHSRequestFull();
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(), any());
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
}
/**
@@ -3459,7 +3579,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
WifiConfigurationTestUtil.assertConfigurationEqualForSoftAp(
config,
mSoftApModeConfigCaptor.getValue().getSoftApConfiguration().toWifiConfiguration());
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
+ mStateMachineSoftApCallback.onStateChanged(
+ new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME));
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
assertEquals(WIFI_AP_STATE_ENABLED, mWifiServiceImpl.getWifiApEnabledState());
@@ -3484,7 +3607,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture(),
eq(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME)));
assertThat(config).isEqualTo(mSoftApModeConfigCaptor.getValue().getSoftApConfiguration());
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ assertNull(mSoftApModeConfigCaptor.getValue().getTetheringRequest());
+ mStateMachineSoftApCallback.onStateChanged(
+ new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME));
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
assertEquals(WIFI_AP_STATE_ENABLED, mWifiServiceImpl.getWifiApEnabledState());
@@ -3504,7 +3630,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
WifiConfiguration config = createValidWifiApConfiguration();
mLooper.startAutoDispatch();
assertTrue(mWifiServiceImpl.startSoftAp(config, TEST_PACKAGE_NAME));
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ mStateMachineSoftApCallback.onStateChanged(
+ new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME));
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mLooper.stopAutoDispatchAndIgnoreExceptions();
@@ -3917,7 +4045,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
.when(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
mWifiServiceImpl.registerSoftApCallback(mClientSoftApCallback);
mLooper.dispatchAll();
- verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
+ verify(mClientSoftApCallback, never()).onStateChanged(any());
verify(mClientSoftApCallback, never()).onConnectedClientsOrInfoChanged(
any(), any(), anyBoolean(), anyBoolean());
verify(mClientSoftApCallback, never()).onCapabilityChanged(any());
@@ -3930,7 +4058,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
private void registerSoftApCallbackAndVerify(ISoftApCallback callback) throws Exception {
mWifiServiceImpl.registerSoftApCallback(callback);
mLooper.dispatchAll();
- verify(callback).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
+ verify(callback).onStateChanged(
+ eq(new SoftApState(WIFI_AP_STATE_DISABLED, 0, null, null)));
verify(callback).onConnectedClientsOrInfoChanged(new HashMap<String, SoftApInfo>(),
new HashMap<String, List<WifiClient>>(), false, true);
verify(callback).onCapabilityChanged(ApConfigUtil.updateCapabilityFromResource(mContext));
@@ -3986,7 +4115,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
reset(mClientSoftApCallback);
when(mClientSoftApCallback.asBinder()).thenReturn(mAppBinder);
// Change state from default before registering the second callback
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ SoftApState state = new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME);
+ mStateMachineSoftApCallback.onStateChanged(state);
mStateMachineSoftApCallback.onConnectedClientsOrInfoChanged(
mTestSoftApInfos, mTestSoftApClients, false);
mStateMachineSoftApCallback.onBlockedClientConnecting(testWifiClient, 0);
@@ -3995,7 +4126,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
// Register another callback and verify the new state is returned in the immediate callback
mWifiServiceImpl.registerSoftApCallback(mAnotherSoftApCallback);
mLooper.dispatchAll();
- verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ verify(mAnotherSoftApCallback).onStateChanged(eq(state));
verify(mAnotherSoftApCallback).onConnectedClientsOrInfoChanged(
eq(mTestSoftApInfos), eq(mTestSoftApClients), eq(false), eq(true));
// Verify only first callback will receive onBlockedClientConnecting since it call after
@@ -4008,13 +4139,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.dispatchAll();
// Update soft AP state and verify the remaining callback receives the event
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED,
- SAP_START_FAILURE_NO_CHANNEL);
+ state = new SoftApState(
+ WIFI_AP_STATE_FAILED, SAP_START_FAILURE_NO_CHANNEL,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME);
+ mStateMachineSoftApCallback.onStateChanged(state);
mLooper.dispatchAll();
- verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_FAILED,
- SAP_START_FAILURE_NO_CHANNEL);
- verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED,
- SAP_START_FAILURE_NO_CHANNEL);
+ verify(mClientSoftApCallback, never()).onStateChanged(eq(state));
+ verify(mAnotherSoftApCallback).onStateChanged(eq(state));
}
/**
@@ -4070,9 +4201,12 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void callsRegisteredCallbacksOnSoftApStateChangedEvent() throws Exception {
registerSoftApCallbackAndVerify(mClientSoftApCallback);
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ SoftApState state = new SoftApState(
+ WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME);
+ mStateMachineSoftApCallback.onStateChanged(state);
mLooper.dispatchAll();
- verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ verify(mClientSoftApCallback).onStateChanged(eq(state));
}
/**
@@ -4083,7 +4217,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void updatesSoftApStateAndConnectedClientsOnSoftApEvents() throws Exception {
WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77"),
WIFI_IFACE_NAME2);
- mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ SoftApState state = new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME);
+ mStateMachineSoftApCallback.onStateChanged(state);
mStateMachineSoftApCallback.onConnectedClientsOrInfoChanged(
mTestSoftApInfos, mTestSoftApClients, false);
mStateMachineSoftApCallback.onBlockedClientConnecting(testWifiClient, 0);
@@ -4091,7 +4227,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
// Register callback after num clients and soft AP are changed.
mWifiServiceImpl.registerSoftApCallback(mClientSoftApCallback);
mLooper.dispatchAll();
- verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ verify(mClientSoftApCallback).onStateChanged(eq(state));
verify(mClientSoftApCallback).onConnectedClientsOrInfoChanged(
eq(mTestSoftApInfos), eq(mTestSoftApClients), eq(false), eq(true));
// Don't need to invoke callback when register.
@@ -5142,11 +5278,11 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testConnectNetworkWithoutPrivilegedPermission() throws Exception {
try {
mWifiServiceImpl.connect(mock(WifiConfiguration.class), TEST_NETWORK_ID,
- mock(IActionListener.class), TEST_PACKAGE_NAME);
+ mock(IActionListener.class), TEST_PACKAGE_NAME, mExtras);
fail();
} catch (SecurityException e) {
mLooper.dispatchAll();
- verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
+ verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any(), any());
}
}
@@ -5196,11 +5332,11 @@ public class WifiServiceImplTest extends WifiBaseTest {
config.SSID = TEST_SSID;
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
mWifiServiceImpl.connect(config, TEST_NETWORK_ID, mock(IActionListener.class),
- TEST_PACKAGE_NAME);
+ TEST_PACKAGE_NAME, mExtras);
mLooper.dispatchAll();
verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt());
verify(mConnectHelper).connectToNetwork(any(NetworkUpdateResult.class),
- any(ActionListenerWrapper.class), anyInt(), any());
+ any(ActionListenerWrapper.class), anyInt(), any(), any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK),
anyInt());
verify(mLastCallerInfoManager).put(eq(WifiManager.API_CONNECT_CONFIG), anyInt(),
@@ -5241,7 +5377,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
// Verify that the secondary internet CMM is stopped when manual connection is started
mWifiServiceImpl.connect(
- config, TEST_NETWORK_ID, mock(IActionListener.class), TEST_PACKAGE_NAME);
+ config, TEST_NETWORK_ID, mock(IActionListener.class), TEST_PACKAGE_NAME, mExtras);
mLooper.dispatchAll();
verify(primaryCmm, never()).stop();
verify(secondaryInternetCmm).stop();
@@ -5280,13 +5416,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
// Verify that the localOnlyCmm is not stopped since security type is different
mWifiServiceImpl.connect(config, TEST_NETWORK_ID, mock(IActionListener.class),
- TEST_PACKAGE_NAME);
+ TEST_PACKAGE_NAME, mExtras);
mLooper.dispatchAll();
verify(primaryCmm, never()).stop();
verify(localOnlyCmm, never()).stop();
verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt());
verify(mConnectHelper).connectToNetwork(any(NetworkUpdateResult.class),
- any(ActionListenerWrapper.class), anyInt(), any());
+ any(ActionListenerWrapper.class), anyInt(), any(), any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK),
anyInt());
@@ -5296,13 +5432,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
// Verify that the localOnlyCmm is stopped this time
mWifiServiceImpl.connect(config, TEST_NETWORK_ID, mock(IActionListener.class),
- TEST_PACKAGE_NAME);
+ TEST_PACKAGE_NAME, mExtras);
mLooper.dispatchAll();
verify(primaryCmm, never()).stop();
verify(localOnlyCmm).stop();
verify(mWifiConfigManager, times(2)).addOrUpdateNetwork(eq(config), anyInt());
verify(mConnectHelper, times(2)).connectToNetwork(any(NetworkUpdateResult.class),
- any(ActionListenerWrapper.class), anyInt(), any());
+ any(ActionListenerWrapper.class), anyInt(), any(), any());
verify(mWifiMetrics, times(2)).logUserActionEvent(
eq(UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK), anyInt());
}
@@ -5318,7 +5454,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(mWifiConfig);
mWifiServiceImpl.connect(mWifiConfig, WifiConfiguration.INVALID_NETWORK_ID,
- mActionListener, TEST_PACKAGE_NAME);
+ mActionListener, TEST_PACKAGE_NAME, mExtras);
mLooper.dispatchAll();
ArgumentCaptor<WifiConfiguration> configCaptor =
@@ -5326,7 +5462,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mWifiConfigManager).addOrUpdateNetwork(configCaptor.capture(), anyInt());
assertThat(configCaptor.getValue().networkId).isEqualTo(TEST_NETWORK_ID);
- verify(mConnectHelper).connectToNetwork(eq(result), any(), anyInt(), any());
+ verify(mConnectHelper).connectToNetwork(eq(result), any(), anyInt(), any(), any());
verify(mContextAsUser).sendBroadcastWithMultiplePermissions(
mIntentCaptor.capture(),
aryEq(new String[]{
@@ -5351,12 +5487,12 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
mWifiServiceImpl.connect(mWifiConfig, WifiConfiguration.INVALID_NETWORK_ID,
- mActionListener, TEST_PACKAGE_NAME);
+ mActionListener, TEST_PACKAGE_NAME, mExtras);
mLooper.dispatchAll();
verify(mWifiConfigManager).addOrUpdateNetwork(eq(mWifiConfig), anyInt());
- verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any());
+ verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any(), any());
verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
verify(mActionListener).onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
verify(mActionListener, never()).onSuccess();
@@ -5370,13 +5506,14 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(mWifiConfig);
- mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME,
+ mExtras);
mLooper.dispatchAll();
verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
verify(mConnectHelper).connectToNetwork(
- eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
+ eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any(), any());
verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
verify(mLastCallerInfoManager).put(eq(WifiManager.API_CONNECT_NETWORK_ID), anyInt(),
@@ -5395,13 +5532,14 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(TEST_SUB_ID);
when(mWifiCarrierInfoManager.isSimReady(TEST_SUB_ID)).thenReturn(true);
- mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME,
+ mExtras);
mLooper.dispatchAll();
verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
verify(mConnectHelper).connectToNetwork(
- eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
+ eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any(), any());
verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
}
@@ -5418,12 +5556,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any())).thenReturn(TEST_SUB_ID);
when(mWifiCarrierInfoManager.isSimReady(TEST_SUB_ID)).thenReturn(false);
- mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME,
+ mExtras);
mLooper.dispatchAll();
verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
- verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
+ verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any(), any());
verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
}
@@ -5442,12 +5581,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiCarrierInfoManager.requiresImsiEncryption(TEST_SUB_ID)).thenReturn(true);
when(mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(TEST_SUB_ID)).thenReturn(false);
- mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME,
+ mExtras);
mLooper.dispatchAll();
verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
- verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
+ verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any(), any());
verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
}
@@ -5466,13 +5606,14 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(anyInt())).thenReturn(true);
when(mWifiPseudonymManager.getValidPseudonymInfo(anyInt())).thenReturn(Optional.empty());
- mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME,
+ mExtras);
mLooper.dispatchAll();
verify(mWifiPseudonymManager).retrievePseudonymOnFailureTimeoutExpired(any());
verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
- verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
+ verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any(), any());
verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
}
@@ -5492,12 +5633,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiPseudonymManager.getValidPseudonymInfo(anyInt()))
.thenReturn(Optional.of(mock(PseudonymInfo.class)));
- mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.connect(null, TEST_NETWORK_ID, mActionListener, TEST_PACKAGE_NAME,
+ mExtras);
mLooper.dispatchAll();
verify(mWifiPseudonymManager).updateWifiConfiguration(any());
verify(mConnectHelper).connectToNetwork(
- eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
+ eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any(), any());
verify(mContextAsUser, never()).sendBroadcastWithMultiplePermissions(any(), any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_MANUAL_CONNECT), anyInt());
}
@@ -5518,7 +5660,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiPermissionsUtil.isAdminRestrictedNetwork(mWifiConfig)).thenReturn(true);
mWifiServiceImpl.connect(mWifiConfig, WifiConfiguration.INVALID_NETWORK_ID,
- mActionListener, TEST_PACKAGE_NAME);
+ mActionListener, TEST_PACKAGE_NAME, mExtras);
mLooper.dispatchAll();
ArgumentCaptor<WifiConfiguration> configCaptor =
@@ -5527,7 +5669,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
assertThat(configCaptor.getValue().networkId).isEqualTo(TEST_NETWORK_ID);
verify(mWifiConfigManager).addOrUpdateNetwork(eq(mWifiConfig), anyInt());
- verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any());
+ verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any(), any());
verify(mActionListener).onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
verify(mActionListener, never()).onSuccess();
}
@@ -5723,7 +5865,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiGlobals.isDeprecatedSecurityTypeNetwork(mWifiConfig)).thenReturn(false);
mWifiServiceImpl.connect(mWifiConfig, WifiConfiguration.INVALID_NETWORK_ID,
- mActionListener, TEST_PACKAGE_NAME);
+ mActionListener, TEST_PACKAGE_NAME, mExtras);
mLooper.dispatchAll();
ArgumentCaptor<WifiConfiguration> configCaptor =
@@ -5731,7 +5873,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mWifiConfigManager).addOrUpdateNetwork(configCaptor.capture(), anyInt());
assertThat(configCaptor.getValue().networkId).isEqualTo(TEST_NETWORK_ID);
- verify(mConnectHelper).connectToNetwork(eq(result), any(), anyInt(), any());
+ verify(mConnectHelper).connectToNetwork(eq(result), any(), anyInt(), any(), any());
}
/**
@@ -5750,7 +5892,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiGlobals.isDeprecatedSecurityTypeNetwork(mWifiConfig)).thenReturn(true);
mWifiServiceImpl.connect(mWifiConfig, WifiConfiguration.INVALID_NETWORK_ID,
- mActionListener, TEST_PACKAGE_NAME);
+ mActionListener, TEST_PACKAGE_NAME, mExtras);
mLooper.dispatchAll();
ArgumentCaptor<WifiConfiguration> configCaptor =
@@ -5759,7 +5901,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
assertThat(configCaptor.getValue().networkId).isEqualTo(TEST_NETWORK_ID);
verify(mWifiConfigManager).addOrUpdateNetwork(eq(mWifiConfig), anyInt());
- verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any());
+ verify(mClientModeManager, never()).connectNetwork(any(), any(), anyInt(), any(), any());
verify(mActionListener).onFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
verify(mActionListener, never()).onSuccess();
}
@@ -6695,38 +6837,6 @@ public class WifiServiceImplTest extends WifiBaseTest {
}
/**
- * Verify that add or update networks is allowed for apps holding system alert permission.
- */
- @Test
- public void testAddOrUpdateNetworkIsAllowedForAppsWithSystemAlertPermission() 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));
-
- // Verify caller fails to add network as Guest user.
- when(mWifiPermissionsUtil.checkSystemAlertWindowPermission(
- Process.myUid(), TEST_PACKAGE_NAME)).thenReturn(true);
- when(mWifiPermissionsUtil.isGuestUser()).thenReturn(true);
- WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
- mLooper.startAutoDispatch();
- assertEquals(-1,
- mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
-
- // Verify caller successfully add network when not a Guest user.
- when(mWifiPermissionsUtil.isGuestUser()).thenReturn(false);
- assertEquals(0,
- mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
- mLooper.stopAutoDispatchAndIgnoreExceptions();
-
- verifyCheckChangePermission(TEST_PACKAGE_NAME);
- verify(mWifiPermissionsUtil, times(2))
- .checkSystemAlertWindowPermission(anyInt(), anyString());
- verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt(), any(), eq(false));
- verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
- }
-
- /**
* Verify that add or update networks is allowed for DeviceOwner app.
*/
@Test
@@ -6888,18 +6998,18 @@ public class WifiServiceImplTest extends WifiBaseTest {
doAnswer(new AnswerWithArguments() {
public void answer(NetworkUpdateResult result, ActionListenerWrapper callback,
- int callingUid, String packageName) {
+ int callingUid, String packageName, String attributionTag) {
callback.sendSuccess(); // return success
}
}).when(mConnectHelper).connectToNetwork(
- eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
+ eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any(), any());
mLooper.startAutoDispatch();
assertTrue(mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME));
mLooper.stopAutoDispatch();
verify(mConnectHelper).connectToNetwork(
- eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
+ eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any(), any());
verify(mWifiMetrics).incrementNumEnableNetworkCalls();
verify(mLastCallerInfoManager).put(eq(WifiManager.API_ENABLE_NETWORK), anyInt(),
anyInt(), anyInt(), anyString(), eq(true));
@@ -6920,18 +7030,18 @@ public class WifiServiceImplTest extends WifiBaseTest {
doAnswer(new AnswerWithArguments() {
public void answer(NetworkUpdateResult result, ActionListenerWrapper callback,
- int callingUid, String packageName) {
+ int callingUid, String packageName, String attributionTag) {
callback.sendSuccess(); // return success
}
}).when(mConnectHelper).connectToNetwork(
- eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
+ eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any(), any());
mLooper.startAutoDispatch();
assertTrue(mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME));
mLooper.stopAutoDispatch();
verify(mConnectHelper).connectToNetwork(
- eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
+ eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any(), any());
verify(mWifiMetrics).incrementNumEnableNetworkCalls();
}
@@ -6970,7 +7080,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
+ verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any(), any());
verify(mWifiMetrics, never()).incrementNumEnableNetworkCalls();
}
@@ -6991,7 +7101,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
+ verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any(), any());
verify(mWifiMetrics, never()).incrementNumEnableNetworkCalls();
}
@@ -7011,7 +7121,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any());
+ verify(mConnectHelper, never()).connectToNetwork(any(), any(), anyInt(), any(), any());
verify(mWifiMetrics, never()).incrementNumEnableNetworkCalls();
}
@@ -8455,6 +8565,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mPasspointManager).initializeProvisioner(any());
verify(mWifiP2pConnection).handleBootCompleted();
verify(mWifiCountryCode).registerListener(any(WifiCountryCode.ChangeListener.class));
+ verify(mWifiDeviceStateChangeManager).handleBootCompleted();
}
/**
@@ -8688,6 +8799,16 @@ public class WifiServiceImplTest extends WifiBaseTest {
validateWifiActivityEnergyInfo(infoCaptor.getValue());
}
+ /**
+ * Tests that {@link WifiServiceImpl#getWifiActivityEnergyInfoAsync} throws exception when
+ * listener is null
+ */
+ @Test
+ public void getWifiActivityEnergyInfoWithNullListener() throws Exception {
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.getWifiActivityEnergyInfoAsync(null));
+ }
+
@Test
public void testCarrierConfigChangeUpdateSoftApCapability() throws Exception {
lenient().when(SubscriptionManager.getActiveDataSubscriptionId())
@@ -9130,8 +9251,18 @@ public class WifiServiceImplTest extends WifiBaseTest {
}
private List<ScanResult> createScanResultList() {
- return Collections.singletonList(new ScanResult(WifiSsid.fromUtf8Text(TEST_SSID),
- TEST_SSID, TEST_BSSID, 1245, 0, TEST_CAP, -78, 2450, 1025, 22, 33, 20, 0, 0, true));
+ return Collections.singletonList(new ScanResult.Builder(WifiSsid.fromUtf8Text(TEST_SSID),
+ TEST_BSSID)
+ .setHessid(1245)
+ .setCaps(TEST_CAP)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setChannelWidth(20)
+ .setIs80211McRTTResponder(true)
+ .build());
}
private void sendCountryCodeChangedBroadcast(String countryCode) {
@@ -9815,6 +9946,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testDriverCountryCodeChangedStoresAvailableSoftApChannels() throws Exception {
+ setup5GhzSupported();
+ setup24GhzSupported();
+ setup6GhzSupported();
+ setup60GhzSupported();
mWifiServiceImpl.handleBootCompleted();
mLooper.dispatchAll();
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
@@ -10208,6 +10343,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testSetExternalPnoScanRequest_Success() throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
+ when(mWifiGlobals.isBackgroundScanSupported()).thenReturn(true);
when(mActiveModeWarden.getSupportedFeatureSet())
.thenReturn(WifiManager.WIFI_FEATURE_PNO);
when(mWifiPermissionsUtil.checkRequestCompanionProfileAutomotiveProjectionPermission(
@@ -10464,7 +10600,18 @@ public class WifiServiceImplTest extends WifiBaseTest {
throws Exception {
mWifiServiceImpl.registerLocalOnlyHotspotSoftApCallback(mClientSoftApCallback, bundle);
mLooper.dispatchAll();
- verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
+
+ ArgumentCaptor<SoftApState> softApStateCaptor =
+ ArgumentCaptor.forClass(SoftApState.class);
+ verify(mClientSoftApCallback).onStateChanged(softApStateCaptor.capture());
+ assertThat(softApStateCaptor.getValue().getState()).isEqualTo(WIFI_AP_STATE_DISABLED);
+ try {
+ softApStateCaptor.getValue().getFailureReason();
+ fail("getFailureReason should throw if not in failure state");
+ } catch (IllegalStateException e) {
+ // Pass.
+ }
+ assertThat(softApStateCaptor.getValue().getFailureReasonInternal()).isEqualTo(0);
verify(mClientSoftApCallback).onConnectedClientsOrInfoChanged(
new HashMap<String, SoftApInfo>(),
new HashMap<String, List<WifiClient>>(), false, true);
@@ -10528,7 +10675,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
reset(mClientSoftApCallback);
when(mClientSoftApCallback.asBinder()).thenReturn(mAppBinder);
// Change state from default before registering the second callback
- mLohsApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ SoftApState state = new SoftApState(WIFI_AP_STATE_ENABLED, 0,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME);
+ mLohsApCallback.onStateChanged(state);
mLohsApCallback.onConnectedClientsOrInfoChanged(
mTestSoftApInfos, mTestSoftApClients, false);
mLohsApCallback.onBlockedClientConnecting(testWifiClient, 0);
@@ -10537,7 +10686,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
// Register another callback and verify the new state is returned in the immediate callback
mWifiServiceImpl.registerLocalOnlyHotspotSoftApCallback(mAnotherSoftApCallback, mExtras);
mLooper.dispatchAll();
- verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ verify(mAnotherSoftApCallback).onStateChanged(eq(state));
verify(mAnotherSoftApCallback).onConnectedClientsOrInfoChanged(
eq(mTestSoftApInfos), eq(mTestSoftApClients), eq(false), eq(true));
// Verify only first callback will receive onBlockedClientConnecting since it call after
@@ -10550,13 +10699,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.dispatchAll();
// Update soft AP state and verify the remaining callback receives the event
- mLohsApCallback.onStateChanged(WIFI_AP_STATE_FAILED,
- SAP_START_FAILURE_NO_CHANNEL);
+ state = new SoftApState(
+ WIFI_AP_STATE_FAILED, SAP_START_FAILURE_NO_CHANNEL,
+ TEST_TETHERING_REQUEST, TEST_IFACE_NAME);
+ mLohsApCallback.onStateChanged(state);
mLooper.dispatchAll();
- verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_FAILED,
- SAP_START_FAILURE_NO_CHANNEL);
- verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED,
- SAP_START_FAILURE_NO_CHANNEL);
+ verify(mClientSoftApCallback, never()).onStateChanged(eq(state));
+ verify(mAnotherSoftApCallback).onStateChanged(eq(state));
}
/**
@@ -10890,6 +11039,86 @@ public class WifiServiceImplTest extends WifiBaseTest {
}
/**
+ * Verify attribution passed to WifiManager#connect is parsed when there's a chain.
+ */
+ @Test
+ public void testConnectAttribution_CorrectParsingWithChain() {
+ assumeTrue(SdkLevel.isAtLeastS());
+ AttributionSource attributionSource = mock(AttributionSource.class);
+ when(attributionSource.checkCallingUid()).thenReturn(true);
+ when(attributionSource.isTrusted(any(Context.class))).thenReturn(true);
+ mAttribution.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, attributionSource);
+ mWifiServiceImpl = spy(mWifiServiceImpl);
+ lenient().when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(Process.SYSTEM_UID);
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt()))
+ .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+
+ when(attributionSource.getUid()).thenReturn(TEST_UID);
+ when(attributionSource.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
+ when(attributionSource.getAttributionTag()).thenReturn(TEST_FEATURE_ID);
+ AttributionSource originalCaller = mock(AttributionSource.class);
+ when(originalCaller.getUid()).thenReturn(OTHER_TEST_UID);
+ when(originalCaller.getPackageName()).thenReturn(TEST_PACKAGE_NAME_OTHER);
+ when(originalCaller.getAttributionTag()).thenReturn(TEST_FEATURE_ID_OTHER);
+ when(originalCaller.isTrusted(any(Context.class))).thenReturn(true);
+ when(attributionSource.getNext()).thenReturn(originalCaller);
+
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = TEST_SSID;
+ when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
+ mWifiServiceImpl.connect(config, TEST_NETWORK_ID, mock(IActionListener.class),
+ TEST_PACKAGE_NAME, mAttribution);
+ mLooper.dispatchAll();
+ verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt());
+ verify(mConnectHelper).connectToNetwork(any(NetworkUpdateResult.class),
+ any(ActionListenerWrapper.class), eq(OTHER_TEST_UID), eq(TEST_PACKAGE_NAME_OTHER),
+ eq(TEST_FEATURE_ID_OTHER));
+ }
+
+ /**
+ * Verify attribution passed to WifiManager#connect is parsed when there's a chain.
+ * However, if the call is not made from the system server then the attribution is ignored and
+ * the attribution is simply to the calling app as before.
+ */
+ @Test
+ public void testConnectAttribution_CorrectParsingWithChainButNotFromSystemServer() {
+ assumeTrue(SdkLevel.isAtLeastS());
+ AttributionSource attributionSource = mock(AttributionSource.class);
+ when(attributionSource.checkCallingUid()).thenReturn(true);
+ when(attributionSource.isTrusted(any(Context.class))).thenReturn(true);
+ mAttribution.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE, attributionSource);
+ mWifiServiceImpl = spy(mWifiServiceImpl);
+ lenient().when(mWifiServiceImpl.getMockableCallingUid()).thenReturn(TEST_UID);
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt()))
+ .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+
+ when(attributionSource.getUid()).thenReturn(TEST_UID);
+ when(attributionSource.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
+ when(attributionSource.getAttributionTag()).thenReturn(TEST_FEATURE_ID);
+ AttributionSource originalCaller = mock(AttributionSource.class);
+ when(originalCaller.getUid()).thenReturn(OTHER_TEST_UID);
+ when(originalCaller.getPackageName()).thenReturn(TEST_PACKAGE_NAME_OTHER);
+ when(originalCaller.getAttributionTag()).thenReturn(TEST_FEATURE_ID_OTHER);
+ when(originalCaller.isTrusted(any(Context.class))).thenReturn(true);
+ when(attributionSource.getNext()).thenReturn(originalCaller);
+
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = TEST_SSID;
+ when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
+ mWifiServiceImpl.connect(config, TEST_NETWORK_ID, mock(IActionListener.class),
+ TEST_PACKAGE_NAME, mAttribution);
+ mLooper.dispatchAll();
+ verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt());
+ verify(mConnectHelper).connectToNetwork(any(NetworkUpdateResult.class),
+ any(ActionListenerWrapper.class), eq(TEST_UID), eq(TEST_PACKAGE_NAME),
+ eq(TEST_FEATURE_ID));
+ }
+
+ /**
* Test that notifyWifiSsidPolicyChanged disconnects the current network
* due to SSID allowlist restriction
*/
@@ -11183,6 +11412,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
// The supported channels in soft AP capability got invalidated.
assertEquals(0, capabilityArgumentCaptor.getValue()
.getSupportedChannelList(SoftApConfiguration.BAND_2GHZ).length);
+ verify(mWifiNative, times(2)).getUsableChannels(eq(WifiScanner.WIFI_BAND_24_GHZ), anyInt(),
+ anyInt());
}
/**
@@ -11380,18 +11611,51 @@ public class WifiServiceImplTest extends WifiBaseTest {
private List<ScanResult> createChannelDataScanResults() {
List<ScanResult> scanResults = new ArrayList<>();
- scanResults.add(
- new ScanResult(WifiSsid.fromUtf8Text(TEST_SSID), TEST_SSID, TEST_BSSID, 1234, 0,
- TEST_CAP, -78, 2412, 1024, 22, 33, 20, 0, 0, true));
- scanResults.add(
- new ScanResult(WifiSsid.fromUtf8Text(TEST_SSID), TEST_SSID, TEST_BSSID, 1234, 0,
- TEST_CAP, -85, 2417, 1024, 22, 33, 20, 0, 0, true));
- scanResults.add(
- new ScanResult(WifiSsid.fromUtf8Text(TEST_SSID), TEST_SSID, TEST_BSSID, 1234, 0,
- TEST_CAP, -60, 5805, 1024, 22, 33, 20, 0, 0, true));
- scanResults.add(
- new ScanResult(WifiSsid.fromUtf8Text(TEST_SSID), TEST_SSID, TEST_BSSID, 1234, 0,
- TEST_CAP, -70, 5805, 1024, 22, 33, 20, 0, 0, true));
+
+ scanResults.add(new ScanResult.Builder(WifiSsid.fromUtf8Text(TEST_SSID), TEST_BSSID)
+ .setHessid(1245)
+ .setCaps(TEST_CAP)
+ .setRssi(-78)
+ .setFrequency(2412)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setChannelWidth(20)
+ .setIs80211McRTTResponder(true)
+ .build());
+ scanResults.add(new ScanResult.Builder(WifiSsid.fromUtf8Text(TEST_SSID), TEST_BSSID)
+ .setHessid(1245)
+ .setCaps(TEST_CAP)
+ .setRssi(-85)
+ .setFrequency(2417)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setChannelWidth(20)
+ .setIs80211McRTTResponder(true)
+ .build());
+ scanResults.add(new ScanResult.Builder(WifiSsid.fromUtf8Text(TEST_SSID), TEST_BSSID)
+ .setHessid(1245)
+ .setCaps(TEST_CAP)
+ .setRssi(-60)
+ .setFrequency(5805)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setChannelWidth(20)
+ .setIs80211McRTTResponder(true)
+ .build());
+ scanResults.add(new ScanResult.Builder(WifiSsid.fromUtf8Text(TEST_SSID), TEST_BSSID)
+ .setHessid(1245)
+ .setCaps(TEST_CAP)
+ .setRssi(-70)
+ .setFrequency(5805)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setChannelWidth(20)
+ .setIs80211McRTTResponder(true)
+ .build());
return scanResults;
}
@@ -11402,7 +11666,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
.thenReturn(true);
}
- private List<QosPolicyParams> createQosPolicyParamsList(int size, boolean uniqueIds) {
+ private List<QosPolicyParams> createDownlinkQosPolicyParamsList(int size, boolean uniqueIds) {
List<QosPolicyParams> policyParamsList = new ArrayList<>();
for (int i = 0; i < size; i++) {
int policyId = uniqueIds ? i + 2 : 5;
@@ -11415,6 +11679,22 @@ public class WifiServiceImplTest extends WifiBaseTest {
return policyParamsList;
}
+ private static List<QosPolicyParams> createUplinkQosPolicyParamsList(int size) {
+ List<QosPolicyParams> policyParamsList = new ArrayList<>();
+ QosCharacteristics mockQosCharacteristics = mock(QosCharacteristics.class);
+ when(mockQosCharacteristics.validate()).thenReturn(true);
+
+ for (int i = 0; i < size; i++) {
+ int policyId = i + 2;
+ policyParamsList.add(new QosPolicyParams.Builder(
+ policyId, QosPolicyParams.DIRECTION_UPLINK)
+ .setQosCharacteristics(mockQosCharacteristics)
+ .build());
+ }
+
+ return policyParamsList;
+ }
+
/**
* Verify that addQosPolicies works correctly.
*/
@@ -11423,14 +11703,28 @@ public class WifiServiceImplTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastU());
enableQosPolicyFeature();
- List<QosPolicyParams> paramsList = createQosPolicyParamsList(5, true);
+ ConcreteClientModeManager primaryCmm = mock(ConcreteClientModeManager.class);
+ when(primaryCmm.isWifiStandardSupported(anyInt())).thenReturn(true);
+ when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(primaryCmm);
+ mLooper.startAutoDispatch(); // handles call to isWifiStandardSupported
+
+ List<QosPolicyParams> paramsList = createDownlinkQosPolicyParamsList(5, true);
IBinder binder = mock(IBinder.class);
IListListener listener = mock(IListListener.class);
mWifiServiceImpl.addQosPolicies(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);
+ expectedNumCalls += 1;
+ }
mLooper.dispatchAll();
- verify(mApplicationQosPolicyRequestHandler).queueAddRequest(
+ verify(mApplicationQosPolicyRequestHandler, times(expectedNumCalls)).queueAddRequest(
anyList(), any(), any(), anyInt());
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
}
/**
@@ -11440,7 +11734,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testAddQosPoliciesError() throws RemoteException {
assumeTrue(SdkLevel.isAtLeastU());
enableQosPolicyFeature();
- List<QosPolicyParams> paramsList = createQosPolicyParamsList(5, true);
+ List<QosPolicyParams> paramsList = createDownlinkQosPolicyParamsList(5, true);
IBinder binder = mock(IBinder.class);
IListListener listener = mock(IListListener.class);
@@ -11464,25 +11758,32 @@ public class WifiServiceImplTest extends WifiBaseTest {
mWifiServiceImpl.addQosPolicies(paramsList, binder, TEST_PACKAGE_NAME, null));
// Invalid QoS policy params list
- List<QosPolicyParams> emptyList = createQosPolicyParamsList(0, true);
- List<QosPolicyParams> largeList = createQosPolicyParamsList(
+ List<QosPolicyParams> emptyList = createDownlinkQosPolicyParamsList(0, true);
+ List<QosPolicyParams> largeList = createDownlinkQosPolicyParamsList(
WifiManager.getMaxNumberOfPoliciesPerQosRequest() + 1, true);
- List<QosPolicyParams> duplicatePolicyList = createQosPolicyParamsList(5, false);
- List<QosPolicyParams> mixedDirectionList = createQosPolicyParamsList(1, true);
- mixedDirectionList.add(
- new QosPolicyParams.Builder(101, QosPolicyParams.DIRECTION_UPLINK)
- .setDscp(15)
- .build());
+ List<QosPolicyParams> duplicatePolicyList = createDownlinkQosPolicyParamsList(5, false);
assertThrows(IllegalArgumentException.class, () ->
- mWifiServiceImpl.addQosPolicies(emptyList, binder, TEST_PACKAGE_NAME, listener));
+ mWifiServiceImpl.addQosPolicies(emptyList, binder, TEST_PACKAGE_NAME,
+ listener));
assertThrows(IllegalArgumentException.class, () ->
- mWifiServiceImpl.addQosPolicies(largeList, binder, TEST_PACKAGE_NAME, listener));
+ mWifiServiceImpl.addQosPolicies(largeList, binder, TEST_PACKAGE_NAME,
+ listener));
assertThrows(IllegalArgumentException.class, () ->
mWifiServiceImpl.addQosPolicies(
duplicatePolicyList, binder, TEST_PACKAGE_NAME, listener));
- assertThrows(IllegalArgumentException.class, () ->
- mWifiServiceImpl.addQosPolicies(
- mixedDirectionList, binder, TEST_PACKAGE_NAME, listener));
+
+ if (SdkLevel.isAtLeastV()) {
+ List<QosPolicyParams> mixedDirectionList = createDownlinkQosPolicyParamsList(1, true);
+ QosCharacteristics mockQosCharacteristics = mock(QosCharacteristics.class);
+ when(mockQosCharacteristics.validate()).thenReturn(true);
+ mixedDirectionList.add(
+ new QosPolicyParams.Builder(101, QosPolicyParams.DIRECTION_UPLINK)
+ .setQosCharacteristics(mockQosCharacteristics)
+ .build());
+ assertThrows(IllegalArgumentException.class, () ->
+ mWifiServiceImpl.addQosPolicies(
+ mixedDirectionList, binder, TEST_PACKAGE_NAME, listener));
+ }
}
/**
@@ -11787,22 +12088,6 @@ public class WifiServiceImplTest extends WifiBaseTest {
}
/**
- * Verify that Pno is supported.
- */
- @Test
- public void testIsPnoSupported() {
- when(mWifiGlobals.isBackgroundScanSupported()).thenReturn(false);
- assertFalse(mWifiServiceImpl.isPnoSupported());
- when(mActiveModeWarden.getSupportedFeatureSet()).thenReturn(0L);
- assertFalse(mWifiServiceImpl.isPnoSupported());
-
- when(mActiveModeWarden.getSupportedFeatureSet()).thenReturn(WifiManager.WIFI_FEATURE_PNO);
- assertTrue(mWifiServiceImpl.isPnoSupported());
- when(mWifiGlobals.isBackgroundScanSupported()).thenReturn(true);
- assertTrue(mWifiServiceImpl.isPnoSupported());
- }
-
- /**
* Verify that on a country code change, we inform the AFC Manager.
*/
@Test
@@ -11845,17 +12130,34 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mWifiSettingsConfigStore).get(eq(WIFI_WEP_ALLOWED));
verify(mWifiGlobals).setWepAllowed(eq(false));
- // verify setWepAllowed with MANAGE_WIFI_NETWORK_SELECTION
+ // verify setWepAllowed with MANAGE_WIFI_NETWORK_SETTING
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
mWifiServiceImpl.setWepAllowed(true);
mLooper.dispatchAll();
verify(mWifiGlobals).setWepAllowed(true);
verify(mWifiSettingsConfigStore).put(eq(WIFI_WEP_ALLOWED), eq(true));
+ }
+ @Test
+ public void testSetWepDisAllowedWithPermission() {
+ when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+ ConcreteClientModeManager cmmWep = mock(ConcreteClientModeManager.class);
+ ConcreteClientModeManager cmmWpa = mock(ConcreteClientModeManager.class);
+ WifiInfo mockWifiInfoWep = mock(WifiInfo.class);
+ WifiInfo mockWifiInfoWpa = mock(WifiInfo.class);
+ List<ClientModeManager> cmms = Arrays.asList(cmmWep, cmmWpa);
+ when(mActiveModeWarden.getClientModeManagers()).thenReturn(cmms);
+ when(mockWifiInfoWep.getCurrentSecurityType()).thenReturn(WifiInfo.SECURITY_TYPE_WEP);
+ when(mockWifiInfoWpa.getCurrentSecurityType()).thenReturn(WifiInfo.SECURITY_TYPE_PSK);
+ when(cmmWep.getConnectionInfo()).thenReturn(mockWifiInfoWep);
+ when(cmmWpa.getConnectionInfo()).thenReturn(mockWifiInfoWpa);
mWifiServiceImpl.setWepAllowed(false);
mLooper.dispatchAll();
- verify(mWifiGlobals, times(2)).setWepAllowed(false);
+ verify(mWifiGlobals).setWepAllowed(false);
verify(mWifiSettingsConfigStore).put(eq(WIFI_WEP_ALLOWED), eq(false));
+ // Only WEP disconnect
+ verify(cmmWep).disconnect();
+ verify(cmmWpa, never()).disconnect();
}
@Test
@@ -11891,4 +12193,488 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mWifiSettingsConfigStore, times(3)).get(eq(WIFI_WEP_ALLOWED));
inOrder.verify(listener).onResult(false);
}
+
+ @Test
+ public void testEnableAndDisableMscsSuccess() {
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(true);
+ when(mActiveModeWarden.getInternetConnectivityClientModeManagers())
+ .thenReturn(Arrays.asList(mClientModeManager));
+ when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
+
+ // Test enableMscs
+ MscsParams mscsParams = new MscsParams.Builder().build();
+ mWifiServiceImpl.enableMscs(mscsParams);
+ mLooper.dispatchAll();
+ verify(mWifiNative).enableMscs(eq(mscsParams), eq(WIFI_IFACE_NAME));
+
+ // Test disableMscs
+ mWifiServiceImpl.disableMscs();
+ mLooper.dispatchAll();
+ verify(mWifiNative).disableMscs(eq(WIFI_IFACE_NAME));
+ }
+
+ @Test
+ public void testEnableAndDisableMscsFailure() {
+ // Verify the permissions check on both methods
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(false);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.enableMscs(mock(MscsParams.class)));
+ assertThrows(SecurityException.class, () -> mWifiServiceImpl.disableMscs());
+
+ // Verify the nullity check on enableMscs
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(true);
+ assertThrows(NullPointerException.class, () -> mWifiServiceImpl.enableMscs(null));
+ }
+
+ @Test(expected = SecurityException.class)
+ public void testSetSendDhcpHostnameRestrictionWithoutPermission() {
+ // by default no permissions are given so the call should fail.
+ mWifiServiceImpl.setSendDhcpHostnameRestriction(
+ TEST_PACKAGE_NAME, WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetSendDhcpHostnameRestrictionInvalidFlags() {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.setSendDhcpHostnameRestriction(
+ TEST_PACKAGE_NAME, -1);
+ }
+
+ @Test
+ public void testSetSendDhcpHostnameRestrictionWithPermission() {
+ // verify setSendDhcpHostnameRestriction with NETWORK_SETTINGS
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.setSendDhcpHostnameRestriction(
+ TEST_PACKAGE_NAME, WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN);
+ mLooper.dispatchAll();
+ verify(mWifiGlobals).setSendDhcpHostnameRestriction(
+ eq(WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN));
+ }
+
+ @Test
+ public void testQuerySendDhcpHostnameRestrictionExceptionCases() {
+ // null listener ==> IllegalArgumentException
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.querySendDhcpHostnameRestriction(TEST_PACKAGE_NAME, null));
+ // by default no permissions are given so the call should fail.
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.querySendDhcpHostnameRestriction(
+ TEST_PACKAGE_NAME, mock(IIntegerListener.class)));
+ }
+
+ @Test
+ public void testQuerySendDhcpHostnameRestrictionNormalCase() throws Exception {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ IIntegerListener listener = mock(IIntegerListener.class);
+
+ InOrder inOrder = inOrder(listener);
+ when(mWifiGlobals.getSendDhcpHostnameRestriction())
+ .thenReturn(0);
+ mWifiServiceImpl.querySendDhcpHostnameRestriction(TEST_PACKAGE_NAME, listener);
+ mLooper.dispatchAll();
+ verify(mWifiGlobals).getSendDhcpHostnameRestriction();
+ inOrder.verify(listener).onResult(0);
+
+ when(mWifiGlobals.getSendDhcpHostnameRestriction())
+ .thenReturn(WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN);
+ mWifiServiceImpl.querySendDhcpHostnameRestriction(TEST_PACKAGE_NAME, listener);
+ mLooper.dispatchAll();
+ verify(mWifiGlobals, times(2)).getSendDhcpHostnameRestriction();
+ inOrder.verify(listener).onResult(WifiManager.FLAG_SEND_DHCP_HOSTNAME_RESTRICTION_OPEN);
+ }
+
+ @Test
+ public void testSetPerSsidRoamingModeByDeviceAdmin() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mActiveModeWarden.getSupportedFeatureSet())
+ .thenReturn(WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.setPerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
+ WifiManager.ROAMING_MODE_NORMAL, TEST_PACKAGE_NAME));
+ when(mWifiPermissionsUtil.isOrganizationOwnedDeviceAdmin(anyInt(),
+ eq(TEST_PACKAGE_NAME))).thenReturn(true);
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.setPerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES), -1, TEST_PACKAGE_NAME));
+
+ mWifiServiceImpl.setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
+ WifiManager.ROAMING_MODE_NORMAL, TEST_PACKAGE_NAME);
+ mLooper.dispatchAll();
+ verify(mWifiRoamingModeManager).setPerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
+ WifiManager.ROAMING_MODE_NORMAL, true);
+ }
+
+ @Test
+ public void testSetPerSsidRoamingModeByNonAdmin() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mActiveModeWarden.getSupportedFeatureSet())
+ .thenReturn(WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.setPerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
+ WifiManager.ROAMING_MODE_NORMAL, TEST_PACKAGE_NAME));
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(
+ anyInt())).thenReturn(true);
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.setPerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES), -1, TEST_PACKAGE_NAME));
+
+ mWifiServiceImpl.setPerSsidRoamingMode(WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
+ WifiManager.ROAMING_MODE_NORMAL, TEST_PACKAGE_NAME);
+ mLooper.dispatchAll();
+ verify(mWifiRoamingModeManager).setPerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
+ WifiManager.ROAMING_MODE_NORMAL, false);
+ }
+
+ @Test
+ public void testRemovePerSsidRoamingModeByDeviceAdmin() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mActiveModeWarden.getSupportedFeatureSet())
+ .thenReturn(WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.removePerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES), TEST_PACKAGE_NAME));
+ when(mWifiPermissionsUtil.isOrganizationOwnedDeviceAdmin(anyInt(),
+ eq(TEST_PACKAGE_NAME))).thenReturn(true);
+
+ mWifiServiceImpl.removePerSsidRoamingMode(WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
+ TEST_PACKAGE_NAME);
+ mLooper.dispatchAll();
+ verify(mWifiRoamingModeManager).removePerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES), true);
+ }
+
+ @Test
+ public void testRemovePerSsidRoamingModeByNonAdmin() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mActiveModeWarden.getSupportedFeatureSet())
+ .thenReturn(WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.removePerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES), TEST_PACKAGE_NAME));
+ when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+
+ mWifiServiceImpl.removePerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES), TEST_PACKAGE_NAME);
+ mLooper.dispatchAll();
+ verify(mWifiRoamingModeManager).removePerSsidRoamingMode(
+ WifiSsid.fromString(TEST_SSID_WITH_QUOTES), false);
+ }
+
+ @Test
+ public void testGetPerSsidRoamingModesByDeviceAdmin() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mActiveModeWarden.getSupportedFeatureSet())
+ .thenReturn(WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT);
+ IMapListener listener = mock(IMapListener.class);
+ InOrder inOrder = inOrder(listener);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.getPerSsidRoamingModes(TEST_PACKAGE_NAME, listener));
+ when(mWifiPermissionsUtil.isOrganizationOwnedDeviceAdmin(anyInt(),
+ eq(TEST_PACKAGE_NAME))).thenReturn(true);
+
+ Map<String, Integer> deviceAdminRoamingPolicies = new ArrayMap<>();
+ deviceAdminRoamingPolicies.put(TEST_SSID_WITH_QUOTES, WifiManager.ROAMING_MODE_NORMAL);
+ when(mWifiRoamingModeManager.getPerSsidRoamingModes(eq(true))).thenReturn(
+ deviceAdminRoamingPolicies);
+
+ mWifiServiceImpl.getPerSsidRoamingModes(TEST_PACKAGE_NAME, listener);
+ mLooper.dispatchAll();
+ ArgumentCaptor<Map<String, Integer>> resultCaptor = ArgumentCaptor.forClass(Map.class);
+ inOrder.verify(listener).onResult(resultCaptor.capture());
+
+ assertEquals(resultCaptor.getValue().get(TEST_SSID_WITH_QUOTES),
+ deviceAdminRoamingPolicies.get(TEST_SSID_WITH_QUOTES));
+ assertEquals(resultCaptor.getValue().size(),
+ deviceAdminRoamingPolicies.size());
+ }
+
+ @Test
+ public void testGetPerSsidRoamingModesByNonAdmin() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mActiveModeWarden.getSupportedFeatureSet())
+ .thenReturn(WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT);
+ IMapListener listener = mock(IMapListener.class);
+ InOrder inOrder = inOrder(listener);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.getPerSsidRoamingModes(TEST_PACKAGE_NAME, listener));
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(
+ anyInt())).thenReturn(true);
+
+ Map<String, Integer> nonAdminRoamingPolicies = new ArrayMap<>();
+ nonAdminRoamingPolicies.put(TEST_SSID_WITH_QUOTES, WifiManager.ROAMING_MODE_NONE);
+ when(mWifiRoamingModeManager.getPerSsidRoamingModes(false)).thenReturn(
+ nonAdminRoamingPolicies);
+
+ mWifiServiceImpl.getPerSsidRoamingModes(TEST_PACKAGE_NAME, listener);
+ mLooper.dispatchAll();
+ ArgumentCaptor<Map<String, Integer>> resultCaptor = ArgumentCaptor.forClass(Map.class);
+ inOrder.verify(listener).onResult(resultCaptor.capture());
+
+ assertEquals(resultCaptor.getValue().get(TEST_SSID_WITH_QUOTES),
+ nonAdminRoamingPolicies.get(TEST_SSID_WITH_QUOTES));
+ assertEquals(resultCaptor.getValue().size(),
+ nonAdminRoamingPolicies.size());
+ }
+
+ private void verifyIsPnoSupported(boolean isBackgroundScanSupported, boolean isSwPnoEnabled,
+ boolean isPnoFeatureSet) {
+ when(mWifiGlobals.isBackgroundScanSupported()).thenReturn(isBackgroundScanSupported);
+ when(mWifiGlobals.isSwPnoEnabled()).thenReturn(isSwPnoEnabled);
+ if (isPnoFeatureSet) {
+ when(mActiveModeWarden.getSupportedFeatureSet())
+ .thenReturn(WifiManager.WIFI_FEATURE_PNO);
+ } else {
+ when(mActiveModeWarden.getSupportedFeatureSet()).thenReturn(0L);
+ }
+ assertEquals(mWifiServiceImpl.isPnoSupported(),
+ (isBackgroundScanSupported && isPnoFeatureSet) || isSwPnoEnabled);
+ }
+
+ /*
+ * Verify that Pno is supported.
+ */
+ @Test
+ public void testIsPnoSupported() throws Exception {
+ verifyIsPnoSupported(false, false, false);
+ verifyIsPnoSupported(true, false, false);
+ verifyIsPnoSupported(false, true, false);
+ verifyIsPnoSupported(false, false, true);
+ verifyIsPnoSupported(true, true, false);
+ verifyIsPnoSupported(false, true, true);
+ verifyIsPnoSupported(true, false, true);
+ verifyIsPnoSupported(true, true, true);
+ }
+
+ @Test
+ public void testSetD2dAllowedWhenInfraStaDisabled() throws Exception {
+ // by default no permissions are given so the call should fail.
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.setD2dAllowedWhenInfraStaDisabled(true));
+ mWifiServiceImpl.checkAndStartWifi();
+ mLooper.dispatchAll();
+ // verify setD2DAllowedWhenInfraStaDisabled with MANAGE_WIFI_NETWORK_SETTING
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.setD2dAllowedWhenInfraStaDisabled(true);
+ mLooper.dispatchAll();
+ verify(mWifiSettingsConfigStore).put(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED), eq(true));
+
+ mWifiServiceImpl.setD2dAllowedWhenInfraStaDisabled(false);
+ mLooper.dispatchAll();
+ verify(mWifiSettingsConfigStore).put(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED), eq(false));
+ }
+
+ @Test
+ public void testQueryD2dAllowedWhenInfraStaDisabled() throws Exception {
+ // null listener ==> IllegalArgumentException
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.queryD2dAllowedWhenInfraStaDisabled(null));
+
+ mWifiServiceImpl.checkAndStartWifi();
+ mLooper.dispatchAll();
+ IBooleanListener listener = mock(IBooleanListener.class);
+
+ InOrder inOrder = inOrder(listener);
+ when(mWifiSettingsConfigStore.get(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED)))
+ .thenReturn(true);
+ mWifiServiceImpl.queryD2dAllowedWhenInfraStaDisabled(listener);
+ mLooper.dispatchAll();
+ verify(mWifiSettingsConfigStore).get(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED));
+ inOrder.verify(listener).onResult(true);
+
+ when(mWifiSettingsConfigStore.get(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED)))
+ .thenReturn(false);
+ mWifiServiceImpl.queryD2dAllowedWhenInfraStaDisabled(listener);
+ mLooper.dispatchAll();
+ verify(mWifiSettingsConfigStore, times(2)).get(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED));
+ inOrder.verify(listener).onResult(false);
+ }
+
+ @Test
+ public void testGetTwtCapabilities() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ ITwtCapabilitiesListener iTwtCapabilitiesListener = mock(ITwtCapabilitiesListener.class);
+ // Test permission check
+ when(mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION)).thenReturn(
+ PackageManager.PERMISSION_DENIED);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.getTwtCapabilities(iTwtCapabilitiesListener, mExtras));
+ mWifiServiceImpl.checkAndStartWifi();
+ mLooper.dispatchAll();
+ when(mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION)).thenReturn(
+ PackageManager.PERMISSION_GRANTED);
+ // Test with null parameters
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.getTwtCapabilities(null, mExtras));
+ // Test getTwtCapabilities call
+ mWifiServiceImpl.getTwtCapabilities(iTwtCapabilitiesListener, mExtras);
+ mLooper.dispatchAll();
+ verify(mTwtManager).getTwtCapabilities(eq(WIFI_IFACE_NAME), eq(iTwtCapabilitiesListener));
+ }
+
+ @Test
+ public void testSetupTwtSession() throws RemoteException {
+ assumeTrue(SdkLevel.isAtLeastV());
+ ITwtCallback iTwtCallback = mock(ITwtCallback.class);
+ TwtRequest twtRequest = mock(TwtRequest.class);
+ // Test permission check
+ when(mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION)).thenReturn(
+ PackageManager.PERMISSION_DENIED);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.setupTwtSession(twtRequest, iTwtCallback, mExtras));
+ mWifiServiceImpl.checkAndStartWifi();
+ mLooper.dispatchAll();
+ when(mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION)).thenReturn(
+ PackageManager.PERMISSION_GRANTED);
+ // Test with null parameters
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.setupTwtSession(null, iTwtCallback, mExtras));
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.setupTwtSession(twtRequest, null, mExtras));
+ // Test with station not connected
+ when(mClientModeManager.isConnected()).thenReturn(false);
+ mWifiServiceImpl.setupTwtSession(twtRequest, iTwtCallback, mExtras);
+ mLooper.dispatchAll();
+ verify(iTwtCallback).onFailure(eq(TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE));
+ // Test setupTwtSession with station connected
+ when(mClientModeManager.isConnected()).thenReturn(true);
+ when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID);
+ mWifiServiceImpl.setupTwtSession(twtRequest, iTwtCallback, mExtras);
+ mLooper.dispatchAll();
+ verify(mTwtManager).setupTwtSession(eq(WIFI_IFACE_NAME), eq(twtRequest), eq(iTwtCallback),
+ eq(Binder.getCallingUid()), eq(TEST_BSSID));
+ }
+
+ @Test
+ public void testGetStatsTwtSession() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ int sessionId = 10;
+ ITwtStatsListener iTwtStatsListener = mock(ITwtStatsListener.class);
+ // Test permission check
+ when(mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION)).thenReturn(
+ PackageManager.PERMISSION_DENIED);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.getStatsTwtSession(sessionId, iTwtStatsListener, mExtras));
+ mWifiServiceImpl.checkAndStartWifi();
+ mLooper.dispatchAll();
+ when(mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION)).thenReturn(
+ PackageManager.PERMISSION_GRANTED);
+ // Test with null parameters
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.getStatsTwtSession(sessionId, null, mExtras));
+ // Test getStatsTwtSession call
+ mWifiServiceImpl.getStatsTwtSession(sessionId, iTwtStatsListener, mExtras);
+ mLooper.dispatchAll();
+ verify(mTwtManager).getStatsTwtSession(eq(WIFI_IFACE_NAME), eq(iTwtStatsListener),
+ eq(sessionId));
+ }
+
+ @Test
+ public void testTeardownTwtSession() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ int sessionId = 10;
+ // Test permission check
+ when(mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION)).thenReturn(
+ PackageManager.PERMISSION_DENIED);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.teardownTwtSession(sessionId, mExtras));
+ mWifiServiceImpl.checkAndStartWifi();
+ mLooper.dispatchAll();
+ when(mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION)).thenReturn(
+ PackageManager.PERMISSION_GRANTED);
+ // Test teardownTwtSession call
+ mWifiServiceImpl.teardownTwtSession(sessionId, mExtras);
+ mLooper.dispatchAll();
+ verify(mTwtManager).tearDownTwtSession(eq(WIFI_IFACE_NAME), eq(sessionId));
+ }
+
+ @SuppressWarnings("BoxedPrimitiveEquality")
+ @Test
+ public void testRetrieveWifiBackupData() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ // Expect exception when caller has no permission
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ IByteArrayListener mockTestListener = mock(IByteArrayListener.class);
+ // by default no permissions are given so the call should fail.
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.retrieveWifiBackupData(mockTestListener));
+ doNothing().when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ // null listener ==> IllegalArgumentException
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.retrieveWifiBackupData(null));
+ mWifiServiceImpl.retrieveWifiBackupData(mockTestListener);
+ mLooper.dispatchAll();
+ verify(mBackupRestoreController).retrieveBackupData();
+ verify(mockTestListener).onResult(any());
+ }
+
+ @SuppressWarnings("BoxedPrimitiveEquality")
+ @Test
+ public void testRestoreWifiBackupData() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ byte[] mockTestRestoredData = new byte[0];
+ // Expect exception when caller has no permission
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ // by default no permissions are given so the call should fail.
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.restoreWifiBackupData(mockTestRestoredData));
+ doNothing().when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ mWifiServiceImpl.restoreWifiBackupData(mockTestRestoredData);
+ mLooper.dispatchAll();
+ verify(mBackupRestoreController).parserBackupDataAndDispatch(mockTestRestoredData);
+ }
+
+ @Test
+ public void testWepAllowedChangedFromCloudRestoration() {
+ when(mWifiSettingsConfigStore.get(eq(WIFI_WEP_ALLOWED))).thenReturn(true);
+ when(mWifiGlobals.isWepAllowed()).thenReturn(true);
+ mWifiServiceImpl.checkAndStartWifi();
+ mLooper.dispatchAll();
+ verify(mWifiSettingsConfigStore).registerChangeListener(
+ eq(WIFI_WEP_ALLOWED),
+ mWepAllowedSettingChangedListenerCaptor.capture(),
+ any(Handler.class));
+ verify(mWifiGlobals).setWepAllowed(true);
+ // Mock wep connection to make sure it will disconnect
+ ConcreteClientModeManager cmmWep = mock(ConcreteClientModeManager.class);
+ WifiInfo mockWifiInfoWep = mock(WifiInfo.class);
+ List<ClientModeManager> cmms = Arrays.asList(cmmWep);
+ when(mActiveModeWarden.getClientModeManagers()).thenReturn(cmms);
+ when(mockWifiInfoWep.getCurrentSecurityType()).thenReturn(WifiInfo.SECURITY_TYPE_WEP);
+ when(cmmWep.getConnectionInfo()).thenReturn(mockWifiInfoWep);
+
+ // Test wep is changed from cloud restoration.
+ mWepAllowedSettingChangedListenerCaptor.getValue()
+ .onSettingsChanged(WIFI_WEP_ALLOWED, false);
+ mLooper.dispatchAll();
+ verify(mWifiGlobals).setWepAllowed(false);
+ // Only WEP disconnect
+ verify(cmmWep).disconnect();
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiSettingsBackupRestoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiSettingsBackupRestoreTest.java
new file mode 100644
index 0000000000..38b4d9e0a4
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiSettingsBackupRestoreTest.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;
+
+import static com.android.server.wifi.WifiSettingsBackupRestore.XML_TAG_SECTION_HEADER_WIFI_SETTINGS_DATA;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.inOrder;
+
+import android.util.Xml;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.WifiSettingsBackupRestoreTest}.
+ */
+@SmallTest
+public class WifiSettingsBackupRestoreTest extends WifiBaseTest {
+
+ @Mock WifiSettingsConfigStore mWifiSettingsConfigStore;
+ @Mock XmlPullParser mXmlPullParser;
+ @Mock ByteArrayOutputStream mByteArrayOutputStream;
+ @Mock XmlSerializer mXmlSerializer;
+
+ @SuppressWarnings("DoubleBraceInitialization")
+ private static final ArrayList<WifiSettingsConfigStore.Key> TEST_KEYS = new ArrayList<>() {{
+ add(WifiSettingsConfigStore.WIFI_WEP_ALLOWED); }};
+
+ /**
+ * The data we backup in this module is <WifiSettingsSection></WifiSettingsSection>
+ * and the depth is 1.
+ */
+ public static String generateTestWifiSettingsTestingXml(String backupKeys) {
+ return "<WifiSettingsSection>\n"
+ + "<Settings>\n"
+ + "<map name=\"Values\">\n"
+ + backupKeys
+ + "</map>\n"
+ + "</Settings>\n"
+ + "</WifiSettingsSection>\n";
+ }
+
+ private WifiSettingsBackupRestore mWifiSettingsBackupRestore;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(mWifiSettingsConfigStore.getAllKeys()).thenReturn(TEST_KEYS);
+ when(mWifiSettingsConfigStore.getAllBackupRestoreKeys()).thenReturn(TEST_KEYS);
+ mWifiSettingsBackupRestore = new WifiSettingsBackupRestore(mWifiSettingsConfigStore);
+ mWifiSettingsBackupRestore.enableVerboseLogging(true);
+ }
+
+ private XmlPullParser generateTestXmlPullParser(byte[] data) throws Exception {
+ final XmlPullParser in = Xml.newPullParser();
+ ByteArrayInputStream inputStream =
+ new ByteArrayInputStream(data);
+ in.setInput(inputStream, StandardCharsets.UTF_8.name());
+ return in;
+ }
+
+ @Test
+ public void testBackupWifiSettings() throws Exception {
+ InOrder order = inOrder(mXmlSerializer);
+ mWifiSettingsBackupRestore.retrieveBackupDataFromSettingsConfigStore(
+ mXmlSerializer, mByteArrayOutputStream);
+ order.verify(mXmlSerializer).startTag(eq(null),
+ eq(XML_TAG_SECTION_HEADER_WIFI_SETTINGS_DATA));
+ order.verify(mXmlSerializer).startTag(eq(null),
+ eq(WifiSettingsConfigStore.StoreData.XML_TAG_SECTION_HEADER));
+ order.verify(mXmlSerializer).startTag(eq(null), eq("map"));
+ order.verify(mXmlSerializer).attribute(eq(null), eq("name"),
+ eq(WifiSettingsConfigStore.StoreData.XML_TAG_VALUES));
+ for (WifiSettingsConfigStore.Key key : mWifiSettingsConfigStore.getAllKeys()) {
+ order.verify(mXmlSerializer).attribute(eq(null), eq("name"), eq(key.getKey()));
+ }
+ order.verify(mXmlSerializer).endTag(eq(null), eq("map"));
+ order.verify(mXmlSerializer).endTag(eq(null),
+ eq(WifiSettingsConfigStore.StoreData.XML_TAG_SECTION_HEADER));
+ order.verify(mXmlSerializer).endTag(eq(null),
+ eq(XML_TAG_SECTION_HEADER_WIFI_SETTINGS_DATA));
+ }
+
+ @Test
+ public void testRestoreWifiSettings() throws Exception {
+ String testBackupMap = "<boolean name=\"wep_allowed\" value=\"true\" />\n";
+ mWifiSettingsBackupRestore.restoreSettingsFromBackupData(
+ generateTestXmlPullParser(
+ generateTestWifiSettingsTestingXml(testBackupMap).getBytes()),
+ 0 /* The depth of Tag: WifiSettingsSection */);
+ verify(mWifiSettingsConfigStore).put(eq(WifiSettingsConfigStore.WIFI_WEP_ALLOWED),
+ eq(Boolean.TRUE));
+ }
+
+ @Test
+ public void testRestoreWifiSettingsWithUnknownTag() throws Exception {
+ String testBackupMap = "<boolean name=\"unknown_tag\" value=\"true\" />\n";
+ mWifiSettingsBackupRestore.restoreSettingsFromBackupData(
+ generateTestXmlPullParser(
+ generateTestWifiSettingsTestingXml(testBackupMap).getBytes()),
+ 0 /* The depth of Tag: WifiSettingsSection */);
+ verify(mWifiSettingsConfigStore, never()).put(any(), any());
+ }
+}
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 07de1876f7..4783d049cf 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
@@ -105,7 +105,6 @@ public class WifiShellCommandTest extends WifiBaseTest {
@Mock WifiDiagnostics mWifiDiagnostics;
@Mock DeviceConfigFacade mDeviceConfig;
@Mock WifiScanner mWifiScanner;
-
WifiShellCommand mWifiShellCommand;
@Before
@@ -826,7 +825,7 @@ public class WifiShellCommandTest extends WifiBaseTest {
return (wifiConfiguration.SSID.equals("\"ssid1234\"")
&& wifiConfiguration.macRandomizationSetting
== WifiConfiguration.RANDOMIZATION_NONE);
- }), eq(-1), any(), any());
+ }), eq(-1), any(), any(), any());
}
@Test
@@ -841,7 +840,7 @@ public class WifiShellCommandTest extends WifiBaseTest {
return (wifiConfiguration.SSID.equals("\"ssid1234\"")
&& wifiConfiguration.macRandomizationSetting
== WifiConfiguration.RANDOMIZATION_NON_PERSISTENT);
- }), eq(-1), any(), any());
+ }), eq(-1), any(), any(), any());
}
@Test
@@ -860,14 +859,14 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"connect-network", "012345", "open", "-x"});
verify(mWifiService, never()).connect(argThat(wifiConfiguration ->
- (wifiConfiguration.SSID.equals("012345"))), eq(-1), any());
+ (wifiConfiguration.SSID.equals("012345"))), eq(-1), any(), any(), any());
BinderUtil.setUid(Process.ROOT_UID);
mWifiShellCommand.exec(
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"connect-network", "012345", "open", "-x"});
verify(mWifiService).connect(argThat(wifiConfiguration ->
- (wifiConfiguration.SSID.equals("012345"))), eq(-1), any(), any());
+ (wifiConfiguration.SSID.equals("012345"))), eq(-1), any(), any(), any());
}
@Test
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 80ab46044d..ba434a573e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -48,6 +48,7 @@ import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.hardware.wifi.WifiStatusCode;
import android.net.InetAddresses;
import android.net.KeepalivePacketData;
import android.net.MacAddress;
@@ -1813,4 +1814,21 @@ public class WifiVendorHalTest extends WifiBaseTest {
mWifiVendorHal.setAfcChannelAllowance(mAfcChannelAllowance);
verify(mWifiChip).setAfcChannelAllowance(mAfcChannelAllowance);
}
+
+ /**
+ * Test setRoamingMode
+ *
+ * A call before the vendor HAL is started should return invalid interface.
+ *
+ * A call after the HAL is started should return success value.
+ */
+ @Test
+ public void testSetRoamingMode() throws Exception {
+ assertTrue(mWifiVendorHal.setRoamingMode(TEST_IFACE_NAME, WifiManager.ROAMING_MODE_NORMAL)
+ == WifiStatusCode.ERROR_WIFI_IFACE_INVALID);
+ // Start the vendor hal
+ assertTrue(mWifiVendorHal.startVendorHalSta(mConcreteClientModeManager));
+ assertTrue(mWifiVendorHal.setRoamingMode(TEST_IFACE_NAME, WifiManager.ROAMING_MODE_NORMAL)
+ == WifiStatusCode.SUCCESS);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java b/service/tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java
index bc453c8f8b..c2ceade67a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java
@@ -140,13 +140,13 @@ public class TestUtils {
}
public boolean respondToBootstrappingRequest(short transactionId, int bootstrappingId,
- boolean accept) {
+ boolean accept, byte pubSubId) {
addTransactionId(transactionId);
return true;
}
public boolean initiateBootstrapping(short transactionId, int peerId, byte[] peer,
- int method, byte[] cookie) {
+ int method, byte[] cookie, byte pubSubId, boolean isComeBack) {
addTransactionId(transactionId);
return true;
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
index b5db3799e4..2adab51238 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
@@ -188,6 +188,11 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
Context.POWER_SERVICE);
when(mMockContext.getSystemService(PowerManager.class)).thenReturn(mMockPowerManager);
when(mMockContext.getSystemService(StatsManager.class)).thenReturn(mStatsManager);
+ mResources = new MockResources();
+ mResources.setBoolean(R.bool.config_wifiAllowMultipleNetworksOnSameAwareNdi, false);
+ mResources.setBoolean(R.bool.config_wifiAwareNdpSecurityUpdateOnSameNdi, false);
+ mResources.setInteger(R.integer.config_wifiConfigurationWifiRunnerThresholdInMs, 4000);
+ when(mMockContext.getResources()).thenReturn(mResources);
when(mInterfaceConflictManager.manageInterfaceConflictForStateMachine(any(), any(), any(),
any(), any(), eq(HalDeviceManager.HDM_CREATE_IFACE_NAN), any(), anyBoolean()))
@@ -220,11 +225,6 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
mDut.mDataPathMgr.mNetdWrapper = mMockNetdWrapper;
mDut.mDataPathMgr.mNiWrapper = mMockNetworkInterface;
-
- mResources = new MockResources();
- mResources.setBoolean(R.bool.config_wifiAllowMultipleNetworksOnSameAwareNdi, false);
- mResources.setBoolean(R.bool.config_wifiAwareNdpSecurityUpdateOnSameNdi, false);
- when(mMockContext.getResources()).thenReturn(mResources);
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java
index 2dc4e26470..8342171c42 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java
@@ -18,9 +18,11 @@ package com.android.server.wifi.aware;
import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_AWARE_VERBOSE_LOGGING_ENABLED;
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;
@@ -31,6 +33,7 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -39,7 +42,7 @@ import static org.mockito.Mockito.when;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.WifiScanner;
import android.net.wifi.aware.Characteristics;
import android.net.wifi.aware.ConfigRequest;
@@ -54,24 +57,30 @@ import android.os.Build;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.IBinder;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.test.TestLooper;
+import android.util.LocalLog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import androidx.test.filters.SmallTest;
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.DeviceConfigFacade;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.InterfaceConflictManager;
+import com.android.server.wifi.MockResources;
import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiSettingsConfigStore;
import com.android.server.wifi.util.NetdWrapper;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
import com.android.wifi.resources.R;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -80,6 +89,9 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
/**
@@ -118,6 +130,9 @@ public class WifiAwareServiceImplTest extends WifiBaseTest {
@Mock private WifiSettingsConfigStore mWifiSettingsConfigStore;
@Mock private InterfaceConflictManager mInterfaceConflictManager;
@Mock private DeviceConfigFacade mDeviceConfigFacade;
+ @Mock private WifiInjector mWifiInjector;
+ @Mock private LocalLog mLocalLog;
+ private StaticMockitoSession mStaticMockSession;
/**
* Using instead of spy to avoid native crash failures - possibly due to
@@ -146,6 +161,11 @@ public class WifiAwareServiceImplTest extends WifiBaseTest {
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
+ mStaticMockSession = mockitoSession()
+ .mockStatic(WifiInjector.class)
+ .startMocking();
+ lenient().when(WifiInjector.getInstance()).thenReturn(mWifiInjector);
+ when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog);
mMockLooper = new TestLooper();
when(mHandlerThreadMock.getLooper()).thenReturn(mMockLooper.getLooper());
@@ -170,10 +190,11 @@ public class WifiAwareServiceImplTest extends WifiBaseTest {
.thenReturn(InterfaceConflictManager.ICM_EXECUTE_COMMAND);
mDut = new WifiAwareServiceImplSpy(mContextMock);
- Resources resources = mock(Resources.class);
+ MockResources resources = new MockResources();
+ resources.setInteger(R.integer.config_wifiVerboseLoggingAlwaysOnLevel, 0);
+ resources.setInteger(R.integer.config_wifiConfigurationWifiRunnerThresholdInMs, 4000);
when(mContextMock.getResources()).thenReturn(resources);
- when(resources.getInteger(
- R.integer.config_wifiVerboseLoggingAlwaysOnLevel)).thenReturn(0);
+
mDut.fakeUid = mDefaultUid;
mDut.start(mHandlerThreadMock, mAwareStateManagerMock, mWifiAwareShellCommandMock,
mAwareMetricsMock, mWifiPermissionsUtil, mPermissionsWrapperMock,
@@ -187,6 +208,11 @@ public class WifiAwareServiceImplTest extends WifiBaseTest {
eq(mInterfaceConflictManager));
}
+ @After
+ public void tearDown() throws Exception {
+ mStaticMockSession.finishMocking();
+ }
+
/**
* Validate isUsageEnabled() function
*/
@@ -237,15 +263,69 @@ public class WifiAwareServiceImplTest extends WifiBaseTest {
*/
@Test
public void testConnectWithConfig() {
- ConfigRequest configRequest = new ConfigRequest.Builder().setMasterPreference(55).build();
+ int clusterLow = 15;
+ ConfigRequest configRequest = new ConfigRequest.Builder()
+ .setClusterLow(clusterLow)
+ .build();
String callingPackage = "com.google.somePackage";
String callingFeatureId = "com.google.someFeature";
mDut.connect(mBinderMock, callingPackage, callingFeatureId, mCallbackMock,
configRequest, false, mExtras, false);
+ ArgumentCaptor<ConfigRequest> configRequestCaptor =
+ ArgumentCaptor.forClass(ConfigRequest.class);
verify(mAwareStateManagerMock).connect(anyInt(), anyInt(), anyInt(), eq(callingPackage),
- eq(callingFeatureId), eq(mCallbackMock), eq(configRequest), eq(false), any(),
- eq(false));
+ eq(callingFeatureId), eq(mCallbackMock), configRequestCaptor.capture(), eq(false),
+ any(), eq(false));
+
+ // Since the caller has the network stack permission,
+ // the provided ConfigRequest should be unmodified
+ assertEquals(clusterLow, configRequestCaptor.getValue().mClusterLow);
+ }
+
+ /**
+ * Validate connect() when a non-null config is passed and the caller has the
+ * manage network selection permission.
+ */
+ @Test
+ public void testConnectWithManageNetworkSelectionPermission() {
+ // Caller has none of the permissions required to include a ConfigRequest
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(false);
+ when(mContextMock.checkCallingOrSelfPermission(anyString()))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+
+ int clusterLow = 15;
+ OuiKeyedData vendorDataElement =
+ new OuiKeyedData.Builder(0x00aabbcc, new PersistableBundle()).build();
+ List<OuiKeyedData> vendorData = Arrays.asList(vendorDataElement);
+ ConfigRequest configRequest = new ConfigRequest.Builder()
+ .setClusterLow(clusterLow)
+ .setVendorData(vendorData)
+ .build();
+
+ String callingPackage = "com.google.somePackage";
+ String callingFeatureId = "com.google.someFeature";
+ assertThrows(SecurityException.class, () ->
+ mDut.connect(mBinderMock, callingPackage, callingFeatureId, mCallbackMock,
+ configRequest, false, mExtras, false));
+
+ // Caller has the manage network selection permission
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(true);
+ ArgumentCaptor<ConfigRequest> configRequestCaptor =
+ ArgumentCaptor.forClass(ConfigRequest.class);
+ mDut.connect(mBinderMock, callingPackage, callingFeatureId, mCallbackMock,
+ configRequest, false, mExtras, false);
+ verify(mAwareStateManagerMock).connect(anyInt(), anyInt(), anyInt(), eq(callingPackage),
+ eq(callingFeatureId), eq(mCallbackMock), configRequestCaptor.capture(),
+ eq(false), any(), eq(false));
+
+ // Since the caller does not have the network stack permission, all ConfigRequest fields
+ // except the vendor data should be reset to a default value
+ assertEquals(vendorData, configRequestCaptor.getValue().getVendorData());
+ assertNotEquals(clusterLow, configRequestCaptor.getValue().mClusterLow);
}
/**
@@ -984,7 +1064,7 @@ public class WifiAwareServiceImplTest extends WifiBaseTest {
// constructed configs.
PublishConfig publishConfig = new PublishConfig(serviceName.getBytes(), ssi, matchFilter,
PublishConfig.PUBLISH_TYPE_UNSOLICITED, 0, true, false, false,
- WifiScanner.WIFI_BAND_24_GHZ, null, null, false);
+ WifiScanner.WIFI_BAND_24_GHZ, null, null, false, Collections.emptyList());
int clientId = doConnect();
IWifiAwareDiscoverySessionCallback mockCallback = mock(
IWifiAwareDiscoverySessionCallback.class);
@@ -1001,7 +1081,7 @@ public class WifiAwareServiceImplTest extends WifiBaseTest {
// constructed configs.
SubscribeConfig subscribeConfig = new SubscribeConfig(serviceName.getBytes(), ssi,
matchFilter, SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE, 0, true, false, 0, false, 0,
- false, WifiScanner.WIFI_BAND_24_GHZ, null, false);
+ false, WifiScanner.WIFI_BAND_24_GHZ, null, false, Collections.emptyList());
int clientId = doConnect();
IWifiAwareDiscoverySessionCallback mockCallback = mock(
IWifiAwareDiscoverySessionCallback.class);
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 130fbf10bb..f1578311f0 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
@@ -65,6 +65,7 @@ import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.wifi.IBooleanListener;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
@@ -86,6 +87,7 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -136,6 +138,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -233,6 +236,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mResources = new MockResources();
mResources.setInteger(R.integer.config_wifiAwareInstantCommunicationModeDurationMillis,
30000);
+ mResources.setInteger(R.integer.config_wifiConfigurationWifiRunnerThresholdInMs, 4000);
when(mMockContext.getResources()).thenReturn(mResources);
when(mInterfaceConflictManager.manageInterfaceConflictForStateMachine(any(), any(), any(),
@@ -331,6 +335,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
* - Get multiple matches (PeerHandles)
* - Request translation as UID of session #1 for PeerHandles of the same UID + of the other
* discovery session (to which we shouldn't have access) + invalid PeerHandle.
+ * - Vendor data list is converted to an array for callback
* -> validate results
*/
@Test
@@ -352,6 +357,12 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final byte[] peerMac3 = HexEncoding.decode("AABBCCDDEEFF".toCharArray(), false);
final int distance = 10;
+ OuiKeyedData vendorDataElement =
+ new OuiKeyedData.Builder(0x00112233, new PersistableBundle()).build();
+ List<OuiKeyedData> vendorDataList = Arrays.asList(vendorDataElement);
+ OuiKeyedData[] vendorDataArray = new OuiKeyedData[vendorDataList.size()];
+ vendorDataList.toArray(vendorDataArray);
+
ConfigRequest configRequest = new ConfigRequest.Builder().build();
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
.build();
@@ -418,22 +429,23 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (3) 2 matches on session 1 (second one with distance), 1 match on session 2
mDut.onMatchNotification(subscribeId1, requestorIdBase, peerMac1, null, null, 0, 0,
- null, 0, null, null, null);
+ null, 0, null, null, null, vendorDataList);
mDut.onMatchNotification(subscribeId1, requestorIdBase + 1, peerMac2, null, null,
- NanRangingIndication.INGRESS_MET_MASK, distance, null, 0, null, null, null);
+ NanRangingIndication.INGRESS_MET_MASK, distance, null, 0, null, null, null,
+ vendorDataList);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback1).onMatch(peerIdCaptor.capture(), isNull(),
- isNull(), anyInt(), isNull(), any(), any());
+ isNull(), anyInt(), isNull(), any(), any(), eq(vendorDataArray));
inOrder.verify(mockSessionCallback1).onMatchWithDistance(peerIdCaptor.capture(), isNull(),
- isNull(), eq(distance), anyInt(), isNull(), any(), any());
+ isNull(), eq(distance), anyInt(), isNull(), any(), any(), eq(vendorDataArray));
int peerId1 = peerIdCaptor.getAllValues().get(0);
int peerId2 = peerIdCaptor.getAllValues().get(1);
mDut.onMatchNotification(subscribeId2, requestorIdBase + 2, peerMac3, null, null, 0, 0,
- null, 0, null, null, null);
+ null, 0, null, null, null, vendorDataList);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback2).onMatch(peerIdCaptor.capture(), isNull(), isNull(),
- anyInt(), isNull(), any(), any());
+ anyInt(), isNull(), any(), any(), eq(vendorDataArray));
int peerId3 = peerIdCaptor.getAllValues().get(0);
// request MAC addresses
@@ -1821,20 +1833,20 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (2) 2 matches : with and w/o range
mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
- peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null);
+ peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), eq(peerSsi.getBytes()),
- eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull());
+ eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull(), isNull());
inOrderM.verify(mAwareMetricsMock).recordMatchIndicationForRangeEnabledSubscribe(false);
int peerId1 = peerIdCaptor.getValue();
mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
peerMatchFilter.getBytes(), EGRESS_MET_MASK, rangedDistance, null, 0, null, null,
- null);
+ null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatchWithDistance(peerIdCaptor.capture(),
eq(peerSsi.getBytes()), eq(peerMatchFilter.getBytes()), eq(rangedDistance),
- anyInt(), isNull(), isNull(), isNull());
+ anyInt(), isNull(), isNull(), isNull(), isNull());
inOrderM.verify(mAwareMetricsMock).recordMatchIndicationForRangeEnabledSubscribe(true);
int peerId2 = peerIdCaptor.getValue();
@@ -2134,11 +2146,11 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
eq(subscribeConfig), isNull());
mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
- peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null);
+ peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), eq(peerSsi.getBytes()),
- eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull());
+ eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull(), isNull());
// (3) send message to invalid peer ID
mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue() + 5,
@@ -2203,11 +2215,11 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
eq(subscribeConfig), isNull());
mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
- peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null);
+ peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), eq(peerSsi.getBytes()),
- eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull());
+ eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull(), isNull());
// (3) send 2 messages and enqueue successfully
mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
@@ -2329,11 +2341,11 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
eq(subscribeConfig), isNull());
mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
- peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null);
+ peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), eq(peerSsi.getBytes()),
- eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull());
+ eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull(), isNull());
// (3) send message and enqueue successfully
mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
@@ -2416,11 +2428,11 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
eq(subscribeConfig), isNull());
mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
- peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null);
+ peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), eq(peerSsi.getBytes()),
- eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull());
+ eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull(), isNull());
// (3) send message and enqueue successfully
mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
@@ -2509,10 +2521,10 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (2) match
mDut.onMatchNotification(subscribeId, requestorId, peerMac, null, null, 0, 0,
- null, 0, null, null, null);
+ null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), isNull(), isNull(),
- anyInt(), isNull(), isNull(), isNull());
+ anyInt(), isNull(), isNull(), isNull(), isNull());
// (3) transmit messages
SendMessageQueueModelAnswer answerObj = new SendMessageQueueModelAnswer(queueDepth,
@@ -2643,16 +2655,16 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (2) match
mDut.onMatchNotification(subscribeId1, requestorId1, peerMac1, null, null, 0, 0,
- null, 0, null, null, null);
+ null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor1.capture(), isNull(), isNull(),
- anyInt(), isNull(), isNull(), isNull());
+ anyInt(), isNull(), isNull(), isNull(), isNull());
mDut.onMatchNotification(subscribeId2, requestorId2, peerMac2, null, null, 0, 0,
- null, 0, null, null, null);
+ null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor2.capture(), isNull(), isNull(),
- anyInt(), isNull(), isNull(), isNull());
+ anyInt(), isNull(), isNull(), isNull(), isNull());
// (3) Enqueue messages
SendMessageQueueModelAnswer answerObj = new SendMessageQueueModelAnswer(queueDepth,
@@ -2768,10 +2780,10 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (2) match
mDut.onMatchNotification(subscribeId, requestorId, peerMac, null, null, 0, 0,
- null, 0, null, null, null);
+ null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), isNull(), isNull(),
- anyInt(), isNull(), isNull(), isNull());
+ anyInt(), isNull(), isNull(), isNull(), isNull());
// (3) transmit messages: configure a mix of failures/success
Set<Integer> failQueueCommandImmediately = new HashSet<>();
@@ -2903,10 +2915,10 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (2) match
mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
- peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null);
+ peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), eq(peerSsi.getBytes()),
- eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull());
+ eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull(), isNull());
// (3) message null Tx successful queuing
mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
@@ -3055,6 +3067,12 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
}
}
+ private List<OuiKeyedData> generateVendorData(int oui) {
+ OuiKeyedData vendorDataElement =
+ new OuiKeyedData.Builder(oui, new PersistableBundle()).build();
+ return Arrays.asList(vendorDataElement);
+ }
+
/**
* Test sequence of configuration: (1) config1, (2) config2 - incompatible,
* (3) config3 - compatible with config1 (requiring upgrade), (4) disconnect
@@ -3075,15 +3093,20 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final int dwInterval1Band24 = 2;
final int dwInterval3Band24 = 1;
final int dwInterval3Band5 = 0;
+ final List<OuiKeyedData> vendorData1 = generateVendorData(1);
+ final List<OuiKeyedData> vendorData3 = generateVendorData(3);
ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
ArgumentCaptor<ConfigRequest> crCapture = ArgumentCaptor.forClass(ConfigRequest.class);
- ConfigRequest configRequest1 = new ConfigRequest.Builder()
+ ConfigRequest.Builder builder = new ConfigRequest.Builder()
.setClusterLow(5).setClusterHigh(100)
.setMasterPreference(masterPref1)
- .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwInterval1Band24)
- .build();
+ .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwInterval1Band24);
+ if (SdkLevel.isAtLeastV()) {
+ builder.setVendorData(vendorData1);
+ }
+ ConfigRequest configRequest1 = builder.build();
ConfigRequest configRequest2 = new ConfigRequest.Builder()
.setSupport5gBand(true) // compatible
@@ -3092,7 +3115,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
.setMasterPreference(0) // compatible
.build();
- ConfigRequest configRequest3 = new ConfigRequest.Builder()
+ builder = new ConfigRequest.Builder()
.setSupport5gBand(true) // compatible (will use true)
.setSupport6gBand(false)
.setClusterLow(5).setClusterHigh(100) // identical (hence compatible)
@@ -3100,8 +3123,11 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// compatible: will use min
.setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwInterval3Band24)
// compatible: will use interval3 since interval1 not init
- .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwInterval3Band5)
- .build();
+ .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwInterval3Band5);
+ if (SdkLevel.isAtLeastV()) {
+ builder.setVendorData(vendorData3);
+ }
+ ConfigRequest configRequest3 = builder.build();
IWifiAwareEventCallback mockCallback1 = mock(IWifiAwareEventCallback.class);
IWifiAwareEventCallback mockCallback2 = mock(IWifiAwareEventCallback.class);
@@ -3155,6 +3181,11 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
collector.checkThat("dw interval on 5: ~min", dwInterval3Band5,
equalTo(crCapture.getValue().mDiscoveryWindowInterval[ConfigRequest
.NAN_BAND_5GHZ]));
+ if (SdkLevel.isAtLeastV()) {
+ // Vendor data from the provided ConfigRequest should be prioritized during the merge
+ collector.checkThat("merge: vendor data 3", crCapture.getValue().getVendorData(),
+ equalTo(vendorData3));
+ }
// (4) disconnect config3: downgrade to config1
mDut.disconnect(clientId3);
@@ -3469,7 +3500,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mDut.onMessageSendQueuedFailResponse(transactionIdConfig, -1);
mDut.onSessionConfigFailResponse(transactionIdConfig, false, -1);
mDut.onMatchNotification(-1, -1, new byte[0], new byte[0], new byte[0], 0, 0, null, 0, null,
- null, null);
+ null, null, null);
mDut.onSessionTerminatedNotification(-1, -1, true);
mDut.onSessionTerminatedNotification(-1, -1, false);
mDut.onMessageReceivedNotification(-1, -1, new byte[0], new byte[0]);
@@ -4177,20 +4208,20 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (2) 2 matches : with and w/o range
mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
- peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null);
+ peerMatchFilter.getBytes(), 0, 0, null, 0, null, null, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), eq(peerSsi.getBytes()),
- eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull());
+ eq(peerMatchFilter.getBytes()), anyInt(), isNull(), isNull(), isNull(), isNull());
inOrderM.verify(mAwareMetricsMock).recordMatchIndicationForRangeEnabledSubscribe(false);
int peerId1 = peerIdCaptor.getValue();
mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
peerMatchFilter.getBytes(), EGRESS_MET_MASK, rangedDistance, null, 0, null, null,
- null);
+ null, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatchWithDistance(peerIdCaptor.capture(),
eq(peerSsi.getBytes()), eq(peerMatchFilter.getBytes()), eq(rangedDistance),
- anyInt(), isNull(), isNull(), isNull());
+ anyInt(), isNull(), isNull(), isNull(), isNull());
inOrderM.verify(mAwareMetricsMock).recordMatchIndicationForRangeEnabledSubscribe(true);
int peerId2 = peerIdCaptor.getValue();
@@ -4633,7 +4664,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mMockLooper.dispatchAll();
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).respondToBootstrappingRequest(transactionId.capture(),
- eq(bootstrappingId), eq(true));
+ eq(bootstrappingId), eq(true), eq(publishId));
mDut.onRespondToBootstrappingIndicationResponseSuccess(transactionId.getValue());
mMockLooper.dispatchAll();
verify(mockSessionCallback).onBootstrappingVerificationConfirmed(peerIdCaptor.capture(),
@@ -4891,10 +4922,10 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (3) Match peer
mDut.onMatchNotification(subscribeId, peerId, peerMac, null, null, 0, 0, null, 0, null,
- null, pairingConfig);
+ null, pairingConfig, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), isNull(),
- isNull(), anyInt(), isNull(), isNull(), any());
+ isNull(), anyInt(), isNull(), isNull(), any(), isNull());
// (4) Initiate bootstrapping request
mDut.initiateBootStrappingSetupRequest(clientId, sessionId.getValue(),
@@ -4902,7 +4933,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).initiateBootstrapping(transactionId.capture(), eq(peerId),
- eq(peerMac), eq(AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN), isNull());
+ eq(peerMac), eq(AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN), isNull(),
+ eq(subscribeId), eq(false));
mDut.onInitiateBootStrappingResponseSuccess(transactionId.getValue(), bootstrappingId);
mDut.onBootstrappingConfirmNotification(bootstrappingId,
WifiAwareStateManager.NAN_BOOTSTRAPPING_ACCEPT, NanStatusCode.SUCCESS, 0, null);
@@ -5027,10 +5059,10 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (3) Match peer
mDut.onMatchNotification(subscribeId, peerId, peerMac1, null, null, 0, 0, null, 0, null,
- null, pairingConfig);
+ null, pairingConfig, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), isNull(),
- isNull(), anyInt(), isNull(), eq(alias), any());
+ isNull(), anyInt(), isNull(), eq(alias), any(), isNull());
int localPeerId = peerIdCaptor.getValue();
// (4) Initiate pairing setup request
@@ -5145,10 +5177,10 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (3) Match peer
mDut.onMatchNotification(subscribeId, peerId, peerMac, null, null, 0, 0, null, 0, null,
- null, pairingConfig);
+ null, pairingConfig, null);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor.capture(), isNull(),
- isNull(), anyInt(), isNull(), isNull(), any());
+ isNull(), anyInt(), isNull(), isNull(), any(), isNull());
// (3) Initiate bootstrapping request
mDut.initiateBootStrappingSetupRequest(clientId, sessionId.getValue(),
@@ -5156,7 +5188,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).initiateBootstrapping(transactionId.capture(), eq(peerId),
- eq(peerMac), eq(AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN), isNull());
+ eq(peerMac), eq(AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN), isNull(),
+ eq(subscribeId), eq(false));
mDut.onInitiateBootStrappingResponseSuccess(transactionId.getValue(), bootstrappingId);
// (4) Receive comeback respond, will send the request again with delay
@@ -5169,7 +5202,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
Thread.sleep(1000);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).initiateBootstrapping(transactionId.capture(), eq(peerId),
- eq(peerMac), eq(AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN), isNull());
+ eq(peerMac), eq(AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN), isNull(),
+ eq(subscribeId), eq(true));
mDut.onInitiateBootStrappingResponseSuccess(transactionId.getValue(), bootstrappingId + 1);
// (5) Receive comeback respond on the followup request, will consider reject and notify the
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
new file mode 100644
index 0000000000..f4b7bfc212
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/b2b/WifiRoamingModeManagerTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.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;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+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;
+import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.WifiRoamingConfigStore;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.b2b.WifiRoamingModeManager}.
+ */
+@SmallTest
+public class WifiRoamingModeManagerTest extends WifiBaseTest {
+ private static final String TEST_SSID = "\"test_ssid\"";
+ private static final String CURRENT_SSID = "\"current_ssid\"";
+ private static final String WIFI_IFACE_NAME = "wlan0";
+ private static final int DEFAULT_ROAMING_MODE = WifiManager.ROAMING_MODE_NORMAL;
+ private static final int TEST_ROAMING_MODE = WifiManager.ROAMING_MODE_AGGRESSIVE;
+ @Mock ActiveModeWarden mActiveModeWarden;
+ @Mock ClientModeManager mClientModeManager;
+ @Mock WifiInfo mWifiInfo;
+ @Mock WifiNative mWifiNative;
+ @Mock WifiRoamingConfigStore mWifiRoamingConfigStore;
+
+ WifiRoamingModeManager mWifiRoamingModeManager;
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mWifiRoamingModeManager = new WifiRoamingModeManager(mWifiNative,
+ mActiveModeWarden, mWifiRoamingConfigStore);
+ when(mActiveModeWarden.getConnectionInfo()).thenReturn(mWifiInfo);
+ when(mWifiInfo.getSSID()).thenReturn(CURRENT_SSID);
+ when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mClientModeManager);
+ when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
+ }
+
+ @Test
+ public void testSetPerSsidRoamingMode() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mWifiRoamingConfigStore.getRoamingMode(CURRENT_SSID)).thenReturn(
+ TEST_ROAMING_MODE);
+ mWifiRoamingModeManager.setPerSsidRoamingMode(WifiSsid.fromString(CURRENT_SSID),
+ TEST_ROAMING_MODE, false);
+ verify(mWifiRoamingConfigStore).addRoamingMode(CURRENT_SSID, TEST_ROAMING_MODE, false);
+ verify(mActiveModeWarden).getConnectionInfo();
+ // set roaming mode when current network is the updated network
+ verify(mWifiNative).setRoamingMode(WIFI_IFACE_NAME, TEST_ROAMING_MODE);
+ }
+
+ @Test
+ public void testRemovePerSsidRoamingMode() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ mWifiRoamingModeManager.removePerSsidRoamingMode(WifiSsid.fromString(TEST_SSID), false);
+ verify(mWifiRoamingConfigStore).removeRoamingMode(TEST_SSID, false);
+ verify(mActiveModeWarden).getConnectionInfo();
+ // do not set roaming mode when current network is not the updated network
+ verify(mWifiNative, never()).setRoamingMode(anyString(), anyInt());
+ }
+
+ @Test
+ public void testGetPerSsidRoamingMode() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ mWifiRoamingModeManager.getPerSsidRoamingModes(false);
+ verify(mWifiRoamingConfigStore).getPerSsidRoamingModes(false);
+ verify(mActiveModeWarden, never()).getConnectionInfo();
+ }
+
+ @Test
+ public void testApplyWifiRoamingMode() {
+ when(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID)).thenReturn(
+ DEFAULT_ROAMING_MODE);
+ mWifiRoamingModeManager.applyWifiRoamingMode(WIFI_IFACE_NAME, TEST_SSID);
+ verify(mWifiNative).setRoamingMode(WIFI_IFACE_NAME, DEFAULT_ROAMING_MODE);
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/entitlement/PseudonymInfoTest.java b/service/tests/wifitests/src/com/android/server/wifi/entitlement/PseudonymInfoTest.java
index a608780bdf..d89a268dec 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/entitlement/PseudonymInfoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/entitlement/PseudonymInfoTest.java
@@ -23,7 +23,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import android.test.suitebuilder.annotation.SmallTest;
+import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -53,7 +53,10 @@ public class PseudonymInfoTest {
PseudonymInfo pseudonymInfo = new PseudonymInfo(PSEUDONYM, IMSI, TTL_IN_MILLIS);
assertEquals(PSEUDONYM, pseudonymInfo.getPseudonym());
assertEquals(TTL_IN_MILLIS, pseudonymInfo.getTtlInMillis());
- assertEquals(TTL_IN_MILLIS - REFRESH_AHEAD_TIME_IN_MILLIS, pseudonymInfo.getLttrInMillis());
+ final long delta = Math.abs(TTL_IN_MILLIS - REFRESH_AHEAD_TIME_IN_MILLIS
+ - pseudonymInfo.getLttrInMillis());
+ assertTrue("(" + delta + ") not in 1ms error margin",
+ delta < 2);
assertFalse(pseudonymInfo.hasExpired());
assertFalse(pseudonymInfo.isOldEnoughToRefresh());
}
@@ -81,6 +84,9 @@ public class PseudonymInfoTest {
public void pseudonymInfoWithSmallTtl() {
PseudonymInfo pseudonymInfo =
new PseudonymInfo(PSEUDONYM, IMSI, TWENTY_MINUTES_IN_MILLIS);
- assertTrue(pseudonymInfo.getLttrInMillis() == TWENTY_MINUTES_IN_MILLIS / 2);
+ final long delta = Math.abs(TWENTY_MINUTES_IN_MILLIS / 2
+ - pseudonymInfo.getLttrInMillis());
+ assertTrue("(" + delta + ") not in 1ms error margin",
+ delta < 2);
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/HalTestUtils.java b/service/tests/wifitests/src/com/android/server/wifi/hal/HalTestUtils.java
index abd1b1cc40..724e7cebcd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hal/HalTestUtils.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/HalTestUtils.java
@@ -20,9 +20,21 @@ import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.when;
+import android.hardware.wifi.common.OuiKeyedData;
+import android.net.wifi.util.PersistableBundleUtils;
+import android.os.PersistableBundle;
+
+import java.util.ArrayList;
+import java.util.List;
import java.util.function.Supplier;
public class HalTestUtils {
+ private static final String BUNDLE_STRING_FIELD_KEY = "stringField";
+ private static final String BUNDLE_ARRAY_FIELD_KEY = "arrayField";
+
+ private static final String BUNDLE_STRING_FIELD_VALUE = "someString";
+ private static final int[] BUNDLE_ARRAY_FIELD_VALUE = new int[] {1, 2, 3};
+
/**
* Check that we get the expected return value when the specified method is called.
*
@@ -35,4 +47,67 @@ public class HalTestUtils {
T retrievedValue = calledMethod.get();
assertEquals(value, retrievedValue);
}
+
+ /**
+ * Generate a single PersistableBundle containing several test fields.
+ */
+ private static PersistableBundle createTestPersistableBundle() {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putString(BUNDLE_STRING_FIELD_KEY, BUNDLE_STRING_FIELD_VALUE);
+ bundle.putIntArray(BUNDLE_ARRAY_FIELD_KEY, BUNDLE_ARRAY_FIELD_VALUE);
+ return bundle;
+ }
+
+ /**
+ * Generate a list of HAL OuiKeyedData objects, each containing several test fields.
+ */
+ public static OuiKeyedData[] createHalOuiKeyedDataList(int size) {
+ OuiKeyedData[] ouiKeyedDataList = new OuiKeyedData[size];
+ for (int i = 0; i < size; i++) {
+ OuiKeyedData ouiKeyedData = new OuiKeyedData();
+ ouiKeyedData.oui = i + 1;
+ ouiKeyedData.vendorData = createTestPersistableBundle();
+ ouiKeyedDataList[i] = ouiKeyedData;
+ }
+ return ouiKeyedDataList;
+ }
+
+ /**
+ * Generate a list of framework OuiKeyedData objects, each containing several test fields.
+ */
+ public static List<android.net.wifi.OuiKeyedData> createFrameworkOuiKeyedDataList(int size) {
+ List<android.net.wifi.OuiKeyedData> ouiKeyedDataList = new ArrayList<>();
+ for (int i = 0; i < size; i++) {
+ android.net.wifi.OuiKeyedData ouiKeyedData = new android.net.wifi.OuiKeyedData.Builder(
+ i + 1, createTestPersistableBundle()).build();
+ ouiKeyedDataList.add(ouiKeyedData);
+ }
+ return ouiKeyedDataList;
+ }
+
+ /**
+ * Check whether a HAL and framework OuiKeyedData object are equivalent.
+ */
+ public static boolean ouiKeyedDataEquals(
+ OuiKeyedData halData, android.net.wifi.OuiKeyedData frameworkData) {
+ return halData.oui == frameworkData.getOui()
+ && PersistableBundleUtils.isEqual(halData.vendorData, frameworkData.getData());
+ }
+
+ /**
+ * Check whether a list of HAL and framework OuiKeyedData objects are equivalent.
+ */
+ public static boolean ouiKeyedDataListEquals(
+ OuiKeyedData[] halDataList, List<android.net.wifi.OuiKeyedData> frameworkDataList) {
+ if (halDataList.length != frameworkDataList.size()) {
+ return false;
+ }
+
+ for (int i = 0; i < halDataList.length; i++) {
+ if (!ouiKeyedDataEquals(halDataList[i], frameworkDataList.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
}
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 0786e60bac..192c97ac8f 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
@@ -45,15 +45,19 @@ import android.hardware.wifi.NanRangingIndication;
import android.hardware.wifi.NanRespondToPairingIndicationRequest;
import android.hardware.wifi.NanSubscribeRequest;
import android.net.MacAddress;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.aware.ConfigRequest;
import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.SubscribeConfig;
import android.net.wifi.aware.WifiAwareDataPathSecurityConfig;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.util.Pair;
+import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.aware.Capabilities;
+import com.android.server.wifi.util.HalAidlUtil;
import org.junit.Before;
import org.junit.Rule;
@@ -63,6 +67,10 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
private static final Capabilities TEST_CAPABILITIES = new Capabilities();
@@ -79,6 +87,39 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
| WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
}
+ private static OuiKeyedData generateFrameworkOuiKeyedData(int oui) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putString("stringKey", "stringValue");
+ bundle.putInt("intKey", 789);
+ return new OuiKeyedData.Builder(oui, bundle).build();
+ }
+
+ private static List<OuiKeyedData> generateFrameworkOuiKeyedDataList(int size) {
+ List<OuiKeyedData> dataList = new ArrayList<>();
+ for (int i = 0; i < size; i++) {
+ dataList.add(generateFrameworkOuiKeyedData(i + 1));
+ }
+ return dataList;
+ }
+
+ private static boolean compareHalOuiKeyedData(android.hardware.wifi.common.OuiKeyedData left,
+ android.hardware.wifi.common.OuiKeyedData right) {
+ return left.oui == right.oui && Objects.equals(left.vendorData, right.vendorData);
+ }
+
+ private static boolean compareHalOuiKeyedDataList(
+ android.hardware.wifi.common.OuiKeyedData[] left,
+ android.hardware.wifi.common.OuiKeyedData[] right) {
+ // Assume both values are non-null
+ if (left.length != right.length) return false;
+ for (int i = 0; i < left.length; i++) {
+ if (!compareHalOuiKeyedData(left[i], right[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
@Test
public void testDiscoveryRangingSettings() throws RemoteException {
short tid = 250;
@@ -87,6 +128,9 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
int maxDistanceMm = 555;
short minDistanceCm = (short) (minDistanceMm / 10);
short maxDistanceCm = (short) (maxDistanceMm / 10);
+ List<OuiKeyedData> frameworkVendorData = generateFrameworkOuiKeyedDataList(5);
+ android.hardware.wifi.common.OuiKeyedData[] halVendorData =
+ HalAidlUtil.frameworkToHalOuiKeyedDataList(frameworkVendorData);
ArgumentCaptor<NanPublishRequest> pubCaptor = ArgumentCaptor.forClass(
NanPublishRequest.class);
@@ -104,6 +148,22 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
SubscribeConfig subWithMinMax = new SubscribeConfig.Builder().setServiceName(
"XXX").setMinDistanceMm(minDistanceMm).setMaxDistanceMm(maxDistanceMm).build();
+ PublishConfig pubWithVendorData = null;
+ SubscribeConfig subWithVendorData = null;
+ if (SdkLevel.isAtLeastV()) {
+ pubWithVendorData = new PublishConfig.Builder()
+ .setServiceName("XXX")
+ .setVendorData(frameworkVendorData)
+ .build();
+ subWithVendorData = new SubscribeConfig.Builder()
+ .setServiceName("XXX")
+ .setVendorData(frameworkVendorData)
+ .build();
+ }
+
+ int numPublishExpected = 2;
+ int numSubscribeExpected = 4;
+
assertTrue(mDut.publish(tid, pid, pubDefault, null));
assertTrue(mDut.publish(tid, pid, pubWithRanging, null));
assertTrue(mDut.subscribe(tid, pid, subDefault, null));
@@ -111,9 +171,16 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
assertTrue(mDut.subscribe(tid, pid, subWithMax, null));
assertTrue(mDut.subscribe(tid, pid, subWithMinMax, null));
- verify(mIWifiNanIfaceMock, times(2))
+ if (SdkLevel.isAtLeastV()) {
+ assertTrue(mDut.publish(tid, pid, pubWithVendorData, null));
+ assertTrue(mDut.subscribe(tid, pid, subWithVendorData, null));
+ numPublishExpected += 1;
+ numSubscribeExpected += 1;
+ }
+
+ verify(mIWifiNanIfaceMock, times(numPublishExpected))
.startPublishRequest(eq((char) tid), pubCaptor.capture());
- verify(mIWifiNanIfaceMock, times(4))
+ verify(mIWifiNanIfaceMock, times(numSubscribeExpected))
.startSubscribeRequest(eq((char) tid), subCaptor.capture());
NanPublishRequest halPubReq;
@@ -176,6 +243,13 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
equalTo((short) halSubReq.baseConfigs.distanceEgressCm));
collector.checkThat("subWithMin.baseConfigs.distanceIngressCm", maxDistanceCm,
equalTo((short) halSubReq.baseConfigs.distanceIngressCm));
+
+ if (SdkLevel.isAtLeastV()) {
+ halPubReq = pubCaptor.getAllValues().get(2);
+ halSubReq = subCaptor.getAllValues().get(4);
+ assertTrue(compareHalOuiKeyedDataList(halVendorData, halPubReq.vendorData));
+ assertTrue(compareHalOuiKeyedDataList(halVendorData, halSubReq.vendorData));
+ }
}
/**
@@ -476,10 +550,11 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
@Test
public void testInitiateNanBootstrappingRequest() throws Exception {
short tid = 251;
+ byte pid = 34;
MacAddress peer = MacAddress.fromString("00:01:02:03:04:05");
ArgumentCaptor<NanBootstrappingRequest> reqCaptor = ArgumentCaptor.forClass(
NanBootstrappingRequest.class);
- assertTrue(mDut.initiateNanBootstrappingRequest(tid, 1, peer, 2, null));
+ assertTrue(mDut.initiateNanBootstrappingRequest(tid, 1, peer, 2, null, pid, false));
verify(mIWifiNanIfaceMock).initiateBootstrappingRequest(eq((char) tid),
reqCaptor.capture());
NanBootstrappingRequest request = reqCaptor.getValue();
@@ -487,19 +562,22 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
assertEquals(2, request.requestBootstrappingMethod);
assertArrayEquals(peer.toByteArray(), request.peerDiscMacAddr);
assertArrayEquals(new byte[0], request.cookie);
+ assertEquals(pid, request.discoverySessionId);
}
@Test
public void testRespondToNanBootstrappingRequest() throws Exception {
short tid = 251;
+ byte pid = 34;
ArgumentCaptor<NanBootstrappingResponse> reqCaptor = ArgumentCaptor.forClass(
NanBootstrappingResponse.class);
- assertTrue(mDut.respondToNanBootstrappingRequest(tid, 1, true));
+ assertTrue(mDut.respondToNanBootstrappingRequest(tid, 1, true, pid));
verify(mIWifiNanIfaceMock).respondToBootstrappingIndicationRequest(eq((char) tid),
reqCaptor.capture());
NanBootstrappingResponse request = reqCaptor.getValue();
assertEquals(1, request.bootstrappingInstanceId);
assertTrue(request.acceptRequest);
+ assertEquals(pid, request.discoverySessionId);
}
// utilities
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 ef10eff7c0..6b541a7bd3 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
@@ -38,6 +38,7 @@ import android.hardware.wifi.RttType;
import android.hardware.wifi.WifiChannelWidthInMhz;
import android.hardware.wifi.WifiInformationElement;
import android.net.MacAddress;
+import android.net.wifi.ScanResult;
import android.net.wifi.rtt.RangingRequest;
import android.net.wifi.rtt.RangingResult;
import android.net.wifi.rtt.ResponderConfig;
@@ -89,6 +90,42 @@ public class WifiRttControllerAidlImplTest extends WifiBaseTest {
}
/**
+ * Verify RTT burst duration with respect to different burst sizes.
+ */
+ @Test
+ public void testBurstDuration() throws Exception {
+ int cmdId = 55;
+ RangingRequest request = RttTestUtils.getDummyRangingRequestMcOnly((byte) 0, 8);
+ mDut.rangeRequest(cmdId, request);
+ verify(mIWifiRttControllerMock).rangeRequest(eq(cmdId), mRttConfigCaptor.capture());
+ RttConfig[] halRequest = mRttConfigCaptor.getValue();
+ RttConfig rttConfig = halRequest[0];
+ collector.checkThat("(1) Rtt burst size", rttConfig.numFramesPerBurst, equalTo(8));
+ collector.checkThat("(1) Rtt burst duration", rttConfig.burstDuration, equalTo(9));
+
+ cmdId = 56;
+ request = RttTestUtils.getDummyRangingRequestMcOnly((byte) 0, 20);
+ mDut.rangeRequest(cmdId, request);
+ verify(mIWifiRttControllerMock).rangeRequest(eq(cmdId), mRttConfigCaptor.capture());
+ halRequest = mRttConfigCaptor.getValue();
+ rttConfig = halRequest[0];
+ collector.checkThat("(2) Rtt burst size", rttConfig.numFramesPerBurst, equalTo(20));
+ collector.checkThat("(2) Rtt burst duration", rttConfig.burstDuration, equalTo(10));
+
+ cmdId = 57;
+ request = RttTestUtils.getDummyRangingRequestMcOnly((byte) 0, 30);
+ mDut.rangeRequest(cmdId, request);
+ verify(mIWifiRttControllerMock).rangeRequest(eq(cmdId), mRttConfigCaptor.capture());
+ halRequest = mRttConfigCaptor.getValue();
+ rttConfig = halRequest[0];
+ collector.checkThat("(3) Rtt burst size", rttConfig.numFramesPerBurst, equalTo(30));
+ collector.checkThat("(3) Rtt burst duration", rttConfig.burstDuration, equalTo(11));
+
+ verifyNoMoreInteractions(mIWifiRttControllerMock);
+
+ }
+
+ /**
* Validate successful ranging flow.
*/
@Test
@@ -286,6 +323,7 @@ public class WifiRttControllerAidlImplTest extends WifiBaseTest {
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
@@ -306,7 +344,8 @@ public class WifiRttControllerAidlImplTest extends WifiBaseTest {
equalTo(MacAddress.fromString("05:06:07:08:09:0A").toByteArray()));
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);
}
@@ -350,12 +389,20 @@ public class WifiRttControllerAidlImplTest extends WifiBaseTest {
public void testRangingWithInvalidParameterCombination() throws Exception {
int cmdId = 88;
RangingRequest request = new RangingRequest.Builder().build();
- ResponderConfig invalidConfig = new ResponderConfig(
- MacAddress.fromString("08:09:08:07:06:88"), ResponderConfig.RESPONDER_AP, true,
- ResponderConfig.CHANNEL_WIDTH_80MHZ, 0, 0, 0, ResponderConfig.PREAMBLE_HT);
- ResponderConfig config = new ResponderConfig(
- MacAddress.fromString("08:09:08:07:06:89"), ResponderConfig.RESPONDER_AP, true,
- ResponderConfig.CHANNEL_WIDTH_80MHZ, 0, 0, 0, ResponderConfig.PREAMBLE_VHT);
+ ResponderConfig invalidConfig = new ResponderConfig.Builder()
+ .setMacAddress(MacAddress.fromString("08:09:08:07:06:88"))
+ .setResponderType(ResponderConfig.RESPONDER_AP)
+ .set80211mcSupported(true)
+ .setChannelWidth(ScanResult.CHANNEL_WIDTH_80MHZ)
+ .setPreamble(ScanResult.PREAMBLE_HT)
+ .build();
+ ResponderConfig config = new ResponderConfig.Builder()
+ .setMacAddress(MacAddress.fromString("08:09:08:07:06:89"))
+ .setResponderType(ResponderConfig.RESPONDER_AP)
+ .set80211mcSupported(true)
+ .setChannelWidth(ScanResult.CHANNEL_WIDTH_80MHZ)
+ .setPreamble(ScanResult.PREAMBLE_VHT)
+ .build();
// Add a ResponderConfig with invalid parameter, should be ignored.
request.mRttPeers.add(invalidConfig);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerHidlImplTest.java
index 632776095b..fdd63d31e1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerHidlImplTest.java
@@ -41,6 +41,7 @@ import android.hardware.wifi.V1_0.WifiChannelWidthInMhz;
import android.hardware.wifi.V1_0.WifiStatus;
import android.hardware.wifi.V1_0.WifiStatusCode;
import android.net.MacAddress;
+import android.net.wifi.ScanResult;
import android.net.wifi.rtt.RangingRequest;
import android.net.wifi.rtt.RangingResult;
import android.net.wifi.rtt.ResponderConfig;
@@ -366,12 +367,20 @@ public class WifiRttControllerHidlImplTest extends WifiBaseTest {
public void testRangingWithInvalidParameterCombination() throws Exception {
int cmdId = 88;
RangingRequest request = new RangingRequest.Builder().build();
- ResponderConfig invalidConfig = new ResponderConfig(
- MacAddress.fromString("08:09:08:07:06:88"), ResponderConfig.RESPONDER_AP, true,
- ResponderConfig.CHANNEL_WIDTH_80MHZ, 0, 0, 0, ResponderConfig.PREAMBLE_HT);
- ResponderConfig config = new ResponderConfig(MacAddress.fromString("08:09:08:07:06:89"),
- ResponderConfig.RESPONDER_AP, true,
- ResponderConfig.CHANNEL_WIDTH_80MHZ, 0, 0, 0, ResponderConfig.PREAMBLE_VHT);
+ ResponderConfig invalidConfig = new ResponderConfig.Builder()
+ .setMacAddress(MacAddress.fromString("08:09:08:07:06:88"))
+ .setResponderType(ResponderConfig.RESPONDER_AP)
+ .set80211mcSupported(true)
+ .setChannelWidth(ScanResult.CHANNEL_WIDTH_80MHZ)
+ .setPreamble(ScanResult.PREAMBLE_HT)
+ .build();
+ ResponderConfig config = new ResponderConfig.Builder()
+ .setMacAddress(MacAddress.fromString("08:09:08:07:06:89"))
+ .setResponderType(ResponderConfig.RESPONDER_AP)
+ .set80211mcSupported(true)
+ .setChannelWidth(ScanResult.CHANNEL_WIDTH_80MHZ)
+ .setPreamble(ScanResult.PREAMBLE_VHT)
+ .build();
// Add a ResponderConfig with invalid parameter, should be ignored.
request.mRttPeers.add(invalidConfig);
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 0ed10caca4..95b978eb01 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
@@ -19,11 +19,14 @@ package com.android.server.wifi.hal;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
+import android.hardware.wifi.CachedScanData;
+import android.hardware.wifi.CachedScanResult;
import android.hardware.wifi.IWifiStaIface;
import android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats;
import android.hardware.wifi.StaLinkLayerIfacePacketStats;
@@ -34,8 +37,10 @@ import android.hardware.wifi.StaLinkLayerStats;
import android.hardware.wifi.StaPeerInfo;
import android.hardware.wifi.StaRateStat;
import android.hardware.wifi.StaRoamingCapabilities;
+import android.hardware.wifi.StaRoamingState;
import android.hardware.wifi.WifiChannelInfo;
import android.hardware.wifi.WifiChannelStats;
+import android.hardware.wifi.WifiChannelWidthInMhz;
import android.hardware.wifi.WifiDebugPacketFateFrameInfo;
import android.hardware.wifi.WifiDebugPacketFateFrameType;
import android.hardware.wifi.WifiDebugRxPacketFate;
@@ -43,7 +48,12 @@ import android.hardware.wifi.WifiDebugRxPacketFateReport;
import android.hardware.wifi.WifiDebugTxPacketFate;
import android.hardware.wifi.WifiDebugTxPacketFateReport;
import android.hardware.wifi.WifiRateInfo;
+import android.hardware.wifi.WifiRatePreamble;
+import android.hardware.wifi.WifiStatusCode;
+import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiScanner.ScanData;
+import android.net.wifi.WifiSsid;
import com.android.server.wifi.SsidTranslator;
import com.android.server.wifi.WifiBaseTest;
@@ -57,6 +67,7 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Random;
@@ -313,6 +324,52 @@ public class WifiStaIfaceAidlImplTest extends WifiBaseTest {
assertEquals(WifiNative.SET_FIRMWARE_ROAMING_FAILURE, mDut.setRoamingState(badState));
}
+ /**
+ * Test the retrieval of cached scan data
+ */
+ @Test
+ public void testGetCachedScanData() throws Exception {
+ CachedScanData halData = new CachedScanData();
+ CachedScanResult[] halResults = new CachedScanResult[2];
+ CachedScanResult halResult = new CachedScanResult();
+ halData.cachedScanResults = halResults;
+ halResults[0] = halResult;
+ halResult.timeStampInUs = 10_000_000;
+ halResult.bssid = new byte[]{0x61, 0x52, 0x43, 0x34, 0x25, 0x16};
+ String test_ssid = "Test SSID";
+ halResult.ssid = test_ssid.getBytes(StandardCharsets.UTF_8);
+ halResult.rssiDbm = -80;
+ halResult.frequencyMhz = 5260;
+ halResult.channelWidthMhz = WifiChannelWidthInMhz.WIDTH_80;
+ halResult.preambleType = WifiRatePreamble.HE;
+
+ when(mIWifiStaIfaceMock.getCachedScanData())
+ .thenReturn(halData);
+ when(mSsidTranslatorMock.getTranslatedSsidAndRecordBssidCharset(any(), any()))
+ .thenReturn(WifiSsid.fromBytes(halResult.ssid));
+
+ ScanData scanData = mDut.getCachedScanData();
+ ScanResult[] scanResults = scanData.getResults();
+ assertEquals(1, scanResults.length);
+ assertEquals(10_000_000, scanResults[0].timestamp);
+ assertEquals(-80, scanResults[0].level);
+ assertEquals(5260, scanResults[0].frequency);
+ assertEquals(ScanResult.CHANNEL_WIDTH_80MHZ, scanResults[0].channelWidth);
+ assertEquals(ScanResult.WIFI_STANDARD_11AX, scanResults[0].getWifiStandard());
+ assertEquals("61:52:43:34:25:16", scanResults[0].BSSID);
+ }
+
+ /**
+ * Tests setRoamingMode.
+ */
+ @Test
+ public void testSetRoamingMode() throws Exception {
+ final int invalidRoamingMode = -1;
+ assertEquals(WifiStatusCode.ERROR_INVALID_ARGS, mDut.setRoamingMode(invalidRoamingMode));
+
+ assertEquals(WifiStatusCode.SUCCESS, mDut.setRoamingMode(WifiManager.ROAMING_MODE_NORMAL));
+ verify(mIWifiStaIfaceMock).setRoamingState(StaRoamingState.ENABLED);
+ }
// Utilities
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImplTest.java
index b4a3cb03ca..208a01b912 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImplTest.java
@@ -20,6 +20,7 @@ import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTL
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -30,14 +31,20 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo;
import android.hardware.wifi.supplicant.P2pDeviceFoundEventParams;
+import android.hardware.wifi.supplicant.P2pGoNegotiationReqEventParams;
import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
+import android.hardware.wifi.supplicant.P2pInvitationEventParams;
+import android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams;
+import android.hardware.wifi.supplicant.P2pPeerClientJoinedEventParams;
import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
import android.hardware.wifi.supplicant.P2pProvisionDiscoveryCompletedEventParams;
import android.hardware.wifi.supplicant.P2pStatusCode;
import android.hardware.wifi.supplicant.WpsConfigMethods;
import android.hardware.wifi.supplicant.WpsDevPasswordId;
+import android.net.MacAddress;
import android.net.wifi.ScanResult;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
@@ -45,11 +52,14 @@ import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pProvDiscEvent;
import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
+import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
+import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.p2p.WifiP2pServiceImpl.P2pStatus;
+import com.android.server.wifi.util.HalAidlUtil;
import com.android.server.wifi.util.NativeUtil;
import org.junit.Before;
@@ -83,6 +93,7 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
private static final String DEVICE_ADDRESS_STR = "00:01:02:03:04:05";
private static final int TEST_NETWORK_ID = 9;
private static final int TEST_GROUP_FREQUENCY = 5400;
+ private static final int DEFAULT_SERVICE_VERSION = 2;
private byte[] mTestPrimaryDeviceTypeBytes = { 0x00, 0x01, 0x02, -1, 0x04, 0x05, 0x06, 0x07 };
private String mTestPrimaryDeviceTypeString = "1-02FF0405-1543";
private String mTestDeviceName = "test device name";
@@ -91,8 +102,9 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
private int mTestGroupCapabilities = 456;
private class SupplicantP2pIfaceCallbackImplSpy extends SupplicantP2pIfaceCallbackAidlImpl {
- SupplicantP2pIfaceCallbackImplSpy(String iface, WifiP2pMonitor monitor) {
- super(iface, monitor);
+ SupplicantP2pIfaceCallbackImplSpy(String iface, WifiP2pMonitor monitor,
+ int serviceVersion) {
+ super(iface, monitor, serviceVersion);
}
}
@@ -100,7 +112,11 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mMonitor = mock(WifiP2pMonitor.class);
- mDut = new SupplicantP2pIfaceCallbackImplSpy(mIface, mMonitor);
+ initializeDut(DEFAULT_SERVICE_VERSION);
+ }
+
+ private void initializeDut(int serviceVersion) {
+ mDut = new SupplicantP2pIfaceCallbackImplSpy(mIface, mMonitor, serviceVersion);
}
/**
@@ -150,6 +166,79 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
anyString(), any(WifiP2pDevice.class));
}
+ private static OuiKeyedData generateHalOuiKeyedData(int oui) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putString("stringKey", "stringValue");
+ bundle.putInt("intKey", 789);
+
+ OuiKeyedData data = new OuiKeyedData();
+ data.oui = oui;
+ data.vendorData = bundle;
+ return data;
+ }
+
+ private static OuiKeyedData[] generateHalOuiKeyedDataList(int size) {
+ OuiKeyedData[] dataList = new OuiKeyedData[size];
+ for (int i = 0; i < size; i++) {
+ dataList[i] = generateHalOuiKeyedData(i + 1);
+ }
+ return dataList;
+ }
+
+ /**
+ * Sunny day scenario for testOnDeviceFoundWithParams call.
+ */
+ @Test
+ public void testOnDeviceFoundWithParams_success() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ initializeDut(3 /* serviceVersion */);
+ byte[] fakePrimaryDeviceTypeBytes = { 0x00, 0x01, 0x02, -1, 0x04, 0x05, 0x06, 0x07 };
+ String fakePrimaryDeviceTypeString = "1-02FF0405-1543";
+ String fakeDeviceName = "test device name";
+ short fakeConfigMethods = 0x1234;
+ byte fakeCapabilities = 123;
+ int fakeGroupCapabilities = 456;
+ OuiKeyedData[] halVendorData = generateHalOuiKeyedDataList(5);
+
+ P2pDeviceFoundEventParams params = new P2pDeviceFoundEventParams();
+ params.srcAddress = mDeviceAddress1Bytes;
+ params.p2pDeviceAddress = mDeviceAddress2Bytes;
+ params.primaryDeviceType = fakePrimaryDeviceTypeBytes;
+ params.deviceName = fakeDeviceName;
+ params.configMethods = fakeConfigMethods;
+ params.deviceCapabilities = fakeCapabilities;
+ params.groupCapabilities = fakeGroupCapabilities;
+ params.wfdDeviceInfo = mDeviceInfoBytes;
+ params.vendorData = halVendorData;
+
+ doAnswer(new AnswerWithArguments() {
+ public void answer(String iface, WifiP2pDevice device) {
+ // NOTE: mDeviceAddress1Bytes seems to be ignored by
+ // legacy implementation of WifiP2pDevice.
+ assertEquals(iface, mIface);
+ assertEquals(device.deviceName, fakeDeviceName);
+ assertEquals(device.primaryDeviceType, fakePrimaryDeviceTypeString);
+ assertEquals(device.deviceCapability, fakeCapabilities);
+ assertEquals(device.groupCapability, fakeGroupCapabilities);
+ assertEquals(device.wpsConfigMethodsSupported, fakeConfigMethods);
+ assertEquals(device.deviceAddress, mDeviceAddress2String);
+ assertEquals(device.status, WifiP2pDevice.AVAILABLE);
+ assertEquals(device.getVendorData(),
+ HalAidlUtil.halToFrameworkOuiKeyedDataList(halVendorData));
+ }
+ }).when(mMonitor).broadcastP2pDeviceFound(
+ anyString(), any(WifiP2pDevice.class));
+
+ mDut.onDeviceFoundWithParams(params);
+
+ params.wfdDeviceInfo = null;
+ mDut.onDeviceFoundWithParams(params);
+
+ // Make sure we issued a broadcast each time.
+ verify(mMonitor, times(2)).broadcastP2pDeviceFound(
+ anyString(), any(WifiP2pDevice.class));
+ }
+
/**
* Sunny day scenario for onDeviceFound call with sign bit set in bytes.
*/
@@ -340,6 +429,60 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
anyString(), any(WifiP2pDevice.class));
}
+ private static OuiKeyedData[] createTestVendorData() {
+ int oui = 0x0033aabb;
+ OuiKeyedData vendorDataElement = new OuiKeyedData();
+ vendorDataElement.oui = oui;
+ vendorDataElement.vendorData = new PersistableBundle();
+ return new OuiKeyedData[]{vendorDataElement};
+ }
+
+ /**
+ * Sunny day scenario for onGoNegotiationRequestWithParams call.
+ */
+ @Test
+ public void testOnGoNegotiationRequestWithParams_success() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ initializeDut(3 /* serviceVersion */);
+ HashSet<Integer> setups = new HashSet<Integer>();
+
+ P2pGoNegotiationReqEventParams params = new P2pGoNegotiationReqEventParams();
+ params.srcAddress = mDeviceAddress1Bytes;
+ params.passwordId = WpsDevPasswordId.USER_SPECIFIED;
+ params.vendorData = createTestVendorData();
+
+ doAnswer(new AnswerWithArguments() {
+ public void answer(String iface, WifiP2pConfig config) {
+ assertEquals(iface, mIface);
+ assertNotNull(config.wps);
+ setups.add(config.wps.setup);
+ assertEquals(config.deviceAddress, mDeviceAddress1String);
+ assertEquals(params.vendorData[0].oui, config.getVendorData().get(0).getOui());
+ }
+ }).when(mMonitor).broadcastP2pGoNegotiationRequest(
+ anyString(), any(WifiP2pConfig.class));
+
+ mDut.onGoNegotiationRequestWithParams(params);
+ assertTrue(setups.contains(WpsInfo.DISPLAY));
+
+ params.passwordId = WpsDevPasswordId.PUSHBUTTON;
+
+ mDut.onGoNegotiationRequestWithParams(params);
+ assertTrue(setups.contains(WpsInfo.PBC));
+
+ params.passwordId = WpsDevPasswordId.REGISTRAR_SPECIFIED;
+
+ mDut.onGoNegotiationRequestWithParams(params);
+ assertTrue(setups.contains(WpsInfo.KEYPAD));
+
+ params.passwordId = 0xffff;
+
+ // Invalid should default to PBC
+ setups.clear();
+ mDut.onGoNegotiationRequestWithParams(params);
+ assertTrue(setups.contains(WpsInfo.PBC));
+ }
+
/**
* Sunny day scenario for onGroupStarted call.
*/
@@ -477,6 +620,59 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
}
/**
+ * Sunny day scenario for onGroupStartedWithParams call when the parameters
+ * include vendor data.
+ */
+ @Test
+ public void testOnGroupStartedWithParams_vendorData_success() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ initializeDut(3 /* serviceVersion */);
+ String fakeName = "group name";
+ String fakePassphrase = "secret";
+ byte[] fakeSsidBytesList = new byte[] {0x30, 0x31, 0x32, 0x33};
+ String fakeSsidString = "0123";
+ HashSet<String> passwords = new HashSet<String>();
+ OuiKeyedData[] halVendorData = generateHalOuiKeyedDataList(5);
+
+ P2pGroupStartedEventParams params = new P2pGroupStartedEventParams();
+ params.groupInterfaceName = fakeName;
+ params.isGroupOwner = true;
+ params.ssid = fakeSsidBytesList;
+ params.frequencyMHz = 1;
+ params.psk = null;
+ params.passphrase = fakePassphrase;
+ params.isPersistent = true;
+ params.goDeviceAddress = mDeviceAddress1Bytes;
+ params.isP2pClientEapolIpAddressInfoPresent = true;
+ params.vendorData = halVendorData;
+
+ doAnswer(new AnswerWithArguments() {
+ public void answer(String iface, WifiP2pGroup group) {
+ assertEquals(iface, mIface);
+ assertNotNull(group.getOwner());
+ assertEquals(group.getOwner().deviceAddress, mDeviceAddress1String);
+ assertEquals(group.getNetworkId(), WifiP2pGroup.NETWORK_ID_PERSISTENT);
+ passwords.add(group.getPassphrase());
+ assertEquals(group.getInterface(), fakeName);
+ assertEquals(group.getNetworkName(), fakeSsidString);
+ assertEquals(group.getVendorData(),
+ HalAidlUtil.halToFrameworkOuiKeyedDataList(halVendorData));
+ }
+ }).when(mMonitor).broadcastP2pGroupStarted(
+ anyString(), any(WifiP2pGroup.class));
+
+ mDut.onGroupStartedWithParams(params);
+ assertTrue(passwords.contains(fakePassphrase));
+
+ params.passphrase = null;
+ mDut.onGroupStartedWithParams(params);
+ assertTrue(passwords.contains(null));
+
+ verify(mMonitor, times(2)).broadcastP2pGroupStarted(
+ anyString(), any(WifiP2pGroup.class));
+ }
+
+ /**
* Failing scenarios for onGroupStartedWithParams call.
*/
@Test
@@ -640,6 +836,35 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
assertEquals(WifiP2pProvDiscEvent.PBC_REQ, discEventCaptor.getValue().event);
}
+ /**
+ * Test provision discovery event callback when the event contains vendor data.
+ */
+ @Test
+ public void testOnProvisionDiscoveryCompletedEvent_vendorData() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ initializeDut(3 /* serviceVersion */);
+ OuiKeyedData[] halVendorData = generateHalOuiKeyedDataList(5);
+ List<android.net.wifi.OuiKeyedData> frameworkVendorData =
+ HalAidlUtil.halToFrameworkOuiKeyedDataList(halVendorData);
+
+ P2pProvisionDiscoveryCompletedEventParams params =
+ new P2pProvisionDiscoveryCompletedEventParams();
+ params.p2pDeviceAddress = DEVICE_ADDRESS;
+ params.isRequest = false;
+ params.status = P2pProvDiscStatusCode.SUCCESS;
+ params.configMethods = WpsConfigMethods.DISPLAY;
+ params.generatedPin = "12345678";
+ params.vendorData = halVendorData;
+
+ ArgumentCaptor<WifiP2pProvDiscEvent> discEventCaptor =
+ ArgumentCaptor.forClass(WifiP2pProvDiscEvent.class);
+ mDut.onProvisionDiscoveryCompletedEvent(params);
+ verify(mMonitor).broadcastP2pProvisionDiscoveryEnterPin(
+ anyString(), discEventCaptor.capture());
+ assertEquals(WifiP2pProvDiscEvent.ENTER_PIN, discEventCaptor.getValue().event);
+ assertEquals(frameworkVendorData, discEventCaptor.getValue().getVendorData());
+ }
+
private void verifyProvisionDiscoveryFailureEvent(
int halStatus, int expectedStatus) throws Exception {
byte[] p2pDeviceAddr = DEVICE_ADDRESS;
@@ -726,6 +951,33 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
assertEquals(mDeviceAddress1String, p2pDeviceCaptor.getValue().deviceAddress);
}
+ /**
+ * Test onPeerClientJoined
+ */
+ @Test
+ public void testOnPeerClientJoined() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ initializeDut(3 /* serviceVersion */);
+ OuiKeyedData[] halVendorData = generateHalOuiKeyedDataList(5);
+ List<android.net.wifi.OuiKeyedData> frameworkVendorData =
+ HalAidlUtil.halToFrameworkOuiKeyedDataList(halVendorData);
+
+ P2pPeerClientJoinedEventParams params = new P2pPeerClientJoinedEventParams();
+ params.clientInterfaceAddress = mDeviceAddress1Bytes;
+ params.clientDeviceAddress = mDeviceAddress2Bytes;
+ params.vendorData = halVendorData;
+ params.clientIpAddress = 0xc831a8c0;
+
+ ArgumentCaptor<WifiP2pDevice> p2pDeviceCaptor =
+ ArgumentCaptor.forClass(WifiP2pDevice.class);
+ mDut.onPeerClientJoined(params);
+ verify(mMonitor).broadcastP2pApStaConnected(eq(mIface), p2pDeviceCaptor.capture());
+ assertEquals(mDeviceAddress2String, p2pDeviceCaptor.getValue().deviceAddress);
+ assertEquals(MacAddress.fromBytes(mDeviceAddress1Bytes),
+ p2pDeviceCaptor.getValue().getInterfaceMacAddress());
+ assertEquals(frameworkVendorData, p2pDeviceCaptor.getValue().getVendorData());
+ }
+
// TLVS hex data encoded as a hex string.
// Taken directly from an observed supplicant service response event
private static final String SERV_DISC_RESP_TLVS = "1d00010100076578616d706c650b5f6166706f766572"
@@ -855,6 +1107,33 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
}
/**
+ * Test testOnInvitationReceivedWithParams should trigger P2pInvitationReceived broadcast.
+ */
+ @Test
+ public void testOnInvitationReceivedWithParams() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ initializeDut(3 /* serviceVersion */);
+
+ P2pInvitationEventParams params = new P2pInvitationEventParams();
+ params.srcAddress = mDeviceAddress1Bytes;
+ params.goDeviceAddress = mDeviceAddress2Bytes;
+ params.bssid = DEVICE_ADDRESS;
+ params.persistentNetworkId = TEST_NETWORK_ID;
+ params.operatingFrequencyMHz = TEST_GROUP_FREQUENCY;
+ params.vendorData = createTestVendorData();
+
+ mDut.onInvitationReceivedWithParams(params);
+
+ ArgumentCaptor<WifiP2pGroup> groupCaptor = ArgumentCaptor.forClass(WifiP2pGroup.class);
+ verify(mMonitor).broadcastP2pInvitationReceived(eq(mIface), groupCaptor.capture());
+
+ WifiP2pGroup group = groupCaptor.getValue();
+ assertEquals(TEST_NETWORK_ID, group.getNetworkId());
+ assertEquals(mDeviceAddress2String, group.getOwner().deviceAddress);
+ assertEquals(params.vendorData[0].oui, group.getVendorData().get(0).getOui());
+ }
+
+ /**
* Test onInvitationResult should trigger P2pInvitationResult broadcast.
*/
@Test
@@ -877,6 +1156,32 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
}
/**
+ * Test onP2pApStaDisconnected callback
+ */
+ @Test
+ public void testOnPeerClientDisconnected() {
+ assumeTrue(SdkLevel.isAtLeastV());
+ initializeDut(3 /* serviceVersion */);
+ OuiKeyedData[] halVendorData = generateHalOuiKeyedDataList(5);
+ List<android.net.wifi.OuiKeyedData> frameworkVendorData =
+ HalAidlUtil.halToFrameworkOuiKeyedDataList(halVendorData);
+
+ P2pPeerClientDisconnectedEventParams params = new P2pPeerClientDisconnectedEventParams();
+ params.clientInterfaceAddress = mDeviceAddress1Bytes;
+ params.clientDeviceAddress = mDeviceAddress2Bytes;
+ params.vendorData = halVendorData;
+
+ ArgumentCaptor<WifiP2pDevice> p2pDeviceCaptor =
+ ArgumentCaptor.forClass(WifiP2pDevice.class);
+ mDut.onPeerClientDisconnected(params);
+ verify(mMonitor).broadcastP2pApStaDisconnected(eq(mIface), p2pDeviceCaptor.capture());
+ assertEquals(mDeviceAddress2String, p2pDeviceCaptor.getValue().deviceAddress);
+ assertEquals(MacAddress.fromBytes(mDeviceAddress1Bytes),
+ p2pDeviceCaptor.getValue().getInterfaceMacAddress());
+ assertEquals(frameworkVendorData, p2pDeviceCaptor.getValue().getVendorData());
+ }
+
+ /**
* Test the sunny case of onDeviceFoundWithVendorElements.
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImplTest.java
index 6de2b79486..9cb54e710f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImplTest.java
@@ -19,8 +19,10 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
@@ -29,6 +31,7 @@ import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -49,27 +52,34 @@ import android.hardware.wifi.supplicant.ISupplicantP2pNetwork;
import android.hardware.wifi.supplicant.IfaceInfo;
import android.hardware.wifi.supplicant.MacAddress;
import android.hardware.wifi.supplicant.MiracastMode;
+import android.hardware.wifi.supplicant.P2pConnectInfo;
+import android.hardware.wifi.supplicant.P2pExtListenInfo;
import android.hardware.wifi.supplicant.P2pFrameTypeMask;
import android.hardware.wifi.supplicant.SupplicantStatusCode;
import android.hardware.wifi.supplicant.WpsProvisionMethod;
import android.net.wifi.CoexUnsafeChannel;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.ScanResult;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pExtListenParams;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pGroupList;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
import android.os.IBinder;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.text.TextUtils;
import androidx.test.filters.SmallTest;
+import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiInjector;
+import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WifiSettingsConfigStore;
import com.android.server.wifi.util.NativeUtil;
@@ -100,7 +110,13 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
private @Mock WifiP2pMonitor mWifiMonitor;
private @Mock WifiInjector mWifiInjector;
private @Mock IBinder mServiceBinderMock;
+ private @Mock WifiSettingsConfigStore mWifiSettingsConfigStore;
+ private @Mock WifiNative.SupplicantDeathEventHandler mSupplicantHalDeathHandler;
+ private ArgumentCaptor<IBinder.DeathRecipient> mSupplicantDeathCaptor =
+ ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
+
+ final int mServiceVersion = 2;
final String mIfaceName = "virtual_interface_name";
final String mSsid = "\"SSID\"";
final byte[] mSsidBytes = {'S', 'S', 'I', 'D'};
@@ -164,6 +180,7 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mDut = new SupplicantP2pIfaceHalSpy();
+ setCachedServiceVersion(mServiceVersion);
}
/**
@@ -646,12 +663,13 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
}
/**
- * Sunny day scenario for connect()
+ * Sunny day scenario for connect() using the HAL method for AIDL <= 2.
*/
@Test
- public void testConnect_success() throws Exception {
+ public void testConnect_V2_success() throws Exception {
final String configPin = "12345";
final HashSet<Integer> methods = new HashSet<>();
+ setCachedServiceVersion(2);
doAnswer(new AnswerWithArguments() {
public String answer(byte[] peer, int method, String pin, boolean joinExisting,
@@ -700,6 +718,61 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
}
/**
+ * Sunny day scenario for connect() using the HAL method for AIDL >= 3.
+ */
+ @Test
+ public void testConnect_V3_success() throws Exception {
+ final String configPin = "12345";
+ final HashSet<Integer> methods = new HashSet<>();
+ setCachedServiceVersion(3);
+
+ doAnswer(new AnswerWithArguments() {
+ public String answer(P2pConnectInfo info) throws RemoteException {
+ String pin = info.preSelectedPin;
+ int method = info.provisionMethod;
+ methods.add(method);
+
+ if (method == WpsProvisionMethod.DISPLAY && TextUtils.isEmpty(pin)) {
+ // Return the configPin for DISPLAY method if the pin was not provided.
+ return configPin;
+ } else {
+ if (method != WpsProvisionMethod.PBC) {
+ // PIN is only required for PIN methods.
+ assertEquals(pin, configPin);
+ }
+ // For all the other cases, there is no generated pin.
+ return "";
+ }
+ }
+ }).when(mISupplicantP2pIfaceMock).connectWithParams(any(P2pConnectInfo.class));
+
+ WifiP2pConfig config = createPlaceholderP2pConfig(mPeerMacAddress, WpsInfo.DISPLAY, "");
+
+ // Default value when service is not initialized.
+ assertNull(mDut.connect(config, false));
+
+ executeAndValidateInitializationSequence(false, false);
+
+ assertEquals(configPin, mDut.connect(config, false));
+ assertTrue(methods.contains(WpsProvisionMethod.DISPLAY));
+ methods.clear();
+
+ config = createPlaceholderP2pConfig(mPeerMacAddress, WpsInfo.DISPLAY, configPin);
+ assertTrue(mDut.connect(config, false).isEmpty());
+ assertTrue(methods.contains(WpsProvisionMethod.DISPLAY));
+ methods.clear();
+
+ config = createPlaceholderP2pConfig(mPeerMacAddress, WpsInfo.PBC, "");
+ assertTrue(mDut.connect(config, false).isEmpty());
+ assertTrue(methods.contains(WpsProvisionMethod.PBC));
+ methods.clear();
+
+ config = createPlaceholderP2pConfig(mPeerMacAddress, WpsInfo.KEYPAD, configPin);
+ assertTrue(mDut.connect(config, false).isEmpty());
+ assertTrue(methods.contains(WpsProvisionMethod.KEYPAD));
+ }
+
+ /**
* Test connect with invalid arguments.
*/
@Test
@@ -746,6 +819,7 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
WifiP2pConfig config = createPlaceholderP2pConfig(mPeerMacAddress,
WpsInfo.DISPLAY, configPin);
+ setCachedServiceVersion(2);
executeAndValidateInitializationSequence(false, false);
doThrow(new ServiceSpecificException(SupplicantStatusCode.FAILURE_UNKNOWN))
.when(mISupplicantP2pIfaceMock).connect(eq(mPeerMacAddressBytes), anyInt(),
@@ -1401,6 +1475,13 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
assertFalse(mDut.isInitializationComplete());
}
+ private void setCachedServiceVersion(int version) {
+ when(mWifiSettingsConfigStore
+ .get(eq(WifiSettingsConfigStore.SUPPLICANT_HAL_AIDL_SERVICE_VERSION)))
+ .thenReturn(version);
+ when(mWifiInjector.getSettingsConfigStore()).thenReturn(mWifiSettingsConfigStore);
+ }
+
/**
* Sunny day scenario for configureExtListen()
*/
@@ -1411,15 +1492,45 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
.configureExtListen(anyInt(), anyInt());
doNothing().when(mISupplicantP2pIfaceMock).configureExtListen(eq(123), eq(456));
doNothing().when(mISupplicantP2pIfaceMock).configureExtListen(eq(0), eq(0));
+ setCachedServiceVersion(2);
// Default value when service is not initialized.
- assertFalse(mDut.configureExtListen(true, 123, 456));
+ assertFalse(mDut.configureExtListen(true, 123, 456, null));
executeAndValidateInitializationSequence(false, false);
- assertTrue(mDut.configureExtListen(true, 123, 456));
+ assertTrue(mDut.configureExtListen(true, 123, 456, null));
// Turning listening off should reset intervals to 0s.
- assertTrue(mDut.configureExtListen(false, 999, 999));
+ assertTrue(mDut.configureExtListen(false, 999, 999, null));
+ // Disable listening.
+ assertTrue(mDut.configureExtListen(false, -1, -1, null));
+ }
+
+ /**
+ * Sunny day scenario for configureExtListenWithParams()
+ */
+ @Test
+ public void testConfigureExtListenWithParams_success() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ setCachedServiceVersion(3); // API requires HAL >= 3
+
+ OuiKeyedData vendorDataElement =
+ new OuiKeyedData.Builder(0x00aabbcc, new PersistableBundle()).build();
+ List<OuiKeyedData> vendorData = Arrays.asList(vendorDataElement);
+ WifiP2pExtListenParams extListenParams =
+ new WifiP2pExtListenParams.Builder().setVendorData(vendorData).build();
+
+ // Default value when service is not initialized.
+ assertFalse(mDut.configureExtListen(true, 123, 456, extListenParams));
+
+ executeAndValidateInitializationSequence(false, false);
+ assertTrue(mDut.configureExtListen(true, 123, 456, extListenParams));
+
// Disable listening.
- assertTrue(mDut.configureExtListen(false, -1, -1));
+ assertTrue(mDut.configureExtListen(false, -1, -1, extListenParams));
+
+ // Legacy HAL API should not get called.
+ verify(mISupplicantP2pIfaceMock, atLeastOnce())
+ .configureExtListenWithParams(any(P2pExtListenInfo.class));
+ verify(mISupplicantP2pIfaceMock, never()).configureExtListen(anyInt(), anyInt());
}
/**
@@ -1427,10 +1538,11 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testConfigureExtListen_invalidArguments() throws Exception {
+ setCachedServiceVersion(2);
executeAndValidateInitializationSequence(false, false);
doNothing().when(mISupplicantP2pIfaceMock).configureExtListen(anyInt(), anyInt());
- assertFalse(mDut.configureExtListen(true, -1, 1));
- assertFalse(mDut.configureExtListen(true, 1, -1));
+ assertFalse(mDut.configureExtListen(true, -1, 1, null));
+ assertFalse(mDut.configureExtListen(true, 1, -1, null));
}
/**
@@ -1438,10 +1550,11 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testConfigureExtListen_failure() throws Exception {
+ setCachedServiceVersion(2);
executeAndValidateInitializationSequence(false, false);
doThrow(new ServiceSpecificException(SupplicantStatusCode.FAILURE_UNKNOWN))
.when(mISupplicantP2pIfaceMock).configureExtListen(anyInt(), anyInt());
- assertFalse(mDut.configureExtListen(true, 1, 1));
+ assertFalse(mDut.configureExtListen(true, 1, 1, null));
// Check that service is still alive.
assertTrue(mDut.isInitializationComplete());
}
@@ -1452,10 +1565,11 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testConfigureExtListen_exception() throws Exception {
+ setCachedServiceVersion(2);
executeAndValidateInitializationSequence(false, false);
doThrow(new RemoteException()).when(mISupplicantP2pIfaceMock)
.configureExtListen(anyInt(), anyInt());
- assertFalse(mDut.configureExtListen(true, 1, 1));
+ assertFalse(mDut.configureExtListen(true, 1, 1, null));
// Check service is dead.
assertFalse(mDut.isInitializationComplete());
}
@@ -2630,7 +2744,7 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
}
assertTrue(mDut.initialize());
- verify(mServiceBinderMock).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
+ verify(mServiceBinderMock).linkToDeath(mSupplicantDeathCaptor.capture(), anyInt());
assertTrue(mDut.isInitializationComplete());
// Now setup the iface.
@@ -2679,4 +2793,47 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
}
return new TestP2pServiceInfo(services);
}
+
+ /**
+ * Tests the terminate function and ensures that its callback gets called.
+ */
+ @Test
+ public void testTerminateAndDeadHandler() throws Exception {
+ executeAndValidateInitializationSequence(false, false);
+ mDut.terminate();
+ verify(mISupplicantMock).terminate();
+ // Trigger the supplicant died.
+ mSupplicantDeathCaptor.getValue().binderDied();
+ // Check that terminate cleared all internal state.
+ assertFalse(mDut.isInitializationComplete());
+ }
+
+ /**
+ * Tests the handling of supplicant death notification.
+ */
+ @Test
+ public void testSupplicantDeathCallback() throws Exception {
+ executeAndValidateInitializationSequence(false, false);
+ assertNotNull(mSupplicantDeathCaptor.getValue());
+ assertTrue(mDut.isInitializationComplete());
+ assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler));
+ mSupplicantDeathCaptor.getValue().binderDied();
+ assertFalse(mDut.isInitializationComplete());
+ verify(mSupplicantHalDeathHandler).onDeath();
+ }
+
+ /**
+ * Tests the handling of supplicant death unregister.
+ */
+ @Test
+ public void testSupplicantDeathCallbackUnregister() throws Exception {
+ executeAndValidateInitializationSequence(false, false);
+ assertNotNull(mSupplicantDeathCaptor.getValue());
+ assertTrue(mDut.isInitializationComplete());
+ assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler));
+ assertTrue(mDut.deregisterDeathHandler());
+ mSupplicantDeathCaptor.getValue().binderDied();
+ assertFalse(mDut.isInitializationComplete());
+ verify(mSupplicantHalDeathHandler, never()).onDeath();
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImplTest.java
index 734255abbc..2520a7b01e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImplTest.java
@@ -1581,13 +1581,13 @@ public class SupplicantP2pIfaceHalHidlImplTest extends WifiBaseTest {
when(mISupplicantP2pIfaceMock.configureExtListen(eq(0), eq(0)))
.thenReturn(mStatusSuccess);
// Default value when service is not initialized.
- assertFalse(mDut.configureExtListen(true, 123, 456));
+ assertFalse(mDut.configureExtListen(true, 123, 456, null));
executeAndValidateInitializationSequence(false, false, false);
- assertTrue(mDut.configureExtListen(true, 123, 456));
+ assertTrue(mDut.configureExtListen(true, 123, 456, null));
// Turning listening off should reset intervals to 0s.
- assertTrue(mDut.configureExtListen(false, 999, 999));
+ assertTrue(mDut.configureExtListen(false, 999, 999, null));
// Disable listening.
- assertTrue(mDut.configureExtListen(false, -1, -1));
+ assertTrue(mDut.configureExtListen(false, -1, -1, null));
}
/**
@@ -1598,8 +1598,8 @@ public class SupplicantP2pIfaceHalHidlImplTest extends WifiBaseTest {
executeAndValidateInitializationSequence(false, false, false);
when(mISupplicantP2pIfaceMock.configureExtListen(anyInt(), anyInt()))
.thenReturn(mStatusFailure);
- assertFalse(mDut.configureExtListen(true, -1, 1));
- assertFalse(mDut.configureExtListen(true, 1, -1));
+ assertFalse(mDut.configureExtListen(true, -1, 1, null));
+ assertFalse(mDut.configureExtListen(true, 1, -1, null));
}
/**
@@ -1610,7 +1610,7 @@ public class SupplicantP2pIfaceHalHidlImplTest extends WifiBaseTest {
executeAndValidateInitializationSequence(false, false, false);
when(mISupplicantP2pIfaceMock.configureExtListen(anyInt(), anyInt()))
.thenReturn(mStatusFailure);
- assertFalse(mDut.configureExtListen(true, 1, 1));
+ assertFalse(mDut.configureExtListen(true, 1, 1, null));
// Check that service is still alive.
assertTrue(mDut.isInitializationComplete());
}
@@ -1623,7 +1623,7 @@ public class SupplicantP2pIfaceHalHidlImplTest extends WifiBaseTest {
executeAndValidateInitializationSequence(false, false, false);
when(mISupplicantP2pIfaceMock.configureExtListen(anyInt(), anyInt()))
.thenThrow(mRemoteException);
- assertFalse(mDut.configureExtListen(true, 1, 1));
+ assertFalse(mDut.configureExtListen(true, 1, 1, null));
// Check service is dead.
assertFalse(mDut.isInitializationComplete());
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java
index 84d870a9c4..bf7194bec5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java
@@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -39,6 +40,7 @@ import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiGlobals;
import com.android.server.wifi.WifiInjector;
+import com.android.server.wifi.WifiNative;
import org.junit.Before;
import org.junit.Test;
@@ -58,6 +60,7 @@ public class SupplicantP2pIfaceHalTest extends WifiBaseTest {
private SupplicantP2pIfaceHalSpy mDut;
private @Mock SupplicantP2pIfaceHalHidlImpl mP2pIfaceHalHidlMock;
private @Mock SupplicantP2pIfaceHalAidlImpl mP2pIfaceHalAidlMock;
+ private @Mock WifiNative.SupplicantDeathEventHandler mSupplicantHalDeathHandler;
private @Mock WifiP2pMonitor mMonitor;
private @Mock WifiGlobals mWifiGlobals;
private @Mock WifiInjector mWifiInjector;
@@ -485,10 +488,11 @@ public class SupplicantP2pIfaceHalTest extends WifiBaseTest {
initializeWithAidlImpl(true);
int period = 2;
int interval = 3;
- when(mP2pIfaceHalAidlMock.configureExtListen(anyBoolean(), anyInt(), anyInt()))
+ when(mP2pIfaceHalAidlMock.configureExtListen(anyBoolean(), anyInt(), anyInt(), any()))
.thenReturn(true);
- assertTrue(mDut.configureExtListen(ENABLE, period, interval));
- verify(mP2pIfaceHalAidlMock).configureExtListen(eq(ENABLE), eq(period), eq(interval));
+ assertTrue(mDut.configureExtListen(ENABLE, period, interval, null));
+ verify(mP2pIfaceHalAidlMock).configureExtListen(
+ eq(ENABLE), eq(period), eq(interval), eq(null));
}
/**
@@ -807,4 +811,38 @@ public class SupplicantP2pIfaceHalTest extends WifiBaseTest {
verify(mP2pIfaceHalAidlMock).configureEapolIpAddressAllocationParams(eq(0x0101A8C0),
eq(0x00FFFFFF), eq(0x0501A8C0), eq(0x0801A8C0));
}
+
+ /**
+ * Test that we can call terminate
+ */
+ @Test
+ public void testTerminate() {
+ initializeWithAidlImpl(true);
+ doNothing().when(mP2pIfaceHalAidlMock).terminate();
+ mDut.terminate();
+ verify(mP2pIfaceHalAidlMock).terminate();
+ }
+
+ /**
+ * Test that we can call registerDeathHandler
+ */
+ @Test
+ public void testRegisterDeathHandler() {
+ initializeWithAidlImpl(true);
+ when(mP2pIfaceHalAidlMock.registerDeathHandler(
+ any(WifiNative.SupplicantDeathEventHandler.class))).thenReturn(true);
+ assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler));
+ verify(mP2pIfaceHalAidlMock).registerDeathHandler(eq(mSupplicantHalDeathHandler));
+ }
+
+ /**
+ * Test that we can call deregisterDeathHandler
+ */
+ @Test
+ public void testDeregisterDeathHandler() {
+ initializeWithAidlImpl(true);
+ when(mP2pIfaceHalAidlMock.deregisterDeathHandler()).thenReturn(true);
+ assertTrue(mDut.deregisterDeathHandler());
+ verify(mP2pIfaceHalAidlMock).deregisterDeathHandler();
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java
index cc2456f238..694c6901fa 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -34,18 +35,22 @@ import android.os.WorkSource;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.DeviceConfigFacade;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
import com.android.server.wifi.HalDeviceManager.ManagerStatusListener;
import com.android.server.wifi.PropertyService;
import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WifiVendorHal;
import com.android.server.wifi.hal.WifiHal;
+import com.android.wifi.flags.FeatureFlags;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -55,8 +60,7 @@ import org.mockito.MockitoAnnotations;
*/
@SmallTest
public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest {
- private static final String P2P_IFACE_NAME = "p2p0";
- private static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface";
+ private static final String TEST_P2P_IFACE_NAME = "p2p0";
private static final WorkSource TEST_WS = new WorkSource();
@Mock private SupplicantP2pIfaceHal mSupplicantP2pIfaceHal;
@@ -70,6 +74,11 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest {
@Mock private WifiNl80211Manager mWifiNl80211Manager;
@Mock private WifiNative mWifiNative;
@Mock private WifiMetrics mWifiMetrics;
+ @Mock private WifiNative.Iface mMockP2pIface;
+ @Mock private WifiInjector mWifiInjector;
+ @Mock private DeviceConfigFacade mDeviceConfigFacade;
+ @Mock private FeatureFlags mFeatureFlags;
+
private WifiP2pNative mWifiP2pNative;
private WifiStatus mWifiStatusSuccess;
private ManagerStatusListener mManagerStatusListener;
@@ -84,31 +93,60 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest {
mWifiStatusSuccess.code = WifiStatusCode.SUCCESS;
when(mHalDeviceManager.isSupported()).thenReturn(true);
+ mMockP2pIface.name = TEST_P2P_IFACE_NAME;
+ when(mWifiNative.createP2pIface(any(InterfaceDestroyedListener.class),
+ any(Handler.class), any(WorkSource.class))).thenReturn(mMockP2pIface);
when(mHalDeviceManager.createP2pIface(any(InterfaceDestroyedListener.class),
- any(Handler.class), any(WorkSource.class))).thenReturn(P2P_IFACE_NAME);
+ any(Handler.class), any(WorkSource.class))).thenReturn(TEST_P2P_IFACE_NAME);
when(mSupplicantP2pIfaceHal.isInitializationStarted()).thenReturn(true);
when(mSupplicantP2pIfaceHal.initialize()).thenReturn(true);
when(mSupplicantP2pIfaceHal.isInitializationComplete()).thenReturn(true);
- when(mSupplicantP2pIfaceHal.setupIface(P2P_IFACE_NAME)).thenReturn(true);
- when(mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME))
- .thenReturn(P2P_IFACE_NAME);
-
+ when(mSupplicantP2pIfaceHal.setupIface(TEST_P2P_IFACE_NAME)).thenReturn(true);
+ when(mSupplicantP2pIfaceHal.registerDeathHandler(any())).thenReturn(true);
+ when(mPropertyService.getString(
+ WifiP2pNative.P2P_INTERFACE_PROPERTY, WifiP2pNative.P2P_IFACE_NAME))
+ .thenReturn(TEST_P2P_IFACE_NAME);
+ when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade);
+ when(mDeviceConfigFacade.getFeatureFlags()).thenReturn(mFeatureFlags);
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(true);
mWifiP2pNative = new WifiP2pNative(mWifiNl80211Manager, mWifiNative, mWifiMetrics,
- mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager, mPropertyService);
+ mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager, mPropertyService,
+ mWifiInjector);
+ }
+
+ /**
+ * Verifies the setup of a p2p interface.
+ */
+ @Test
+ public void testSetUpInterfaceByHDM() throws Exception {
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(false);
+ testSetUpInterface(false);
}
/**
* Verifies the setup of a p2p interface.
*/
@Test
- public void testSetUpInterface() throws Exception {
- assertEquals(P2P_IFACE_NAME,
+ public void testSetUpInterfaceByWifiNative() throws Exception {
+ testSetUpInterface(true);
+ }
+
+ private void testSetUpInterface(boolean isD2dAloneFeatureEnabled) throws Exception {
+ assertEquals(TEST_P2P_IFACE_NAME,
mWifiP2pNative.setupInterface(
mHalDeviceInterfaceDestroyedListener, mHandler, TEST_WS));
-
- verify(mHalDeviceManager).createP2pIface(any(InterfaceDestroyedListener.class),
- eq(mHandler), eq(TEST_WS));
- verify(mSupplicantP2pIfaceHal).setupIface(eq(P2P_IFACE_NAME));
+ if (isD2dAloneFeatureEnabled) {
+ verify(mWifiNative).createP2pIface(any(InterfaceDestroyedListener.class),
+ eq(mHandler), eq(TEST_WS));
+ verify(mHalDeviceManager, never()).createP2pIface(any(InterfaceDestroyedListener.class),
+ any(), any());
+ } else {
+ verify(mHalDeviceManager).createP2pIface(any(InterfaceDestroyedListener.class),
+ eq(mHandler), eq(TEST_WS));
+ verify(mWifiNative, never()).createP2pIface(any(InterfaceDestroyedListener.class),
+ any(), any());
+ }
+ verify(mSupplicantP2pIfaceHal).setupIface(eq(TEST_P2P_IFACE_NAME));
}
/**
@@ -118,13 +156,22 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest {
public void testSetUpInterfaceWithNoVendorHal() throws Exception {
when(mHalDeviceManager.isSupported()).thenReturn(false);
- assertEquals(P2P_IFACE_NAME, mWifiP2pNative.setupInterface(
+ assertEquals(TEST_P2P_IFACE_NAME, mWifiP2pNative.setupInterface(
mHalDeviceInterfaceDestroyedListener, mHandler, TEST_WS));
verify(mHalDeviceManager, never())
.createP2pIface(any(InterfaceDestroyedListener.class), any(Handler.class),
any(WorkSource.class));
- verify(mSupplicantP2pIfaceHal).setupIface(eq(P2P_IFACE_NAME));
+ verify(mSupplicantP2pIfaceHal).setupIface(eq(TEST_P2P_IFACE_NAME));
+ }
+
+ /**
+ * Verifies the teardown of a p2p interface.
+ */
+ @Test
+ public void testTeardownInterfaceWhenD2dWithoutSTADisabled() throws Exception {
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(false);
+ testTeardownInterface(false);
}
/**
@@ -132,29 +179,54 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest {
*/
@Test
public void testTeardownInterface() throws Exception {
- assertEquals(P2P_IFACE_NAME,
+ testTeardownInterface(true);
+ }
+
+ private void testTeardownInterface(boolean isD2dAloneFeatureEnabled) throws Exception {
+ assertEquals(TEST_P2P_IFACE_NAME,
mWifiP2pNative.setupInterface(mHalDeviceInterfaceDestroyedListener,
mHandler, TEST_WS));
mWifiP2pNative.teardownInterface();
verify(mHalDeviceManager).removeP2pIface(anyString());
- verify(mSupplicantP2pIfaceHal).teardownIface(eq(P2P_IFACE_NAME));
+ if (!isD2dAloneFeatureEnabled) {
+ verify(mSupplicantP2pIfaceHal).teardownIface(eq(TEST_P2P_IFACE_NAME));
+ }
}
/**
* Verifies the teardown of a p2p interface with no HAL (HIDL) support.
*/
@Test
- public void testTeardownInterfaceWithNoVendorHal() throws Exception {
- when(mHalDeviceManager.isSupported()).thenReturn(false);
+ public void testTeardownInterfaceWithNoVendorHalWhenD2dAloneFeatureEnabled() throws Exception {
+ testTeardownInterfaceWithNoVendorHal(true);
+ }
+ /**
+ * Verifies the teardown of a p2p interface with no HAL (HIDL) support.
+ */
+ @Test
+ public void testTeardownInterfaceWithNoVendorHalD2dAloneFeatureDisabled() throws Exception {
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(false);
+ testTeardownInterfaceWithNoVendorHal(false);
+ }
- assertEquals(P2P_IFACE_NAME, mWifiP2pNative.setupInterface(
+ private void testTeardownInterfaceWithNoVendorHal(boolean isD2dAloneFeatureEnabled)
+ throws Exception {
+ when(mHalDeviceManager.isSupported()).thenReturn(false);
+ InOrder order = inOrder(mSupplicantP2pIfaceHal, mWifiNative);
+ assertEquals(TEST_P2P_IFACE_NAME, mWifiP2pNative.setupInterface(
mHalDeviceInterfaceDestroyedListener, mHandler, TEST_WS));
mWifiP2pNative.teardownInterface();
verify(mHalDeviceManager, never()).removeIface(any(WifiHal.WifiInterface.class));
- verify(mSupplicantP2pIfaceHal).teardownIface(eq(P2P_IFACE_NAME));
+ if (isD2dAloneFeatureEnabled) {
+ order.verify(mSupplicantP2pIfaceHal).deregisterDeathHandler();
+ order.verify(mSupplicantP2pIfaceHal).teardownIface(eq(TEST_P2P_IFACE_NAME));
+ order.verify(mWifiNative).teardownP2pIface(eq(mMockP2pIface.id));
+ } else {
+ order.verify(mSupplicantP2pIfaceHal).teardownIface(eq(TEST_P2P_IFACE_NAME));
+ }
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java
index 153fb6ee2a..e70588f5bd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java
@@ -46,13 +46,16 @@ import android.os.WorkSource;
import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.server.wifi.DeviceConfigFacade;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.PropertyService;
import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WifiVendorHal;
import com.android.server.wifi.hal.WifiHal;
+import com.android.wifi.flags.FeatureFlags;
import org.junit.After;
import org.junit.Before;
@@ -104,6 +107,10 @@ public class WifiP2pNativeTest extends WifiBaseTest {
@Mock private Handler mHandlerMock;
@Mock private WorkSource mWorkSourceMock;
@Mock private IWifiP2pIface mIWifiP2pIfaceMock;
+ @Mock private WifiNative.Iface mMockP2pIface;
+ @Mock private WifiInjector mWifiInjector;
+ @Mock private DeviceConfigFacade mDeviceConfigFacade;
+ @Mock private FeatureFlags mFeatureFlags;
private MockitoSession mSession;
private WifiP2pNative mWifiP2pNative;
@@ -131,10 +138,12 @@ public class WifiP2pNativeTest extends WifiBaseTest {
.startMocking();
mWifiClientInterfaceNames.add("wlan0");
mWifiClientInterfaceNames.add("wlan1");
-
+ when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade);
+ when(mDeviceConfigFacade.getFeatureFlags()).thenReturn(mFeatureFlags);
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(true);
mWifiP2pNative = new WifiP2pNative(mWifiCondManager, mWifiNative, mWifiMetrics,
mWifiVendorHalMock, mSupplicantP2pIfaceHalMock, mHalDeviceManagerMock,
- mPropertyServiceMock);
+ mPropertyServiceMock, mWifiInjector);
when(mWifiNative.getClientInterfaceNames()).thenReturn(mWifiClientInterfaceNames);
@@ -149,7 +158,9 @@ public class WifiP2pNativeTest extends WifiBaseTest {
// setup default mock behaviors
when(mHalDeviceManagerMock.isSupported()).thenReturn(true);
-
+ mMockP2pIface.name = TEST_IFACE;
+ when(mWifiNative.createP2pIface(any(HalDeviceManager.InterfaceDestroyedListener.class),
+ any(Handler.class), any(WorkSource.class))).thenReturn(mMockP2pIface);
doAnswer(new AnswerWithArguments() {
public boolean answer(WifiP2pGroupList groupList) {
for (WifiP2pGroup g : mWifiP2pGroupList.getGroupList()) {
@@ -178,16 +189,34 @@ public class WifiP2pNativeTest extends WifiBaseTest {
}
/**
- * Verifies that setupInterface returns correct values when successfully creating P2P Iface.
+ * Verifies that setupInterface by calling HalDeviceManager returns correct values
+ * when successfully creating P2P Iface. (Old design, feature is disabled)
*/
@Test
- public void testSetupInterfaceSuccessInCreatingP2pIface() {
- when(mHalDeviceManagerMock.createP2pIface(
- any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
+ public void testSetupInterfaceByHDMSuccessInCreatingP2pIface() {
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(false);
+ testSetupInterfaceSuccessInCreatingP2pIface(false);
+ }
+
+ /**
+ * Verifies that setupInterface by WifiNative returns correct values
+ * when successfully creating P2P Iface. (The default behavior)
+ */
+ @Test
+ public void testSetupInterfaceByWifiNativeSuccessInCreatingP2pIface() {
+ testSetupInterfaceSuccessInCreatingP2pIface(true);
+ }
+
+ private void testSetupInterfaceSuccessInCreatingP2pIface(boolean isD2dAloneFeatureEnabled) {
+ if (!isD2dAloneFeatureEnabled) {
+ when(mHalDeviceManagerMock.createP2pIface(
+ any(HalDeviceManager.InterfaceDestroyedListener.class),
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
+ }
when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.setupIface(eq(TEST_IFACE))).thenReturn(true);
+ when(mSupplicantP2pIfaceHalMock.registerDeathHandler(any())).thenReturn(true);
assertEquals(
mWifiP2pNative.setupInterface(
@@ -205,6 +234,7 @@ public class WifiP2pNativeTest extends WifiBaseTest {
when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.setupIface(eq(TEST_IFACE))).thenReturn(true);
+ when(mSupplicantP2pIfaceHalMock.registerDeathHandler(any())).thenReturn(true);
assertEquals(
mWifiP2pNative.setupInterface(
@@ -213,13 +243,34 @@ public class WifiP2pNativeTest extends WifiBaseTest {
}
/**
- * Verifies that setupInterface returns correct values when failing in creating P2P Iface.
+ * Verifies that setupInterface returns correct values when failing in creating P2P Iface
+ * by HDM.
*/
@Test
- public void testSetupInterfaceFailureInCreatingP2pIface() {
- when(mHalDeviceManagerMock.createP2pIface(
- any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null);
+ public void testSetupInterfaceFailureInCreatingP2pIfaceByHDM() {
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(false);
+ testSetupInterfaceFailureInCreatingP2pIface(false);
+ }
+
+ /**
+ * Verifies that setupInterface returns correct values when failing in creating P2P Iface
+ * by WifiNative.
+ */
+ @Test
+ public void testSetupInterfaceFailureInCreatingP2pIfaceByWifiNative() {
+ testSetupInterfaceFailureInCreatingP2pIface(true);
+ }
+
+ private void testSetupInterfaceFailureInCreatingP2pIface(boolean isD2dAloneFeatureEnabled) {
+ if (isD2dAloneFeatureEnabled) {
+ when(mWifiNative.createP2pIface(
+ any(HalDeviceManager.InterfaceDestroyedListener.class),
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null);
+ } else {
+ when(mHalDeviceManagerMock.createP2pIface(
+ any(HalDeviceManager.InterfaceDestroyedListener.class),
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null);
+ }
when(mHalDeviceManagerMock.isItPossibleToCreateIface(
eq(HalDeviceManager.HDM_CREATE_IFACE_P2P), eq(mWorkSourceMock))).thenReturn(true);
@@ -236,10 +287,31 @@ public class WifiP2pNativeTest extends WifiBaseTest {
* HalDevMgr not possibly creating it.
*/
@Test
- public void testSetupInterfaceFailureInCreatingP2pIfaceWhenHalDevMgrNotPossiblyCreate() {
- when(mHalDeviceManagerMock.createP2pIface(
- any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null);
+ public void testSetupInterfaceFailureInHDMCreatingP2pIfaceWhenHalDevMgrNotPossiblyCreate() {
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(false);
+ testSetupInterfaceFailureInCreatingP2pIfaceAndHalDevMgrNotPossiblyCreate(false);
+ }
+
+ /**
+ * Verifies that Wi-Fi metrics do correct action when setting up p2p interface failed and
+ * HalDevMgr not possibly creating it.
+ */
+ @Test
+ public void testSetupInterfaceFailureInCreatingP2pByWifiNativeAndHalDevMgrNotPossiblyCreate() {
+ testSetupInterfaceFailureInCreatingP2pIfaceAndHalDevMgrNotPossiblyCreate(true);
+ }
+
+ private void testSetupInterfaceFailureInCreatingP2pIfaceAndHalDevMgrNotPossiblyCreate(
+ boolean isD2dAloneFeatureEnabled) {
+ if (isD2dAloneFeatureEnabled) {
+ when(mWifiNative.createP2pIface(
+ any(HalDeviceManager.InterfaceDestroyedListener.class),
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null);
+ } else {
+ when(mHalDeviceManagerMock.createP2pIface(
+ any(HalDeviceManager.InterfaceDestroyedListener.class),
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null);
+ }
when(mHalDeviceManagerMock.isItPossibleToCreateIface(
eq(HalDeviceManager.HDM_CREATE_IFACE_P2P), eq(mWorkSourceMock))).thenReturn(false);
@@ -252,19 +324,34 @@ public class WifiP2pNativeTest extends WifiBaseTest {
* initialization fails.
*/
@Test
- public void testSetupInterfaceFailureInSupplicantConnectionInitialization() {
- when(mHalDeviceManagerMock.createP2pIface(
- any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
+ public void testSetupInterfaceByHDMAndFailureInSupplicantConnectionInitialization() {
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(false);
+ testSetupInterfaceFailureInSupplicantConnectionInitialization(false);
+ }
+
+ /**
+ * Verifies that setupInterface returns correct values when supplicant connection
+ * initialization fails.
+ */
+ @Test
+ public void testSetupInterfaceByWifiNativeAndFailureInSupplicantConnectionInitialization() {
+ testSetupInterfaceFailureInSupplicantConnectionInitialization(true);
+ }
+
+ private void testSetupInterfaceFailureInSupplicantConnectionInitialization(
+ boolean isD2dAloneFeatureEnabled) {
+ if (!isD2dAloneFeatureEnabled) {
+ when(mHalDeviceManagerMock.createP2pIface(
+ any(HalDeviceManager.InterfaceDestroyedListener.class),
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
+ }
when(mSupplicantP2pIfaceHalMock.isInitializationStarted()).thenReturn(false);
when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(false);
-
- mWifiP2pNative.setupInterface(mDestroyedListenerMock, mHandlerMock, mWorkSourceMock);
- verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant();
assertEquals(
mWifiP2pNative.setupInterface(
mDestroyedListenerMock, mHandlerMock, mWorkSourceMock),
null);
+ verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant();
}
/**
@@ -272,20 +359,36 @@ public class WifiP2pNativeTest extends WifiBaseTest {
* initialization never completes.
*/
@Test
- public void testSetupInterfaceFailureInSupplicantConnectionInitNotCompleted() {
- when(mHalDeviceManagerMock.createP2pIface(
- any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
+ public void testSetupInterfaceByHDMAndFailureInSupplicantConnectionInitNotCompleted() {
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(false);
+ testSetupInterfaceFailureInSupplicantConnectionInitNotCompleted(false);
+ }
+
+ /**
+ * Verifies that setupInterface returns correct values when supplicant connection
+ * initialization never completes.
+ */
+ @Test
+ public void testSetupInterfaceByWifiNativeAndFailureInSupplicantConnectionInitNotCompleted() {
+ testSetupInterfaceFailureInSupplicantConnectionInitNotCompleted(true);
+ }
+
+ private void testSetupInterfaceFailureInSupplicantConnectionInitNotCompleted(
+ boolean isD2dAloneFeatureEnabled) {
+ if (!isD2dAloneFeatureEnabled) {
+ when(mHalDeviceManagerMock.createP2pIface(
+ any(HalDeviceManager.InterfaceDestroyedListener.class),
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
+ }
when(mSupplicantP2pIfaceHalMock.setupIface(eq(TEST_IFACE))).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(false);
- mWifiP2pNative.setupInterface(mDestroyedListenerMock, mHandlerMock, mWorkSourceMock);
- verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant();
assertEquals(
mWifiP2pNative.setupInterface(
mDestroyedListenerMock, mHandlerMock, mWorkSourceMock),
null);
+ verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant();
}
/**
@@ -293,20 +396,52 @@ public class WifiP2pNativeTest extends WifiBaseTest {
* for supplicant.
*/
@Test
- public void testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicant() {
- when(mHalDeviceManagerMock.createP2pIface(
- any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
+ public void testSetupInterfaceByHDMAndFailureInSettingUpP2pIfaceInSupplicant() {
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(false);
+ testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicant(false);
+ }
+
+ /**
+ * Verifies that setupInterface returns correct values when failing in setting up P2P Iface
+ * for supplicant.
+ */
+ @Test
+ public void testSetupInterfaceByWifiNativeAndFailureInSettingUpP2pIfaceInSupplicant() {
+ testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicant(true);
+ }
+ private void testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicant(
+ boolean isD2dAloneFeatureEnabled) {
+ if (!isD2dAloneFeatureEnabled) {
+ when(mHalDeviceManagerMock.createP2pIface(
+ any(HalDeviceManager.InterfaceDestroyedListener.class),
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
+ }
when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.setupIface(eq(TEST_IFACE))).thenReturn(false);
- mWifiP2pNative.setupInterface(mDestroyedListenerMock, mHandlerMock, mWorkSourceMock);
+ assertEquals(
+ mWifiP2pNative.setupInterface(
+ mDestroyedListenerMock, mHandlerMock, mWorkSourceMock),
+ null);
verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant();
+ }
+
+ /**
+ * Verifies that setupInterface returns correct values when failing in setting up
+ * P2P supplicant handler.
+ */
+ @Test
+ public void testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicantRegisterDeathHandler() {
+ when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true);
+ when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(true);
+ when(mSupplicantP2pIfaceHalMock.setupIface(eq(TEST_IFACE))).thenReturn(true);
+ when(mSupplicantP2pIfaceHalMock.registerDeathHandler(any())).thenReturn(false);
assertEquals(
mWifiP2pNative.setupInterface(
mDestroyedListenerMock, mHandlerMock, mWorkSourceMock),
null);
+ verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant();
}
/**
@@ -613,10 +748,11 @@ public class WifiP2pNativeTest extends WifiBaseTest {
*/
@Test
public void testP2pExtListen() {
- when(mSupplicantP2pIfaceHalMock.configureExtListen(anyBoolean(), anyInt(), anyInt()))
+ when(mSupplicantP2pIfaceHalMock.configureExtListen(anyBoolean(), anyInt(), anyInt(), any()))
.thenReturn(true);
- assertTrue(mWifiP2pNative.p2pExtListen(true, 10000, 20000));
- verify(mSupplicantP2pIfaceHalMock).configureExtListen(eq(true), eq(10000), eq(20000));
+ assertTrue(mWifiP2pNative.p2pExtListen(true, 10000, 20000, null));
+ verify(mSupplicantP2pIfaceHalMock).configureExtListen(
+ eq(true), eq(10000), eq(20000), eq(null));
}
/**
@@ -1013,6 +1149,7 @@ public class WifiP2pNativeTest extends WifiBaseTest {
when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.setupIface(any())).thenReturn(true);
+ when(mSupplicantP2pIfaceHalMock.registerDeathHandler(any())).thenReturn(true);
mWifiP2pNative.setupInterface(mDestroyedListenerMock, mHandlerMock, mWorkSourceMock);
}
@@ -1055,4 +1192,15 @@ public class WifiP2pNativeTest extends WifiBaseTest {
verify(mSupplicantP2pIfaceHalMock).configureEapolIpAddressAllocationParams(eq(0x0101A8C0),
eq(0x00FFFFFF), eq(0x0501A8C0), eq(0x0801A8C0));
}
+
+ @Test
+ public void testStopP2pSupplicantIfNecessary() throws Exception {
+ when(mSupplicantP2pIfaceHalMock.isInitializationStarted()).thenReturn(false);
+ mWifiP2pNative.stopP2pSupplicantIfNecessary();
+ verify(mSupplicantP2pIfaceHalMock, never()).terminate();
+
+ when(mSupplicantP2pIfaceHalMock.isInitializationStarted()).thenReturn(true);
+ mWifiP2pNative.stopP2pSupplicantIfNecessary();
+ verify(mSupplicantP2pIfaceHalMock).terminate();
+ }
}
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 546da0c60f..4589a287dd 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
@@ -24,6 +24,7 @@ import static android.net.wifi.WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTL;
+import static com.android.server.wifi.WifiSettingsConfigStore.D2D_ALLOWED_WHEN_INFRA_STA_DISABLED;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_DEVICE_ADDRESS;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_DEVICE_NAME;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_PENDING_FACTORY_RESET;
@@ -78,21 +79,26 @@ import android.content.res.Resources;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.InetAddresses;
+import android.net.LinkAddress;
import android.net.MacAddress;
import android.net.NetworkInfo;
import android.net.NetworkStack;
+import android.net.TetheredClient;
import android.net.TetheringInterface;
import android.net.TetheringManager;
import android.net.wifi.CoexUnsafeChannel;
+import android.net.wifi.OuiKeyedData;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WpsInfo;
+import android.net.wifi.p2p.IWifiP2pListener;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
+import android.net.wifi.p2p.WifiP2pExtListenParams;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pGroupList;
import android.net.wifi.p2p.WifiP2pInfo;
@@ -106,9 +112,12 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
+import android.os.PersistableBundle;
import android.os.Process;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.WorkSource;
@@ -116,6 +125,7 @@ import android.os.test.TestLooper;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArraySet;
+import android.util.LocalLog;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
@@ -151,6 +161,7 @@ import com.android.server.wifi.util.StringUtil;
import com.android.server.wifi.util.WaitingState;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
+import com.android.wifi.flags.FeatureFlags;
import com.android.wifi.resources.R;
import org.junit.After;
@@ -169,9 +180,11 @@ import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -182,11 +195,14 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
private static final String TAG = "WifiP2pServiceImplTest";
private static final String IFACE_NAME_P2P = "mockP2p0";
private static final String P2P_GO_IP = "192.168.49.1";
+ private static final String P2P_PEER_IP = "192.168.49.50";
private static final long STATE_CHANGE_WAITING_TIME = 1000;
private static final String thisDeviceMac = "11:22:33:44:55:66";
+ private static final String PEER_INTERFACE_ADDRESS = "aa:bb:cc:dd:aa:bb";
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_NETWORK_NAME = "DIRECT-xy-NEW";
private static final String TEST_ANDROID_ID = "314Deadbeef";
private static final String[] TEST_REQUIRED_PERMISSIONS_T =
new String[] {
@@ -234,6 +250,11 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
private ArgumentCaptor<TetheringManager.TetheringEventCallback> mTetheringEventCallbackCaptor =
ArgumentCaptor.forClass(TetheringManager.TetheringEventCallback.class);
private TetheringManager.TetheringEventCallback mTetheringEventCallback;
+ private Bundle mExtras = new Bundle();
+ private IWifiP2pListener mP2pListener = mock(IWifiP2pListener.class);
+ private ArgumentCaptor<WifiSettingsConfigStore.OnSettingsChangedListener>
+ mD2DAllowedSettingsCallbackCaptor =
+ ArgumentCaptor.forClass(WifiSettingsConfigStore.OnSettingsChangedListener.class);
@Mock Bundle mBundle;
@Mock Context mContext;
@@ -277,6 +298,12 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
@Mock TetheringManager mTetheringManager;
@Mock WifiDiagnostics mWifiDiagnostics;
@Mock WifiP2pConnection mWifiP2pConnection;
+ @Mock Collection<TetheredClient> mClients;
+ @Mock TetheredClient mTetheredClient;
+ @Mock TetheredClient.AddressInfo mAddressInfo;
+ @Mock List<TetheredClient.AddressInfo> mAddresses;
+ @Mock LocalLog mLocalLog;
+ @Mock FeatureFlags mFeatureFlags;
private void generatorTestData() {
mTestWifiP2pGroup = new WifiP2pGroup();
@@ -306,7 +333,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
// for general group started event
mTestWifiP2pNewPersistentGoGroup = new WifiP2pGroup();
mTestWifiP2pNewPersistentGoGroup.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
- mTestWifiP2pNewPersistentGoGroup.setNetworkName("DIRECT-xy-NEW");
+ mTestWifiP2pNewPersistentGoGroup.setNetworkName(TEST_NETWORK_NAME);
mTestWifiP2pNewPersistentGoGroup.setOwner(new WifiP2pDevice(thisDeviceMac));
mTestWifiP2pNewPersistentGoGroup.setIsGroupOwner(true);
mTestWifiP2pNewPersistentGoGroup.setInterface(IFACE_NAME_P2P);
@@ -407,6 +434,14 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
}
}
+ private void simulateOnClientsChanged() throws Exception {
+ List<TetheredClient> clients = new ArrayList<>(1);
+ clients.add(mTetheredClient);
+ mClients = clients;
+ mTetheringEventCallback.onClientsChanged(mClients);
+ mLooper.dispatchAll();
+ }
+
/**
* Mock send WifiP2pManager.UPDATE_CHANNEL_INFO
*
@@ -665,6 +700,32 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
}
/**
+ * Send WifiP2pMonitor.AP_STA_CONNECTED_EVENT.
+ *
+ * @param device Peer device information.
+ */
+ private void sendApStaConnectedEvent(WifiP2pDevice device) throws Exception {
+ Message msg = Message.obtain();
+ msg.what = WifiP2pMonitor.AP_STA_CONNECTED_EVENT;
+ msg.obj = device;
+ mP2pStateMachineMessenger.send(Message.obtain(msg));
+ mLooper.dispatchAll();
+ }
+
+ /**
+ * Send WifiP2pMonitor.AP_STA_DISCONNECTED_EVENT.
+ *
+ * @param device Peer device information.
+ */
+ private void sendApStaDisConnectedEvent(WifiP2pDevice device) throws Exception {
+ Message msg = Message.obtain();
+ msg.what = WifiP2pMonitor.AP_STA_DISCONNECTED_EVENT;
+ msg.obj = device;
+ mP2pStateMachineMessenger.send(Message.obtain(msg));
+ mLooper.dispatchAll();
+ }
+
+ /**
* Mock send WifiP2pManager.SET_CHANNEL
*
* @param replyMessenger for checking replied message.
@@ -1217,7 +1278,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
/**
* Check the broadcast of WIFI_P2P_THIS_DEVICE_CHANGED_ACTION is sent as expected.
*/
- private void checkSendThisDeviceChangedBroadcast() {
+ private void checkSendThisDeviceChangedBroadcast() throws RemoteException {
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
String[] permission_gold;
if (mWifiPermissionsUtil.isLocationModeEnabled()) {
@@ -1259,6 +1320,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
}
verifyDeviceChangedBroadcastIntent(intentCaptor.getValue());
}
+ if (SdkLevel.isAtLeastT()) {
+ verify(mP2pListener, atLeastOnce()).onDeviceConfigurationChanged(any());
+ }
}
/**
@@ -1340,6 +1404,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
when(mWifiSettingsConfigStore.get(eq(WIFI_P2P_DEVICE_ADDRESS))).thenReturn(thisDeviceMac);
when(mWifiSettingsConfigStore.get(eq(WIFI_P2P_DEVICE_NAME))).thenReturn(thisDeviceName);
when(mWifiSettingsConfigStore.get(eq(WIFI_P2P_PENDING_FACTORY_RESET))).thenReturn(false);
+ when(mWifiSettingsConfigStore.get(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED)))
+ .thenReturn(false);
when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
if (supported) {
when(mPackageManager.hasSystemFeature(eq(PackageManager.FEATURE_WIFI_DIRECT)))
@@ -1362,6 +1428,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
.config_p2pWaitForPeerInviteOnInviteStatusInfoUnavailable)).thenReturn(false);
when(mResources.getBoolean(R.bool
.config_wifiP2pGoIpAddressAllocationInEapolFrames)).thenReturn(false);
+ when(mResources.getInteger(R.integer.config_wifiConfigurationWifiRunnerThresholdInMs))
+ .thenReturn(4000);
when(mResources.getConfiguration()).thenReturn(mConfiguration);
when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade);
when(mWifiInjector.getUserManager()).thenReturn(mUserManager);
@@ -1443,9 +1511,12 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
when(mCoexManager.getCoexRestrictions()).thenReturn(0);
when(mCoexManager.getCoexUnsafeChannels()).thenReturn(Collections.emptyList());
when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade);
+ when(mDeviceConfigFacade.getFeatureFlags()).thenReturn(mFeatureFlags);
when(mWifiInjector.getWifiDiagnostics()).thenReturn(mWifiDiagnostics);
+ when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog);
when(mDeviceConfigFacade.isP2pFailureBugreportEnabled()).thenReturn(false);
when(mContext.getSystemService(TetheringManager.class)).thenReturn(mTetheringManager);
+ when(mP2pListener.asBinder()).thenReturn(mock(IBinder.class));
mWifiP2pServiceImpl = new WifiP2pServiceImpl(mContext, mWifiInjector);
if (supported) {
@@ -1468,6 +1539,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
}
mWifiStateChangedReceiver = mBcastRxCaptor.getAllValues().get(0);
mLocationModeReceiver = mBcastRxCaptor.getAllValues().get(1);
+ verify(mWifiSettingsConfigStore).registerChangeListener(
+ eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED),
+ mD2DAllowedSettingsCallbackCaptor.capture(), any());
}
verify(mWifiPermissionsUtil, never()).isLocationModeEnabled();
@@ -1503,6 +1577,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
mClient2 = new Binder();
when(mContext.createContextAsUser(any(), anyInt())).thenReturn(mContext);
mWifiP2pServiceImpl.handleBootCompleted();
+ if (SdkLevel.isAtLeastT()) {
+ mWifiP2pServiceImpl.registerWifiP2pListener(mP2pListener, TEST_PACKAGE_NAME, mExtras);
+ }
}
@After
@@ -1555,7 +1632,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
forceP2pEnabled(mClient1);
WifiP2pGroup group = new WifiP2pGroup();
group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
- group.setNetworkName("DIRECT-xy-NEW");
+ group.setNetworkName(TEST_NETWORK_NAME);
group.setOwner(new WifiP2pDevice("thisDeviceMac"));
group.setIsGroupOwner(true);
group.setInterface(IFACE_NAME_P2P);
@@ -1709,6 +1786,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
inOrder.verify(mContext).sendStickyBroadcastAsUser(argThat(
new WifiP2pServiceImplTest.P2pStateChangedIntentMatcher(
WifiP2pManager.WIFI_P2P_STATE_ENABLED)), any());
+ if (SdkLevel.isAtLeastT()) {
+ verify(mP2pListener).onP2pStateChanged(eq(WifiP2pManager.WIFI_P2P_STATE_ENABLED));
+ }
// disabled broadcast sent when user restriction is set
simulateUserRestrictionChange(true);
@@ -1716,6 +1796,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
inOrder.verify(mContext).sendStickyBroadcastAsUser(argThat(
new WifiP2pServiceImplTest.P2pStateChangedIntentMatcher(
WifiP2pManager.WIFI_P2P_STATE_DISABLED)), any());
+ if (SdkLevel.isAtLeastT()) {
+ verify(mP2pListener).onP2pStateChanged(eq(WifiP2pManager.WIFI_P2P_STATE_DISABLED));
+ }
// no disabled broadcast sent when Wi-Fi is disabled since broadcast already sent
simulateWifiStateChange(false);
@@ -2184,6 +2267,10 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
assertTrue(mClientHandler.hasMessages(WifiP2pManager.DISCOVER_PEERS_SUCCEEDED));
verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_DISCOVER_PEERS), anyInt(),
anyInt(), anyInt(), anyString(), eq(true));
+ if (SdkLevel.isAtLeastT()) {
+ verify(mP2pListener).onDiscoveryStateChanged(
+ eq(WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED));
+ }
}
/**
@@ -2696,7 +2783,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
// p2pFlush should be invoked once in forceP2pEnabled.
verify(mWifiNative).p2pFlush();
verify(mWifiNative, never()).p2pStopFind();
- verify(mWifiNative, never()).p2pExtListen(anyBoolean(), anyInt(), anyInt());
+ verify(mWifiNative, never()).p2pExtListen(anyBoolean(), anyInt(), anyInt(), eq(null));
}
/**
@@ -2705,14 +2792,14 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
@Test
public void testStartListenFailureWhenNativeCallFailure() throws Exception {
setTargetSdkGreaterThanT();
- when(mWifiNative.p2pExtListen(eq(true), anyInt(), anyInt())).thenReturn(false);
+ when(mWifiNative.p2pExtListen(eq(true), anyInt(), anyInt(), any())).thenReturn(false);
forceP2pEnabled(mClient1);
sendSimpleMsg(mClientMessenger, WifiP2pManager.START_LISTEN);
// p2pFlush should be invoked once in forceP2pEnabled.
verify(mWifiNative).p2pFlush();
verify(mWifiNative).p2pStopFind();
verify(mWifiNative).p2pExtListen(eq(true), eq(P2P_EXT_LISTEN_PERIOD_MS),
- eq(P2P_EXT_LISTEN_INTERVAL_MS));
+ eq(P2P_EXT_LISTEN_INTERVAL_MS), eq(null));
assertTrue(mClientHandler.hasMessages(WifiP2pManager.START_LISTEN_FAILED));
if (SdkLevel.isAtLeastT()) {
verify(mWifiPermissionsUtil, atLeastOnce()).checkNearbyDevicesPermission(
@@ -2731,14 +2818,14 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
@Test
public void testStartListenSuccess() throws Exception {
setTargetSdkGreaterThanT();
- when(mWifiNative.p2pExtListen(eq(true), anyInt(), anyInt())).thenReturn(true);
+ when(mWifiNative.p2pExtListen(eq(true), anyInt(), anyInt(), any())).thenReturn(true);
forceP2pEnabled(mClient1);
sendSimpleMsg(mClientMessenger, WifiP2pManager.START_LISTEN);
// p2pFlush should be invoked once in forceP2pEnabled.
verify(mWifiNative).p2pFlush();
verify(mWifiNative).p2pStopFind();
verify(mWifiNative).p2pExtListen(eq(true), eq(P2P_EXT_LISTEN_PERIOD_MS),
- eq(P2P_EXT_LISTEN_INTERVAL_MS));
+ eq(P2P_EXT_LISTEN_INTERVAL_MS), eq(null));
assertTrue(mClientHandler.hasMessages(WifiP2pManager.START_LISTEN_SUCCEEDED));
if (SdkLevel.isAtLeastT()) {
verify(mWifiPermissionsUtil, atLeastOnce()).checkNearbyDevicesPermission(
@@ -2749,6 +2836,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
verify(mWifiPermissionsUtil).checkCanAccessWifiDirect(eq(TEST_PACKAGE_NAME),
eq("testFeature"), anyInt(), eq(true));
}
+ if (SdkLevel.isAtLeastT()) {
+ verify(mP2pListener).onListenStateChanged(eq(WifiP2pManager.WIFI_P2P_LISTEN_STARTED));
+ }
}
/**
@@ -2757,14 +2847,14 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
@Test
public void testStartListenSuccessWithGroup() throws Exception {
setTargetSdkGreaterThanT();
- when(mWifiNative.p2pExtListen(eq(true), anyInt(), anyInt())).thenReturn(true);
+ when(mWifiNative.p2pExtListen(eq(true), anyInt(), anyInt(), any())).thenReturn(true);
mockEnterGroupCreatedState();
sendSimpleMsg(mClientMessenger, WifiP2pManager.START_LISTEN);
// p2pFlush should be invoked once in forceP2pEnabled.
verify(mWifiNative).p2pFlush();
verify(mWifiNative, times(2)).p2pStopFind();
verify(mWifiNative).p2pExtListen(eq(true), eq(P2P_EXT_LISTEN_PERIOD_MS),
- eq(P2P_EXT_LISTEN_INTERVAL_MS));
+ eq(P2P_EXT_LISTEN_INTERVAL_MS), eq(null));
assertTrue(mClientHandler.hasMessages(WifiP2pManager.START_LISTEN_SUCCEEDED));
if (SdkLevel.isAtLeastT()) {
verify(mWifiPermissionsUtil, atLeastOnce()).checkNearbyDevicesPermission(
@@ -2779,6 +2869,47 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
anyInt(), anyInt(), anyString(), eq(true));
}
+ /**
+ * Verify that a caller with proper permission can send WifiP2pManager.START_LISTEN
+ * with additional parameters.
+ */
+ @Test
+ public void testStartListenSuccessWithExtListenParams() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ setTargetSdkGreaterThanT();
+ when(mWifiNative.p2pExtListen(eq(true), anyInt(), anyInt(), any())).thenReturn(true);
+ forceP2pEnabled(mClient1);
+
+ OuiKeyedData vendorDataElement =
+ new OuiKeyedData.Builder(0x00aabbcc, new PersistableBundle()).build();
+ List<OuiKeyedData> vendorData = Arrays.asList(vendorDataElement);
+ WifiP2pExtListenParams extListenParams =
+ new WifiP2pExtListenParams.Builder().setVendorData(vendorData).build();
+
+ Message msg = Message.obtain();
+ msg.what = WifiP2pManager.START_LISTEN;
+ msg.arg1 = WifiP2pManager.WIFI_P2P_EXT_LISTEN_WITH_PARAMS;
+ msg.replyTo = mClientMessenger;
+ msg.obj = new AttributionSource(1000, TEST_PACKAGE_NAME, null);
+
+ Bundle extras = new Bundle();
+ extras.putParcelable(WifiP2pManager.EXTRA_PARAM_KEY_EXT_LISTEN_PARAMS, extListenParams);
+ msg.getData().putBundle(WifiP2pManager.EXTRA_PARAM_KEY_BUNDLE, extras);
+ mP2pStateMachineMessenger.send(Message.obtain(msg));
+ mLooper.dispatchAll();
+
+ // p2pFlush should be invoked once during forceP2pEnabled.
+ verify(mWifiNative).p2pFlush();
+ verify(mWifiNative).p2pStopFind();
+ verify(mWifiNative).p2pExtListen(eq(true), eq(P2P_EXT_LISTEN_PERIOD_MS),
+ eq(P2P_EXT_LISTEN_INTERVAL_MS), any(WifiP2pExtListenParams.class));
+ assertTrue(mClientHandler.hasMessages(WifiP2pManager.START_LISTEN_SUCCEEDED));
+ verify(mWifiPermissionsUtil, atLeastOnce()).checkNearbyDevicesPermission(
+ any(), eq(true), any());
+ verify(mWifiPermissionsUtil, never()).checkCanAccessWifiDirect(
+ any(), any(), anyInt(), anyBoolean());
+ }
+
@Test
public void testStartListenAndSetChannelFailureWithDefaultStateHandling() throws Exception {
setTargetSdkGreaterThanT();
@@ -2802,11 +2933,11 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
*/
@Test
public void testStopListenFailureWhenNativeCallFailure() throws Exception {
- when(mWifiNative.p2pExtListen(eq(false), anyInt(), anyInt())).thenReturn(false);
+ when(mWifiNative.p2pExtListen(eq(false), anyInt(), anyInt(), any())).thenReturn(false);
forceP2pEnabled(mClient1);
sendSimpleMsg(mClientMessenger, WifiP2pManager.STOP_LISTEN);
verify(mWifiNative).p2pStopFind();
- verify(mWifiNative).p2pExtListen(eq(false), anyInt(), anyInt());
+ verify(mWifiNative).p2pExtListen(eq(false), anyInt(), anyInt(), eq(null));
assertTrue(mClientHandler.hasMessages(WifiP2pManager.STOP_LISTEN_FAILED));
}
@@ -2815,11 +2946,11 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
*/
@Test
public void testStopListenSuccess() throws Exception {
- when(mWifiNative.p2pExtListen(eq(false), anyInt(), anyInt())).thenReturn(true);
+ when(mWifiNative.p2pExtListen(eq(false), anyInt(), anyInt(), any())).thenReturn(true);
forceP2pEnabled(mClient1);
sendSimpleMsg(mClientMessenger, WifiP2pManager.STOP_LISTEN);
verify(mWifiNative).p2pStopFind();
- verify(mWifiNative).p2pExtListen(eq(false), anyInt(), anyInt());
+ verify(mWifiNative).p2pExtListen(eq(false), anyInt(), anyInt(), eq(null));
assertTrue(mClientHandler.hasMessages(WifiP2pManager.STOP_LISTEN_SUCCEEDED));
verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_STOP_LISTENING), anyInt(),
anyInt(), anyInt(), anyString(), eq(true));
@@ -3311,7 +3442,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
WifiP2pGroup group = new WifiP2pGroup();
group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
- group.setNetworkName("DIRECT-xy-NEW");
+ group.setNetworkName(TEST_NETWORK_NAME);
group.setOwner(new WifiP2pDevice("thisDeviceMac"));
group.setIsGroupOwner(true);
group.setInterface(IFACE_NAME_P2P);
@@ -3321,6 +3452,144 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
eq(P2pConnectionEvent.CLF_NONE));
}
+ @Test
+ public void testOnClientsChangedOnApStaConnection() throws Exception {
+ when(mTetheredClient.getTetheringType()).thenReturn(TetheringManager.TETHERING_WIFI_P2P);
+ when(mTetheredClient.getAddresses()).thenReturn(mAddresses);
+ when(mAddresses.size()).thenReturn(1);
+ when(mAddresses.get(0)).thenReturn(mAddressInfo);
+ when(mTetheredClient.getMacAddress())
+ .thenReturn(MacAddress.fromString(PEER_INTERFACE_ADDRESS));
+ when(mAddressInfo.getAddress()).thenReturn(new LinkAddress(P2P_PEER_IP + "/" + "24"));
+
+ forceP2pEnabled(mClient1);
+
+ // Update the P2P peer list.
+ WifiP2pDeviceList peers;
+ WifiP2pDevice dev;
+ mockPeersList();
+ sendRequestPeersMsg(mClientMessenger);
+ verify(mClientHandler, times(1)).sendMessage(mMessageCaptor.capture());
+
+ // Start the P2P GO.
+ WifiP2pGroup group = new WifiP2pGroup();
+ group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
+ group.setNetworkName("DIRECT-xy-NEW");
+ group.setOwner(new WifiP2pDevice("thisDeviceMac"));
+ group.setIsGroupOwner(true);
+ group.setInterface(IFACE_NAME_P2P);
+ sendGroupStartedMsg(group);
+ simulateTetherReady();
+
+ // Trigger AP_STA_CONNECTED event & validate the results.
+ WifiP2pDevice connectedClientDevice = new WifiP2pDevice(mTestWifiP2pDevice);
+ connectedClientDevice.setInterfaceMacAddress(MacAddress.fromString(PEER_INTERFACE_ADDRESS));
+ sendApStaConnectedEvent(connectedClientDevice);
+ simulateOnClientsChanged();
+ // Verify that the connected client is added to the p2p group client list.
+ sendRequestGroupInfoMsg(mClientMessenger);
+ verify(mClientHandler, times(2)).sendMessage(mMessageCaptor.capture());
+ assertEquals(WifiP2pManager.RESPONSE_GROUP_INFO, mMessageCaptor.getValue().what);
+ WifiP2pGroup wifiP2pGroup = (WifiP2pGroup) mMessageCaptor.getValue().obj;
+ assertEquals(1, wifiP2pGroup.getClientList().size());
+ WifiP2pDevice client = wifiP2pGroup.getClientList().iterator().next();
+ assertNotNull(client);
+ assertEquals(mTestWifiP2pDevice.deviceAddress, client.deviceAddress);
+ assertEquals(MacAddress.fromString(PEER_INTERFACE_ADDRESS),
+ client.getInterfaceMacAddress());
+ if (SdkLevel.isAtLeastV()) {
+ assertEquals(InetAddresses.parseNumericAddress(P2P_PEER_IP), client.getIpAddress());
+ }
+
+ // Verify that the interface MAC address and IP address is not updated in the P2P peer list.
+ sendRequestPeersMsg(mClientMessenger);
+ verify(mClientHandler, times(3)).sendMessage(mMessageCaptor.capture());
+ peers = (WifiP2pDeviceList) mMessageCaptor.getValue().obj;
+ assertEquals(WifiP2pManager.RESPONSE_PEERS, mMessageCaptor.getValue().what);
+ dev = peers.get(mTestWifiP2pDevice.deviceAddress);
+ assertNotNull(dev);
+ assertNull(dev.getInterfaceMacAddress());
+ if (SdkLevel.isAtLeastV()) {
+ assertNull(dev.getIpAddress());
+ }
+
+ }
+
+ @Test
+ public void testApStaConnectedDisconnectedEventWithEapolIPAddress() throws Exception {
+ forceP2pEnabled(mClient1);
+
+ WifiP2pDeviceList peers;
+ WifiP2pDevice dev;
+ WifiP2pGroup wifiP2pGroup;
+
+ // Update the P2P Peer list.
+ mockPeersList();
+ sendRequestPeersMsg(mClientMessenger);
+ verify(mClientHandler, times(1)).sendMessage(mMessageCaptor.capture());
+
+ // Start the P2P GO.
+ WifiP2pGroup group = new WifiP2pGroup();
+ group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
+ group.setNetworkName("DIRECT-xy-NEW");
+ group.setOwner(new WifiP2pDevice("thisDeviceMac"));
+ group.setIsGroupOwner(true);
+ group.setInterface(IFACE_NAME_P2P);
+ sendGroupStartedMsg(group);
+ simulateTetherReady();
+
+ // Trigger AP_STA_CONNECTED event & validate the results.
+ WifiP2pDevice connectedClientDevice = new WifiP2pDevice(mTestWifiP2pDevice);
+ connectedClientDevice.setInterfaceMacAddress(MacAddress.fromString(PEER_INTERFACE_ADDRESS));
+ connectedClientDevice.setIpAddress(InetAddresses.parseNumericAddress(P2P_PEER_IP));
+ sendApStaConnectedEvent(connectedClientDevice);
+ // Verify that the connected client is added to the p2p group client list.
+ sendRequestGroupInfoMsg(mClientMessenger);
+ verify(mClientHandler, times(2)).sendMessage(mMessageCaptor.capture());
+ assertEquals(WifiP2pManager.RESPONSE_GROUP_INFO, mMessageCaptor.getValue().what);
+ wifiP2pGroup = (WifiP2pGroup) mMessageCaptor.getValue().obj;
+ assertEquals(1, wifiP2pGroup.getClientList().size());
+ WifiP2pDevice client = wifiP2pGroup.getClientList().iterator().next();
+ assertNotNull(client);
+ assertEquals(mTestWifiP2pDevice.deviceAddress, client.deviceAddress);
+ assertEquals(MacAddress.fromString(PEER_INTERFACE_ADDRESS),
+ client.getInterfaceMacAddress());
+ if (SdkLevel.isAtLeastV()) {
+ assertEquals(InetAddresses.parseNumericAddress(P2P_PEER_IP), client.getIpAddress());
+ }
+
+ // Verify that the interface MAC address and IP address is not set in the P2P peer list.
+ sendRequestPeersMsg(mClientMessenger);
+ verify(mClientHandler, times(3)).sendMessage(mMessageCaptor.capture());
+ peers = (WifiP2pDeviceList) mMessageCaptor.getValue().obj;
+ assertEquals(WifiP2pManager.RESPONSE_PEERS, mMessageCaptor.getValue().what);
+ dev = peers.get(mTestWifiP2pDevice.deviceAddress);
+ assertNotNull(dev);
+ assertNull(dev.getInterfaceMacAddress());
+ if (SdkLevel.isAtLeastV()) {
+ assertNull(dev.getIpAddress());
+ }
+
+ // Trigger AP_STA_DISCONNECTED event & validate the results.
+ sendApStaDisConnectedEvent(connectedClientDevice);
+ // Verify that the client is removed from the P2P group client list.
+ sendRequestGroupInfoMsg(mClientMessenger);
+ verify(mClientHandler, times(4)).sendMessage(mMessageCaptor.capture());
+ assertEquals(WifiP2pManager.RESPONSE_GROUP_INFO, mMessageCaptor.getValue().what);
+ wifiP2pGroup = (WifiP2pGroup) mMessageCaptor.getValue().obj;
+ assertNotNull(wifiP2pGroup);
+ assertEquals(0, wifiP2pGroup.getClientList().size());
+
+ // Verify that the P2P device is not removed from the P2P peer list.
+ sendRequestPeersMsg(mClientMessenger);
+ verify(mClientHandler, times(5)).sendMessage(mMessageCaptor.capture());
+ peers = (WifiP2pDeviceList) mMessageCaptor.getValue().obj;
+ assertEquals(WifiP2pManager.RESPONSE_PEERS, mMessageCaptor.getValue().what);
+ dev = peers.get(mTestWifiP2pDevice.deviceAddress);
+ assertNotNull(dev);
+ assertEquals(mTestWifiP2pDevice.deviceAddress, dev.deviceAddress);
+ }
+
/**
* Verify the connection event ends due to timeout.
*/
@@ -3479,7 +3748,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
WifiP2pServiceImpl.P2pStatus.NO_COMMON_CHANNEL);
WifiP2pGroup group = new WifiP2pGroup();
group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
- group.setNetworkName("DIRECT-xy-NEW");
+ group.setNetworkName(TEST_NETWORK_NAME);
group.setOwner(new WifiP2pDevice("thisDeviceMac"));
group.setIsGroupOwner(true);
group.setInterface(IFACE_NAME_P2P);
@@ -4069,7 +4338,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
*/
@Test
public void testStopListenSuccessWhenNativeCallSucceedInCreatingGroup() throws Exception {
- when(mWifiNative.p2pExtListen(eq(false), anyInt(), anyInt())).thenReturn(true);
+ when(mWifiNative.p2pExtListen(eq(false), anyInt(), anyInt(), any())).thenReturn(true);
// Move to group creating state
testConnectWithConfigValidAsGroupSuccess();
sendSimpleMsg(mClientMessenger, WifiP2pManager.STOP_LISTEN);
@@ -4084,7 +4353,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
*/
@Test
public void testStopListenFailureWhenNativeCallFailInCreatingGroup() throws Exception {
- when(mWifiNative.p2pExtListen(eq(false), anyInt(), anyInt())).thenReturn(false);
+ when(mWifiNative.p2pExtListen(eq(false), anyInt(), anyInt(), any())).thenReturn(false);
// Move to group creating state
testConnectWithConfigValidAsGroupSuccess();
sendSimpleMsg(mClientMessenger, WifiP2pManager.STOP_LISTEN);
@@ -5080,6 +5349,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
when(mWifiNative.p2pListNetworks(any())).thenReturn(true);
sendSimpleMsg(mClientMessenger, WifiP2pManager.FACTORY_RESET);
checkSendP2pPersistentGroupsChangedBroadcast();
+ if (SdkLevel.isAtLeastT()) {
+ verify(mP2pListener, atLeastOnce()).onPersistentGroupsChanged(any());
+ }
verify(mWifiInjector).getUserManager();
verify(mPackageManager).getNameForUid(anyInt());
verify(mWifiPermissionsUtil).checkNetworkSettingsPermission(anyInt());
@@ -5492,13 +5764,13 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
when(mWifiPermissionsUtil.checkCanAccessWifiDirect(eq(TEST_PACKAGE_NAME), eq("testFeature"),
anyInt(), anyBoolean())).thenReturn(true);
- when(mWifiNative.p2pExtListen(anyBoolean(), anyInt(), anyInt())).thenReturn(true);
+ when(mWifiNative.p2pExtListen(anyBoolean(), anyInt(), anyInt(), any())).thenReturn(true);
sendSimpleMsg(mClientMessenger, WifiP2pManager.START_LISTEN);
verify(mWifiNative).p2pStopFind();
sendSimpleMsg(mClientMessenger, WifiP2pManager.GET_LISTEN_STATE);
sendSimpleMsg(mClientMessenger, WifiP2pManager.STOP_LISTEN);
- verify(mWifiNative, times(2)).p2pExtListen(anyBoolean(), anyInt(), anyInt());
+ verify(mWifiNative, times(2)).p2pExtListen(anyBoolean(), anyInt(), anyInt(), eq(null));
sendSimpleMsg(mClientMessenger, WifiP2pManager.GET_LISTEN_STATE);
verify(mClientHandler, times(5)).sendMessage(mMessageCaptor.capture());
@@ -6233,7 +6505,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
WifiP2pGroup group = new WifiP2pGroup();
group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
- group.setNetworkName("DIRECT-xy-NEW");
+ group.setNetworkName(TEST_NETWORK_NAME);
group.setOwner(new WifiP2pDevice("thisDeviceMac"));
group.setIsGroupOwner(true);
group.setInterface(IFACE_NAME_P2P);
@@ -6416,7 +6688,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
forceP2pEnabled(mClient1);
WifiP2pGroup group = new WifiP2pGroup();
group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
- group.setNetworkName("DIRECT-xy-NEW");
+ group.setNetworkName(TEST_NETWORK_NAME);
group.setOwner(new WifiP2pDevice("thisDeviceMac"));
group.setIsGroupOwner(true);
group.setInterface(IFACE_NAME_P2P);
@@ -7013,6 +7285,27 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
WpsInfo.PBC, WifiP2pManager.CONNECTION_REQUEST_ACCEPT);
}
+ /** Verify the failure scenario for setConnectionRequestResult without a saved peer config. */
+ @Test
+ public void testSetConnectionRequestResultFailureWithoutSavedPeerConfig() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(true);
+ when(mWifiPermissionsUtil.checkNearbyDevicesPermission(any(), anyBoolean(), any()))
+ .thenReturn(true);
+ Binder binder = new Binder();
+ mockEnterGroupCreatedState();
+ sendSetConnectionRequestResultMsg(
+ mClientMessenger,
+ MacAddress.fromString(mTestWifiP2pDevice.deviceAddress),
+ WifiP2pManager.CONNECTION_REQUEST_ACCEPT,
+ binder);
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(mClientHandler).sendMessage(messageCaptor.capture());
+ List<Message> messages = messageCaptor.getAllValues();
+ assertEquals(WifiP2pManager.SET_CONNECTION_REQUEST_RESULT_FAILED, messages.get(0).what);
+ }
+
/**
* Verify that deferring pin to the framework works normally.
*/
@@ -7173,7 +7466,10 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
WifiP2pMonitor.PROV_DISC_STATUS_REJECTED,
pdEvent);
verify(mWifiNative).p2pCancelConnect();
-
+ if (SdkLevel.isAtLeastT()) {
+ verify(mP2pListener).onGroupCreationFailed(
+ eq(WifiP2pManager.GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED));
+ }
}
/**
@@ -7204,6 +7500,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
sendSimpleMsg(null, WifiP2pServiceImpl.PEER_CONNECTION_USER_REJECT);
verify(mWifiNative).p2pReject(eq(mTestWifiP2pDevice.deviceAddress));
+ if (SdkLevel.isAtLeastT()) {
+ verify(mP2pListener).onGroupNegotiationRejectedByUser();
+ }
}
/**
@@ -7431,7 +7730,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
forceP2pEnabled(mClient1);
WifiP2pGroup group = new WifiP2pGroup();
group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
- group.setNetworkName("DIRECT-xy-NEW");
+ group.setNetworkName(TEST_NETWORK_NAME);
group.setOwner(new WifiP2pDevice("thisDeviceMac"));
group.setIsGroupOwner(true);
group.setInterface(IFACE_NAME_P2P);
@@ -7458,7 +7757,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
@Test
public void testGroupStartedTetheringDirectCallback() throws Exception {
- when(mWifiNative.p2pExtListen(anyBoolean(), anyInt(), anyInt())).thenReturn(true);
+ when(mWifiNative.p2pExtListen(anyBoolean(), anyInt(), anyInt(), any())).thenReturn(true);
assumeTrue(SdkLevel.isAtLeastS());
forceP2pEnabled(mClient1);
verify(mTetheringManager).registerTetheringEventCallback(any(), any());
@@ -7476,7 +7775,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
simulateTetherReady();
verify(mWifiP2pMetrics).startGroupEvent(group);
verify(mWifiNative).p2pStopFind();
- verify(mWifiNative).p2pExtListen(eq(false), anyInt(), anyInt());
+ verify(mWifiNative).p2pExtListen(eq(false), anyInt(), anyInt(), eq(null));
sendGroupRemovedMsg();
//force to back disabled state
@@ -7554,7 +7853,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
@Test
public void testSetListenOnInviteStatusCodeInfoUnavailable() throws Exception {
forceP2pEnabled(mClient1);
- when(mWifiNative.p2pExtListen(anyBoolean(), anyInt(), anyInt())).thenReturn(true);
+ when(mWifiNative.p2pExtListen(anyBoolean(), anyInt(), anyInt(), any())).thenReturn(true);
when(mWifiNative.getGroupCapability(any())).thenReturn(0);
when(mWifiNative.p2pReinvoke(anyInt(), any())).thenReturn(true);
when(mWifiNative.p2pGetSsid(any())).thenReturn(null);
@@ -7572,7 +7871,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
verify(mWifiNative, times(2)).p2pStopFind();
verify(mWifiNative).p2pExtListen(eq(true), eq(P2P_EXT_LISTEN_PERIOD_MS),
- eq(P2P_EXT_LISTEN_INTERVAL_MS));
+ eq(P2P_EXT_LISTEN_INTERVAL_MS), eq(null));
}
/**
@@ -7630,4 +7929,227 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
verify(mWifiNative, never()).configureEapolIpAddressAllocationParams(anyInt(),
anyInt(), anyInt(), anyInt());
}
+
+ @Test
+ public void testSendP2pConnectionChangedBroadcast() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ ArgumentCaptor<String[]> permissionCaptor = ArgumentCaptor.forClass(String[].class);
+ String[] receiverPermissions;
+ int flags = Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT;
+
+ // mock p2p enabled
+ forceP2pEnabled(mClient1);
+ if (!SdkLevel.isAtLeastU()) {
+ receiverPermissions = new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_WIFI_STATE};
+ verify(mContext).sendBroadcastWithMultiplePermissions(argThat((Intent intent) -> {
+ WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
+ WifiP2pGroup p2pGroup = intent.getParcelableExtra(
+ WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
+ assert p2pInfo != null;
+ return intent.getAction().equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)
+ && intent.getFlags() == Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ && Objects.isNull(intent.getPackage())
+ && !p2pInfo.groupFormed && Objects.isNull(p2pGroup);
+ }), permissionCaptor.capture());
+ assertEquals(receiverPermissions, permissionCaptor.getValue());
+ } else {
+ receiverPermissions = new String[]{NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK};
+ flags |= Intent.FLAG_RECEIVER_FOREGROUND;
+ verify(mContext).sendBroadcastWithMultiplePermissions(intentCaptor.capture(),
+ permissionCaptor.capture());
+ Intent intent = intentCaptor.getValue();
+ assertEquals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION, intent.getAction());
+ assertEquals(flags, intent.getFlags());
+ WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
+ WifiP2pGroup p2pGroup = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
+ assert p2pInfo != null;
+ assertFalse(p2pInfo.groupFormed);
+ assertFalse(p2pInfo.isGroupOwner);
+ assertNull(p2pGroup);
+ assertEquals(receiverPermissions, permissionCaptor.getValue());
+ }
+
+ // mock group started
+ WifiP2pGroup group = new WifiP2pGroup();
+ group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
+ group.setNetworkName("DIRECT-xy-NEW");
+ group.setOwner(new WifiP2pDevice("thisDeviceMac"));
+ group.setIsGroupOwner(true);
+ group.setInterface(IFACE_NAME_P2P);
+ sendGroupStartedMsg(group);
+ simulateTetherReady();
+
+ // reassign captor again, otherwise captor.getAllValues() will include previous values
+ intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ permissionCaptor = ArgumentCaptor.forClass(String[].class);
+ if (!SdkLevel.isAtLeastU()) {
+ // there are other broadcasts from sendThisDeviceChangedBroadcast() called by
+ // updateThisDevice()
+ verify(mContext, times(6)).sendBroadcastWithMultiplePermissions(intentCaptor.capture(),
+ permissionCaptor.capture());
+ } else {
+ verify(mContext, times(3)).sendBroadcastWithMultiplePermissions(intentCaptor.capture(),
+ permissionCaptor.capture());
+ }
+ ArrayList<Intent> intentArrayList = new ArrayList<>();
+ ArrayList<String[]> permissionArrayList = new ArrayList<>();
+ for (int i = 0; i < intentCaptor.getAllValues().size(); i++) {
+ Intent intent = intentCaptor.getAllValues().get(i);
+ if (intent.getAction().equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
+ intentArrayList.add(intent);
+ permissionArrayList.add(permissionCaptor.getAllValues().get(i));
+ }
+ }
+ assertEquals(3, intentArrayList.size());
+ /* Total three WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION broadcasts are as follows.
+ * ----------------------------------------------------------------------------------------
+ * State p2pInfo.groupFormed p2pGroup intent.permission intent.flag intent.package
+ * ----------------------------------------------------------------------------------------
+ * PreU:
+ * P2pEnabledState :false null RECEIVER_PERMISSIONS_FOR_BROADCAST(location ON)
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ * null
+ * GroupCreatingState :false p2pGroup.isGo RECEIVER_PERMISSIONS_FOR_BROADCAST(location ON)
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ * null
+ * GroupNegotiationState:true p2pGroup.isGo android.Manifest.permission.TETHER_PRIVILEGED
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ * com.android.networkstack.tethering
+ *
+ * PostU:
+ * P2pEnabledState : false null android.permission.MAINLINE_NETWORK_STACK
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT|Intent.FLAG_RECEIVER_FOREGROUND
+ * null
+ * GroupCreatingState : false p2pGroup.isGo android.permission.MAINLINE_NETWORK_STACK
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT|Intent.FLAG_RECEIVER_FOREGROUND
+ * null
+ * GroupNegotiationState: true p2pGroup.isGo android.permission.MAINLINE_NETWORK_STACK
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT|Intent.FLAG_RECEIVER_FOREGROUND
+ * com.android.networkstack.tethering
+ */
+ Intent intent = intentArrayList.get(1);
+ assertEquals(flags, intent.getFlags());
+ assertNull(intent.getPackage());
+ WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
+ assert p2pInfo != null;
+ assertFalse(p2pInfo.groupFormed);
+ WifiP2pGroup p2pGroup = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
+ assert p2pGroup != null;
+ assertTrue(p2pGroup.isGroupOwner());
+ assertEquals(receiverPermissions, permissionArrayList.get(1));
+
+ intent = intentArrayList.get(2);
+ assertEquals(flags, intent.getFlags());
+ assertNotNull(intent.getPackage());
+ p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
+ assert p2pInfo != null;
+ assertTrue(p2pInfo.groupFormed);
+ p2pGroup = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
+ assert p2pGroup != null;
+ assertTrue(p2pGroup.isGroupOwner());
+ if (!SdkLevel.isAtLeastU()) {
+ receiverPermissions = new String[]{android.Manifest.permission.TETHER_PRIVILEGED};
+ }
+ assertEquals(receiverPermissions, permissionArrayList.get(2));
+ }
+
+ /**
+ * Verify that p2p doesn't disable when wifi disabled and D2d is allowed when
+ * infra sta is disabled.
+ */
+ @Test
+ public void testP2pDoesInitWhenClientConnectWithWifiDisabledAndD2DAllowed()
+ throws Exception {
+ when(mWifiSettingsConfigStore.get(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED)))
+ .thenReturn(true);
+ when(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled()).thenReturn(true);
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(true);
+ simulateWifiStateChange(false);
+ checkIsP2pInitWhenClientConnected(true, mClient1,
+ new WorkSource(mClient1.getCallingUid(), TEST_PACKAGE_NAME));
+ }
+
+ @Test
+ public void testWifiP2pListener() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ forceP2pEnabled(mClient1);
+ when(mWifiNative.p2pGroupAdd(any(), eq(false))).thenReturn(true);
+ WifiP2pGroup p2pGroup = new WifiP2pGroup();
+ p2pGroup.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
+ p2pGroup.setNetworkName(TEST_NETWORK_NAME);
+ p2pGroup.setOwner(new WifiP2pDevice("thisDeviceMac"));
+ p2pGroup.setIsGroupOwner(true);
+ p2pGroup.setInterface(IFACE_NAME_P2P);
+
+ sendCreateGroupMsgWithConfigValidAsGroup(mClientMessenger);
+ sendGroupStartedMsg(p2pGroup);
+ simulateTetherReady();
+ verify(mP2pListener).onGroupCreating();
+ ArgumentCaptor<WifiP2pInfo> p2pInfoCaptor = ArgumentCaptor.forClass(WifiP2pInfo.class);
+ ArgumentCaptor<WifiP2pGroup> p2pGroupCaptor = ArgumentCaptor.forClass(WifiP2pGroup.class);
+ verify(mP2pListener).onGroupCreated(p2pInfoCaptor.capture(), p2pGroupCaptor.capture());
+ assertEquals(TEST_NETWORK_NAME, p2pGroupCaptor.getValue().getNetworkName());
+ assertTrue(p2pGroupCaptor.getValue().isClientListEmpty());
+ assertTrue(p2pInfoCaptor.getValue().groupFormed);
+
+ 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(p2pInfoCaptor.capture(),
+ p2pGroupCaptor.capture());
+ assertFalse(p2pGroupCaptor.getValue().isClientListEmpty());
+ assertTrue(p2pInfoCaptor.getValue().groupFormed);
+
+ sendSimpleMsg(null, WifiP2pMonitor.AP_STA_DISCONNECTED_EVENT, peerClientDevice);
+ verify(mP2pListener).onPeerClientDisconnected(p2pInfoCaptor.capture(),
+ p2pGroupCaptor.capture());
+ assertTrue(p2pGroupCaptor.getValue().isClientListEmpty());
+ assertTrue(p2pInfoCaptor.getValue().groupFormed);
+ verify(mP2pListener, atLeastOnce()).onPeerListChanged(any());
+
+ sendSimpleMsg(null, WifiP2pMonitor.P2P_FREQUENCY_CHANGED_EVENT, TEST_GROUP_FREQUENCY);
+ verify(mP2pListener).onFrequencyChanged(p2pInfoCaptor.capture(),
+ p2pGroupCaptor.capture());
+ assertEquals(TEST_GROUP_FREQUENCY, p2pGroupCaptor.getValue().getFrequency());
+
+ sendGroupRemovedMsg();
+ mockEnterDisabledState();
+ mLooper.dispatchAll();
+ verify(mP2pListener).onGroupRemoved();
+
+ mWifiP2pServiceImpl.unregisterWifiP2pListener(mP2pListener);
+ doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceNearbyDevicesPermission(
+ any(), anyBoolean(), any());
+ assertThrows(SecurityException.class,
+ () -> mWifiP2pServiceImpl.registerWifiP2pListener(mP2pListener, TEST_PACKAGE_NAME,
+ mExtras));
+ }
+
+ /**
+ * Verify that p2p disable when the D2d allowed value changes to false
+ */
+ @Test
+ public void testP2pChangeToDisableWhenD2DAllowedToFalse()
+ throws Exception {
+ when(mWifiSettingsConfigStore.get(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED)))
+ .thenReturn(true);
+ when(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled()).thenReturn(true);
+ when(mFeatureFlags.d2dWhenInfraStaOff()).thenReturn(true);
+ simulateWifiStateChange(false);
+ checkIsP2pInitWhenClientConnected(true, mClient1,
+ new WorkSource(mClient1.getCallingUid(), TEST_PACKAGE_NAME));
+ when(mWifiSettingsConfigStore.get(eq(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED)))
+ .thenReturn(false);
+ mD2DAllowedSettingsCallbackCaptor.getValue().onSettingsChanged(
+ D2D_ALLOWED_WHEN_INFRA_STA_DISABLED, false);
+ mLooper.dispatchAll();
+ // P2P is really disabled when wifi is off.
+ verify(mWifiNative).teardownInterface();
+ verify(mWifiMonitor).stopMonitoring(anyString());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttMetricsTest.java b/service/tests/wifitests/src/com/android/server/wifi/rtt/RttMetricsTest.java
index 7cb196d20f..3488351c9c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/rtt/RttMetricsTest.java
@@ -599,13 +599,19 @@ public class RttMetricsTest extends WifiBaseTest {
for (int i = 0; i < countAp; ++i) {
placeholderMacBase[0]++;
- builder.addResponder(new ResponderConfig(MacAddress.fromBytes(placeholderMacBase),
- ResponderConfig.RESPONDER_AP, true, 0, 0, 0, 0, 0));
+ builder.addResponder(new ResponderConfig.Builder()
+ .setMacAddress(MacAddress.fromBytes(placeholderMacBase))
+ .setResponderType(ResponderConfig.RESPONDER_AP)
+ .set80211mcSupported(true)
+ .build());
}
for (int i = 0; i < countAware; ++i) {
placeholderMacBase[0]++;
- builder.addResponder(new ResponderConfig(MacAddress.fromBytes(placeholderMacBase),
- ResponderConfig.RESPONDER_AWARE, true, 0, 0, 0, 0, 0));
+ builder.addResponder(new ResponderConfig.Builder()
+ .setMacAddress(MacAddress.fromBytes(placeholderMacBase))
+ .setResponderType(ResponderConfig.RESPONDER_AWARE)
+ .set80211mcSupported(true)
+ .build());
}
return builder.build();
@@ -618,8 +624,14 @@ public class RttMetricsTest extends WifiBaseTest {
for (ResponderConfig peer : request.mRttPeers) {
- RangingResult rttResult = new RangingResult(status, peer.macAddress,
- (int) (distance * 1000), 0, 0, 8, 8, null, null, null, 0, true);
+ RangingResult rttResult = new RangingResult.Builder()
+ .setStatus(status)
+ .setMacAddress(peer.getMacAddress())
+ .setDistanceMm((int) (distance * 1000))
+ .setNumAttemptedMeasurements(8)
+ .setNumSuccessfulMeasurements(8)
+ .set80211mcMeasurement(true)
+ .build();
distance += incrDistanceM;
rangingResults.add(rttResult);
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/rtt/RttServiceImplTest.java
index 7c779ddc5f..c96116914d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/rtt/RttServiceImplTest.java
@@ -315,7 +315,8 @@ public class RttServiceImplTest extends WifiBaseTest {
for (int i = 0; i < numIter; ++i) { // even: MC, non-MC, Aware, odd: MC only
if (i % 2 == 0) {
- requests[i] = RttTestUtils.getDummyRangingRequestMcOnly((byte) i);
+ requests[i] = RttTestUtils.getDummyRangingRequestMcOnly((byte) i,
+ RangingRequest.getDefaultRttBurstSize());
} else {
requests[i] = RttTestUtils.getDummyRangingRequest((byte) i);
}
@@ -423,21 +424,9 @@ public class RttServiceImplTest extends WifiBaseTest {
RttTestUtils.getDummyRangingResults(mRequestCaptor.getValue());
results.first.remove(results.first.size() - 1);
RangingResult removed = results.second.remove(results.second.size() - 1);
- results.second.add(
- new RangingResult(
- RangingResult.STATUS_FAIL,
- removed.getPeerHandle(),
- 0,
- 0,
- 0,
- 0,
- 0,
- null,
- null,
- null,
- 0,
- RangingResult.UNSPECIFIED,
- RangingResult.UNSPECIFIED));
+ results.second.add(new RangingResult.Builder()
+ .setPeerHandle(removed.getPeerHandle())
+ .build());
clock.time += MEASUREMENT_DURATION;
mRangingResultsCbCaptor.getValue()
.onRangingResults(mIntCaptor.getValue(), results.first);
@@ -899,16 +888,14 @@ public class RttServiceImplTest extends WifiBaseTest {
RttTestUtils.getDummyRangingResults(request);
results.first.remove(1); // remove a direct AWARE request
RangingResult removed = results.second.remove(1);
- results.second.add(
- new RangingResult(RangingResult.STATUS_FAIL, removed.getMacAddress(), 0, 0, 0, 0, 0,
- null, null, null, 0, false, RangingResult.UNSPECIFIED,
- RangingResult.UNSPECIFIED));
+ results.second.add(new RangingResult.Builder()
+ .setMacAddress(removed.getMacAddress())
+ .build());
results.first.remove(0); // remove an AP request
removed = results.second.remove(0);
- results.second.add(
- new RangingResult(RangingResult.STATUS_FAIL, removed.getMacAddress(), 0, 0, 0, 0, 0,
- null, null, null, 0, false, RangingResult.UNSPECIFIED,
- RangingResult.UNSPECIFIED));
+ results.second.add(new RangingResult.Builder()
+ .setMacAddress(removed.getMacAddress())
+ .build());
// (1) request ranging operation
mDut.startRanging(mockIbinder, mPackageName, mFeatureId, null, request,
@@ -949,10 +936,9 @@ public class RttServiceImplTest extends WifiBaseTest {
RttTestUtils.getDummyRangingResults(request);
List<RangingResult> allFailResults = new ArrayList<>();
for (RangingResult result : results.second) {
- allFailResults.add(
- new RangingResult(RangingResult.STATUS_FAIL, result.getMacAddress(), 0, 0, 0, 0,
- 0, null, null, null, 0, false, RangingResult.UNSPECIFIED,
- RangingResult.UNSPECIFIED));
+ allFailResults.add(new RangingResult.Builder()
+ .setMacAddress(result.getMacAddress())
+ .build());
}
// (1) request ranging operation
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 3af1324bab..2ddeeeb03e 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,10 +77,9 @@ public class RttTestUtils {
}
/**
- * Returns a placeholder ranging request with 2 requests:
- * - First: 802.11mc capable
+ * Returns a placeholder ranging request with 11mc request with a specified burst size.
*/
- public static RangingRequest getDummyRangingRequestMcOnly(byte lastMacByte) {
+ public static RangingRequest getDummyRangingRequestMcOnly(byte lastMacByte, int rttBurstSize) {
RangingRequest.Builder builder = new RangingRequest.Builder();
ScanResult scan1 = new ScanResult();
@@ -89,6 +88,7 @@ public class RttTestUtils {
scan1.channelWidth = ScanResult.CHANNEL_WIDTH_40MHZ;
builder.addAccessPoint(scan1);
+ builder.setRttBurstSize(rttBurstSize);
return builder.build();
}
@@ -127,49 +127,78 @@ public class RttTestUtils {
if (request != null) {
for (ResponderConfig peer : request.mRttPeers) {
- RangingResult rangingResult;
- halResults.add(new RangingResult(RangingResult.STATUS_SUCCESS,
- peer.macAddress, rangeCmBase, rangeStdDevCmBase, rssiBase,
- 8, 5, null, null, null, rangeTimestampBase, true, 5180,
- ScanResult.CHANNEL_WIDTH_40MHZ));
+ halResults.add(new RangingResult.Builder()
+ .setStatus(RangingResult.STATUS_SUCCESS)
+ .setMacAddress(peer.getMacAddress())
+ .setDistanceMm(rangeCmBase)
+ .setDistanceStdDevMm(rangeStdDevCmBase)
+ .setRssi(rssiBase)
+ .setNumAttemptedMeasurements(8)
+ .setNumSuccessfulMeasurements(5)
+ .setRangingTimestampMillis(rangeTimestampBase)
+ .set80211mcMeasurement(true)
+ .setMeasurementChannelFrequencyMHz(5180)
+ .setMeasurementBandwidth(ScanResult.CHANNEL_WIDTH_40MHZ)
+ .build());
+ RangingResult.Builder builder = new RangingResult.Builder()
+ .setStatus(RangingResult.STATUS_SUCCESS)
+ .setDistanceMm(rangeCmBase++)
+ .setDistanceStdDevMm(rangeStdDevCmBase++)
+ .setRssi(rssiBase++)
+ .setNumAttemptedMeasurements(8)
+ .setNumSuccessfulMeasurements(5)
+ .setRangingTimestampMillis(rangeTimestampBase++)
+ .set80211mcMeasurement(true)
+ .setMeasurementChannelFrequencyMHz(5180)
+ .setMeasurementBandwidth(ScanResult.CHANNEL_WIDTH_40MHZ);
if (peer.peerHandle == null) {
- rangingResult = new RangingResult(RangingResult.STATUS_SUCCESS,
- peer.macAddress, rangeCmBase++, rangeStdDevCmBase++, rssiBase++,
- 8, 5, null, null, null, rangeTimestampBase++, true, 5180,
- ScanResult.CHANNEL_WIDTH_40MHZ);
+ builder.setMacAddress(peer.getMacAddress());
} else {
- rangingResult =
- new RangingResult(
- RangingResult.STATUS_SUCCESS,
- peer.peerHandle,
- rangeCmBase++,
- rangeStdDevCmBase++,
- rssiBase++,
- 8,
- 5,
- null,
- null,
- null,
- rangeTimestampBase++,
- 5180,
- ScanResult.CHANNEL_WIDTH_40MHZ);
+ builder.setPeerHandle(peer.peerHandle);
}
+ RangingResult rangingResult = builder.build();
results.add(rangingResult);
-
}
} else {
- results.add(new RangingResult(RangingResult.STATUS_SUCCESS,
- MacAddress.fromString("10:01:02:03:04:05"), rangeCmBase++,
- rangeStdDevCmBase++, rssiBase++, 8, 4, null, null,
- null, rangeTimestampBase++, true, 5180, ScanResult.CHANNEL_WIDTH_40MHZ));
- results.add(new RangingResult(RangingResult.STATUS_SUCCESS,
- MacAddress.fromString("1A:0B:0C:0D:0E:0F"), rangeCmBase++,
- rangeStdDevCmBase++, rssiBase++, 9, 3, null, null,
- null, rangeTimestampBase++, true, 5180, ScanResult.CHANNEL_WIDTH_40MHZ));
- results.add(new RangingResult(RangingResult.STATUS_SUCCESS,
- MacAddress.fromString("08:09:08:07:06:05"), rangeCmBase++,
- rangeStdDevCmBase++, rssiBase++, 10, 2, null, null,
- null, rangeTimestampBase++, true, 5180, ScanResult.CHANNEL_WIDTH_40MHZ));
+ results.add(new RangingResult.Builder()
+ .setStatus(RangingResult.STATUS_SUCCESS)
+ .setMacAddress(MacAddress.fromString("10:01:02:03:04:05"))
+ .setDistanceMm(rangeCmBase++)
+ .setDistanceStdDevMm(rangeStdDevCmBase++)
+ .setRssi(rssiBase++)
+ .setNumAttemptedMeasurements(8)
+ .setNumSuccessfulMeasurements(4)
+ .setRangingTimestampMillis(rangeTimestampBase++)
+ .set80211mcMeasurement(true)
+ .setMeasurementChannelFrequencyMHz(5180)
+ .setMeasurementBandwidth(ScanResult.CHANNEL_WIDTH_40MHZ)
+ .build());
+ results.add(new RangingResult.Builder()
+ .setStatus(RangingResult.STATUS_SUCCESS)
+ .setMacAddress(MacAddress.fromString("1A:0B:0C:0D:0E:0F"))
+ .setDistanceMm(rangeCmBase++)
+ .setDistanceStdDevMm(rangeStdDevCmBase++)
+ .setRssi(rssiBase++)
+ .setNumAttemptedMeasurements(9)
+ .setNumSuccessfulMeasurements(3)
+ .setRangingTimestampMillis(rangeTimestampBase++)
+ .set80211mcMeasurement(true)
+ .setMeasurementChannelFrequencyMHz(5180)
+ .setMeasurementBandwidth(ScanResult.CHANNEL_WIDTH_40MHZ)
+ .build());
+ results.add(new RangingResult.Builder()
+ .setStatus(RangingResult.STATUS_SUCCESS)
+ .setMacAddress(MacAddress.fromString("08:09:08:07:06:05"))
+ .setDistanceMm(rangeCmBase++)
+ .setDistanceStdDevMm(rangeStdDevCmBase++)
+ .setRssi(rssiBase++)
+ .setNumAttemptedMeasurements(10)
+ .setNumSuccessfulMeasurements(2)
+ .setRangingTimestampMillis(rangeTimestampBase++)
+ .set80211mcMeasurement(true)
+ .setMeasurementChannelFrequencyMHz(5180)
+ .setMeasurementBandwidth(ScanResult.CHANNEL_WIDTH_40MHZ)
+ .build());
halResults.addAll(results);
}
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 456d2fe971..b8f3a6bd46 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
@@ -97,6 +97,7 @@ import com.android.server.wifi.FrameworkFacade;
import com.android.server.wifi.MockResources;
import com.android.server.wifi.ScanResults;
import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.WifiGlobals;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiLocalServices;
import com.android.server.wifi.WifiMetrics;
@@ -163,6 +164,7 @@ public class WifiScanningServiceTest extends WifiBaseTest {
@Mock WifiManager mWifiManager;
@Mock LastCallerInfoManager mLastCallerInfoManager;
@Mock DeviceConfigFacade mDeviceConfigFacade;
+ @Mock WifiGlobals mWifiGlobals;
PresetKnownBandsChannelHelper mChannelHelper0;
PresetKnownBandsChannelHelper mChannelHelper1;
TestLooper mLooper;
@@ -193,7 +195,8 @@ public class WifiScanningServiceTest extends WifiBaseTest {
mSwPnoMobilityIterations);
mResources.setInteger(R.integer.config_wifiSwPnoFastTimerIterations, mSwPnoFastIterations);
mResources.setInteger(R.integer.config_wifiSwPnoSlowTimerIterations, mSwPnoSlowIterations);
- mResources.setBoolean(R.bool.config_wifiSwPnoEnabled, true);
+ when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals);
+ when(mWifiGlobals.isSwPnoEnabled()).thenReturn(true);
when(mContext.getResources()).thenReturn(mResources);
when(mWifiInjector.getWifiPermissionsUtil())
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 40f1c5364e..e0d780ee14 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
@@ -839,7 +839,7 @@ public class ApConfigUtilTest extends WifiBaseTest {
when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ))
.thenReturn(ALLOWED_5G_FREQS); // ch# 149, 153
mCapability = ApConfigUtil.updateSoftApCapabilityWithAvailableChannelList(mCapability,
- mContext, mWifiNative);
+ mContext, mWifiNative, null);
assertEquals(SoftApManager.START_RESULT_SUCCESS,
ApConfigUtil.updateApChannelConfig(mWifiNative, mCoexManager, mResources,
TEST_COUNTRY_CODE, configBuilder, configBuilder.build(),
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 7703e0af99..102ef51d8a 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
@@ -21,6 +21,7 @@ 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;
@@ -56,6 +57,13 @@ public class HalAidlUtilTest {
oui, createTestPersistableBundle()).build();
}
+ private static OuiKeyedData createHalOuiKeyedData(int oui) {
+ OuiKeyedData data = new OuiKeyedData();
+ data.oui = oui;
+ data.vendorData = createTestPersistableBundle();
+ return data;
+ }
+
private static boolean frameworkAndHalOuiKeyedDataEqual(
android.net.wifi.OuiKeyedData frameworkData,
android.hardware.wifi.common.OuiKeyedData halData) {
@@ -97,4 +105,39 @@ public class HalAidlUtilTest {
HalAidlUtil.frameworkToHalOuiKeyedDataList(frameworkList);
assertEquals(0, halList.length);
}
+
+ /**
+ * Test the conversion of a valid HAL OuiKeyedData list to its framework equivalent.
+ */
+ @Test
+ public void testConvertOuiKeyedDataToFramework() {
+ OuiKeyedData[] halList = new OuiKeyedData[TEST_VENDOR_DATA_LIST_SIZE];
+ for (int i = 0; i < TEST_VENDOR_DATA_LIST_SIZE; i++) {
+ halList[i] = createHalOuiKeyedData(i + 1);
+ }
+
+ List<android.net.wifi.OuiKeyedData> frameworkList =
+ HalAidlUtil.halToFrameworkOuiKeyedDataList(halList);
+ assertEquals(frameworkList.size(), halList.length);
+ for (int i = 0; i < TEST_VENDOR_DATA_LIST_SIZE; i++) {
+ assertTrue(frameworkAndHalOuiKeyedDataEqual(frameworkList.get(i), halList[i]));
+ }
+ }
+
+ /**
+ * Test the conversion of an invalid OuiKeyedData list. Invalid entries should be ignored.
+ */
+ @Test
+ public void testConvertOuiKeyedDataToFramework_invalid() {
+ OuiKeyedData[] halList = new OuiKeyedData[TEST_VENDOR_DATA_LIST_SIZE];
+ for (int i = 0; i < TEST_VENDOR_DATA_LIST_SIZE; i++) {
+ // Fill list with entries that have an invalid OUI.
+ halList[i] = createHalOuiKeyedData(0);
+ }
+
+ // No entries should appear in the converted list.
+ List<android.net.wifi.OuiKeyedData> frameworkList =
+ HalAidlUtil.halToFrameworkOuiKeyedDataList(halList);
+ assertEquals(0, frameworkList.size());
+ }
}
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 f595de37f6..0d5e495193 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
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
import android.net.MacAddress;
import android.net.wifi.ScanResult;
import android.net.wifi.ScanResult.InformationElement;
+import android.util.SparseIntArray;
import androidx.test.filters.SmallTest;
@@ -462,33 +463,38 @@ public class InformationElementUtilTest extends WifiBaseTest {
}
private void verifyCapabilityStringFromIes(
- InformationElement[] ies, int beaconCap, boolean isOweSupported,
- String capsStr) {
+ InformationElement[] ies,
+ int beaconCap,
+ boolean isOweSupported,
+ String capsStr,
+ SparseIntArray unknownAkmMap) {
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(ies, beaconCap, isOweSupported, 2400);
+ capabilities.from(ies, beaconCap, isOweSupported, 2400, unknownAkmMap);
String result = capabilities.generateCapabilitiesString();
assertEquals(capsStr, result);
}
private void verifyCapabilityStringFromIe(
- InformationElement ie, int beaconCap, boolean isOweSupported,
- String capsStr) {
+ InformationElement ie,
+ int beaconCap,
+ boolean isOweSupported,
+ String capsStr,
+ SparseIntArray unknownAkmMap) {
InformationElement[] ies = new InformationElement[] { ie };
- verifyCapabilityStringFromIes(new InformationElement[] { ie },
- beaconCap, isOweSupported, capsStr);
-
+ verifyCapabilityStringFromIes(
+ new InformationElement[] {ie}, beaconCap, isOweSupported, capsStr, unknownAkmMap);
}
private void verifyCapabilityStringFromIeWithoutOweSupported(
InformationElement ie, String capsStr) {
- verifyCapabilityStringFromIe(ie, 0x1 << 4, false, capsStr);
+ verifyCapabilityStringFromIe(ie, 0x1 << 4, false, capsStr, null);
}
private void verifyCapabilityStringFromIeWithOweSupported(
- InformationElement ie, String capsStr) {
- verifyCapabilityStringFromIe(ie, 0x1 << 4, true, capsStr);
+ InformationElement ie, String capsStr, SparseIntArray unknownAkmMap) {
+ verifyCapabilityStringFromIe(ie, 0x1 << 4, true, capsStr, unknownAkmMap);
}
/**
@@ -791,10 +797,12 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0xF2, (byte) 0x02, (byte) 0x00, (byte) 0x00 };
InformationElement[] ies = new InformationElement[] { ieWpa, ieRsn };
- verifyCapabilityStringFromIes(ies,
+ verifyCapabilityStringFromIes(
+ ies,
0x1 << 4,
false,
- "[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][RSN-PSK-CCMP+TKIP]");
+ "[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][RSN-PSK-CCMP+TKIP]",
+ null);
}
/**
@@ -822,8 +830,8 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x08,
// Padding
(byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIeWithOweSupported(ieRsn,
- "[WPA2-PSK-CCMP][RSN-PSK+SAE-CCMP]");
+ verifyCapabilityStringFromIeWithOweSupported(
+ ieRsn, "[WPA2-PSK-CCMP][RSN-PSK+SAE-CCMP]", null);
}
/**
@@ -851,8 +859,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x09,
// Padding
(byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIeWithOweSupported(ieRsn,
- "[RSN-SAE+FT/SAE-CCMP]");
+ verifyCapabilityStringFromIeWithOweSupported(ieRsn, "[RSN-SAE+FT/SAE-CCMP]", null);
}
/**
@@ -880,8 +887,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x18,
// Padding
(byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIeWithOweSupported(ieRsn,
- "[RSN-SAE+SAE_EXT_KEY-CCMP]");
+ verifyCapabilityStringFromIeWithOweSupported(ieRsn, "[RSN-SAE+SAE_EXT_KEY-CCMP]", null);
}
/**
@@ -910,8 +916,8 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x19,
// Padding
(byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIeWithOweSupported(ieRsn,
- "[RSN-SAE_EXT_KEY+FT/SAE_EXT_KEY-CCMP]");
+ verifyCapabilityStringFromIeWithOweSupported(
+ ieRsn, "[RSN-SAE_EXT_KEY+FT/SAE_EXT_KEY-CCMP]", null);
}
/**
@@ -937,8 +943,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x12,
// Padding
(byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIeWithOweSupported(ieRsn,
- "[RSN-OWE-CCMP]");
+ verifyCapabilityStringFromIeWithOweSupported(ieRsn, "[RSN-OWE-CCMP]", null);
}
/**
@@ -954,8 +959,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x1C,
// OWE IE contains BSSID, SSID and channel of other BSS, but we don't parse it.
(byte) 0x00, (byte) 0x000, (byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIe(ieOwe, 0x1 << 0, true,
- "[RSN-OWE_TRANSITION-CCMP][ESS]");
+ verifyCapabilityStringFromIe(ieOwe, 0x1 << 0, true, "[RSN-OWE_TRANSITION-CCMP][ESS]", null);
}
/**
@@ -971,8 +975,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x1C,
// OWE IE contains BSSID, SSID and channel of other BSS, but we don't parse it.
(byte) 0x00, (byte) 0x000, (byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIe(ieOwe, 0x1 << 0, false,
- "[ESS]");
+ verifyCapabilityStringFromIe(ieOwe, 0x1 << 0, false, "[ESS]", null);
}
/**
@@ -1035,9 +1038,11 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x0E,
// RSN capabilities
(byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIeWithOweSupported(ieRsn,
+ verifyCapabilityStringFromIeWithOweSupported(
+ ieRsn,
"[WPA2-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA256-CCMP]"
- + "[RSN-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA256-CCMP]");
+ + "[RSN-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA256-CCMP]",
+ null);
}
/**
@@ -1068,9 +1073,60 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x0F,
// RSN capabilities
(byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIeWithOweSupported(ieRsn,
+ verifyCapabilityStringFromIeWithOweSupported(
+ ieRsn,
"[WPA2-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA384-CCMP]"
- + "[RSN-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA384-CCMP]");
+ + "[RSN-EAP/SHA1+EAP/SHA256+EAP-FILS-SHA384-CCMP]",
+ null);
+ }
+
+ /**
+ * Test Capabilities.generateCapabilitiesString() with RSN IE, CCMP and unknown AKM suite
+ * selector. Expect the function to return a capability string with the mapped AKM scheme.
+ */
+ @Test
+ public void buildCapabilities_rsnIeUnknownAkmMapping() {
+ // unknown AKM (0x00, 0x40, 0x96, 0x00) -> known AKM (0x00, 0x0F, 0xAC, 0x18) - SAE_EXT_KEY
+ SparseIntArray unknownAkmMap =
+ new SparseIntArray() {
+ {
+ put(0x00964000, 0x12);
+ }
+ };
+ 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 cipher suites (1)
+ (byte) 0x01,
+ (byte) 0x00,
+ // Cipher suite: CCMP
+ (byte) 0x00,
+ (byte) 0x0F,
+ (byte) 0xAC,
+ (byte) 0x04,
+ // Number of AKMs (1)
+ (byte) 0x01,
+ (byte) 0x00,
+ // unknown AKM (0x00, 0x40, 0x96, 0x00)
+ (byte) 0x00,
+ (byte) 0x40,
+ (byte) 0x96,
+ (byte) 0x00,
+ // RSN capabilities
+ (byte) 0x00,
+ (byte) 0x00
+ };
+ verifyCapabilityStringFromIeWithOweSupported(
+ ieRsn, "[RSN-SAE_EXT_KEY-CCMP]", unknownAkmMap);
}
/**
@@ -1092,10 +1148,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]");
+ verifyCapabilityStringFromIes(ies, 0x1 << 4, false, "[WPA][RSN]", null);
}
/**
@@ -1119,10 +1172,7 @@ 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]");
+ verifyCapabilityStringFromIes(ies, 0x1 << 4, false, "[WPA-PSK-CCMP+TKIP][WPS]", null);
}
/**
@@ -1156,7 +1206,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
ie.bytes = new byte[] { (byte) 0x00, (byte) 0x04, (byte) 0x0E, (byte) 0x01,
(byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIe(ie, 0, false, "");
+ verifyCapabilityStringFromIe(ie, 0, false, "", null);
}
/**
@@ -1172,7 +1222,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
ie.bytes = new byte[] { (byte) 0x00, (byte) 0x04, (byte) 0x0E, (byte) 0x01,
(byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIe(ie, 0x1 << 0, false, "[ESS]");
+ verifyCapabilityStringFromIe(ie, 0x1 << 0, false, "[ESS]", null);
}
/**
@@ -1189,7 +1239,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
ie.bytes = new byte[] { (byte) 0x00, (byte) 0x04, (byte) 0x0E, (byte) 0x01,
(byte) 0x01, (byte) 0x02, (byte) 0x01, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
- verifyCapabilityStringFromIe(ie, 0, false, "");
+ verifyCapabilityStringFromIe(ie, 0, false, "", null);
}
/**
@@ -1203,7 +1253,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(new InformationElement[0], beaconCap, false, 2400);
+ capabilities.from(new InformationElement[0], beaconCap, false, 2400, null);
String result = capabilities.generateCapabilitiesString();
assertEquals("[IBSS]", result);
@@ -1220,7 +1270,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(new InformationElement[0], beaconCap, false, 58320);
+ capabilities.from(new InformationElement[0], beaconCap, false, 58320, null);
String result = capabilities.generateCapabilitiesString();
assertEquals("[IBSS]", result);
@@ -1237,7 +1287,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(new InformationElement[0], beaconCap, false, 58320);
+ capabilities.from(new InformationElement[0], beaconCap, false, 58320, null);
String result = capabilities.generateCapabilitiesString();
assertEquals("[ESS]", result);
@@ -1259,8 +1309,8 @@ public class InformationElementUtilTest extends WifiBaseTest {
extendedCap.from(ie);
assertFalse(extendedCap.isStrictUtf8());
assertFalse(extendedCap.is80211McRTTResponder());
- assertFalse(extendedCap.isTriggerBasedRangingRespSupported());
- assertFalse(extendedCap.isNonTriggerBasedRangingRespSupported());
+ assertFalse(extendedCap.is80211azTbResponder());
+ assertFalse(extendedCap.is80211azNtbResponder());
assertFalse(extendedCap.isTwtRequesterSupported());
assertFalse(extendedCap.isTwtResponderSupported());
assertFalse(extendedCap.isFilsCapable());
@@ -1318,8 +1368,8 @@ public class InformationElementUtilTest extends WifiBaseTest {
InformationElementUtil.ExtendedCapabilities extendedCap =
new InformationElementUtil.ExtendedCapabilities();
extendedCap.from(ie);
- assertTrue(extendedCap.isTriggerBasedRangingRespSupported());
- assertTrue(extendedCap.isNonTriggerBasedRangingRespSupported());
+ assertTrue(extendedCap.is80211azTbResponder());
+ assertTrue(extendedCap.is80211azNtbResponder());
assertTrue(extendedCap.isTwtRequesterSupported());
assertTrue(extendedCap.isTwtResponderSupported());
assertTrue(extendedCap.isFilsCapable());
@@ -2519,11 +2569,10 @@ public class InformationElementUtilTest extends WifiBaseTest {
}
/**
- * Verify that the expected EHT Operation information element is parsed and
- * DisabledSubchannelBitmap is present.
+ * Verify that the expected EHT Operation information element is parsed correctly.
*/
@Test
- public void testEhtOperationElementWithDisabledSubchannelBitmapPresent() throws Exception {
+ public void testEhtOperationElement() throws Exception {
InformationElement ie = new InformationElement();
ie.id = InformationElement.EID_EXTENSION_PRESENT;
ie.idExt = InformationElement.EID_EXT_EHT_OPERATION;
@@ -2549,8 +2598,28 @@ public class InformationElementUtilTest extends WifiBaseTest {
ehtOperation.from(ie);
assertTrue(ehtOperation.isPresent());
+ assertTrue(ehtOperation.isEhtOperationInfoPresent());
assertTrue(ehtOperation.isDisabledSubchannelBitmapPresent());
assertArrayEquals(new byte[]{(byte) 0x3, (byte) 0x0},
ehtOperation.getDisabledSubchannelBitmap());
+ assertEquals(ScanResult.CHANNEL_WIDTH_160MHZ, ehtOperation.getChannelWidth());
+ assertEquals(5250, ehtOperation.getCenterFreq0(ScanResult.WIFI_BAND_5_GHZ));
+ assertEquals(5250, ehtOperation.getCenterFreq0(ScanResult.WIFI_BAND_5_GHZ));
+
+ ie.bytes = new byte[]{(byte) 0x01, //EHT Operation Param
+ (byte) 0x44, (byte) 0x44, (byte) 0x44, (byte) 0x44, //EHT-MCS
+ (byte) 0x04, (byte) 0x2f, (byte) 0x1f}; //EHT Operation Info: Control, CCFS0, CCFS1
+
+ ehtOperation.from(ie);
+
+ assertTrue(ehtOperation.isPresent());
+ assertTrue(ehtOperation.isEhtOperationInfoPresent());
+ assertFalse(ehtOperation.isDisabledSubchannelBitmapPresent());
+ assertEquals(ScanResult.CHANNEL_WIDTH_320MHZ, ehtOperation.getChannelWidth());
+ // Center frequency of channel index 47 (0x2F), 160 Mhz
+ assertEquals(6185, ehtOperation.getCenterFreq0(ScanResult.WIFI_BAND_6_GHZ));
+ // Center frequency of channel index 31 (0x1F), 320 Mhz
+ assertEquals(6105, ehtOperation.getCenterFreq1(ScanResult.WIFI_BAND_6_GHZ));
+
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
index efdc2d5c9f..a53ace0010 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
@@ -770,8 +770,8 @@ public class WifiPermissionsUtilTest extends WifiBaseTest {
codeUnderTest.enforceLocationPermission(TEST_PACKAGE_NAME, TEST_FEATURE_ID, mUid);
// verify that checking FINE for legacy apps!
- verify(mMockAppOps).noteOp(eq(AppOpsManager.OPSTR_FINE_LOCATION), anyInt(), anyString(),
- any(), any());
+ verify(mMockAppOps).noteOpNoThrow(eq(AppOpsManager.OPSTR_FINE_LOCATION), anyInt(),
+ anyString(), any(), any());
}
/**
@@ -793,7 +793,8 @@ public class WifiPermissionsUtilTest extends WifiBaseTest {
codeUnderTest.enableVerboseLogging(true);
codeUnderTest.enforceLocationPermission(TEST_PACKAGE_NAME, TEST_FEATURE_ID, mUid);
verify(mMockAppOps)
- .noteOp(eq(AppOpsManager.OPSTR_FINE_LOCATION), anyInt(), anyString(), any(), any());
+ .noteOpNoThrow(eq(AppOpsManager.OPSTR_FINE_LOCATION), anyInt(), anyString(),
+ any(), any());
}
/**
@@ -821,7 +822,7 @@ public class WifiPermissionsUtilTest extends WifiBaseTest {
} catch (SecurityException e) {
// empty
}
- verify(mMockAppOps, never()).noteOp(anyInt(), anyInt(), anyString());
+ verify(mMockAppOps, never()).noteOpNoThrow(anyInt(), anyInt(), anyString());
}
/**
@@ -869,52 +870,6 @@ public class WifiPermissionsUtilTest extends WifiBaseTest {
}
/**
- * Verifies the helper method exposed for checking SYSTERM_ALERT_WINDOW permission.
- */
- @Test
- public void testCheckSystemAlertWindowPermissionWithModeDefaultAppOps() throws Exception {
- setupMocks();
- WifiPermissionsUtil wifiPermissionsUtil = new WifiPermissionsUtil(mMockPermissionsWrapper,
- mMockContext, mMockUserManager, mWifiInjector);
- wifiPermissionsUtil.enableVerboseLogging(true);
-
- when(mMockAppOps.noteOp(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID,
- TEST_PACKAGE_NAME, null, null))
- .thenReturn(AppOpsManager.MODE_DEFAULT);
- when(mMockPermissionsWrapper.getUidPermission(
- Manifest.permission.SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID))
- .thenReturn(PackageManager.PERMISSION_DENIED);
- assertFalse(wifiPermissionsUtil.checkSystemAlertWindowPermission(
- MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
-
- when(mMockAppOps.noteOp(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID,
- TEST_PACKAGE_NAME, null, null))
- .thenReturn(AppOpsManager.MODE_DEFAULT);
- when(mMockPermissionsWrapper.getUidPermission(
- Manifest.permission.SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID))
- .thenReturn(PackageManager.PERMISSION_GRANTED);
- assertTrue(wifiPermissionsUtil.checkSystemAlertWindowPermission(
- MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
- }
-
- /**
- * Verifies the helper method exposed for checking SYSTERM_ALERT_WINDOW permission.
- */
- @Test
- public void testCheckSystemAlertWindowPermissionWithModeAllowedAppOps() throws Exception {
- setupMocks();
- WifiPermissionsUtil wifiPermissionsUtil = new WifiPermissionsUtil(mMockPermissionsWrapper,
- mMockContext, mMockUserManager, mWifiInjector);
- wifiPermissionsUtil.enableVerboseLogging(true);
-
- when(mMockAppOps.noteOp(
- AppOpsManager.OP_SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID, TEST_PACKAGE_NAME))
- .thenReturn(AppOpsManager.MODE_ALLOWED);
- assertTrue(wifiPermissionsUtil.checkSystemAlertWindowPermission(
- MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
- }
-
- /**
* Verifies the helper method exposed for checking if the app is a DeviceOwner.
*/
@Test
@@ -1186,8 +1141,8 @@ public class WifiPermissionsUtilTest extends WifiBaseTest {
verify(mMockAppOps, never())
.unsafeCheckOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME);
- verify(mMockAppOps).noteOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME,
- TEST_FEATURE_ID, null);
+ verify(mMockAppOps).noteOpNoThrow(AppOpsManager.OPSTR_FINE_LOCATION, mUid,
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID, null);
}
/**
@@ -1315,7 +1270,7 @@ public class WifiPermissionsUtilTest extends WifiBaseTest {
verify(mMockAppOps).unsafeCheckOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid,
TEST_PACKAGE_NAME);
- verify(mMockAppOps, never()).noteOp(
+ verify(mMockAppOps, never()).noteOpNoThrow(
AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME, null, null);
}
@@ -1491,8 +1446,8 @@ public class WifiPermissionsUtilTest extends WifiBaseTest {
codeUnderTest.enableVerboseLogging(true);
codeUnderTest.enforceCanAccessScanResultsForWifiScanner(TEST_PACKAGE_NAME, TEST_FEATURE_ID,
mUid, IGNORE_LOCATION_SETTINGS, DONT_HIDE_FROM_APP_OPS);
- verify(mMockAppOps).noteOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME,
- TEST_FEATURE_ID, null);
+ verify(mMockAppOps).noteOpNoThrow(AppOpsManager.OPSTR_FINE_LOCATION, mUid,
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID, null);
}
/**
@@ -1785,12 +1740,12 @@ public class WifiPermissionsUtilTest extends WifiBaseTest {
eq(GET_PERMISSIONS | MATCH_UNINSTALLED_PACKAGES))).thenReturn(
mPackagePermissionInfo);
when(mMockContext.getPackageManager()).thenReturn(mMockPkgMgr);
- when(mMockAppOps.noteOp(AppOpsManager.OPSTR_WIFI_SCAN, mUid, TEST_PACKAGE_NAME,
+ when(mMockAppOps.noteOpNoThrow(AppOpsManager.OPSTR_WIFI_SCAN, mUid, TEST_PACKAGE_NAME,
TEST_FEATURE_ID, null)).thenReturn(mWifiScanAllowApps);
- when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_COARSE_LOCATION), eq(mUid),
+ when(mMockAppOps.noteOpNoThrow(eq(AppOpsManager.OPSTR_COARSE_LOCATION), eq(mUid),
eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID), nullable(String.class)))
.thenReturn(mAllowCoarseLocationApps);
- when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_FINE_LOCATION), eq(mUid),
+ when(mMockAppOps.noteOpNoThrow(eq(AppOpsManager.OPSTR_FINE_LOCATION), eq(mUid),
eq(TEST_PACKAGE_NAME), eq(TEST_FEATURE_ID), nullable(String.class)))
.thenReturn(mAllowFineLocationApps);
when(mMockAppOps.unsafeCheckOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME))
@@ -1875,8 +1830,8 @@ public class WifiPermissionsUtilTest extends WifiBaseTest {
codeUnderTest.enableVerboseLogging(true);
codeUnderTest.enforceCoarseLocationPermission(TEST_PACKAGE_NAME, TEST_FEATURE_ID, mUid);
// verify that checking Coarse for apps!
- verify(mMockAppOps).noteOp(eq(AppOpsManager.OPSTR_COARSE_LOCATION), anyInt(), anyString(),
- any(), any());
+ verify(mMockAppOps).noteOpNoThrow(eq(AppOpsManager.OPSTR_COARSE_LOCATION), anyInt(),
+ anyString(), any(), any());
}
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
index 79d9cce0b8..389686ee77 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
@@ -16,8 +16,15 @@
package com.android.server.wifi.util;
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.net.IpConfiguration;
import android.net.MacAddress;
@@ -32,6 +39,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.MacAddressUtils;
+import com.android.server.wifi.OuiKeyedDataUtil;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiConfigurationTestUtil;
import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
@@ -143,7 +151,9 @@ public class XmlUtilTest extends WifiBaseTest {
throws IOException, XmlPullParserException {
mWifiConfigStoreEncryptionUtil = mock(WifiConfigStoreEncryptionUtil.class);
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+ wepNetwork.wepKeys = WifiConfigurationTestUtil.TEST_WEP_KEYS_WITH_NULL;
for (int i = 0; i < wepNetwork.wepKeys.length; i++) {
+ if (wepNetwork.wepKeys[i] == null) continue;
EncryptedData encryptedData = new EncryptedData(new byte[]{(byte) i},
new byte[]{(byte) i});
when(mWifiConfigStoreEncryptionUtil.encrypt(wepNetwork.wepKeys[i].getBytes()))
@@ -163,7 +173,9 @@ public class XmlUtilTest extends WifiBaseTest {
throws IOException, XmlPullParserException {
mWifiConfigStoreEncryptionUtil = mock(WifiConfigStoreEncryptionUtil.class);
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+ wepNetwork.wepKeys = WifiConfigurationTestUtil.TEST_WEP_KEYS_WITH_NULL;
for (int i = 0; i < wepNetwork.wepKeys.length; i++) {
+ if (wepNetwork.wepKeys[i] == null) continue;
when(mWifiConfigStoreEncryptionUtil.encrypt(wepNetwork.wepKeys[i].getBytes()))
.thenReturn(null);
}
@@ -630,6 +642,73 @@ public class XmlUtilTest extends WifiBaseTest {
retrieved.second.macRandomizationSetting);
}
+ /**
+ * Verify serializing/deserializing DHCP hostname setting.
+ * @throws Exception
+ */
+ @Test
+ public void testSendDhcpHostnameEnabledSerializeDeserialize() throws Exception {
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ config.setSendDhcpHostnameEnabled(true);
+ serializeDeserializeWifiConfiguration(config);
+ }
+
+ /**
+ * Verify that deserializing an XML without SEND_DHCP_HOSTNAME will automatically set the value
+ * to true for secure networks.
+ * @throws IOException
+ * @throws XmlPullParserException
+ */
+ @Test
+ public void testSendDhcpHostnameEnabledUpgradeToTrueForSecure()
+ throws IOException, XmlPullParserException {
+ final XmlSerializer out = new FastXmlSerializer();
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+ XmlUtil.writeDocumentStart(out, mXmlDocHeader);
+ XmlUtil.writeNextSectionStart(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS_LIST);
+ XmlUtil.writeNextSectionStart(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS);
+ XmlUtil.writeNextValue(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_TYPE,
+ WifiConfiguration.SECURITY_TYPE_PSK);
+ XmlUtil.writeNextValue(out, WifiConfigurationXmlUtil.XML_TAG_IS_ENABLED, true);
+ XmlUtil.writeNextSectionEnd(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS);
+ XmlUtil.writeNextSectionEnd(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS_LIST);
+ XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
+
+ Pair<String, WifiConfiguration> retrieved =
+ deserializeWifiConfiguration(outputStream.toByteArray(), false);
+
+ assertTrue(retrieved.second.isSendDhcpHostnameEnabled());
+ }
+
+ /**
+ * Verify that deserializing an XML without SEND_DHCP_HOSTNAME will automatically set the value
+ * to true for secure networks.
+ * @throws IOException
+ * @throws XmlPullParserException
+ */
+ @Test
+ public void testSendDhcpHostnameEnabledUpgradeToFalseForOpen()
+ throws IOException, XmlPullParserException {
+ final XmlSerializer out = new FastXmlSerializer();
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+ XmlUtil.writeDocumentStart(out, mXmlDocHeader);
+ XmlUtil.writeNextSectionStart(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS_LIST);
+ XmlUtil.writeNextSectionStart(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS);
+ XmlUtil.writeNextValue(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_TYPE,
+ WifiConfiguration.SECURITY_TYPE_OPEN);
+ XmlUtil.writeNextValue(out, WifiConfigurationXmlUtil.XML_TAG_IS_ENABLED, true);
+ XmlUtil.writeNextSectionEnd(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS);
+ XmlUtil.writeNextSectionEnd(out, WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS_LIST);
+ XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
+
+ Pair<String, WifiConfiguration> retrieved =
+ deserializeWifiConfiguration(outputStream.toByteArray(), false);
+
+ assertFalse(retrieved.second.isSendDhcpHostnameEnabled());
+ }
+
private WifiEnterpriseConfig makeTestWifiEnterpriseConfig() {
final WifiEnterpriseConfig config = new WifiEnterpriseConfig();
config.setFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, TEST_IDENTITY);
@@ -892,4 +971,16 @@ public class XmlUtilTest extends WifiBaseTest {
throws IOException, XmlPullParserException {
testConfigStoreWithEncryptedPreSharedKey(true, true);
}
+
+ /**
+ * Verify that the vendor data field is serialized and deserialized correctly
+ * when provided.
+ */
+ @Test
+ public void testWifiConfigurationWithVendorData() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ config.setVendorData(OuiKeyedDataUtil.createTestOuiKeyedDataList(10));
+ serializeDeserializeWifiConfiguration(config);
+ }
}
diff --git a/wifi_upload_hook.py b/wifi_upload_hook.py
index 55fa267c15..ff063f5b02 100755
--- a/wifi_upload_hook.py
+++ b/wifi_upload_hook.py
@@ -28,13 +28,26 @@ STYLES_FILE = BASE_DIR + "values/styles.xml"
DRAWABLE_DIR = BASE_DIR + "drawable/"
LAYOUT_DIR = BASE_DIR + "layout/"
-def is_commit_msg_valid(commit_msg):
+BASE_WIFI_SERVICE_DIR = "service/java/com/android/server/wifi/"
+XML_UTIL_FILE = BASE_WIFI_SERVICE_DIR + "util/XmlUtil.java"
+CLOUD_BACKUP_RESTORE_FILE = BASE_WIFI_SERVICE_DIR + "WifiBackupRestore.java"
+CLOUD_BACKUP_PARSER_FILE = BASE_WIFI_SERVICE_DIR + "WifiBackupDataV1Parser.java"
+
+def is_commit_msg_valid(commit_msg, checkResource, checkXmlTag):
+ isValid = True
for line in commit_msg.splitlines():
line = line.strip().lower()
- if line.startswith('updated-overlayable'):
- return True
-
- return False
+ if checkResource:
+ if line.startswith('updated-overlayable'):
+ isValid = True
+ checkResource = False
+ if checkXmlTag:
+ isValid = False
+ if line.startswith('reviewed-cloud-b&r'):
+ isValid = True
+ checkXmlTag = False
+
+ return isValid
def is_in_aosp():
branches = subprocess.check_output(['git', 'branch', '-vv']).splitlines()
@@ -61,6 +74,16 @@ def get_changed_resource_file(commit_files):
return commit_file
return None
+def get_changed_xml_related_file(commit_files):
+ for commit_file in commit_files:
+ if commit_file == XML_UTIL_FILE:
+ return commit_file
+ if commit_file == CLOUD_BACKUP_RESTORE_FILE:
+ return commit_file
+ if commit_file == CLOUD_BACKUP_PARSER_FILE:
+ return commit_file
+ return None
+
def is_commit_msg_has_translation_bug_id(commit_msg):
for line in commit_msg.splitlines():
line = line.strip().lower()
@@ -68,51 +91,75 @@ def is_commit_msg_has_translation_bug_id(commit_msg):
return True
return False
+def is_xml_tag_in_commits():
+ cmd_run = subprocess.Popen('git show | grep -iE "XML_TAG"',
+ shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE
+ )
+ out, err = cmd_run.communicate()
+ for line in out.splitlines():
+ if line.startswith(b'+') or line.startswith(b'-'):
+ print('This commit has xml tag changed: "{changed_line}".'.format(changed_line=line.decode("utf-8")))
+ print()
+ return True
+ return False
def main():
- parser = ArgumentParser(description='Check if the overlayable file has been updated')
+ parser = ArgumentParser(description='Check if the dependency file has been updated')
parser.add_argument('commit_msg', type=str, help='commit message')
parser.add_argument('commit_files', type=str, nargs='*', help='files changed in the commit')
args = parser.parse_args()
commit_msg = args.commit_msg
commit_files = args.commit_files
-
if is_in_aosp():
return 0
- changed_file = get_changed_resource_file(commit_files)
-
- if not changed_file:
- return 0
- if changed_file == STRING_FILE:
- if not is_commit_msg_has_translation_bug_id(commit_msg):
- print('This commit has changed: "{changed_file}".'.format(changed_file=changed_file))
+ changed_resource_file = get_changed_resource_file(commit_files)
+
+ if changed_resource_file:
+ if changed_resource_file == STRING_FILE:
+ if not is_commit_msg_has_translation_bug_id(commit_msg):
+ print('This commit has changed: "{changed_file}".'.format(changed_resource_file=changed_resource_file))
+ print()
+ print('Please add the following line to your commit message')
+ print()
+ print('Bug: 294871353')
+ print()
+ return 1
+
+ if not is_commit_msg_valid(commit_msg, True, False):
+ print('This commit has changed: "{changed_file}".'.format(changed_file=changed_resource_file))
+ print()
+ print('If this change added/changed/removed overlayable resources used by the Wifi Module, ')
+ print('please update the "{overlay_file}".'.format(overlay_file=OVERLAY_FILE))
+ print('and acknowledge you have done so by adding this line to your commit message:')
+ print()
+ print('Updated-Overlayable: TRUE')
print()
- print('Please add the following line to your commit message')
+ print('Otherwise, please explain why the Overlayable does not need to be updated:')
print()
- print('Bug: 294871353')
+ print('Updated-Overlayable: Not applicable - changing default value')
+ print()
+ return 1
+ changed_xml_related_file = get_changed_xml_related_file(commit_files)
+ if changed_xml_related_file and is_xml_tag_in_commits():
+ if not is_commit_msg_valid(commit_msg, False, True):
+ print('This commit has changed: "{changed_file}".'.format(changed_file=changed_xml_related_file))
+ print()
+ print('If this change added/changed/removed xml resources used by the Wifi Module, ')
+ print('please review if it may break/miss the cloud B&R , check "{b_r_file}".'.format(b_r_file=CLOUD_BACKUP_PARSER_FILE))
+ print('and acknowledge you have done so by adding this line to your commit message:')
+ print()
+ print('Reviewed-Cloud-B&R: TRUE')
+ print()
+ print('Otherwise, please explain why the cloud B&R does not need to be updated:')
+ print()
+ print('Reviewed-Cloud-B&R: Not applicable - not xml format change')
print()
return 1
- if is_commit_msg_valid(commit_msg):
- return 0
-
- print('This commit has changed: "{changed_file}".'.format(changed_file=changed_file))
- print()
- print('If this change added/changed/removed overlayable resources used by the Wifi Module, ')
- print('please update the "{overlay_file}".'.format(overlay_file=OVERLAY_FILE))
- print('and acknowledge you have done so by adding this line to your commit message:')
- print()
- print('Updated-Overlayable: TRUE')
- print()
- print('Otherwise, please explain why the Overlayable does not need to be updated:')
- print()
- print('Updated-Overlayable: Not applicable - changing default value')
- print()
- return 1
-
+ return 0
if __name__ == '__main__':
exit_code = main()
- sys.exit(exit_code) \ No newline at end of file
+ sys.exit(exit_code)