summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--OsuLogin/Android.bp3
-rw-r--r--WifiDialog/Android.bp5
-rw-r--r--WifiDialog/AndroidManifest.xml1
-rw-r--r--WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java106
-rw-r--r--framework/Android.bp4
-rw-r--r--framework/api/current.txt41
-rw-r--r--framework/api/system-current.txt80
-rw-r--r--framework/jarjar-rules.txt3
-rw-r--r--framework/java/android/net/wifi/BaseWifiService.java18
-rw-r--r--framework/java/android/net/wifi/IWifiManager.aidl6
-rw-r--r--framework/java/android/net/wifi/IWifiScanner.aidl2
-rw-r--r--framework/java/android/net/wifi/WifiAvailableChannel.java4
-rw-r--r--framework/java/android/net/wifi/WifiConfiguration.java29
-rw-r--r--framework/java/android/net/wifi/WifiEnterpriseConfig.java67
-rw-r--r--framework/java/android/net/wifi/WifiManager.java524
-rw-r--r--framework/java/android/net/wifi/WifiNetworkSelectionConfig.java77
-rw-r--r--framework/java/android/net/wifi/WifiNetworkSpecifier.java88
-rw-r--r--framework/java/android/net/wifi/WifiScanner.java14
-rw-r--r--framework/java/android/net/wifi/WifiUsabilityStatsEntry.java3
-rw-r--r--framework/java/android/net/wifi/hotspot2/pps/Credential.java47
-rw-r--r--framework/java/android/net/wifi/hotspot2/pps/HomeSp.java10
-rw-r--r--framework/java/android/net/wifi/hotspot2/pps/Policy.java9
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pConfig.java108
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pGroup.java7
-rw-r--r--framework/java/android/net/wifi/p2p/WifiP2pManager.java3
-rw-r--r--framework/java/android/net/wifi/rtt/CivicLocation.java4
-rw-r--r--framework/java/android/net/wifi/rtt/IWifiRttManager.aidl1
-rw-r--r--framework/java/android/net/wifi/rtt/RangingResult.java24
-rw-r--r--framework/java/android/net/wifi/rtt/WifiRttManager.java50
-rw-r--r--framework/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java34
-rw-r--r--framework/tests/src/android/net/wifi/WifiManagerTest.java43
-rw-r--r--framework/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java26
-rw-r--r--framework/tests/src/android/net/wifi/WifiNetworkSelectionConfigTest.java6
-rw-r--r--framework/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java62
-rw-r--r--framework/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java14
-rw-r--r--framework/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java38
-rw-r--r--framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java56
-rw-r--r--framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java8
-rw-r--r--service/Android.bp8
-rw-r--r--service/ServiceWifiResources/res/values-af/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-am/strings.xml6
-rw-r--r--service/ServiceWifiResources/res/values-ar/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-as/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-az/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-be/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-bg/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-bn/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-bs/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ca/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-cs/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-da/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-de/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-el/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-en-rAU/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-en-rCA/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-en-rGB/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-en-rIN/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-en-rXC/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-es-rUS/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-es/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-et/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-eu/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-fa/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-fi/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-fr-rCA/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-fr/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-gl/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-gu/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-hi/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-hr/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-hu/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-hy/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-in/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-is/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-it/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-iw/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ja/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ka/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-kk/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-km/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-kn/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ko/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ky/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-lo/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-lt/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-lv/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-mk/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ml/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-mn/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-mr/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ms/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-my/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-nb/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ne/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-nl/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-or/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-pa/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-pl/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-pt-rBR/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-pt-rPT/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-pt/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ro/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ru/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-si/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-sk/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-sl/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-sq/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-sr/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-sv/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-sw/strings.xml6
-rw-r--r--service/ServiceWifiResources/res/values-ta/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-te/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-th/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-tl/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-tr/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-uk/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-ur/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-uz/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-vi/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-zh-rCN/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-zh-rHK/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-zh-rTW/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values-zu/strings.xml10
-rw-r--r--service/ServiceWifiResources/res/values/config.xml31
-rw-r--r--service/ServiceWifiResources/res/values/overlayable.xml29
-rw-r--r--service/ServiceWifiResources/res/values/strings.xml10
-rw-r--r--service/java/com/android/server/wifi/ActiveModeWarden.java186
-rw-r--r--service/java/com/android/server/wifi/ClientMode.java20
-rw-r--r--service/java/com/android/server/wifi/ClientModeDefaults.java10
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java616
-rw-r--r--service/java/com/android/server/wifi/ConcreteClientModeManager.java161
-rw-r--r--service/java/com/android/server/wifi/HalDeviceManager.java1854
-rw-r--r--service/java/com/android/server/wifi/HalDeviceManagerUtil.java61
-rw-r--r--service/java/com/android/server/wifi/InterfaceConflictManager.java83
-rw-r--r--service/java/com/android/server/wifi/MultiInternetManager.java105
-rw-r--r--service/java/com/android/server/wifi/MultiInternetWifiNetworkFactory.java32
-rw-r--r--service/java/com/android/server/wifi/NetworkConnectionEventInfo.java7
-rw-r--r--service/java/com/android/server/wifi/RunnerHandler.java148
-rw-r--r--service/java/com/android/server/wifi/RunnerState.java117
-rw-r--r--service/java/com/android/server/wifi/ScanRequestProxy.java128
-rw-r--r--service/java/com/android/server/wifi/ScoringParams.java24
-rw-r--r--service/java/com/android/server/wifi/SoftApManager.java101
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java61
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_2Impl.java3
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java73
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java38
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java196
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaNetworkHalHidlImpl.java42
-rw-r--r--service/java/com/android/server/wifi/ThroughputScorer.java6
-rw-r--r--service/java/com/android/server/wifi/WakeupController.java25
-rw-r--r--service/java/com/android/server/wifi/WifiApConfigStore.java31
-rw-r--r--service/java/com/android/server/wifi/WifiBackupDataV1Parser.java108
-rw-r--r--service/java/com/android/server/wifi/WifiBackupRestore.java6
-rw-r--r--service/java/com/android/server/wifi/WifiBlocklistMonitor.java226
-rw-r--r--service/java/com/android/server/wifi/WifiCandidates.java13
-rw-r--r--service/java/com/android/server/wifi/WifiCarrierInfoManager.java88
-rw-r--r--service/java/com/android/server/wifi/WifiCarrierInfoStoreManagerData.java44
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java16
-rw-r--r--service/java/com/android/server/wifi/WifiConfigStore.java5
-rw-r--r--service/java/com/android/server/wifi/WifiConfigurationUtil.java17
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java113
-rw-r--r--service/java/com/android/server/wifi/WifiCountryCode.java2
-rw-r--r--service/java/com/android/server/wifi/WifiDialogManager.java343
-rw-r--r--service/java/com/android/server/wifi/WifiHealthMonitor.java15
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java18
-rw-r--r--service/java/com/android/server/wifi/WifiLastResortWatchdog.java2
-rw-r--r--service/java/com/android/server/wifi/WifiLocalServices.java71
-rw-r--r--service/java/com/android/server/wifi/WifiMonitor.java38
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java353
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java62
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSelector.java39
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java7
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java214
-rw-r--r--service/java/com/android/server/wifi/WifiSettingsConfigStore.java13
-rw-r--r--service/java/com/android/server/wifi/WifiSettingsStore.java7
-rw-r--r--service/java/com/android/server/wifi/WifiShellCommand.java32
-rw-r--r--service/java/com/android/server/wifi/WifiThreadRunner.java8
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java3010
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java8
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java17
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareMetrics.java44
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java1000
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java666
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java106
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java4
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareStateManager.java99
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiApIface.java77
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiChip.java438
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiHal.java102
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiNanIface.java227
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiP2pIface.java27
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiRttController.java89
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiStaIface.java248
-rw-r--r--service/java/com/android/server/wifi/hal/WifiApIface.java135
-rw-r--r--service/java/com/android/server/wifi/hal/WifiApIfaceAidlImpl.java198
-rw-r--r--service/java/com/android/server/wifi/hal/WifiApIfaceHidlImpl.java225
-rw-r--r--service/java/com/android/server/wifi/hal/WifiChip.java860
-rw-r--r--service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java1623
-rw-r--r--service/java/com/android/server/wifi/hal/WifiChipHidlImpl.java2292
-rw-r--r--service/java/com/android/server/wifi/hal/WifiHal.java238
-rw-r--r--service/java/com/android/server/wifi/hal/WifiHalAidlImpl.java398
-rw-r--r--service/java/com/android/server/wifi/hal/WifiHalHidlImpl.java591
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIface.java701
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java843
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java514
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackHidlImpl.java678
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceHidlImpl.java1149
-rw-r--r--service/java/com/android/server/wifi/hal/WifiP2pIface.java66
-rw-r--r--service/java/com/android/server/wifi/hal/WifiP2pIfaceAidlImpl.java78
-rw-r--r--service/java/com/android/server/wifi/hal/WifiP2pIfaceHidlImpl.java72
-rw-r--r--service/java/com/android/server/wifi/hal/WifiRttController.java267
-rw-r--r--service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java579
-rw-r--r--service/java/com/android/server/wifi/hal/WifiRttControllerHidlImpl.java (renamed from service/java/com/android/server/wifi/rtt/RttNative.java)1139
-rw-r--r--service/java/com/android/server/wifi/hal/WifiStaIface.java356
-rw-r--r--service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java1203
-rw-r--r--service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java1543
-rw-r--r--service/java/com/android/server/wifi/hotspot2/LegacyPasspointConfig.java3
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointManager.java8
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointProvider.java1
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointXmlUtils.java6
-rw-r--r--service/java/com/android/server/wifi/mockwifi/MockWifiNl80211Manager.java40
-rw-r--r--service/java/com/android/server/wifi/mockwifi/MockWifiServiceUtil.java147
-rw-r--r--service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java24
-rw-r--r--service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlV1_4Impl.java3
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pNative.java45
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java305
-rw-r--r--service/java/com/android/server/wifi/rtt/RttMetrics.java33
-rw-r--r--service/java/com/android/server/wifi/rtt/RttService.java10
-rw-r--r--service/java/com/android/server/wifi/rtt/RttServiceImpl.java157
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScannerInternal.java182
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java112
-rw-r--r--service/java/com/android/server/wifi/util/HalAidlUtil.java92
-rw-r--r--service/java/com/android/server/wifi/util/NativeUtil.java89
-rw-r--r--service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java27
-rw-r--r--service/java/com/android/server/wifi/util/XmlUtil.java6
-rw-r--r--service/tests/OWNERS4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java58
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java32
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java491
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java11
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java2629
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/InterfaceConflictManagerTest.java202
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/MemoryStoreImplTest.java9
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/MultiInternetManagerTest.java91
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/MultiInternetWifiNetworkFactoryTest.java72
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java19
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java32
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java9
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java194
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java26
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java113
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java28
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java159
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java124
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java365
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoStoreManagerDataTest.java19
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java69
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java41
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java733
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java6
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java44
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java25
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java30
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java29
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java786
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java94
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java230
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java186
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java306
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiSettingsStoreTest.java11
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java26
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java2985
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java51
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java56
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java749
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeManagerTest.java81
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java139
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/HalTestUtils.java38
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiApIfaceTest.java158
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipTest.java148
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiHalTest.java120
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceHidlImplTest.java756
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceTest.java111
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiP2pIfaceTest.java111
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerHidlImplTest.java (renamed from service/tests/wifitests/src/com/android/server/wifi/rtt/RttNativeTest.java)144
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerTest.java112
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceTest.java122
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImplTest.java104
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImplTest.java23
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalAidlImplTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalHidlImplTest.java57
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java18
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java50
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java23
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/rtt/RttMetricsTest.java59
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/rtt/RttServiceImplTest.java382
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java103
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/NativeUtilTest.java100
308 files changed, 30069 insertions, 15820 deletions
diff --git a/OsuLogin/Android.bp b/OsuLogin/Android.bp
index 864883f443..ff8748c31e 100644
--- a/OsuLogin/Android.bp
+++ b/OsuLogin/Android.bp
@@ -15,6 +15,9 @@ android_app {
"com.android.wifi",
"test_com.android.wifi",
],
+ optimize: {
+ shrink_resources: true,
+ },
}
android_app_certificate {
diff --git a/WifiDialog/Android.bp b/WifiDialog/Android.bp
index 8a9de613cf..1941294fa8 100644
--- a/WifiDialog/Android.bp
+++ b/WifiDialog/Android.bp
@@ -35,7 +35,10 @@ android_app {
apex_available: [
"com.android.wifi",
"test_com.android.wifi",
- ]
+ ],
+ optimize: {
+ shrink_resources: true,
+ },
}
android_app_certificate {
diff --git a/WifiDialog/AndroidManifest.xml b/WifiDialog/AndroidManifest.xml
index 66132822c6..dfeafabda0 100644
--- a/WifiDialog/AndroidManifest.xml
+++ b/WifiDialog/AndroidManifest.xml
@@ -42,6 +42,7 @@
android:configChanges="keyboardHidden|screenSize"
android:hardwareAccelerated="true"
android:launchMode="singleInstance"
+ android:excludeFromRecents="true"
android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight" />
</application>
</manifest>
diff --git a/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java b/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java
index b73bee04be..c73afa9134 100644
--- a/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java
+++ b/WifiDialog/src/com/android/wifi/dialog/WifiDialogActivity.java
@@ -37,7 +37,6 @@ import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
-import android.os.Process;
import android.os.SystemClock;
import android.os.Vibrator;
import android.text.Editable;
@@ -72,8 +71,6 @@ import java.util.Set;
* Main Activity of the WifiDialog application. All dialogs should be created and managed from here.
*/
public class WifiDialogActivity extends Activity {
- private static int sNumActiveInstances = 0;
-
private static final String TAG = "WifiDialog";
private static final String KEY_DIALOG_INTENTS = "KEY_DIALOG_INTENTS";
private static final String EXTRA_DIALOG_EXPIRATION_TIME_MS =
@@ -213,10 +210,6 @@ public class WifiDialogActivity extends Activity {
@Override
protected void onStart() {
super.onStart();
- sNumActiveInstances++;
- if (mIsVerboseLoggingEnabled) {
- Log.v(TAG, "onStart() incrementing sActiveInstances to " + sNumActiveInstances);
- }
registerReceiver(
mCloseSystemDialogsReceiver, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
ArraySet<Integer> invalidDialogIds = new ArraySet<>();
@@ -260,10 +253,6 @@ public class WifiDialogActivity extends Activity {
@Override
protected void onStop() {
super.onStop();
- sNumActiveInstances--;
- if (mIsVerboseLoggingEnabled) {
- Log.v(TAG, "onStop() decrementing sActiveInstances to " + sNumActiveInstances);
- }
unregisterReceiver(mCloseSystemDialogsReceiver);
if (isChangingConfigurations()) {
@@ -328,28 +317,11 @@ public class WifiDialogActivity extends Activity {
}
}
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (isFinishing()) {
- if (sNumActiveInstances > 0) {
- if (mIsVerboseLoggingEnabled) {
- Log.v(TAG, "Finished with sNumActiveInstances: " + sNumActiveInstances);
- }
- return;
- }
- if (mIsVerboseLoggingEnabled) {
- Log.v(TAG, "Finished with no active instances left. Killing process.");
- }
- Process.killProcess(android.os.Process.myPid());
- }
- }
-
/**
* Creates and shows a dialog for the given dialogId and Intent.
* Returns {@code true} if the dialog was successfully created, {@code false} otherwise.
*/
- private @Nullable boolean createAndShowDialogForIntent(int dialogId, @NonNull Intent intent) {
+ private boolean createAndShowDialogForIntent(int dialogId, @NonNull Intent intent) {
String action = intent.getAction();
if (!WifiManager.ACTION_LAUNCH_DIALOG.equals(action)) {
return false;
@@ -389,9 +361,6 @@ public class WifiDialogActivity extends Activity {
}
return false;
}
- if (dialog == null) {
- return false;
- }
dialog.setOnDismissListener((dialogDismiss) -> {
if (mIsVerboseLoggingEnabled) {
Log.v(TAG, "Dialog id=" + dialogId
@@ -480,9 +449,9 @@ public class WifiDialogActivity extends Activity {
}
/**
- * Returns a simple dialog for the given Intent, or {@code null} if no dialog could be created.
+ * Returns a simple dialog for the given Intent.
*/
- private @Nullable AlertDialog createSimpleDialog(
+ private @NonNull AlertDialog createSimpleDialog(
int dialogId,
@Nullable String title,
@Nullable String message,
@@ -495,10 +464,18 @@ public class WifiDialogActivity extends Activity {
SpannableString spannableMessage = null;
if (message != null) {
spannableMessage = new SpannableString(message);
- if (messageUrlStart >= 0 && messageUrlEnd <= message.length()
- && messageUrlStart < messageUrlEnd) {
- spannableMessage.setSpan(new URLSpan(messageUrl), messageUrlStart, messageUrlEnd,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ if (messageUrl != null) {
+ if (messageUrlStart < 0) {
+ Log.w(TAG, "Span start cannot be less than 0!");
+ } else if (messageUrlEnd > message.length()) {
+ Log.w(TAG, "Span end index " + messageUrlEnd
+ + " cannot be greater than message length " + message.length() + "!");
+ } else if (messageUrlStart > messageUrlEnd) {
+ Log.w(TAG, "Span start index cannot be greater than end index!");
+ } else {
+ spannableMessage.setSpan(new URLSpan(messageUrl), messageUrlStart,
+ messageUrlEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
}
}
AlertDialog dialog = new AlertDialog.Builder(
@@ -552,27 +529,21 @@ public class WifiDialogActivity extends Activity {
}
/**
- * Returns a P2P Invitation Sent Dialog for the given Intent, or {@code null} if no Dialog
- * could be created.
+ * Returns a P2P Invitation Sent Dialog for the given Intent.
*/
- private @Nullable AlertDialog createP2pInvitationSentDialog(
+ private @NonNull AlertDialog createP2pInvitationSentDialog(
final int dialogId,
- final @NonNull String deviceName,
- @Nullable String displayPin) {
- if (TextUtils.isEmpty(deviceName)) {
- if (mIsVerboseLoggingEnabled) {
- Log.v(TAG, "Could not create P2P Invitation Sent dialog with null or empty"
- + " device name."
- + " id=" + dialogId
- + " deviceName=" + deviceName
- + " displayPin=" + displayPin);
- }
- return null;
- }
-
+ @Nullable final String deviceName,
+ @Nullable final String displayPin) {
final View textEntryView = LayoutInflater.from(this)
.inflate(getLayoutId("wifi_p2p_dialog"), null);
ViewGroup group = textEntryView.findViewById(getViewId("info"));
+ if (TextUtils.isEmpty(deviceName)) {
+ Log.w(TAG, "P2P Invitation Sent dialog device name is null or empty."
+ + " id=" + dialogId
+ + " deviceName=" + deviceName
+ + " displayPin=" + displayPin);
+ }
addRowToP2pDialog(group, getStringId("wifi_p2p_to_message"), deviceName);
if (displayPin != null) {
@@ -601,29 +572,22 @@ public class WifiDialogActivity extends Activity {
}
/**
- * Returns a P2P Invitation Received Dialog for the given Intent, or {@code null} if no Dialog
- * could be created.
+ * Returns a P2P Invitation Received Dialog for the given Intent.
*/
- private @Nullable AlertDialog createP2pInvitationReceivedDialog(
+ private @NonNull AlertDialog createP2pInvitationReceivedDialog(
final int dialogId,
- final @NonNull String deviceName,
+ @Nullable final String deviceName,
final boolean isPinRequested,
- @Nullable String displayPin) {
- if (TextUtils.isEmpty(deviceName)) {
- if (mIsVerboseLoggingEnabled) {
- Log.v(TAG, "Could not create P2P Invitation Received dialog with null or empty"
- + " device name."
- + " id=" + dialogId
- + " deviceName=" + deviceName
- + " isPinRequested=" + isPinRequested
- + " displayPin=" + displayPin);
- }
- return null;
- }
-
+ @Nullable final String displayPin) {
final View textEntryView = LayoutInflater.from(this)
.inflate(getLayoutId("wifi_p2p_dialog"), null);
ViewGroup group = textEntryView.findViewById(getViewId("info"));
+ if (TextUtils.isEmpty(deviceName)) {
+ Log.w(TAG, "P2P Invitation Received dialog device name is null or empty."
+ + " id=" + dialogId
+ + " deviceName=" + deviceName
+ + " displayPin=" + displayPin);
+ }
addRowToP2pDialog(group, getStringId("wifi_p2p_from_message"), deviceName);
final EditText pinEditText;
diff --git a/framework/Android.bp b/framework/Android.bp
index 3c1d0a0fdf..f2ea514792 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -19,7 +19,6 @@ package {
java_defaults {
name: "wifi-module-sdk-version-defaults",
min_sdk_version: "30",
- target_sdk_version: "33",
}
filegroup {
@@ -104,6 +103,7 @@ java_defaults {
"app-compat-annotations",
],
aidl: {
+ generate_get_transaction_name: true,
include_dirs: [
"packages/modules/Connectivity/framework/aidl-export",
],
@@ -121,8 +121,6 @@ java_library {
defaults: ["framework-wifi-defaults"],
sdk_version: "module_current",
libs: ["framework-annotations-lib"],
- // java_api_finder must accompany `srcs` (`srcs` defined in `framework-wifi-defaults`)
- plugins: ["java_api_finder"],
installable: false,
visibility: [
"//frameworks/opt/net/wifi/service",
diff --git a/framework/api/current.txt b/framework/api/current.txt
index f78a462c90..8bda5fa395 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -137,6 +137,21 @@ package android.net.wifi {
enum_constant public static final android.net.wifi.SupplicantState UNINITIALIZED;
}
+ public final class WifiAvailableChannel implements android.os.Parcelable {
+ ctor public WifiAvailableChannel(int, int);
+ method public int describeContents();
+ method public int getFrequencyMhz();
+ method public int getOperationalModes();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiAvailableChannel> CREATOR;
+ field public static final int OP_MODE_SAP = 2; // 0x2
+ field public static final int OP_MODE_STA = 1; // 0x1
+ field public static final int OP_MODE_TDLS = 32; // 0x20
+ field public static final int OP_MODE_WIFI_AWARE = 16; // 0x10
+ field public static final int OP_MODE_WIFI_DIRECT_CLI = 4; // 0x4
+ field public static final int OP_MODE_WIFI_DIRECT_GO = 8; // 0x8
+ }
+
@Deprecated public class WifiConfiguration implements android.os.Parcelable {
ctor @Deprecated public WifiConfiguration();
ctor @Deprecated public WifiConfiguration(@NonNull android.net.wifi.WifiConfiguration);
@@ -273,6 +288,7 @@ package android.net.wifi {
method public String getDomainSuffixMatch();
method public int getEapMethod();
method public String getIdentity();
+ method public int getMinimumTlsVersion();
method public String getPassword();
method public int getPhase2Method();
method public String getPlmn();
@@ -294,6 +310,7 @@ package android.net.wifi {
method public void setDomainSuffixMatch(String);
method public void setEapMethod(int);
method public void setIdentity(String);
+ method public void setMinimumTlsVersion(int) throws java.lang.IllegalArgumentException;
method public void setPassword(String);
method public void setPhase2Method(int);
method public void setPlmn(String);
@@ -305,6 +322,10 @@ package android.net.wifi {
field public static final String EXTRA_WAPI_AS_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_AS_CERTIFICATE_NAME";
field public static final String EXTRA_WAPI_USER_CERTIFICATE_DATA = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_DATA";
field public static final String EXTRA_WAPI_USER_CERTIFICATE_NAME = "android.net.wifi.extra.WAPI_USER_CERTIFICATE_NAME";
+ field public static final int TLS_V1_0 = 0; // 0x0
+ field public static final int TLS_V1_1 = 1; // 0x1
+ field public static final int TLS_V1_2 = 2; // 0x2
+ field public static final int TLS_V1_3 = 3; // 0x3
field public static final String WAPI_AS_CERTIFICATE = "WAPIAS_";
field public static final String WAPI_USER_CERTIFICATE = "WAPIUSR_";
}
@@ -411,16 +432,19 @@ package android.net.wifi {
method @Deprecated public boolean disconnect();
method @Deprecated public boolean enableNetwork(int, boolean);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_MANAGED_PROVISIONING, android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}, conditional=true) public void flushPasspointAnqpCache();
+ method @NonNull @RequiresPermission(android.Manifest.permission.NEARBY_WIFI_DEVICES) public java.util.List<android.net.wifi.WifiAvailableChannel> getAllowedChannels(int, int);
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiConfiguration> getCallerConfiguredNetworks();
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE}) public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public android.net.wifi.WifiInfo getConnectionInfo();
method @Deprecated public android.net.DhcpInfo getDhcpInfo();
+ method public int getMaxNumberOfChannelsPerNetworkSpecifierRequest();
method public int getMaxNumberOfNetworkSuggestionsPerApp();
method @IntRange(from=0) public int getMaxSignalLevel();
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiNetworkSuggestion> getNetworkSuggestions();
method @Deprecated public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
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);
method public int getWifiState();
method public boolean is24GHzBandSupported();
method public boolean is5GHzBandSupported();
@@ -431,6 +455,7 @@ package android.net.wifi {
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isCarrierNetworkOffloadEnabled(int, boolean);
method public boolean isDecoratedIdentitySupported();
method @Deprecated public boolean isDeviceToApRttSupported();
+ method public boolean isDualBandSimultaneousSupported();
method public boolean isEasyConnectDppAkmSupported();
method public boolean isEasyConnectEnrolleeResponderModeSupported();
method public boolean isEasyConnectSupported();
@@ -447,6 +472,8 @@ package android.net.wifi {
method public boolean isStaConcurrencyForLocalOnlyConnectionsSupported();
method public boolean isStaConcurrencyForMultiInternetSupported();
method public boolean isTdlsSupported();
+ method public boolean isTlsMinimumVersionSupported();
+ method public boolean isTlsV13Supported();
method public boolean isTrustOnFirstUseSupported();
method public boolean isWapiSupported();
method public boolean isWifiDisplayR2Supported();
@@ -481,6 +508,7 @@ package android.net.wifi {
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void unregisterScanResultsCallback(@NonNull android.net.wifi.WifiManager.ScanResultsCallback);
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public void unregisterSubsystemRestartTrackingCallback(@NonNull android.net.wifi.WifiManager.SubsystemRestartTrackingCallback);
method @Deprecated public int updateNetwork(android.net.wifi.WifiConfiguration);
+ method public boolean validateSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
field public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
field public static final int ACTION_REMOVE_SUGGESTION_DISCONNECT = 2; // 0x2
field public static final int ACTION_REMOVE_SUGGESTION_LINGER = 1; // 0x1
@@ -636,6 +664,7 @@ package android.net.wifi {
public final class WifiNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
method public int describeContents();
method public int getBand();
+ method @NonNull public int[] getPreferredChannelFrequenciesMhz();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSpecifier> CREATOR;
}
@@ -648,6 +677,7 @@ package android.net.wifi {
method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setBssidPattern(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsEnhancedOpen(boolean);
method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setIsHiddenSsid(boolean);
+ method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setPreferredChannelsFrequenciesMhz(@NonNull int[]);
method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsid(@NonNull String);
method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setSsidPattern(@NonNull android.os.PatternMatcher);
method @NonNull public android.net.wifi.WifiNetworkSpecifier.Builder setWpa2EnterpriseConfig(@NonNull android.net.wifi.WifiEnterpriseConfig);
@@ -1019,6 +1049,7 @@ package android.net.wifi.hotspot2.pps {
method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
method public java.security.cert.X509Certificate[] getClientCertificateChain();
method public java.security.PrivateKey getClientPrivateKey();
+ method public int getMinimumTlsVersion();
method public String getRealm();
method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
@@ -1026,6 +1057,7 @@ package android.net.wifi.hotspot2.pps {
method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
method public void setClientPrivateKey(java.security.PrivateKey);
+ method public void setMinimumTlsVersion(int) throws java.lang.IllegalArgumentException;
method public void setRealm(String);
method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
@@ -1101,12 +1133,15 @@ package android.net.wifi.p2p {
ctor public WifiP2pConfig();
ctor public WifiP2pConfig(android.net.wifi.p2p.WifiP2pConfig);
method public int describeContents();
+ method public int getGroupClientIpProvisioningMode();
method public int getGroupOwnerBand();
method public int getNetworkId();
method @Nullable public String getNetworkName();
method @Nullable public String getPassphrase();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pConfig> CREATOR;
+ field public static final int GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP = 0; // 0x0
+ field public static final int GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL = 1; // 0x1
field public static final int GROUP_OWNER_BAND_2GHZ = 1; // 0x1
field public static final int GROUP_OWNER_BAND_5GHZ = 2; // 0x2
field public static final int GROUP_OWNER_BAND_AUTO = 0; // 0x0
@@ -1123,6 +1158,7 @@ package android.net.wifi.p2p {
method @NonNull public android.net.wifi.p2p.WifiP2pConfig build();
method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder enablePersistentMode(boolean);
method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setDeviceAddress(@Nullable android.net.MacAddress);
+ method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupClientIpProvisioningMode(int);
method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingBand(int);
method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setGroupOperatingFrequency(int);
method @NonNull public android.net.wifi.p2p.WifiP2pConfig.Builder setNetworkName(@NonNull String);
@@ -1231,6 +1267,7 @@ package android.net.wifi.p2p {
method public void setServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ServiceResponseListener);
method public void setUpnpServiceResponseListener(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.UpnpServiceResponseListener);
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 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);
@@ -1579,9 +1616,13 @@ package android.net.wifi.rtt {
}
public class WifiRttManager {
+ method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.os.Bundle getRttCharacteristics();
method public boolean isAvailable();
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.NEARBY_WIFI_DEVICES}) public void startRanging(@NonNull android.net.wifi.rtt.RangingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.rtt.RangingResultCallback);
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 public static final String CHARACTERISTICS_KEY_BOOLEAN_ONE_SIDED_RTT = "key_one_sided_rtt";
}
}
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 2249e02e1c..d41553f7ef 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -360,21 +360,6 @@ package android.net.wifi {
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApInfo> CREATOR;
}
- public final class WifiAvailableChannel implements android.os.Parcelable {
- ctor public WifiAvailableChannel(int, int);
- method public int describeContents();
- method public int getFrequencyMhz();
- method public int getOperationalModes();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiAvailableChannel> CREATOR;
- field public static final int OP_MODE_SAP = 2; // 0x2
- field public static final int OP_MODE_STA = 1; // 0x1
- field public static final int OP_MODE_TDLS = 32; // 0x20
- field public static final int OP_MODE_WIFI_AWARE = 16; // 0x10
- field public static final int OP_MODE_WIFI_DIRECT_CLI = 4; // 0x4
- field public static final int OP_MODE_WIFI_DIRECT_GO = 8; // 0x8
- }
-
public final class WifiClient implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.net.MacAddress getMacAddress();
@@ -405,6 +390,7 @@ package android.net.wifi {
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);
+ 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
field @Deprecated public static final int METERED_OVERRIDE_NONE = 0; // 0x0
@@ -429,12 +415,14 @@ package android.net.wifi {
field @Deprecated public boolean fromWifiNetworkSpecifier;
field @Deprecated public boolean fromWifiNetworkSuggestion;
field @Deprecated public int lastConnectUid;
+ field @Deprecated public long lastConnected;
field @Deprecated public String lastUpdateName;
field @Deprecated public int lastUpdateUid;
field @Deprecated public int macRandomizationSetting;
field @Deprecated public boolean meteredHint;
field @Deprecated public int meteredOverride;
field @Deprecated public int numAssociation;
+ field @Deprecated public int numRebootsSinceLastUse;
field @Deprecated public int numScorerOverride;
field @Deprecated public int numScorerOverrideAndSwitchedNetwork;
field @Deprecated public boolean requirePmf;
@@ -471,6 +459,7 @@ package android.net.wifi {
field @Deprecated public static final int DISABLED_NONE = 0; // 0x0
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 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
@@ -554,7 +543,6 @@ package android.net.wifi {
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>);
- method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.net.wifi.WifiAvailableChannel> getAllowedChannels(int, int);
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public String getCountryCode();
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public android.net.Network getCurrentNetwork();
method public static int getEasyConnectMaxAllowedResponderDeviceInfoLength();
@@ -568,7 +556,6 @@ 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 @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.net.wifi.WifiAvailableChannel> getUsableChannels(int, int);
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();
@@ -579,6 +566,7 @@ package android.net.wifi {
method @Deprecated public boolean isDeviceToDeviceRttSupported();
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();
method public boolean isVerboseLoggingEnabled();
method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
method public boolean isWifiScannerSupported();
@@ -607,6 +595,8 @@ package android.net.wifi {
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);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setMacRandomizationSettingPasspointEnabled(@NonNull String, boolean);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}) public void setNetworkSelectionConfig(@NonNull android.net.wifi.WifiNetworkSelectionConfig);
+ 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 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setScanAlwaysAvailable(boolean);
@@ -615,6 +605,7 @@ package android.net.wifi {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public boolean setSoftApConfiguration(@NonNull android.net.wifi.SoftApConfiguration);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION}, conditional=true) public void setSsidsAllowlist(@NonNull java.util.Set<android.net.wifi.WifiSsid>);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public boolean setStaConcurrencyForMultiInternetMode(int);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setThirdPartyAppEnablingWifiConfirmationDialogEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setVerboseLoggingEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setVerboseLoggingLevel(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
@@ -646,12 +637,39 @@ package android.net.wifi {
field @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public static final String ACTION_REFRESH_USER_PROVISIONING = "android.net.wifi.action.REFRESH_USER_PROVISIONING";
field public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE";
field public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE";
+ field public static final int API_ADD_NETWORK = 10; // 0xa
+ field public static final int API_ALLOW_AUTOJOIN = 12; // 0xc
field public static final int API_AUTOJOIN_GLOBAL = 5; // 0x5
+ field public static final int API_CONNECT_CONFIG = 13; // 0xd
+ field public static final int API_CONNECT_NETWORK_ID = 14; // 0xe
+ field public static final int API_DISABLE_NETWORK = 15; // 0xf
+ field public static final int API_ENABLE_NETWORK = 16; // 0x10
+ field public static final int API_FORGET = 17; // 0x11
+ field public static final int API_P2P_CANCEL_CONNECT = 26; // 0x1a
+ field public static final int API_P2P_CONNECT = 25; // 0x19
+ field public static final int API_P2P_CREATE_GROUP = 27; // 0x1b
+ field public static final int API_P2P_CREATE_GROUP_P2P_CONFIG = 28; // 0x1c
+ 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 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
+ field public static final int API_P2P_STOP_LISTENING = 31; // 0x1f
+ field public static final int API_P2P_STOP_PEER_DISCOVERY = 24; // 0x18
+ field public static final int API_SAVE = 18; // 0x12
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 public static final int API_SET_SCAN_SCHEDULE = 6; // 0x6
+ field public static final int API_SET_THIRD_PARTY_APPS_ENABLING_WIFI_CONFIRMATION_DIALOG = 9; // 0x9
field public static final int API_SOFT_AP = 3; // 0x3
+ field public static final int API_START_LOCAL_ONLY_HOTSPOT = 20; // 0x14
+ field public static final int API_START_SCAN = 19; // 0x13
field public static final int API_TETHERED_HOTSPOT = 4; // 0x4
+ field public static final int API_UPDATE_NETWORK = 11; // 0xb
field public static final int API_WIFI_ENABLED = 2; // 0x2
+ field public static final int API_WIFI_SCANNER_START_SCAN = 33; // 0x21
field public static final int CHANGE_REASON_ADDED = 0; // 0x0
field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
@@ -695,6 +713,7 @@ package android.net.wifi {
field public static final int SAP_START_FAILURE_GENERAL = 0; // 0x0
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 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
@@ -818,6 +837,30 @@ package android.net.wifi {
field @Deprecated public int numUsage;
}
+ public final class WifiNetworkSelectionConfig implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getAssociatedNetworkSelectionOverride();
+ method public boolean isLastSelectionWeightEnabled();
+ method public boolean isSufficiencyCheckEnabledWhenScreenOff();
+ method public boolean isSufficiencyCheckEnabledWhenScreenOn();
+ method public boolean isUserConnectChoiceOverrideEnabled();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int ASSOCIATED_NETWORK_SELECTION_OVERRIDE_DISABLED = 2; // 0x2
+ field public static final int ASSOCIATED_NETWORK_SELECTION_OVERRIDE_ENABLED = 1; // 0x1
+ field public static final int ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE = 0; // 0x0
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSelectionConfig> CREATOR;
+ }
+
+ public static final class WifiNetworkSelectionConfig.Builder {
+ ctor public WifiNetworkSelectionConfig.Builder();
+ method @NonNull public android.net.wifi.WifiNetworkSelectionConfig build();
+ method @NonNull public android.net.wifi.WifiNetworkSelectionConfig.Builder setAssociatedNetworkSelectionOverride(int) throws java.lang.IllegalArgumentException;
+ method @NonNull public android.net.wifi.WifiNetworkSelectionConfig.Builder setLastSelectionWeightEnabled(boolean);
+ method @NonNull public android.net.wifi.WifiNetworkSelectionConfig.Builder setSufficiencyCheckEnabledWhenScreenOff(boolean);
+ method @NonNull public android.net.wifi.WifiNetworkSelectionConfig.Builder setSufficiencyCheckEnabledWhenScreenOn(boolean);
+ method @NonNull public android.net.wifi.WifiNetworkSelectionConfig.Builder setUserConnectChoiceOverrideEnabled(boolean);
+ }
+
public final class WifiNetworkSuggestion implements android.os.Parcelable {
method public int getCarrierId();
method @NonNull public android.net.wifi.WifiConfiguration getWifiConfiguration();
@@ -834,7 +877,7 @@ package android.net.wifi {
public class WifiScanner {
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.LOCATION_HARDWARE) public java.util.List<java.lang.Integer> getAvailableChannels(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NEARBY_WIFI_DEVICES) public java.util.List<java.lang.Integer> getAvailableChannels(int);
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();
@@ -1206,7 +1249,6 @@ package android.net.wifi.p2p {
method @RequiresPermission(allOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.READ_WIFI_CREDENTIAL, android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public void requestPersistentGroupInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener);
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(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(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);
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
diff --git a/framework/jarjar-rules.txt b/framework/jarjar-rules.txt
index 64c2138afa..719a37eefa 100644
--- a/framework/jarjar-rules.txt
+++ b/framework/jarjar-rules.txt
@@ -60,9 +60,6 @@ rule android.net.shared.InetAddressUtils* com.android.wifi.x.@0
rule android.net.shared.InitialConfiguration* com.android.wifi.x.@0
rule android.net.shared.IpConfigurationParcelableUtil* com.android.wifi.x.@0
rule android.net.shared.Layer2Information* com.android.wifi.x.@0
-rule android.net.shared.LinkPropertiesParcelableUtil* com.android.wifi.x.@0
-rule android.net.shared.NetdUtils* com.android.wifi.x.@0
-rule android.net.shared.NetworkMonitorUtils* com.android.wifi.x.@0
rule android.net.shared.ParcelableUtil* com.android.wifi.x.@0
rule android.net.shared.PrivateDnsConfig* com.android.wifi.x.@0
rule android.net.shared.ProvisioningConfiguration* com.android.wifi.x.@0
diff --git a/framework/java/android/net/wifi/BaseWifiService.java b/framework/java/android/net/wifi/BaseWifiService.java
index 785f5c0202..bc1b9759ff 100644
--- a/framework/java/android/net/wifi/BaseWifiService.java
+++ b/framework/java/android/net/wifi/BaseWifiService.java
@@ -438,6 +438,11 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
+ public boolean validateSoftApConfiguration(SoftApConfiguration config) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName,
String featureId, SoftApConfiguration customConfig, Bundle extras) {
throw new UnsupportedOperationException();
@@ -854,13 +859,19 @@ public class BaseWifiService extends IWifiManager.Stub {
throw new UnsupportedOperationException();
}
- @Override
+ /** TO BE REMOVED */
public List<WifiAvailableChannel> getUsableChannels(
int band, int mode, int filter) {
throw new UnsupportedOperationException();
}
@Override
+ public List<WifiAvailableChannel> getUsableChannels(
+ int band, int mode, int filter, String packageName, Bundle extras) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public boolean isWifiPasspointEnabled() {
throw new UnsupportedOperationException();
}
@@ -922,4 +933,9 @@ public class BaseWifiService extends IWifiManager.Stub {
boolean requireNewInterface, IInterfaceCreationInfoCallback callback) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public int getMaxNumberOfChannelsPerRequest() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/framework/java/android/net/wifi/IWifiManager.aidl b/framework/java/android/net/wifi/IWifiManager.aidl
index 010e222100..e669316de2 100644
--- a/framework/java/android/net/wifi/IWifiManager.aidl
+++ b/framework/java/android/net/wifi/IWifiManager.aidl
@@ -211,6 +211,8 @@ interface IWifiManager
boolean stopSoftAp();
+ boolean validateSoftApConfiguration(in SoftApConfiguration config);
+
int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName,
String featureId, in SoftApConfiguration customConfig, in Bundle extras);
@@ -380,7 +382,7 @@ interface IWifiManager
void flushPasspointAnqpCache(String packageName);
- List<WifiAvailableChannel> getUsableChannels(int band, int mode, int filter);
+ List<WifiAvailableChannel> getUsableChannels(int band, int mode, int filter, String packageName, in Bundle extras);
boolean isWifiPasspointEnabled();
@@ -405,4 +407,6 @@ interface IWifiManager
void removeCustomDhcpOptions(in WifiSsid ssid, in byte[] oui);
void reportCreateInterfaceImpact(String packageName, int interfaceType, boolean requireNewInterface, in IInterfaceCreationInfoCallback callback);
+
+ int getMaxNumberOfChannelsPerRequest();
}
diff --git a/framework/java/android/net/wifi/IWifiScanner.aidl b/framework/java/android/net/wifi/IWifiScanner.aidl
index 9c1b7ab586..bb1b34b5a5 100644
--- a/framework/java/android/net/wifi/IWifiScanner.aidl
+++ b/framework/java/android/net/wifi/IWifiScanner.aidl
@@ -28,7 +28,7 @@ import android.net.wifi.IWifiScannerListener;
*/
interface IWifiScanner
{
- Bundle getAvailableChannels(int band, String packageName, String featureId);
+ Bundle getAvailableChannels(int band, String packageName, String featureId, in Bundle extras);
boolean isScanning();
diff --git a/framework/java/android/net/wifi/WifiAvailableChannel.java b/framework/java/android/net/wifi/WifiAvailableChannel.java
index 6e56214448..11a4054c52 100644
--- a/framework/java/android/net/wifi/WifiAvailableChannel.java
+++ b/framework/java/android/net/wifi/WifiAvailableChannel.java
@@ -18,7 +18,6 @@ package android.net.wifi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,10 +31,7 @@ import java.util.Objects;
* filtered by regulatory constraints. Use {@link WifiManager#getUsableChannels(int, int)} to
* retrieve the list of channels filtered by regulatory and dynamic constraints like concurrency and
* interference due to other radios.
- *
- * @hide
*/
-@SystemApi
public final class WifiAvailableChannel implements Parcelable {
/**
diff --git a/framework/java/android/net/wifi/WifiConfiguration.java b/framework/java/android/net/wifi/WifiConfiguration.java
index 1c3bc7934b..798b903ed1 100644
--- a/framework/java/android/net/wifi/WifiConfiguration.java
+++ b/framework/java/android/net/wifi/WifiConfiguration.java
@@ -1474,9 +1474,15 @@ public class WifiConfiguration implements Parcelable {
public boolean osu;
/**
- * Last time the system was connected to this configuration.
+ * Last time the system was connected to this configuration represented as the difference,
+ * measured in milliseconds, between the last connected time and midnight, January 1, 1970 UTC.
+ * <P>
+ * Note that this information is only in memory will be cleared (reset to 0) for all
+ * WifiConfiguration(s) after a reboot.
* @hide
*/
+ @SuppressLint("MutableBareField")
+ @SystemApi
public long lastConnected;
/**
@@ -1497,6 +1503,8 @@ public class WifiConfiguration implements Parcelable {
* Number of reboots since this config was last used (either connected or updated).
* @hide
*/
+ @SuppressLint("MutableBareField")
+ @SystemApi
public int numRebootsSinceLastUse;
/**
@@ -1564,14 +1572,6 @@ public class WifiConfiguration implements Parcelable {
public boolean oemPrivate;
/**
- * Indicate whether or not the network is a secondary network with internet, associated with
- * a DBS AP same as the primary network on a different band.
- * This bit is set when this Wifi configuration is created from {@link WifiConnectivityManager}.
- * @hide
- */
- public boolean dbsSecondaryInternet;
-
- /**
* Indicate whether or not the network is a carrier merged network.
* This bit can only be used by suggestion network, see
* {@link WifiNetworkSuggestion.Builder#setCarrierMerged(boolean)}
@@ -2127,7 +2127,6 @@ public class WifiConfiguration implements Parcelable {
/**
* This code is used to disable a network when a security params is disabled
* by the transition disable indication.
- * @hide
*/
public static final int DISABLED_TRANSITION_DISABLE_INDICATION = 13;
/**
@@ -3205,7 +3204,6 @@ public class WifiConfiguration implements Parcelable {
carrierMerged = false;
fromWifiNetworkSuggestion = false;
fromWifiNetworkSpecifier = false;
- dbsSecondaryInternet = false;
meteredHint = false;
mIsRepeaterEnabled = false;
meteredOverride = METERED_OVERRIDE_NONE;
@@ -3354,14 +3352,13 @@ public class WifiConfiguration implements Parcelable {
if (this.carrierMerged) sbuf.append(" carrierMerged");
if (this.fromWifiNetworkSuggestion) sbuf.append(" fromWifiNetworkSuggestion");
if (this.fromWifiNetworkSpecifier) sbuf.append(" fromWifiNetworkSpecifier");
- if (this.dbsSecondaryInternet) sbuf.append(" dbsSecondaryInternet");
if (this.meteredHint) sbuf.append(" meteredHint");
if (this.mIsRepeaterEnabled) sbuf.append(" repeaterEnabled");
if (this.useExternalScores) sbuf.append(" useExternalScores");
if (this.validatedInternetAccess || this.ephemeral || this.trusted || this.oemPaid
|| this.oemPrivate || this.carrierMerged || this.fromWifiNetworkSuggestion
|| this.fromWifiNetworkSpecifier || this.meteredHint || this.useExternalScores
- || this.restricted || this.dbsSecondaryInternet) {
+ || this.restricted) {
sbuf.append("\n");
}
if (this.meteredOverride != METERED_OVERRIDE_NONE) {
@@ -3641,6 +3638,7 @@ public class WifiConfiguration implements Parcelable {
/**
* Get the authentication type of the network.
* @return One of the {@link KeyMgmt} constants. e.g. {@link KeyMgmt#WPA2_PSK}.
+ * @throws IllegalStateException if config is invalid for authentication type.
* @hide
*/
@SystemApi
@@ -3936,7 +3934,6 @@ public class WifiConfiguration implements Parcelable {
carrierMerged = source.carrierMerged;
fromWifiNetworkSuggestion = source.fromWifiNetworkSuggestion;
fromWifiNetworkSpecifier = source.fromWifiNetworkSpecifier;
- dbsSecondaryInternet = source.dbsSecondaryInternet;
meteredHint = source.meteredHint;
mIsRepeaterEnabled = source.mIsRepeaterEnabled;
meteredOverride = source.meteredOverride;
@@ -4040,7 +4037,6 @@ public class WifiConfiguration implements Parcelable {
dest.writeInt(carrierMerged ? 1 : 0);
dest.writeInt(fromWifiNetworkSuggestion ? 1 : 0);
dest.writeInt(fromWifiNetworkSpecifier ? 1 : 0);
- dest.writeInt(dbsSecondaryInternet ? 1 : 0);
dest.writeInt(meteredHint ? 1 : 0);
dest.writeBoolean(mIsRepeaterEnabled);
dest.writeInt(meteredOverride);
@@ -4080,7 +4076,7 @@ public class WifiConfiguration implements Parcelable {
}
/** Implement the Parcelable interface {@hide} */
- @UnsupportedAppUsage
+ @SystemApi
public static final @android.annotation.NonNull Creator<WifiConfiguration> CREATOR =
new Creator<WifiConfiguration>() {
public WifiConfiguration createFromParcel(Parcel in) {
@@ -4137,7 +4133,6 @@ public class WifiConfiguration implements Parcelable {
config.carrierMerged = in.readInt() != 0;
config.fromWifiNetworkSuggestion = in.readInt() != 0;
config.fromWifiNetworkSpecifier = in.readInt() != 0;
- config.dbsSecondaryInternet = in.readInt() != 0;
config.meteredHint = in.readInt() != 0;
config.mIsRepeaterEnabled = in.readBoolean();
config.meteredOverride = in.readInt();
diff --git a/framework/java/android/net/wifi/WifiEnterpriseConfig.java b/framework/java/android/net/wifi/WifiEnterpriseConfig.java
index 2a53e35f16..0f6c1d605e 100644
--- a/framework/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/framework/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -246,6 +246,39 @@ public class WifiEnterpriseConfig implements Parcelable {
*/
private static final List<String> UNQUOTED_KEYS = Arrays.asList(ENGINE_KEY, OPP_KEY_CACHING,
EAP_ERP);
+ /** Constant definition for TLS v1.0 which is used in {@link #setMinimumTlsVersion(int)} */
+ public static final int TLS_V1_0 = 0;
+
+ /** Constant definition for TLS v1.1 which is used in {@link #setMinimumTlsVersion(int)} */
+ public static final int TLS_V1_1 = 1;
+
+ /** Constant definition for TLS v1.2 which is used in {@link #setMinimumTlsVersion(int)} */
+ public static final int TLS_V1_2 = 2;
+
+ /** Constant definition for TLS v1.3 which is used in {@link #setMinimumTlsVersion(int)} */
+ public static final int TLS_V1_3 = 3;
+
+ /**
+ * The minimum valid value for a TLS version.
+ * @hide
+ */
+ public static final int TLS_VERSION_MIN = TLS_V1_0;
+
+ /**
+ * The maximum valid value for a TLS version.
+ * @hide
+ */
+ public static final int TLS_VERSION_MAX = TLS_V1_3;
+
+ /** @hide */
+ @IntDef(prefix = {"TLS_"}, value = {
+ TLS_V1_0,
+ TLS_V1_1,
+ TLS_V1_2,
+ TLS_V1_3
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TlsVersion {}
@UnsupportedAppUsage
private HashMap<String, String> mFields = new HashMap<String, String>();
@@ -259,6 +292,8 @@ public class WifiEnterpriseConfig implements Parcelable {
private String mKeyChainAlias;
private boolean mIsTrustOnFirstUseEnabled = false;
private boolean mUserApproveNoCaCert = false;
+ // Default is 1.0, i.e. accept any TLS version.
+ private int mMinimumTlsVersion = TLS_V1_0;
// Not included in parceling, hashing, or equality because it is an internal, temporary value
// which is valid only during an actual connection to a Passpoint network with an RCOI-based
@@ -313,6 +348,7 @@ public class WifiEnterpriseConfig implements Parcelable {
mIsTrustOnFirstUseEnabled = source.mIsTrustOnFirstUseEnabled;
mUserApproveNoCaCert = source.mUserApproveNoCaCert;
mSelectedRcoi = source.mSelectedRcoi;
+ mMinimumTlsVersion = source.mMinimumTlsVersion;
}
/**
@@ -362,6 +398,7 @@ public class WifiEnterpriseConfig implements Parcelable {
dest.writeInt(mOcsp);
dest.writeBoolean(mIsTrustOnFirstUseEnabled);
dest.writeBoolean(mUserApproveNoCaCert);
+ dest.writeInt(mMinimumTlsVersion);
}
public static final @android.annotation.NonNull Creator<WifiEnterpriseConfig> CREATOR =
@@ -387,6 +424,7 @@ public class WifiEnterpriseConfig implements Parcelable {
enterpriseConfig.mOcsp = in.readInt();
enterpriseConfig.mIsTrustOnFirstUseEnabled = in.readBoolean();
enterpriseConfig.mUserApproveNoCaCert = in.readBoolean();
+ enterpriseConfig.mMinimumTlsVersion = in.readInt();
return enterpriseConfig;
}
@@ -1409,6 +1447,7 @@ public class WifiEnterpriseConfig implements Parcelable {
sb.append(" trust_on_first_use: ").append(mIsTrustOnFirstUseEnabled).append("\n");
sb.append(" user_approve_no_ca_cert: ").append(mUserApproveNoCaCert).append("\n");
sb.append(" selected_rcoi: ").append(mSelectedRcoi).append("\n");
+ sb.append(" minimum_tls_version: ").append(mMinimumTlsVersion).append("\n");
return sb.toString();
}
@@ -1736,4 +1775,32 @@ public class WifiEnterpriseConfig implements Parcelable {
return mUserApproveNoCaCert;
}
+ /**
+ * Set the minimum TLS version for TLS-based EAP methods.
+ *
+ * {@link WifiManager#isTlsMinimumVersionSupported()} indicates whether or not a minimum
+ * TLS version can be set. If not supported, the minimum TLS version is always TLS v1.0.
+ * <p>
+ * {@link WifiManager#isTlsV13Supported()} indicates whether or not TLS v1.3 is supported.
+ * If requested minimum is not supported, it will default to the maximum supported version.
+ *
+ * @param tlsVersion the TLS version
+ * @throws IllegalArgumentException if the TLS version is invalid.
+ */
+ public void setMinimumTlsVersion(@TlsVersion int tlsVersion) throws IllegalArgumentException {
+ if (tlsVersion < TLS_VERSION_MIN || tlsVersion > TLS_VERSION_MAX) {
+ throw new IllegalArgumentException(
+ "Invalid TLS version: " + tlsVersion);
+ }
+ mMinimumTlsVersion = tlsVersion;
+ }
+
+ /**
+ * Get the minimum TLS version for TLS-based EAP methods.
+ *
+ * @return the TLS version
+ */
+ public @TlsVersion int getMinimumTlsVersion() {
+ return mMinimumTlsVersion;
+ }
}
diff --git a/framework/java/android/net/wifi/WifiManager.java b/framework/java/android/net/wifi/WifiManager.java
index 13746c78d8..07005c1f0c 100644
--- a/framework/java/android/net/wifi/WifiManager.java
+++ b/framework/java/android/net/wifi/WifiManager.java
@@ -56,6 +56,8 @@ import android.net.wifi.hotspot2.IProvisioningCallback;
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.WifiP2pManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -428,7 +430,33 @@ public class WifiManager {
API_AUTOJOIN_GLOBAL,
API_SET_SCAN_SCHEDULE,
API_SET_ONE_SHOT_SCREEN_ON_CONNECTIVITY_SCAN_DELAY,
- API_SET_NETWORK_SELECTION_CONFIG})
+ API_SET_NETWORK_SELECTION_CONFIG,
+ API_SET_THIRD_PARTY_APPS_ENABLING_WIFI_CONFIRMATION_DIALOG,
+ API_ADD_NETWORK,
+ API_UPDATE_NETWORK,
+ API_ALLOW_AUTOJOIN,
+ API_CONNECT_CONFIG,
+ API_CONNECT_NETWORK_ID,
+ API_DISABLE_NETWORK,
+ API_ENABLE_NETWORK,
+ API_FORGET,
+ API_SAVE,
+ API_START_SCAN,
+ API_START_LOCAL_ONLY_HOTSPOT,
+ API_P2P_DISCOVER_PEERS,
+ API_P2P_DISCOVER_PEERS_ON_SOCIAL_CHANNELS,
+ API_P2P_DISCOVER_PEERS_ON_SPECIFIC_FREQUENCY,
+ API_P2P_STOP_PEER_DISCOVERY,
+ API_P2P_CONNECT,
+ API_P2P_CANCEL_CONNECT,
+ API_P2P_CREATE_GROUP,
+ API_P2P_CREATE_GROUP_P2P_CONFIG,
+ API_P2P_REMOVE_GROUP,
+ API_P2P_START_LISTENING,
+ API_P2P_STOP_LISTENING,
+ API_P2P_SET_CHANNELS,
+ API_WIFI_SCANNER_START_SCAN
+ })
public @interface ApiType {}
/**
@@ -487,6 +515,7 @@ public class WifiManager {
* Tracks usage of {@link WifiManager#setOneShotScreenOnConnectivityScanDelayMillis(int)}.
* @hide
*/
+ @SystemApi
public static final int API_SET_ONE_SHOT_SCREEN_ON_CONNECTIVITY_SCAN_DELAY = 7;
/**
@@ -496,6 +525,7 @@ public class WifiManager {
* {@link WifiManager#setNetworkSelectionConfig(WifiNetworkSelectionConfig)}
* @hide
*/
+ @SystemApi
public static final int API_SET_NETWORK_SELECTION_CONFIG = 8;
/**
@@ -505,13 +535,260 @@ public class WifiManager {
* {@link WifiManager#setThirdPartyAppEnablingWifiConfirmationDialogEnabled(boolean)}
* @hide
*/
+ @SystemApi
public static final int API_SET_THIRD_PARTY_APPS_ENABLING_WIFI_CONFIRMATION_DIALOG = 9;
/**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#addNetwork(WifiConfiguration)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_ADD_NETWORK = 10;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#updateNetwork(WifiConfiguration)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_UPDATE_NETWORK = 11;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#allowAutojoin(int, boolean)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_ALLOW_AUTOJOIN = 12;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#connect(WifiConfiguration, ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_CONNECT_CONFIG = 13;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#connect(int, ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_CONNECT_NETWORK_ID = 14;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#disableNetwork(int)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_DISABLE_NETWORK = 15;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#enableNetwork(int, boolean)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_ENABLE_NETWORK = 16;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#forget(int, ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_FORGET = 17;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#save(WifiConfiguration, ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_SAVE = 18;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#startScan()}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_START_SCAN = 19;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_START_LOCAL_ONLY_HOTSPOT = 20;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#discoverPeers(WifiP2pManager.Channel, WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_DISCOVER_PEERS = 21;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#discoverPeersOnSocialChannels(WifiP2pManager.Channel,
+ * WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_DISCOVER_PEERS_ON_SOCIAL_CHANNELS = 22;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#discoverPeersOnSpecificFrequency(WifiP2pManager.Channel, int,
+ * WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_DISCOVER_PEERS_ON_SPECIFIC_FREQUENCY = 23;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#stopPeerDiscovery(WifiP2pManager.Channel,
+ * WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_STOP_PEER_DISCOVERY = 24;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#connect(WifiP2pManager.Channel, WifiP2pConfig,
+ * WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_CONNECT = 25;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#cancelConnect(WifiP2pManager.Channel, WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_CANCEL_CONNECT = 26;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#createGroup(WifiP2pManager.Channel, WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_CREATE_GROUP = 27;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#createGroup(WifiP2pManager.Channel, WifiP2pConfig,
+ * WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_CREATE_GROUP_P2P_CONFIG = 28;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#removeGroup(WifiP2pManager.Channel, WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_REMOVE_GROUP = 29;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#startListening(WifiP2pManager.Channel, WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_START_LISTENING = 30;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#stopListening(WifiP2pManager.Channel, WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_STOP_LISTENING = 31;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiP2pManager#setWifiP2pChannels(WifiP2pManager.Channel, int, int,
+ * WifiP2pManager.ActionListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_P2P_SET_CHANNELS = 32;
+
+ /**
+ * A constant used in
+ * {@link WifiManager#getLastCallerInfoForApi(int, Executor, BiConsumer)}
+ * Tracks usage of
+ * {@link WifiScanner#startScan(WifiScanner.ScanSettings, WifiScanner.ScanListener)}
+ * @hide
+ */
+ @SystemApi
+ public static final int API_WIFI_SCANNER_START_SCAN = 33;
+
+ /**
* Used internally to keep track of boundary.
* @hide
*/
- public static final int API_MAX = 10;
+ public static final int API_MAX = 34;
/**
* Broadcast intent action indicating that a Passpoint provider icon has been received.
@@ -941,6 +1218,7 @@ public class WifiManager {
*
* @hide
*/
+ @SystemApi
public static final int SAP_START_FAILURE_USER_REJECTED = 3;
/** @hide */
@@ -1887,6 +2165,7 @@ public class WifiManager {
android.Manifest.permission.NETWORK_SETTINGS,
MANAGE_WIFI_NETWORK_SELECTION
})
+ @SystemApi
public void setNetworkSelectionConfig(@NonNull WifiNetworkSelectionConfig nsConfig) {
try {
if (nsConfig == null) {
@@ -1920,6 +2199,7 @@ public class WifiManager {
android.Manifest.permission.NETWORK_SETTINGS,
android.Manifest.permission.NETWORK_SETUP_WIZARD
})
+ @SystemApi
public void setThirdPartyAppEnablingWifiConfirmationDialogEnabled(boolean enable) {
try {
mService.setThirdPartyAppEnablingWifiConfirmationDialogEnabled(enable);
@@ -1948,6 +2228,7 @@ public class WifiManager {
android.Manifest.permission.NETWORK_SETTINGS,
android.Manifest.permission.NETWORK_SETUP_WIZARD
})
+ @SystemApi
public boolean isThirdPartyAppEnablingWifiConfirmationDialogEnabled() {
try {
return mService.isThirdPartyAppEnablingWifiConfirmationDialogEnabled();
@@ -2036,6 +2317,7 @@ public class WifiManager {
android.Manifest.permission.NETWORK_SETTINGS,
MANAGE_WIFI_NETWORK_SELECTION
})
+ @SystemApi
public void setOneShotScreenOnConnectivityScanDelayMillis(@IntRange(from = 0) int delayMs) {
try {
mService.setOneShotScreenOnConnectivityScanDelayMillis(delayMs);
@@ -3213,159 +3495,166 @@ public class WifiManager {
return isWifiEnabled();
}
- /** TODO(b/181364583): Convert all of these to 1 << X form. */
- /** @hide */
- public static final long WIFI_FEATURE_INFRA = 0x0001L; // Basic infrastructure mode
- /** @hide */
- public static final long WIFI_FEATURE_PASSPOINT = 0x0004L; // Support for GAS/ANQP
/** @hide */
- public static final long WIFI_FEATURE_P2P = 0x0008L; // Wifi-Direct
+ public static final long WIFI_FEATURE_INFRA = 1L << 0; // Basic infrastructure mode
/** @hide */
- public static final long WIFI_FEATURE_MOBILE_HOTSPOT = 0x0010L; // Soft AP
+ public static final long WIFI_FEATURE_PASSPOINT = 1L << 2; // Support for GAS/ANQP
/** @hide */
- public static final long WIFI_FEATURE_SCANNER = 0x0020L; // WifiScanner APIs
+ public static final long WIFI_FEATURE_P2P = 1L << 3; // Wifi-Direct
/** @hide */
- public static final long WIFI_FEATURE_AWARE = 0x0040L; // Wi-Fi AWare networking
+ public static final long WIFI_FEATURE_MOBILE_HOTSPOT = 1L << 4; // Soft AP
/** @hide */
- public static final long WIFI_FEATURE_D2D_RTT = 0x0080L; // Device-to-device RTT
+ public static final long WIFI_FEATURE_SCANNER = 1L << 5; // WifiScanner APIs
/** @hide */
- public static final long WIFI_FEATURE_D2AP_RTT = 0x0100L; // Device-to-AP RTT
+ public static final long WIFI_FEATURE_AWARE = 1L << 6; // Wi-Fi Aware networking
/** @hide */
- public static final long WIFI_FEATURE_BATCH_SCAN = 0x0200L; // Batched Scan (deprecated)
+ public static final long WIFI_FEATURE_D2D_RTT = 1L << 7; // Device-to-device RTT
/** @hide */
- public static final long WIFI_FEATURE_PNO = 0x0400L; // Preferred network offload
+ public static final long WIFI_FEATURE_D2AP_RTT = 1L << 8; // Device-to-AP RTT
/** @hide */
- public static final long WIFI_FEATURE_ADDITIONAL_STA = 0x0800L; // (unused)
+ public static final long WIFI_FEATURE_PNO = 1L << 10; // Preferred network offload
/** @hide */
- public static final long WIFI_FEATURE_TDLS = 0x1000L; // Tunnel directed link setup
+ public static final long WIFI_FEATURE_TDLS = 1L << 12; // Tunnel directed link setup
/** @hide */
- public static final long WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000L; // TDLS off channel
+ public static final long WIFI_FEATURE_TDLS_OFFCHANNEL = 1L << 13; // TDLS off channel
/** @hide */
- public static final long WIFI_FEATURE_EPR = 0x4000L; // Enhanced power reporting
+ public static final long WIFI_FEATURE_AP_STA = 1L << 15; // AP STA Concurrency
/** @hide */
- public static final long WIFI_FEATURE_AP_STA = 0x8000L; // AP STA Concurrency
+ public static final long WIFI_FEATURE_LINK_LAYER_STATS = 1L << 16; // Link layer stats
/** @hide */
- public static final long WIFI_FEATURE_LINK_LAYER_STATS = 0x10000L; // Link layer stats
+ public static final long WIFI_FEATURE_LOGGER = 1L << 17; // WiFi Logger
/** @hide */
- public static final long WIFI_FEATURE_LOGGER = 0x20000L; // WiFi Logger
+ public static final long WIFI_FEATURE_RSSI_MONITOR = 1L << 19; // RSSI Monitor
/** @hide */
- public static final long WIFI_FEATURE_HAL_EPNO = 0x40000L; // Enhanced PNO
+ public static final long WIFI_FEATURE_MKEEP_ALIVE = 1L << 20; // mkeep_alive
/** @hide */
- public static final long WIFI_FEATURE_RSSI_MONITOR = 0x80000L; // RSSI Monitor
+ public static final long WIFI_FEATURE_CONFIG_NDO = 1L << 21; // ND offload
/** @hide */
- public static final long WIFI_FEATURE_MKEEP_ALIVE = 0x100000L; // mkeep_alive
+ public static final long WIFI_FEATURE_CONTROL_ROAMING = 1L << 23; // Control firmware roaming
/** @hide */
- public static final long WIFI_FEATURE_CONFIG_NDO = 0x200000L; // ND offload
+ public static final long WIFI_FEATURE_IE_WHITELIST = 1L << 24; // Probe IE white listing
/** @hide */
- public static final long WIFI_FEATURE_TRANSMIT_POWER = 0x400000L; // Capture transmit power
+ public static final long WIFI_FEATURE_SCAN_RAND = 1L << 25; // Random MAC & Probe seq
/** @hide */
- public static final long WIFI_FEATURE_CONTROL_ROAMING = 0x800000L; // Control firmware roaming
+ public static final long WIFI_FEATURE_TX_POWER_LIMIT = 1L << 26; // Set Tx power limit
/** @hide */
- public static final long WIFI_FEATURE_IE_WHITELIST = 0x1000000L; // Probe IE white listing
+ public static final long WIFI_FEATURE_WPA3_SAE = 1L << 27; // WPA3-Personal SAE
/** @hide */
- public static final long WIFI_FEATURE_SCAN_RAND = 0x2000000L; // Random MAC & Probe seq
+ public static final long WIFI_FEATURE_WPA3_SUITE_B = 1L << 28; // WPA3-Enterprise Suite-B
/** @hide */
- public static final long WIFI_FEATURE_TX_POWER_LIMIT = 0x4000000L; // Set Tx power limit
+ public static final long WIFI_FEATURE_OWE = 1L << 29; // Enhanced Open
/** @hide */
- public static final long WIFI_FEATURE_WPA3_SAE = 0x8000000L; // WPA3-Personal SAE
+ public static final long WIFI_FEATURE_LOW_LATENCY = 1L << 30; // Low Latency modes
/** @hide */
- public static final long WIFI_FEATURE_WPA3_SUITE_B = 0x10000000L; // WPA3-Enterprise Suite-B
+ public static final long WIFI_FEATURE_DPP = 1L << 31; // DPP (Easy-Connect)
/** @hide */
- public static final long WIFI_FEATURE_OWE = 0x20000000L; // Enhanced Open
+ public static final long WIFI_FEATURE_P2P_RAND_MAC = 1L << 32; // Random P2P MAC
/** @hide */
- public static final long WIFI_FEATURE_LOW_LATENCY = 0x40000000L; // Low Latency modes
+ public static final long WIFI_FEATURE_CONNECTED_RAND_MAC = 1L << 33; // Random STA MAC
/** @hide */
- public static final long WIFI_FEATURE_DPP = 0x80000000L; // DPP (Easy-Connect)
+ public static final long WIFI_FEATURE_AP_RAND_MAC = 1L << 34; // Random AP MAC
/** @hide */
- public static final long WIFI_FEATURE_P2P_RAND_MAC = 0x100000000L; // Random P2P MAC
+ public static final long WIFI_FEATURE_MBO = 1L << 35; // MBO Support
/** @hide */
- public static final long WIFI_FEATURE_CONNECTED_RAND_MAC = 0x200000000L; // Random STA MAC
+ public static final long WIFI_FEATURE_OCE = 1L << 36; // OCE Support
/** @hide */
- public static final long WIFI_FEATURE_AP_RAND_MAC = 0x400000000L; // Random AP MAC
- /** @hide */
- public static final long WIFI_FEATURE_MBO = 0x800000000L; // MBO Support
- /** @hide */
- public static final long WIFI_FEATURE_OCE = 0x1000000000L; // OCE Support
- /** @hide */
- public static final long WIFI_FEATURE_WAPI = 0x2000000000L; // WAPI
+ public static final long WIFI_FEATURE_WAPI = 1L << 37; // WAPI
/** @hide */
- public static final long WIFI_FEATURE_FILS_SHA256 = 0x4000000000L; // FILS-SHA256
+ public static final long WIFI_FEATURE_FILS_SHA256 = 1L << 38; // FILS-SHA256
/** @hide */
- public static final long WIFI_FEATURE_FILS_SHA384 = 0x8000000000L; // FILS-SHA384
+ public static final long WIFI_FEATURE_FILS_SHA384 = 1L << 39; // FILS-SHA384
/** @hide */
- public static final long WIFI_FEATURE_SAE_PK = 0x10000000000L; // SAE-PK
+ public static final long WIFI_FEATURE_SAE_PK = 1L << 40; // SAE-PK
/** @hide */
- public static final long WIFI_FEATURE_STA_BRIDGED_AP = 0x20000000000L; // STA + Bridged AP
+ public static final long WIFI_FEATURE_STA_BRIDGED_AP = 1L << 41; // STA + Bridged AP
/** @hide */
- public static final long WIFI_FEATURE_BRIDGED_AP = 0x40000000000L; // Bridged AP
+ public static final long WIFI_FEATURE_BRIDGED_AP = 1L << 42; // Bridged AP
/** @hide */
- public static final long WIFI_FEATURE_INFRA_60G = 0x80000000000L; // 60 GHz Band Support
+ public static final long WIFI_FEATURE_INFRA_60G = 1L << 43; // 60 GHz Band Support
/**
* Support for 2 STA's for the local-only (peer to peer) connection + internet connection
* concurrency.
* @hide
*/
- public static final long WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY = 0x100000000000L;
+ public static final long WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY = 1L << 44;
/**
* Support for 2 STA's for the make before break concurrency.
* @hide
*/
- public static final long WIFI_FEATURE_ADDITIONAL_STA_MBB = 0x200000000000L;
+ public static final long WIFI_FEATURE_ADDITIONAL_STA_MBB = 1L << 45;
/**
* Support for 2 STA's for the restricted connection + internet connection concurrency.
* @hide
*/
- public static final long WIFI_FEATURE_ADDITIONAL_STA_RESTRICTED = 0x400000000000L;
+ public static final long WIFI_FEATURE_ADDITIONAL_STA_RESTRICTED = 1L << 46;
/**
* DPP (Easy-Connect) Enrollee Responder mode support
* @hide
*/
- public static final long WIFI_FEATURE_DPP_ENROLLEE_RESPONDER = 0x800000000000L;
+ public static final long WIFI_FEATURE_DPP_ENROLLEE_RESPONDER = 1L << 47;
/**
* Passpoint Terms and Conditions feature support
* @hide
*/
- public static final long WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS = 0x1000000000000L;
+ public static final long WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS = 1L << 48;
/** @hide */
- public static final long WIFI_FEATURE_SAE_H2E = 0x2000000000000L; // Hash-to-Element
+ public static final long WIFI_FEATURE_SAE_H2E = 1L << 49; // Hash-to-Element
/** @hide */
- public static final long WIFI_FEATURE_WFD_R2 = 0x4000000000000L; // Wi-Fi Display R2
+ public static final long WIFI_FEATURE_WFD_R2 = 1L << 50; // Wi-Fi Display R2
/**
* RFC 7542 decorated identity support
* @hide */
- public static final long WIFI_FEATURE_DECORATED_IDENTITY = 0x8000000000000L;
+ public static final long WIFI_FEATURE_DECORATED_IDENTITY = 1L << 51;
/**
* Trust On First Use support for WPA Enterprise network
* @hide
*/
- public static final long WIFI_FEATURE_TRUST_ON_FIRST_USE = 0x10000000000000L;
+ public static final long WIFI_FEATURE_TRUST_ON_FIRST_USE = 1L << 52;
/**
* Support for 2 STA's multi internet concurrency.
* @hide
*/
- public static final long WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET = 0x20000000000000L;
+ public static final long WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET = 1L << 53;
/**
* Support for DPP (Easy-Connect) AKM.
* @hide
*/
- public static final long WIFI_FEATURE_DPP_AKM = 0x40000000000000L;
+ public static final long WIFI_FEATURE_DPP_AKM = 1L << 54;
+
+ /**
+ * Support for setting TLS minimum version.
+ * @hide
+ */
+ public static final long WIFI_FEATURE_SET_TLS_MINIMUM_VERSION = 1L << 55;
+
+ /**
+ * Support for TLS v.13.
+ * @hide
+ */
+ public static final long WIFI_FEATURE_TLS_V1_3 = 1L << 56;
+
+ /**
+ * Support for Dual Band Simultaneous (DBS) operation.
+ * @hide
+ */
+ public static final long WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS = 1L << 57;
private long getSupportedFeatures() {
try {
@@ -4769,9 +5058,13 @@ public class WifiManager {
* Start Soft AP (hotspot) mode for tethering purposes with the specified configuration.
* Note that starting Soft AP mode may disable station mode operation if the device does not
* support concurrency.
- * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP,
- * or null to use the persisted Soft AP configuration that was previously
- * set using {@link #setSoftApConfiguration(softApConfiguration)}.
+ *
+ * Note: Call {@link WifiManager#validateSoftApConfiguration(SoftApConfiguration)} to avoid
+ * unexpected error due to invalid configuration.
+ *
+ * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP, or
+ * null to use the persisted Soft AP configuration that was previously set
+ * using {@link WifiManager#setSoftApConfiguration(SoftApConfiguration)}.
* @return {@code true} if the operation succeeded, {@code false} otherwise
*
* @hide
@@ -4811,6 +5104,23 @@ public class WifiManager {
}
/**
+ * Check if input configuration is valid.
+ *
+ * @param config a configuration would like to be checked.
+ * @return true if config is valid, otherwise false.
+ */
+ public boolean validateSoftApConfiguration(@NonNull SoftApConfiguration config) {
+ if (config == null) {
+ throw new IllegalArgumentException(TAG + ": config can not be null");
+ }
+ try {
+ return mService.validateSoftApConfiguration(config);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Request a local only hotspot that an application can use to communicate between co-located
* devices connected to the created WiFi hotspot. The network created by this method will not
* have Internet access. Each application can make a single request for the hotspot, but
@@ -5254,6 +5564,9 @@ public class WifiManager {
* Otherwise, the configuration changes will be applied when the Soft AP is next started
* (the framework will not stop/start the AP).
*
+ * Note: Call {@link WifiManager#validateSoftApConfiguration(SoftApConfiguration)} to avoid
+ * unexpected error due to invalid configuration.
+ *
* @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP.
* @return {@code true} if the operation succeeded, {@code false} otherwise
*
@@ -7529,6 +7842,35 @@ public class WifiManager {
}
/**
+ * Indicate that whether or not settings required TLS minimum version is supported.
+ *
+ * If the device doesn't support this capability, the minimum accepted TLS version is 1.0.
+ *
+ * @return true if this device supports setting TLS minimum version.
+ */
+ public boolean isTlsMinimumVersionSupported() {
+ return isFeatureSupported(WIFI_FEATURE_SET_TLS_MINIMUM_VERSION);
+ }
+
+ /**
+ * Indicate that whether or not TLS v1.3 is supported.
+ *
+ * If requested minimum is not supported, it will default to the maximum supported version.
+ *
+ * @return true if this device supports TLS v1.3.
+ */
+ public boolean isTlsV13Supported() {
+ return isFeatureSupported(WIFI_FEATURE_TLS_V1_3);
+ }
+
+ /**
+ * @return true if this device supports Dual Band Simultaneous (DBS) operation.
+ */
+ public boolean isDualBandSimultaneousSupported() {
+ return isFeatureSupported(WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS);
+ }
+
+ /**
* Gets the factory Wi-Fi MAC addresses.
* @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array
* if failed.
@@ -9318,6 +9660,13 @@ public class WifiManager {
* mode(s), that is allowed for the current regulatory domain. An empty list implies that there
* are no available channels for use.
*
+ * Note: the {@code band} parameter which is specified as a {@code WifiScanner#WIFI_BAND_*}
+ * constant is limited to one of the band values specified below. Specifically, if the 5GHz
+ * band is included then it must include the DFS channels - an exception will be thrown
+ * otherwise. The caller should not make any assumptions about whether DFS channels are allowed.
+ * This API will indicate whether DFS channels are allowed for the specified operation mode(s)
+ * per device policy.
+ *
* @param band one of the following band constants defined in {@code WifiScanner#WIFI_BAND_*}
* constants.
* 1. {@code WifiScanner#WIFI_BAND_UNSPECIFIED} - no band specified; Looks for the
@@ -9336,12 +9685,10 @@ public class WifiManager {
* @throws UnsupportedOperationException - if this API is not supported on this device
* or IllegalArgumentException - if the band specified is not one among the list
* of bands mentioned above.
- * @hide
*/
@RequiresApi(Build.VERSION_CODES.S)
- @SystemApi
@NonNull
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ @RequiresPermission(NEARBY_WIFI_DEVICES)
public List<WifiAvailableChannel> getAllowedChannels(
@WifiScanner.WifiBand int band,
@WifiAvailableChannel.OpMode int mode) {
@@ -9349,8 +9696,13 @@ public class WifiManager {
throw new UnsupportedOperationException();
}
try {
+ Bundle extras = new Bundle();
+ if (SdkLevel.isAtLeastS()) {
+ extras.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE,
+ mContext.getAttributionSource());
+ }
return mService.getUsableChannels(band, mode,
- WifiAvailableChannel.FILTER_REGULATORY);
+ WifiAvailableChannel.FILTER_REGULATORY, mContext.getOpPackageName(), extras);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -9362,6 +9714,13 @@ public class WifiManager {
* state and interference due to other radios. An empty list implies that there are no available
* channels for use.
*
+ * Note: the {@code band} parameter which is specified as a {@code WifiScanner#WIFI_BAND_*}
+ * constant is limited to one of the band values specified below. Specifically, if the 5GHz
+ * band is included then it must include the DFS channels - an exception will be thrown
+ * otherwise. The caller should not make any assumptions about whether DFS channels are allowed.
+ * This API will indicate whether DFS channels are allowed for the specified operation mode(s)
+ * per device policy.
+ *
* @param band one of the following band constants defined in {@code WifiScanner#WIFI_BAND_*}
* constants.
* 1. {@code WifiScanner#WIFI_BAND_UNSPECIFIED} - no band specified; Looks for the
@@ -9380,12 +9739,10 @@ public class WifiManager {
* @throws UnsupportedOperationException - if this API is not supported on this device
* or IllegalArgumentException - if the band specified is not one among the list
* of bands mentioned above.
- * @hide
*/
@RequiresApi(Build.VERSION_CODES.S)
- @SystemApi
@NonNull
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ @RequiresPermission(NEARBY_WIFI_DEVICES)
public List<WifiAvailableChannel> getUsableChannels(
@WifiScanner.WifiBand int band,
@WifiAvailableChannel.OpMode int mode) {
@@ -9393,8 +9750,13 @@ public class WifiManager {
throw new UnsupportedOperationException();
}
try {
+ Bundle extras = new Bundle();
+ if (SdkLevel.isAtLeastS()) {
+ extras.putParcelable(EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE,
+ mContext.getAttributionSource());
+ }
return mService.getUsableChannels(band, mode,
- WifiAvailableChannel.getUsableFilter());
+ WifiAvailableChannel.getUsableFilter(), mContext.getOpPackageName(), extras);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -10017,4 +10379,20 @@ public class WifiManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Returns the max number of channels that is allowed to be set on a
+ * {@link WifiNetworkSpecifier}.
+ * @see WifiNetworkSpecifier.Builder#setPreferredChannelsFrequenciesMhz(int[])
+ *
+ * @return The max number of channels can be set on a request.
+ */
+
+ public int getMaxNumberOfChannelsPerNetworkSpecifierRequest() {
+ try {
+ return mService.getMaxNumberOfChannelsPerRequest();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/framework/java/android/net/wifi/WifiNetworkSelectionConfig.java b/framework/java/android/net/wifi/WifiNetworkSelectionConfig.java
index 69dc2f70d6..672cb1863d 100644
--- a/framework/java/android/net/wifi/WifiNetworkSelectionConfig.java
+++ b/framework/java/android/net/wifi/WifiNetworkSelectionConfig.java
@@ -18,6 +18,7 @@ package android.net.wifi;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,6 +31,7 @@ import java.util.function.Consumer;
* An Object used in {@link WifiManager#setNetworkSelectionConfig(WifiNetworkSelectionConfig)}.
* @hide
*/
+@SystemApi
public final class WifiNetworkSelectionConfig implements Parcelable {
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -60,6 +62,8 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
private boolean mSufficiencyCheckEnabledWhenScreenOff = true;
private boolean mSufficiencyCheckEnabledWhenScreenOn = true;
+ private boolean mUserConnectChoiceOverrideEnabled = true;
+ private boolean mLastSelectionWeightEnabled = true;
private int mAssociatedNetworkSelectionOverride = ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE;
// empty constructor
@@ -72,6 +76,8 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
mSufficiencyCheckEnabledWhenScreenOff = that.mSufficiencyCheckEnabledWhenScreenOff;
mSufficiencyCheckEnabledWhenScreenOn = that.mSufficiencyCheckEnabledWhenScreenOn;
mAssociatedNetworkSelectionOverride = that.mAssociatedNetworkSelectionOverride;
+ mUserConnectChoiceOverrideEnabled = that.mUserConnectChoiceOverrideEnabled;
+ mLastSelectionWeightEnabled = that.mLastSelectionWeightEnabled;
}
/**
@@ -89,6 +95,20 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
}
/**
+ * See {@link Builder#setUserConnectChoiceOverrideEnabled(boolean)}.
+ */
+ public boolean isUserConnectChoiceOverrideEnabled() {
+ return mUserConnectChoiceOverrideEnabled;
+ }
+
+ /**
+ * See {@link Builder#setLastSelectionWeightEnabled(boolean)}.
+ */
+ public boolean isLastSelectionWeightEnabled() {
+ return mLastSelectionWeightEnabled;
+ }
+
+ /**
* See {@link Builder#setAssociatedNetworkSelectionOverride(int)}.
* @return
*/
@@ -118,6 +138,8 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
public Builder() {
mWifiNetworkSelectionConfig.mSufficiencyCheckEnabledWhenScreenOff = true;
mWifiNetworkSelectionConfig.mSufficiencyCheckEnabledWhenScreenOn = true;
+ mWifiNetworkSelectionConfig.mUserConnectChoiceOverrideEnabled = true;
+ mWifiNetworkSelectionConfig.mLastSelectionWeightEnabled = true;
mWifiNetworkSelectionConfig.mAssociatedNetworkSelectionOverride =
ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE;
}
@@ -198,6 +220,44 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
}
/**
+ * Enable or disable candidate override with the user connect choice.
+ * <p>
+ * If the override is enabled, the network selector overrides any selected candidate
+ * with a network previously chosen by the user over the candidate (i.e. when the
+ * candidate was connected the user explicitly selected another network), if one exists.
+ * <p>
+ * If the override is disabled, network selector uses the network nominator candidate
+ * and does not override it with the user chosen configuration.
+ * <p>
+ * By default, user connect choice override is enabled.
+ * @param enabled Set to true to enable candidate override with the user connect choice,
+ * and false to disable the override.
+ */
+ public @NonNull Builder setUserConnectChoiceOverrideEnabled(boolean enabled) {
+ mWifiNetworkSelectionConfig.mUserConnectChoiceOverrideEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Enable or disable last selection weight.
+ * <p>
+ * If the last selection weight is enabled, network selector prefers the latest
+ * user selected network over all other networks for a limited duration.
+ * This duration is configurable via {@code config_wifiFrameworkLastSelectionMinutes}.
+ * <p>
+ * If the last selection weight is disabled, network selector does not prefer a
+ * recently selected network over other networks.
+ * <p>
+ * By default, last selection weight is enabled.
+ * @param enabled Set to true to enable the last selection weight,
+ * and false to disable it.
+ */
+ public @NonNull Builder setLastSelectionWeightEnabled(boolean enabled) {
+ mWifiNetworkSelectionConfig.mLastSelectionWeightEnabled = enabled;
+ return this;
+ }
+
+ /**
* Creates a WifiNetworkSelectionConfig for use in
* {@link WifiManager#setNetworkSelectionConfig(WifiNetworkSelectionConfig, Consumer)}
*/
@@ -209,7 +269,8 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mSufficiencyCheckEnabledWhenScreenOff,
- mSufficiencyCheckEnabledWhenScreenOn, mAssociatedNetworkSelectionOverride);
+ mSufficiencyCheckEnabledWhenScreenOn, mAssociatedNetworkSelectionOverride,
+ mUserConnectChoiceOverrideEnabled, mLastSelectionWeightEnabled);
}
@Override
@@ -223,7 +284,9 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
WifiNetworkSelectionConfig lhs = (WifiNetworkSelectionConfig) obj;
return mSufficiencyCheckEnabledWhenScreenOff == lhs.mSufficiencyCheckEnabledWhenScreenOff
&& mSufficiencyCheckEnabledWhenScreenOn == lhs.mSufficiencyCheckEnabledWhenScreenOn
- && mAssociatedNetworkSelectionOverride == lhs.mAssociatedNetworkSelectionOverride;
+ && mAssociatedNetworkSelectionOverride == lhs.mAssociatedNetworkSelectionOverride
+ && mUserConnectChoiceOverrideEnabled == lhs.mUserConnectChoiceOverrideEnabled
+ && mLastSelectionWeightEnabled == lhs.mLastSelectionWeightEnabled;
}
public static final @NonNull Creator<WifiNetworkSelectionConfig> CREATOR =
@@ -234,6 +297,8 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
config.mSufficiencyCheckEnabledWhenScreenOff = in.readBoolean();
config.mSufficiencyCheckEnabledWhenScreenOn = in.readBoolean();
config.mAssociatedNetworkSelectionOverride = in.readInt();
+ config.mUserConnectChoiceOverrideEnabled = in.readBoolean();
+ config.mLastSelectionWeightEnabled = in.readBoolean();
return config;
}
@@ -253,6 +318,8 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
dest.writeBoolean(mSufficiencyCheckEnabledWhenScreenOff);
dest.writeBoolean(mSufficiencyCheckEnabledWhenScreenOn);
dest.writeInt(mAssociatedNetworkSelectionOverride);
+ dest.writeBoolean(mUserConnectChoiceOverrideEnabled);
+ dest.writeBoolean(mLastSelectionWeightEnabled);
}
@Override
@@ -263,7 +330,11 @@ public final class WifiNetworkSelectionConfig implements Parcelable {
.append(", mSufficiencyCheckEnabledWhenScreenOn=")
.append(mSufficiencyCheckEnabledWhenScreenOn)
.append(", mAssociatedNetworkSelectionOverride=")
- .append(mAssociatedNetworkSelectionOverride);
+ .append(mAssociatedNetworkSelectionOverride)
+ .append(", mUserConnectChoiceOverrideEnabled=")
+ .append(mUserConnectChoiceOverrideEnabled)
+ .append(", mLastSelectionWeightEnabled=")
+ .append(mLastSelectionWeightEnabled);
return sb.toString();
}
}
diff --git a/framework/java/android/net/wifi/WifiNetworkSpecifier.java b/framework/java/android/net/wifi/WifiNetworkSpecifier.java
index 045a9a4c90..3b1042de64 100644
--- a/framework/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/framework/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -16,6 +16,8 @@
package android.net.wifi;
+import static android.net.wifi.ScanResult.UNSPECIFIED;
+
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.NonNull;
@@ -37,6 +39,7 @@ import com.android.modules.utils.build.SdkLevel;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
import java.util.Objects;
/**
@@ -60,6 +63,7 @@ import java.util.Objects;
* </p>
*/
public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+
private static final String TAG = "WifiNetworkSpecifier";
/**
@@ -76,7 +80,23 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
} else if (ScanResult.is60GHz(freqMHz)) {
return ScanResult.WIFI_BAND_60_GHZ;
}
- return ScanResult.UNSPECIFIED;
+ return UNSPECIFIED;
+ }
+
+ /**
+ * Check the channel in the array is valid.
+ * @hide
+ */
+ public static boolean validateChannelFrequencyInMhz(@NonNull int[] channels) {
+ if (channels == null) {
+ return false;
+ }
+ for (int channel : channels) {
+ if (ScanResult.convertFrequencyMhzToChannelIfSupported(channel) == UNSPECIFIED) {
+ return false;
+ }
+ }
+ return true;
}
/**
@@ -87,7 +107,7 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
*/
public static boolean validateBand(@WifiBand int band) {
switch (band) {
- case ScanResult.UNSPECIFIED:
+ case UNSPECIFIED:
case ScanResult.WIFI_BAND_24_GHZ:
case ScanResult.WIFI_BAND_5_GHZ:
case ScanResult.WIFI_BAND_6_GHZ:
@@ -168,6 +188,8 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
*/
@WifiBand private int mBand;
+ private int[] mChannels;
+
public Builder() {
mSsidPatternMatcher = null;
mBssidPatternMatcher = null;
@@ -177,7 +199,8 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
mWpa2EnterpriseConfig = null;
mWpa3EnterpriseConfig = null;
mIsHiddenSSID = false;
- mBand = ScanResult.UNSPECIFIED;
+ mBand = UNSPECIFIED;
+ mChannels = new int[0];
}
/**
@@ -426,6 +449,27 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
return this;
}
+ /**
+ * Specifies the preferred channels for this network. The channels set in the request will
+ * be used to optimize the scan and connection.
+ * <p>
+ * <li>Should only be set to request local-only network</li>
+ * <li>If not set, defaults to an empty array and device will do a full band scan.</li>
+ *
+ * @param channelFreqs an Array of the channels in MHz. The length of the array must not
+ * exceed {@link WifiManager#getMaxNumberOfChannelsPerNetworkSpecifierRequest()}
+ *
+ * @return Instance of {@link Builder} to enable chaining of the builder method.
+ */
+ @NonNull public Builder setPreferredChannelsFrequenciesMhz(@NonNull int[] channelFreqs) {
+ Objects.requireNonNull(channelFreqs);
+ if (!validateChannelFrequencyInMhz(channelFreqs)) {
+ throw new IllegalArgumentException("Invalid channel frequency in the input array");
+ }
+ mChannels = channelFreqs.clone();
+ return this;
+ }
+
private void setSecurityParamsInWifiConfiguration(
@NonNull WifiConfiguration configuration) {
if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
@@ -604,7 +648,7 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
* @throws IllegalStateException on invalid params set.
*/
public @NonNull WifiNetworkSpecifier build() {
- if (!hasSetAnyPattern() && mBand == ScanResult.UNSPECIFIED) {
+ if (!hasSetAnyPattern() && mBand == UNSPECIFIED) {
throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/"
+ "setBssid/setBand should be invoked for specifier");
}
@@ -612,20 +656,25 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
if (hasSetMatchNonePattern()) {
throw new IllegalStateException("cannot set match-none pattern for specifier");
}
- if (hasSetMatchAllPattern() && mBand == ScanResult.UNSPECIFIED) {
+ if (hasSetMatchAllPattern() && mBand == UNSPECIFIED) {
throw new IllegalStateException("cannot set match-all pattern for specifier");
}
if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
throw new IllegalStateException("setSsid should also be invoked when "
+ "setIsHiddenSsid is invoked for network specifier");
}
+ if (mChannels.length != 0 && mBand != UNSPECIFIED) {
+ throw new IllegalStateException("cannot setPreferredChannelsFrequencyInMhz with "
+ + "setBand together");
+ }
validateSecurityParams();
return new WifiNetworkSpecifier(
mSsidPatternMatcher,
mBssidPatternMatcher,
mBand,
- buildWifiConfiguration());
+ buildWifiConfiguration(),
+ mChannels);
}
}
@@ -647,6 +696,8 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
*/
@WifiBand private final int mBand;
+ private final int[] mChannelFreqs;
+
/**
* Security credentials for the network.
* <p>
@@ -665,9 +716,10 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
/** @hide */
public WifiNetworkSpecifier(@NonNull PatternMatcher ssidPatternMatcher,
- @NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
- @WifiBand int band,
- @NonNull WifiConfiguration wifiConfiguration) {
+ @NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
+ @WifiBand int band,
+ @NonNull WifiConfiguration wifiConfiguration,
+ @NonNull int[] channelFreqs) {
checkNotNull(ssidPatternMatcher);
checkNotNull(bssidPatternMatcher);
checkNotNull(wifiConfiguration);
@@ -676,6 +728,7 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
this.bssidPatternMatcher = bssidPatternMatcher;
this.mBand = band;
this.wifiConfiguration = wifiConfiguration;
+ this.mChannelFreqs = channelFreqs;
}
/**
@@ -685,6 +738,14 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
return mBand;
}
+ /**
+ * The preferred channels fot this network specifier.
+ * @see Builder#setPreferredChannelsFrequenciesMhz(int[])
+ */
+ @NonNull public int[] getPreferredChannelFrequenciesMhz() {
+ return mChannelFreqs.clone();
+ }
+
public static final @NonNull Creator<WifiNetworkSpecifier> CREATOR =
new Creator<WifiNetworkSpecifier>() {
@Override
@@ -696,8 +757,9 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
Pair.create(baseAddress, mask);
int band = in.readInt();
WifiConfiguration wifiConfiguration = in.readParcelable(null);
+ int[] mChannels = in.createIntArray();
return new WifiNetworkSpecifier(ssidPatternMatcher, bssidPatternMatcher, band,
- wifiConfiguration);
+ wifiConfiguration, mChannels);
}
@Override
@@ -718,13 +780,14 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
dest.writeParcelable(bssidPatternMatcher.second, flags);
dest.writeInt(mBand);
dest.writeParcelable(wifiConfiguration, flags);
+ dest.writeIntArray(mChannelFreqs);
}
@Override
public int hashCode() {
return Objects.hash(
ssidPatternMatcher.getPath(), ssidPatternMatcher.getType(), bssidPatternMatcher,
- mBand, wifiConfiguration.allowedKeyManagement);
+ mBand, wifiConfiguration.allowedKeyManagement, Arrays.hashCode(mChannelFreqs));
}
@Override
@@ -744,7 +807,8 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
lhs.bssidPatternMatcher)
&& this.mBand == lhs.mBand
&& Objects.equals(this.wifiConfiguration.allowedKeyManagement,
- lhs.wifiConfiguration.allowedKeyManagement);
+ lhs.wifiConfiguration.allowedKeyManagement)
+ && Arrays.equals(mChannelFreqs, lhs.mChannelFreqs);
}
@Override
diff --git a/framework/java/android/net/wifi/WifiScanner.java b/framework/java/android/net/wifi/WifiScanner.java
index a2257d99dd..b21ffe69d2 100644
--- a/framework/java/android/net/wifi/WifiScanner.java
+++ b/framework/java/android/net/wifi/WifiScanner.java
@@ -16,6 +16,8 @@
package android.net.wifi;
+import static android.Manifest.permission.NEARBY_WIFI_DEVICES;
+
import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
@@ -244,16 +246,18 @@ public class WifiScanner {
* @param band one of the WifiScanner#WIFI_BAND_* constants, e.g. {@link #WIFI_BAND_24_GHZ}
* @return a list of all the frequencies, in MHz, for the given band(s) e.g. channel 1 is
* 2412, or null if an error occurred.
- *
- * @hide
*/
- @SystemApi
@NonNull
- @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ @RequiresPermission(NEARBY_WIFI_DEVICES)
public List<Integer> getAvailableChannels(int band) {
try {
+ Bundle extras = new Bundle();
+ if (SdkLevel.isAtLeastS()) {
+ extras.putParcelable(WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE,
+ mContext.getAttributionSource());
+ }
Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mContext.getAttributionTag(), extras);
List<Integer> channels = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
return channels == null ? new ArrayList<>() : channels;
} catch (RemoteException e) {
diff --git a/framework/java/android/net/wifi/WifiUsabilityStatsEntry.java b/framework/java/android/net/wifi/WifiUsabilityStatsEntry.java
index 5c1f4b21c4..f4c9bbb7d6 100644
--- a/framework/java/android/net/wifi/WifiUsabilityStatsEntry.java
+++ b/framework/java/android/net/wifi/WifiUsabilityStatsEntry.java
@@ -879,7 +879,8 @@ public final class WifiUsabilityStatsEntry implements Parcelable {
&& mContentionTimeStats.length == NUM_WME_ACCESS_CATEGORIES) {
return mContentionTimeStats[ac];
}
- Log.e(TAG, "The ContentionTimeStats is not filled out correctly: " + mContentionTimeStats);
+ Log.e(TAG, "The ContentionTimeStats is not filled out correctly: "
+ + Arrays.toString(mContentionTimeStats));
return new ContentionTimeStats();
}
diff --git a/framework/java/android/net/wifi/hotspot2/pps/Credential.java b/framework/java/android/net/wifi/hotspot2/pps/Credential.java
index 4ca724a58c..658588ae8b 100644
--- a/framework/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/framework/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -20,6 +20,7 @@ import static android.net.wifi.hotspot2.PasspointConfiguration.MAX_STRING_LENGTH
import android.net.wifi.EAPConstants;
import android.net.wifi.ParcelUtil;
+import android.net.wifi.WifiEnterpriseConfig;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -959,6 +960,43 @@ public final class Credential implements Parcelable {
}
/**
+ * The required minimum TLS version.
+ */
+ private @WifiEnterpriseConfig.TlsVersion int mMinimumTlsVersion = WifiEnterpriseConfig.TLS_V1_0;
+ /**
+ * Set the minimum TLS version for TLS-based EAP methods.
+ *
+ * {@link android.net.wifi.WifiManager#isTlsMinimumVersionSupported()} indicates whether
+ * or not a minimum TLS version can be set. If not supported, the minimum TLS version
+ * is always TLS v1.0.
+ * <p>
+ * {@link android.net.wifi.WifiManager#isTlsV13Supported()} indicates whether or not
+ * TLS v1.3 is supported. If requested minimum is not supported, it will default to
+ * the maximum supported version.
+ *
+ * @param tlsVersion the TLS version
+ * @throws IllegalArgumentException if the TLS version is invalid.
+ */
+ public void setMinimumTlsVersion(@WifiEnterpriseConfig.TlsVersion int tlsVersion)
+ throws IllegalArgumentException {
+ if (tlsVersion < WifiEnterpriseConfig.TLS_VERSION_MIN
+ || tlsVersion > WifiEnterpriseConfig.TLS_VERSION_MAX) {
+ throw new IllegalArgumentException(
+ "Invalid TLS version: " + tlsVersion);
+ }
+ mMinimumTlsVersion = tlsVersion;
+ }
+
+ /**
+ * Get the minimum TLS version for TLS-based EAP methods.
+ *
+ * @return the TLS version
+ */
+ public @WifiEnterpriseConfig.TlsVersion int getMinimumTlsVersion() {
+ return mMinimumTlsVersion;
+ }
+
+ /**
* Constructor for creating Credential with default values.
*/
public Credential() {}
@@ -993,6 +1031,7 @@ public final class Credential implements Parcelable {
}
mClientPrivateKey = source.mClientPrivateKey;
+ mMinimumTlsVersion = source.mMinimumTlsVersion;
}
}
@@ -1013,6 +1052,7 @@ public final class Credential implements Parcelable {
ParcelUtil.writeCertificates(dest, mCaCertificates);
ParcelUtil.writeCertificates(dest, mClientCertificateChain);
ParcelUtil.writePrivateKey(dest, mClientPrivateKey);
+ dest.writeInt(mMinimumTlsVersion);
}
@Override
@@ -1037,7 +1077,8 @@ public final class Credential implements Parcelable {
: mSimCredential.equals(that.mSimCredential))
&& isX509CertificatesEquals(mCaCertificates, that.mCaCertificates)
&& isX509CertificatesEquals(mClientCertificateChain, that.mClientCertificateChain)
- && isPrivateKeyEquals(mClientPrivateKey, that.mClientPrivateKey);
+ && isPrivateKeyEquals(mClientPrivateKey, that.mClientPrivateKey)
+ && mMinimumTlsVersion == that.mMinimumTlsVersion;
}
@Override
@@ -1045,7 +1086,7 @@ public final class Credential implements Parcelable {
return Objects.hash(mCreationTimeInMillis, mExpirationTimeInMillis, mRealm,
mCheckAaaServerCertStatus, mUserCredential, mCertCredential, mSimCredential,
mClientPrivateKey, Arrays.hashCode(mCaCertificates),
- Arrays.hashCode(mClientCertificateChain));
+ Arrays.hashCode(mClientCertificateChain), mMinimumTlsVersion);
}
/**
@@ -1079,6 +1120,7 @@ public final class Credential implements Parcelable {
builder.append(mCertCredential);
builder.append("CertificateCredential End ---\n");
}
+ builder.append("MinimumTlsVersion: ").append(mMinimumTlsVersion).append("\n");
if (mSimCredential != null) {
builder.append("SIMCredential Begin ---\n");
builder.append(mSimCredential);
@@ -1140,6 +1182,7 @@ public final class Credential implements Parcelable {
credential.setCaCertificates(ParcelUtil.readCertificates(in));
credential.setClientCertificateChain(ParcelUtil.readCertificates(in));
credential.setClientPrivateKey(ParcelUtil.readPrivateKey(in));
+ credential.setMinimumTlsVersion(in.readInt());
return credential;
}
diff --git a/framework/java/android/net/wifi/hotspot2/pps/HomeSp.java b/framework/java/android/net/wifi/hotspot2/pps/HomeSp.java
index 34aff6c027..e90502c6a5 100644
--- a/framework/java/android/net/wifi/hotspot2/pps/HomeSp.java
+++ b/framework/java/android/net/wifi/hotspot2/pps/HomeSp.java
@@ -393,10 +393,12 @@ public final class HomeSp implements Parcelable {
builder.append("FriendlyName: ").append(mFriendlyName).append("\n");
builder.append("IconURL: ").append(mIconUrl).append("\n");
builder.append("HomeNetworkIDs: ").append(mHomeNetworkIds).append("\n");
- builder.append("MatchAllOIs: ").append(mMatchAllOis).append("\n");
- builder.append("MatchAnyOIs: ").append(mMatchAnyOis).append("\n");
- builder.append("OtherHomePartners: ").append(mOtherHomePartners).append("\n");
- builder.append("RoamingConsortiumOIs: ").append(mRoamingConsortiumOis).append("\n");
+ builder.append("MatchAllOIs: ").append(Arrays.toString(mMatchAllOis)).append("\n");
+ builder.append("MatchAnyOIs: ").append(Arrays.toString(mMatchAnyOis)).append("\n");
+ builder.append("OtherHomePartners: ").append(Arrays.toString(mOtherHomePartners))
+ .append("\n");
+ builder.append("RoamingConsortiumOIs: ").append(Arrays.toString(mRoamingConsortiumOis))
+ .append("\n");
return builder.toString();
}
diff --git a/framework/java/android/net/wifi/hotspot2/pps/Policy.java b/framework/java/android/net/wifi/hotspot2/pps/Policy.java
index b0a2cc397c..f0a1751064 100644
--- a/framework/java/android/net/wifi/hotspot2/pps/Policy.java
+++ b/framework/java/android/net/wifi/hotspot2/pps/Policy.java
@@ -397,9 +397,9 @@ public final class Policy implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mMinHomeDownlinkBandwidth, mMinHomeUplinkBandwidth,
- mMinRoamingDownlinkBandwidth, mMinRoamingUplinkBandwidth, mExcludedSsidList,
- mRequiredProtoPortMap, mMaximumBssLoadValue, mPreferredRoamingPartnerList,
- mPolicyUpdate);
+ mMinRoamingDownlinkBandwidth, mMinRoamingUplinkBandwidth,
+ Arrays.hashCode(mExcludedSsidList), mRequiredProtoPortMap, mMaximumBssLoadValue,
+ mPreferredRoamingPartnerList, mPolicyUpdate);
}
@Override
@@ -412,7 +412,8 @@ public final class Policy implements Parcelable {
.append("\n");
builder.append("MinRoamingUplinkBandwidth: ").append(mMinRoamingUplinkBandwidth)
.append("\n");
- builder.append("ExcludedSSIDList: ").append(mExcludedSsidList).append("\n");
+ builder.append("ExcludedSSIDList: ").append(Arrays.toString(mExcludedSsidList))
+ .append("\n");
builder.append("RequiredProtoPortMap: ").append(mRequiredProtoPortMap).append("\n");
builder.append("MaximumBSSLoadValue: ").append(mMaximumBssLoadValue).append("\n");
builder.append("PreferredRoamingPartnerList: ").append(mPreferredRoamingPartnerList)
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pConfig.java b/framework/java/android/net/wifi/p2p/WifiP2pConfig.java
index d8658cc900..4444bcdefb 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -28,6 +28,10 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
@@ -94,6 +98,16 @@ public class WifiP2pConfig implements Parcelable {
public @interface GroupOperatingBandType {}
/**
+ * IP provisioning via IPv4 DHCP, when joining a group as a group client.
+ */
+ public static final int GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP = 0;
+
+ /**
+ * IP provisioning via IPv6 link-local, when joining a group as a group client.
+ */
+ public static final int GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL = 1;
+
+ /**
* Allow the system to pick the operating frequency from all supported bands.
*/
public static final int GROUP_OWNER_BAND_AUTO = 0;
@@ -139,6 +153,17 @@ public class WifiP2pConfig implements Parcelable {
public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO;
/** @hide */
+ @IntDef(prefix = { "GROUP_CLIENT_IP_PROVISIONING_MODE_" }, value = {
+ GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP,
+ GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface GroupClientIpProvisioningMode {}
+
+ @GroupClientIpProvisioningMode
+ private int mGroupClientIpProvisioningMode = GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP;
+
+ /** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public int netId = WifiP2pGroup.NETWORK_ID_PERSISTENT;
@@ -203,6 +228,17 @@ public class WifiP2pConfig implements Parcelable {
}
}
+ /**
+ * Get the IP provisioning mode when joining a group as a group client.
+ * The result will be one of the following:
+ * {@link #GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP},
+ * {@link #GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL}
+ */
+ @GroupClientIpProvisioningMode
+ public int getGroupClientIpProvisioningMode() {
+ return mGroupClientIpProvisioningMode;
+ }
+
public String toString() {
StringBuffer sbuf = new StringBuffer();
sbuf.append("\n address: ").append(deviceAddress);
@@ -213,6 +249,7 @@ public class WifiP2pConfig implements Parcelable {
sbuf.append("\n passphrase: ").append(
TextUtils.isEmpty(passphrase) ? "<empty>" : "<non-empty>");
sbuf.append("\n groupOwnerBand: ").append(groupOwnerBand);
+ sbuf.append("\n groupClientIpProvisioningMode: ").append(mGroupClientIpProvisioningMode);
return sbuf.toString();
}
@@ -231,6 +268,7 @@ public class WifiP2pConfig implements Parcelable {
networkName = source.networkName;
passphrase = source.passphrase;
groupOwnerBand = source.groupOwnerBand;
+ mGroupClientIpProvisioningMode = source.mGroupClientIpProvisioningMode;
}
}
@@ -243,10 +281,12 @@ public class WifiP2pConfig implements Parcelable {
dest.writeString(networkName);
dest.writeString(passphrase);
dest.writeInt(groupOwnerBand);
+ dest.writeInt(mGroupClientIpProvisioningMode);
}
/** Implement the Parcelable interface */
- public static final @android.annotation.NonNull Creator<WifiP2pConfig> CREATOR =
+ @NonNull
+ public static final Creator<WifiP2pConfig> CREATOR =
new Creator<WifiP2pConfig>() {
public WifiP2pConfig createFromParcel(Parcel in) {
WifiP2pConfig config = new WifiP2pConfig();
@@ -257,6 +297,7 @@ public class WifiP2pConfig implements Parcelable {
config.networkName = in.readString();
config.passphrase = in.readString();
config.groupOwnerBand = in.readInt();
+ config.mGroupClientIpProvisioningMode = in.readInt();
return config;
}
@@ -292,6 +333,7 @@ public class WifiP2pConfig implements Parcelable {
private int mGroupOperatingBand = GROUP_OWNER_BAND_AUTO;
private int mGroupOperatingFrequency = GROUP_OWNER_BAND_AUTO;
private int mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY;
+ private int mGroupClientIpProvisioningMode = GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP;
/**
* Specify the peer's MAC address. If not set, the device will
@@ -307,7 +349,8 @@ public class WifiP2pConfig implements Parcelable {
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public @NonNull Builder setDeviceAddress(@Nullable MacAddress deviceAddress) {
+ @NonNull
+ public Builder setDeviceAddress(@Nullable MacAddress deviceAddress) {
if (deviceAddress == null) {
mDeviceAddress = MAC_ANY_ADDRESS;
} else {
@@ -333,7 +376,8 @@ public class WifiP2pConfig implements Parcelable {
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public @NonNull Builder setNetworkName(@NonNull String networkName) {
+ @NonNull
+ public Builder setNetworkName(@NonNull String networkName) {
if (TextUtils.isEmpty(networkName)) {
throw new IllegalArgumentException(
"network name must be non-empty.");
@@ -366,7 +410,8 @@ public class WifiP2pConfig implements Parcelable {
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public @NonNull Builder setPassphrase(@NonNull String passphrase) {
+ @NonNull
+ public Builder setPassphrase(@NonNull String passphrase) {
if (TextUtils.isEmpty(passphrase)) {
throw new IllegalArgumentException(
"passphrase must be non-empty.");
@@ -411,7 +456,8 @@ public class WifiP2pConfig implements Parcelable {
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public @NonNull Builder setGroupOperatingBand(@GroupOperatingBandType int band) {
+ @NonNull
+ public Builder setGroupOperatingBand(@GroupOperatingBandType int band) {
switch (band) {
case GROUP_OWNER_BAND_AUTO:
case GROUP_OWNER_BAND_2GHZ:
@@ -452,7 +498,8 @@ public class WifiP2pConfig implements Parcelable {
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public @NonNull Builder setGroupOperatingFrequency(int frequency) {
+ @NonNull
+ public Builder setGroupOperatingFrequency(int frequency) {
if (frequency < 0) {
throw new IllegalArgumentException(
"Invalid group operating frequency!");
@@ -471,7 +518,8 @@ public class WifiP2pConfig implements Parcelable {
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public @NonNull Builder enablePersistentMode(boolean persistent) {
+ @NonNull
+ public Builder enablePersistentMode(boolean persistent) {
if (persistent) {
mNetId = WifiP2pGroup.NETWORK_ID_PERSISTENT;
} else {
@@ -481,10 +529,53 @@ public class WifiP2pConfig implements Parcelable {
}
/**
+ * Specify the IP provisioning mode when joining a group as a group client. The IP
+ * provisioning mode should be {@link #GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP} or
+ * {@link #GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL}.
+ * <p>
+ * When joining a group as Group Client using {@link
+ * WifiP2pManager#connect(WifiP2pManager.Channel, WifiP2pConfig,
+ * WifiP2pManager.ActionListener)},
+ * specifying {@link #GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP} directs the system to
+ * assign a IPv4 to the group client using DHCP. Specifying
+ * {@link #GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL} directs the system to assign
+ * a link-local IPv6 to the group client.
+ * <p>
+ * Optional. {@link #GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP} by default.
+ *
+ * @param groupClientIpProvisioningMode the IP provisioning mode of the group client.
+ * This should be one of {@link #GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP},
+ * {@link #GROUP_OWNER_BAND_2GHZ}, {@link #GROUP_OWNER_BAND_5GHZ}.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ @NonNull
+ public Builder setGroupClientIpProvisioningMode(
+ @GroupClientIpProvisioningMode int groupClientIpProvisioningMode) {
+ // Since group client IP provisioning modes use NetworkStack functionalities introduced
+ // in T, hence we need at least T sdk for this to be supported.
+ if (!SdkLevel.isAtLeastT()) {
+ throw new UnsupportedOperationException();
+ }
+ switch (groupClientIpProvisioningMode) {
+ case GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP:
+ case GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL:
+ mGroupClientIpProvisioningMode = groupClientIpProvisioningMode;
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Invalid constant for the group client IP provisioning mode!");
+ }
+ return this;
+ }
+
+ /**
* Build {@link WifiP2pConfig} given the current requests made on the builder.
* @return {@link WifiP2pConfig} constructed based on builder method calls.
*/
- public @NonNull WifiP2pConfig build() {
+ @NonNull
+ public WifiP2pConfig build() {
if ((TextUtils.isEmpty(mNetworkName) && !TextUtils.isEmpty(mPassphrase))
|| (!TextUtils.isEmpty(mNetworkName) && TextUtils.isEmpty(mPassphrase))) {
throw new IllegalStateException(
@@ -512,6 +603,7 @@ public class WifiP2pConfig implements Parcelable {
config.groupOwnerBand = mGroupOperatingBand;
}
config.netId = mNetId;
+ config.mGroupClientIpProvisioningMode = mGroupClientIpProvisioningMode;
return config;
}
}
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pGroup.java b/framework/java/android/net/wifi/p2p/WifiP2pGroup.java
index e497b22d77..f761b80a0d 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pGroup.java
@@ -59,6 +59,13 @@ public class WifiP2pGroup implements Parcelable {
*/
public static final int NETWORK_ID_PERSISTENT = -2;
+ /**
+ * Group owner P2P interface MAC address.
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public byte[] interfaceAddress;
+
/** The network name */
private String mNetworkName;
diff --git a/framework/java/android/net/wifi/p2p/WifiP2pManager.java b/framework/java/android/net/wifi/p2p/WifiP2pManager.java
index 5de438a5f2..a99ad564da 100644
--- a/framework/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/framework/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -2326,10 +2326,7 @@ public class WifiP2pManager {
* @param channel is the channel created at {@link #initialize}
* @param wfdInfo the Wifi Display information to set
* @param listener for callbacks on success or failure. Can be null.
- *
- * @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
public void setWfdInfo(@NonNull Channel channel, @NonNull WifiP2pWfdInfo wfdInfo,
@Nullable ActionListener listener) {
diff --git a/framework/java/android/net/wifi/rtt/CivicLocation.java b/framework/java/android/net/wifi/rtt/CivicLocation.java
index 1d41177926..60b745ddfd 100644
--- a/framework/java/android/net/wifi/rtt/CivicLocation.java
+++ b/framework/java/android/net/wifi/rtt/CivicLocation.java
@@ -25,6 +25,7 @@ import android.os.Parcelable.Creator;
import android.util.SparseArray;
import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
import java.util.Locale;
import java.util.Objects;
@@ -267,7 +268,8 @@ public final class CivicLocation implements Parcelable {
public int hashCode() {
int[] civicAddressKeys = getSparseArrayKeys(mCivicAddressElements);
String[] civicAddressValues = getSparseArrayValues(mCivicAddressElements);
- return Objects.hash(mIsValid, mCountryCode, civicAddressKeys, civicAddressValues);
+ return Objects.hash(mIsValid, mCountryCode, Arrays.hashCode(civicAddressKeys),
+ Arrays.hashCode(civicAddressValues));
}
/**
diff --git a/framework/java/android/net/wifi/rtt/IWifiRttManager.aidl b/framework/java/android/net/wifi/rtt/IWifiRttManager.aidl
index facbd87041..3618ce2f59 100644
--- a/framework/java/android/net/wifi/rtt/IWifiRttManager.aidl
+++ b/framework/java/android/net/wifi/rtt/IWifiRttManager.aidl
@@ -32,4 +32,5 @@ interface IWifiRttManager
in WorkSource workSource, in RangingRequest request, in IRttCallback callback,
in Bundle extras);
void cancelRanging(in WorkSource workSource);
+ Bundle getRttCharacteristics();
}
diff --git a/framework/java/android/net/wifi/rtt/RangingResult.java b/framework/java/android/net/wifi/rtt/RangingResult.java
index d9d0717d60..c5854c9446 100644
--- a/framework/java/android/net/wifi/rtt/RangingResult.java
+++ b/framework/java/android/net/wifi/rtt/RangingResult.java
@@ -445,14 +445,18 @@ public final class RangingResult implements Parcelable {
/** @hide */
@Override
public String toString() {
- return new StringBuilder("RangingResult: [status=").append(mStatus).append(", mac=").append(
- mMac).append(", peerHandle=").append(
- mPeerHandle == null ? "<null>" : mPeerHandle.peerId).append(", distanceMm=").append(
- mDistanceMm).append(", distanceStdDevMm=").append(mDistanceStdDevMm).append(
- ", rssi=").append(mRssi).append(", numAttemptedMeasurements=").append(
- mNumAttemptedMeasurements).append(", numSuccessfulMeasurements=").append(
- mNumSuccessfulMeasurements).append(", lci=").append(mLci).append(", lcr=").append(
- mLcr).append(", responderLocation=").append(mResponderLocation)
+ return new StringBuilder("RangingResult: [status=").append(mStatus)
+ .append(", mac=").append(mMac)
+ .append(", peerHandle=").append(
+ mPeerHandle == null ? "<null>" : mPeerHandle.peerId)
+ .append(", distanceMm=").append(mDistanceMm)
+ .append(", distanceStdDevMm=").append(mDistanceStdDevMm)
+ .append(", rssi=").append(mRssi)
+ .append(", numAttemptedMeasurements=").append(mNumAttemptedMeasurements)
+ .append(", numSuccessfulMeasurements=").append(mNumSuccessfulMeasurements)
+ .append(", lci=").append(Arrays.toString(mLci))
+ .append(", lcr=").append(Arrays.toString(mLcr))
+ .append(", responderLocation=").append(mResponderLocation)
.append(", timestamp=").append(mTimestamp).append(", is80211mcMeasurement=")
.append(mIs80211mcMeasurement).append("]").toString();
}
@@ -483,7 +487,7 @@ public final class RangingResult implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mStatus, mMac, mPeerHandle, mDistanceMm, mDistanceStdDevMm, mRssi,
- mNumAttemptedMeasurements, mNumSuccessfulMeasurements, mLci, mLcr,
- mResponderLocation, mTimestamp, mIs80211mcMeasurement);
+ mNumAttemptedMeasurements, mNumSuccessfulMeasurements, Arrays.hashCode(mLci),
+ Arrays.hashCode(mLcr), mResponderLocation, mTimestamp, mIs80211mcMeasurement);
}
}
diff --git a/framework/java/android/net/wifi/rtt/WifiRttManager.java b/framework/java/android/net/wifi/rtt/WifiRttManager.java
index 3ef865c66b..60f4c2805a 100644
--- a/framework/java/android/net/wifi/rtt/WifiRttManager.java
+++ b/framework/java/android/net/wifi/rtt/WifiRttManager.java
@@ -27,9 +27,11 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
+import android.annotation.StringDef;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
+import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Bundle;
@@ -39,6 +41,8 @@ import android.util.Log;
import com.android.modules.utils.build.SdkLevel;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.concurrent.Executor;
@@ -81,6 +85,33 @@ public class WifiRttManager {
public static final String ACTION_WIFI_RTT_STATE_CHANGED =
"android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED";
+ /**
+ * Bundle key to access if one-sided Wi-Fi RTT is supported. When it is not supported, only
+ * two-sided RTT can be performed, which requires responder supports IEEE 802.11mc and this can
+ * be determined by the method {@link ScanResult#is80211mcResponder()}
+ */
+ public static final String CHARACTERISTICS_KEY_BOOLEAN_ONE_SIDED_RTT = "key_one_sided_rtt";
+ /**
+ * Bundle key to access if getting the Location Configuration Information(LCI) from responder is
+ * supported.
+ * @see ResponderLocation
+ */
+ public static final String CHARACTERISTICS_KEY_BOOLEAN_LCI = "key_lci";
+ /**
+ * Bundle key to access if getting the Location Civic Report(LCR) from responder is supported.
+ * @see ResponderLocation
+ */
+ public static final String CHARACTERISTICS_KEY_BOOLEAN_LCR = "key_lcr";
+
+ /** @hide */
+ @StringDef(prefix = { "CHARACTERISTICS_KEY_"}, value = {
+ CHARACTERISTICS_KEY_BOOLEAN_ONE_SIDED_RTT,
+ CHARACTERISTICS_KEY_BOOLEAN_LCI,
+ CHARACTERISTICS_KEY_BOOLEAN_LCR,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RttCharacteristicsKey {}
+
/** @hide */
public WifiRttManager(@NonNull Context context, @NonNull IWifiRttManager service) {
mContext = context;
@@ -210,4 +241,23 @@ public class WifiRttManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Returns a Bundle which represents the characteristics of the Wi-Fi RTT interface: a set of
+ * parameters which specify feature support. Each parameter can be accessed by the specified
+ * Bundle key, one of the {@code CHARACTERISTICS_KEY_*} value.
+ * <p>
+ * May return an empty Bundle if the Wi-Fi RTT service is not initialized.
+ *
+ * @return A Bundle specifying feature support of RTT.
+ */
+ @RequiresPermission(ACCESS_WIFI_STATE)
+ @NonNull
+ public Bundle getRttCharacteristics() {
+ try {
+ return mService.getRttCharacteristics();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/framework/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/framework/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
index 940a612d3b..35cafcd791 100644
--- a/framework/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ b/framework/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
@@ -754,4 +754,38 @@ public class WifiEnterpriseConfigTest {
mEnterpriseConfig.setCaCertificateForTrustOnFirstUse(mockCert);
}
+
+ /**
+ * Verify setMinimumTlsVersion sunny cases.
+ */
+ @Test
+ public void testSetMinimumTlsVersionWithValidValues() throws Exception {
+ for (int i = WifiEnterpriseConfig.TLS_VERSION_MIN;
+ i <= WifiEnterpriseConfig.TLS_VERSION_MAX; i++) {
+ mEnterpriseConfig.setMinimumTlsVersion(i);
+ assertEquals(i, mEnterpriseConfig.getMinimumTlsVersion());
+ }
+ }
+
+ /**
+ * Verify that setMinimumTlsVersion() raises IllegalArgumentException when
+ * an invalid TLS version is set.
+ *
+ * @throws IllegalArgumentException
+ */
+ @Test (expected = IllegalArgumentException.class)
+ public void testSetMinimumTlsVersionWithVersionLargerThanMaxVersion() throws Exception {
+ mEnterpriseConfig.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_VERSION_MAX + 1);
+ }
+
+ /**
+ * Verify that setMinimumTlsVersion() raises IllegalArgumentException when
+ * an invalid TLS version is set.
+ *
+ * @throws IllegalArgumentException
+ */
+ @Test (expected = IllegalArgumentException.class)
+ public void testSetMinimumTlsVersionWithVersionSmallerThanMinVersion() throws Exception {
+ mEnterpriseConfig.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_VERSION_MIN - 1);
+ }
}
diff --git a/framework/tests/src/android/net/wifi/WifiManagerTest.java b/framework/tests/src/android/net/wifi/WifiManagerTest.java
index 8e78900a9c..68ac135f89 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_DECORATED_IDENTITY;
import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP;
import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP_AKM;
import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP_ENROLLEE_RESPONDER;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS;
import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_P2P;
import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT;
@@ -60,6 +61,7 @@ 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.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
@@ -512,6 +514,29 @@ public class WifiManagerTest {
}
/**
+ * Check the call to validateSoftApConfiguration calls WifiService to
+ * validateSoftApConfiguration.
+ */
+ @Test
+ public void testValidateSoftApConfigurationCallsService() throws Exception {
+ SoftApConfiguration apConfig = generatorTestSoftApConfig();
+ when(mWifiService.validateSoftApConfiguration(any())).thenReturn(true);
+ assertTrue(mWifiManager.validateSoftApConfiguration(apConfig));
+
+ when(mWifiService.validateSoftApConfiguration(any())).thenReturn(false);
+ assertFalse(mWifiManager.validateSoftApConfiguration(apConfig));
+ }
+
+ /**
+ * Throws IllegalArgumentException when calling validateSoftApConfiguration with null.
+ */
+ @Test
+ public void testValidateSoftApConfigurationWithNullConfiguration() throws Exception {
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiManager.validateSoftApConfiguration(null));
+ }
+
+ /**
* Check the call to startSoftAp calls WifiService to startSoftAp with the provided
* WifiConfiguration. Verify that the return value is propagated to the caller.
*/
@@ -3573,7 +3598,7 @@ public class WifiManagerTest {
| WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI;
mWifiManager.getAllowedChannels(band, mode);
verify(mWifiService).getUsableChannels(eq(band), eq(mode),
- eq(WifiAvailableChannel.FILTER_REGULATORY));
+ eq(WifiAvailableChannel.FILTER_REGULATORY), eq(TEST_PACKAGE_NAME), any());
}
/**
@@ -3588,7 +3613,8 @@ public class WifiManagerTest {
mWifiManager.getUsableChannels(band, mode);
verify(mWifiService).getUsableChannels(eq(band), eq(mode),
eq(WifiAvailableChannel.FILTER_CONCURRENCY
- | WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE));
+ | WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE),
+ eq(TEST_PACKAGE_NAME), any());
}
/**
@@ -3852,6 +3878,19 @@ public class WifiManagerTest {
WifiManager.WIFI_MULTI_INTERNET_MODE_DBS_AP);
}
+ /*
+ * Verify call to {@link WifiManager#isDualBandSimultaneousSupported}.
+ */
+ @Test
+ public void testIsDualBandSimultaneousSupported() throws Exception {
+ when(mWifiService.getSupportedFeatures())
+ .thenReturn(new Long(WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS));
+ assertTrue(mWifiManager.isDualBandSimultaneousSupported());
+ when(mWifiService.getSupportedFeatures())
+ .thenReturn(new Long(~WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS));
+ assertFalse(mWifiManager.isDualBandSimultaneousSupported());
+ }
+
/**
* Verify call to
* {@link WifiManager#reportCreateInterfaceImpact(int, boolean, Executor, BiConsumer)}.
diff --git a/framework/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/framework/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
index 9d1d55d21c..53a0130366 100644
--- a/framework/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
+++ b/framework/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
@@ -195,7 +195,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_5_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -224,7 +224,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_5_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -253,7 +253,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_5_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -285,7 +285,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_24_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -316,7 +316,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_5_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -325,7 +325,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_24_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -334,7 +334,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.UNSPECIFIED,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
}
@@ -364,7 +364,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_5_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -383,7 +383,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_24_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -393,7 +393,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.UNSPECIFIED,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
}
@@ -425,7 +425,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_5_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -458,7 +458,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.WIFI_BAND_24_GHZ,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
@@ -486,7 +486,7 @@ public class WifiNetworkAgentSpecifierTest {
ssidPattern,
bssidPattern,
ScanResult.UNSPECIFIED,
- wificonfigurationNetworkSpecifier);
+ wificonfigurationNetworkSpecifier, new int[0]);
assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier));
assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier));
diff --git a/framework/tests/src/android/net/wifi/WifiNetworkSelectionConfigTest.java b/framework/tests/src/android/net/wifi/WifiNetworkSelectionConfigTest.java
index 34248273d6..0f1c8812ef 100644
--- a/framework/tests/src/android/net/wifi/WifiNetworkSelectionConfigTest.java
+++ b/framework/tests/src/android/net/wifi/WifiNetworkSelectionConfigTest.java
@@ -42,6 +42,8 @@ public class WifiNetworkSelectionConfigTest {
.setAssociatedNetworkSelectionOverride(
WifiNetworkSelectionConfig.ASSOCIATED_NETWORK_SELECTION_OVERRIDE_ENABLED)
.setSufficiencyCheckEnabledWhenScreenOff(false)
+ .setUserConnectChoiceOverrideEnabled(false)
+ .setLastSelectionWeightEnabled(false)
.build();
Parcel parcelW = Parcel.obtain();
@@ -59,6 +61,8 @@ public class WifiNetworkSelectionConfigTest {
parcelConfig.getAssociatedNetworkSelectionOverride());
assertFalse(parcelConfig.isSufficiencyCheckEnabledWhenScreenOff());
assertTrue(parcelConfig.isSufficiencyCheckEnabledWhenScreenOn());
+ assertFalse(parcelConfig.isUserConnectChoiceOverrideEnabled());
+ assertFalse(parcelConfig.isLastSelectionWeightEnabled());
assertEquals(config, parcelConfig);
assertEquals(config.hashCode(), parcelConfig.hashCode());
}
@@ -81,5 +85,7 @@ public class WifiNetworkSelectionConfigTest {
config.getAssociatedNetworkSelectionOverride());
assertTrue(config.isSufficiencyCheckEnabledWhenScreenOff());
assertTrue(config.isSufficiencyCheckEnabledWhenScreenOn());
+ assertTrue(config.isUserConnectChoiceOverrideEnabled());
+ assertTrue(config.isLastSelectionWeightEnabled());
}
}
diff --git a/framework/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/framework/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
index 0a24523b3a..12dfd6e9a5 100644
--- a/framework/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
+++ b/framework/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
@@ -16,14 +16,17 @@
package android.net.wifi;
+import static android.net.wifi.ScanResult.WIFI_BAND_5_GHZ;
import static android.os.PatternMatcher.PATTERN_LITERAL;
import static android.os.PatternMatcher.PATTERN_PREFIX;
import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
@@ -653,8 +656,8 @@ public class WifiNetworkSpecifierTest {
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- ScanResult.WIFI_BAND_5_GHZ,
- wifiConfiguration);
+ WIFI_BAND_5_GHZ,
+ wifiConfiguration, new int[0]);
Parcel parcelW = Parcel.obtain();
specifier.writeToParcel(parcelW, 0);
@@ -686,7 +689,7 @@ public class WifiNetworkSpecifierTest {
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
ScanResult.UNSPECIFIED, /* band */
- wifiConfiguration);
+ wifiConfiguration, new int[0]);
assertFalse(specifier.canBeSatisfiedBy(null));
assertFalse(specifier.canBeSatisfiedBy(new MatchAllNetworkSpecifier()));
@@ -708,15 +711,15 @@ public class WifiNetworkSpecifierTest {
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- ScanResult.WIFI_BAND_5_GHZ,
- wifiConfiguration);
+ WIFI_BAND_5_GHZ,
+ wifiConfiguration, new int[0]);
WifiNetworkSpecifier specifier2 =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- ScanResult.WIFI_BAND_5_GHZ,
- wifiConfiguration);
+ WIFI_BAND_5_GHZ,
+ wifiConfiguration, new int[0]);
assertTrue(specifier2.canBeSatisfiedBy(specifier1));
}
@@ -738,7 +741,7 @@ public class WifiNetworkSpecifierTest {
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
ScanResult.WIFI_BAND_24_GHZ,
- wifiConfiguration1);
+ wifiConfiguration1, new int[0]);
WifiConfiguration wifiConfiguration2 = new WifiConfiguration();
wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
@@ -747,7 +750,7 @@ public class WifiNetworkSpecifierTest {
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
ScanResult.WIFI_BAND_24_GHZ,
- wifiConfiguration2);
+ wifiConfiguration2, new int[0]);
assertFalse(specifier2.canBeSatisfiedBy(specifier1));
}
@@ -768,15 +771,15 @@ public class WifiNetworkSpecifierTest {
new WifiNetworkSpecifier(new PatternMatcher("", PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- ScanResult.WIFI_BAND_5_GHZ,
- wifiConfiguration);
+ WIFI_BAND_5_GHZ,
+ wifiConfiguration, new int[0]);
WifiNetworkSpecifier specifier2 =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- ScanResult.WIFI_BAND_5_GHZ,
- wifiConfiguration);
+ WIFI_BAND_5_GHZ,
+ wifiConfiguration, new int[0]);
assertFalse(specifier2.canBeSatisfiedBy(specifier1));
}
@@ -798,14 +801,14 @@ public class WifiNetworkSpecifierTest {
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
ScanResult.WIFI_BAND_24_GHZ,
- wifiConfiguration);
+ wifiConfiguration, new int[0]);
WifiNetworkSpecifier specifier2 =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS,
WifiManager.ALL_ZEROS_MAC_ADDRESS),
ScanResult.WIFI_BAND_24_GHZ,
- wifiConfiguration);
+ wifiConfiguration, new int[0]);
assertFalse(specifier2.canBeSatisfiedBy(specifier1));
}
@@ -824,14 +827,14 @@ public class WifiNetworkSpecifierTest {
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
ScanResult.WIFI_BAND_24_GHZ,
- wifiConfiguration);
+ wifiConfiguration, new int[0]);
WifiNetworkSpecifier specifier2 =
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
ScanResult.WIFI_BAND_24_GHZ,
- wifiConfiguration);
+ wifiConfiguration, new int[0]);
// Same band matches.
assertTrue(specifier2.canBeSatisfiedBy(specifier1));
@@ -841,8 +844,8 @@ public class WifiNetworkSpecifierTest {
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS,
WifiManager.ALL_ZEROS_MAC_ADDRESS),
- ScanResult.WIFI_BAND_5_GHZ,
- wifiConfiguration);
+ WIFI_BAND_5_GHZ,
+ wifiConfiguration, new int[0]);
// Different band does not match.
assertFalse(specifier2.canBeSatisfiedBy(specifier1));
@@ -853,7 +856,7 @@ public class WifiNetworkSpecifierTest {
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS,
WifiManager.ALL_ZEROS_MAC_ADDRESS),
ScanResult.UNSPECIFIED,
- wifiConfiguration);
+ wifiConfiguration, new int[0]);
// An UNSPECIFIED band does not match a specified band, because a WifiNetworkSpecifier
// satisfies another only if they are equal.
@@ -874,16 +877,29 @@ public class WifiNetworkSpecifierTest {
new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
MacAddress.fromString(TEST_BSSID_OUI_MASK)),
- ScanResult.WIFI_BAND_5_GHZ,
- wifiConfiguration);
+ WIFI_BAND_5_GHZ,
+ wifiConfiguration, new int[0]);
final NetworkSpecifier redacted = specifier.redact();
if (SdkLevel.isAtLeastS()) {
assertEquals(
- new WifiNetworkSpecifier.Builder().setBand(ScanResult.WIFI_BAND_5_GHZ).build(),
+ new WifiNetworkSpecifier.Builder().setBand(WIFI_BAND_5_GHZ).build(),
redacted);
} else {
assertTrue(redacted == specifier);
}
}
+
+ @Test
+ public void testSetPreferredChannel() {
+ WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX));
+ assertThrows(IllegalArgumentException.class, () -> builder
+ .setPreferredChannelsFrequenciesMhz(new int[]{0}));
+ WifiNetworkSpecifier networkSpecifier = builder
+ .setPreferredChannelsFrequenciesMhz(new int[]{5180}).build();
+ assertArrayEquals(new int[]{5180}, networkSpecifier.getPreferredChannelFrequenciesMhz());
+ builder.setBand(WIFI_BAND_5_GHZ);
+ assertThrows(IllegalStateException.class, builder::build);
+ }
}
diff --git a/framework/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/framework/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
index 93e62b2c14..8eb7c42c5b 100644
--- a/framework/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
+++ b/framework/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
@@ -41,14 +41,12 @@ public class OsuProviderTest {
private static final WifiSsid TEST_SSID =
WifiSsid.fromBytes("TEST SSID".getBytes(StandardCharsets.UTF_8));
private static final String TEST_FRIENDLY_NAME = "Friendly Name";
- private static final Map<String, String> TEST_FRIENDLY_NAMES =
- new HashMap<String, String>() {
- {
- put("en", TEST_FRIENDLY_NAME);
- put("kr", TEST_FRIENDLY_NAME + 2);
- put("jp", TEST_FRIENDLY_NAME + 3);
- }
- };
+ private static final Map<String, String> TEST_FRIENDLY_NAMES = new HashMap<>();
+ static {
+ TEST_FRIENDLY_NAMES.put("en", TEST_FRIENDLY_NAME);
+ TEST_FRIENDLY_NAMES.put("kr", TEST_FRIENDLY_NAME + 2);
+ TEST_FRIENDLY_NAMES.put("jp", TEST_FRIENDLY_NAME + 3);
+ }
private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
diff --git a/framework/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/framework/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
index a44df40a8e..511f37a58d 100644
--- a/framework/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ b/framework/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue;
import android.net.wifi.EAPConstants;
import android.net.wifi.FakeKeys;
+import android.net.wifi.WifiEnterpriseConfig;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
@@ -633,4 +634,41 @@ public class CredentialTest {
assertNotEquals(certCred1.getUniqueId(), certCred2.getUniqueId());
}
+
+ /**
+ * Verify setMinimumTlsVersion sunny cases.
+ */
+ @Test
+ public void testSetMinimumTlsVersionWithValidValues() throws Exception {
+ Credential cred = new Credential();
+ for (int i = WifiEnterpriseConfig.TLS_VERSION_MIN;
+ i <= WifiEnterpriseConfig.TLS_VERSION_MAX; i++) {
+ cred.setMinimumTlsVersion(i);
+ assertEquals(i, cred.getMinimumTlsVersion());
+ }
+ }
+
+ /**
+ * Verify that setMinimumTlsVersion() raises IllegalArgumentException when
+ * an invalid TLS version is set.
+ *
+ * @throws IllegalArgumentException
+ */
+ @Test (expected = IllegalArgumentException.class)
+ public void testSetMinimumTlsVersionWithVersionLargerThanMaxVersion() throws Exception {
+ Credential cred = new Credential();
+ cred.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_VERSION_MAX + 1);
+ }
+
+ /**
+ * Verify that setMinimumTlsVersion() raises IllegalArgumentException when
+ * an invalid TLS version is set.
+ *
+ * @throws IllegalArgumentException
+ */
+ @Test (expected = IllegalArgumentException.class)
+ public void testSetMinimumTlsVersionWithVersionSmallerThanMinVersion() throws Exception {
+ Credential cred = new Credential();
+ cred.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_VERSION_MIN - 1);
+ }
}
diff --git a/framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java b/framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
index e5f2431918..bcd8d9556d 100644
--- a/framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
+++ b/framework/tests/src/android/net/wifi/p2p/WifiP2pConfigTest.java
@@ -16,14 +16,20 @@
package android.net.wifi.p2p;
+import static android.net.wifi.p2p.WifiP2pConfig.GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP;
+import static android.net.wifi.p2p.WifiP2pConfig.GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import android.net.MacAddress;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
+import com.android.modules.utils.build.SdkLevel;
+
import org.junit.Test;
/**
@@ -151,6 +157,54 @@ public class WifiP2pConfigTest {
assertEquals(WifiP2pGroup.NETWORK_ID_TEMPORARY, c.netId);
}
+ /** Verify that a config by default has group client IP provisioning with DHCP IPv4. */
+ @Test
+ public void testBuildConfigWithGroupClientIpProvisioningModeDefault() throws Exception {
+ WifiP2pConfig c = new WifiP2pConfig.Builder()
+ .setDeviceAddress(MacAddress.fromString(DEVICE_ADDRESS))
+ .build();
+ assertEquals(c.deviceAddress, DEVICE_ADDRESS);
+ assertEquals(c.getGroupClientIpProvisioningMode(),
+ GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP);
+ }
+
+ /** Verify that a config with group client IP provisioning with IPv4 DHCP can be built. */
+ @Test
+ public void testBuildConfigWithGroupClientIpProvisioningModeIpv4Dhcp() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ WifiP2pConfig c = new WifiP2pConfig.Builder()
+ .setDeviceAddress(MacAddress.fromString(DEVICE_ADDRESS))
+ .setGroupClientIpProvisioningMode(GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP)
+ .build();
+ assertEquals(c.deviceAddress, DEVICE_ADDRESS);
+ assertEquals(c.getGroupClientIpProvisioningMode(),
+ GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP);
+ }
+
+ /** Verify that a config with group client IP provisioning with IPv6 link-local can be built. */
+ @Test
+ public void testBuildConfigWithGroupClientIpProvisioningModeIpv6LinkLocal() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ WifiP2pConfig c = new WifiP2pConfig.Builder()
+ .setDeviceAddress(MacAddress.fromString(DEVICE_ADDRESS))
+ .setGroupClientIpProvisioningMode(GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL)
+ .build();
+ assertEquals(c.deviceAddress, DEVICE_ADDRESS);
+ assertEquals(c.getGroupClientIpProvisioningMode(),
+ GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL);
+ }
+
+ /**
+ * Verify that the builder throws IllegalArgumentException if invalid group client IP
+ * provisioning mode is set.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testBuilderWithInvalidGroupClientIpProvisioningMode()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ WifiP2pConfig c = new WifiP2pConfig.Builder().setGroupClientIpProvisioningMode(5).build();
+ }
+
/**
* Verify that the builder throws IllegalStateException if none of
* network name, passphrase, and device address is set.
@@ -203,7 +257,6 @@ public class WifiP2pConfigTest {
// no equals operator, use toString for comparison.
assertEquals(config.toString(), configFromParcel.toString());
-
}
@Test
@@ -216,5 +269,4 @@ public class WifiP2pConfigTest {
config.invalidate();
assertEquals("", config.deviceAddress);
}
-
}
diff --git a/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
index 8f517980ca..b9e482e448 100644
--- a/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
+++ b/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
@@ -620,4 +620,12 @@ public class WifiRttManagerTest {
assertEquals(ResponderConfig.PREAMBLE_HE, config.preamble);
}
+
+ @Test
+ public void testGetRttCharacteristics() throws Exception {
+ when(mockRttService.getRttCharacteristics()).thenReturn(new Bundle());
+ Bundle characteristics = mDut.getRttCharacteristics();
+ verify(mockRttService).getRttCharacteristics();
+ assertEquals(0, characteristics.size());
+ }
}
diff --git a/service/Android.bp b/service/Android.bp
index 2beb972154..f5bc67cf07 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -48,8 +48,6 @@ java_library {
installable: false,
defaults: ["wifi-service-common"],
srcs: [ ":wifi-service-srcs" ],
- // java_api_finder must accompany `srcs`
- plugins: ["java_api_finder"],
sdk_version: "system_server_current",
lint: {
@@ -67,6 +65,7 @@ java_library {
// compile time
"framework-wifi-pre-jarjar",
"framework-bluetooth",
+ "framework-configinfrastructure",
"framework-connectivity.stubs.module_lib",
"framework-connectivity-t.stubs.module_lib",
"framework-statsd.stubs.module_lib",
@@ -76,6 +75,9 @@ java_library {
],
static_libs: [
+ // AIDL vendor hal implementation
+ "android.hardware.wifi-V1-java",
+ // HIDL vendor hal implementation
"android.hardware.wifi-V1.0-java",
"android.hardware.wifi-V1.1-java",
"android.hardware.wifi-V1.2-java",
@@ -91,7 +93,7 @@ java_library {
"android.hardware.wifi.hostapd-V1.2-java",
"android.hardware.wifi.hostapd-V1.3-java",
// AIDL supplicant implementation
- "android.hardware.wifi.supplicant-V1-java",
+ "android.hardware.wifi.supplicant-V2-java",
// HIDL supplicant implementation
"android.hardware.wifi.supplicant-V1.0-java",
"android.hardware.wifi.supplicant-V1.1-java",
diff --git a/service/ServiceWifiResources/res/values-af/strings.xml b/service/ServiceWifiResources/res/values-af/strings.xml
index 5d1f8d355d..a40a9ca746 100644
--- a/service/ServiceWifiResources/res/values-af/strings.xml
+++ b/service/ServiceWifiResources/res/values-af/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Jy kan wi-fi in Kitsinstellings afskakel"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Laat toe"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Moenie toelaat nie"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑fi is aan in vliegtuigmodus"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"As jy wi-fi aangeskakel hou, sal jou foon onthou om dit aan te hou wanneer jy weer in vliegtuigmodus is"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑fi bly aan"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Jou foon onthou om wi‑fi aan te hou in vliegtuigmodus. Skakel wi-fi af as jy nie wil hê dit moet aan bly nie."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Netwerk is onbeskikbaar"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> is deur jou administrateur gedeaktiveer."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Maak toe"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑fi is aan in vliegtuigmodus"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑fi bly aan"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-am/strings.xml b/service/ServiceWifiResources/res/values-am/strings.xml
index df8b970d02..2826bf3685 100644
--- a/service/ServiceWifiResources/res/values-am/strings.xml
+++ b/service/ServiceWifiResources/res/values-am/strings.xml
@@ -160,13 +160,13 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"በፈጣን ቅንብሮች ውስጥ Wi-Fiን ማጥፋት ይችላሉ"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"ፍቀድ"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"አትፍቀድ"</string>
- <string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"የማይገኝ አውታረ መረብ"</string>
- <string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> በእርስዎ አስተዳዳሪ ተሰናክሏል።"</string>
- <string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"ዝጋ"</string>
<string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"በአውሮፕላን ሁነታ ላይ Wi-Fi በርቷል"</string>
<!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
<skip />
<string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi በርቶ ይቆያል"</string>
<!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
<skip />
+ <string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"የማይገኝ አውታረ መረብ"</string>
+ <string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> በእርስዎ አስተዳዳሪ ተሰናክሏል።"</string>
+ <string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"ዝጋ"</string>
</resources>
diff --git a/service/ServiceWifiResources/res/values-ar/strings.xml b/service/ServiceWifiResources/res/values-ar/strings.xml
index 213e287182..d7ce4e1271 100644
--- a/service/ServiceWifiResources/res/values-ar/strings.xml
+++ b/service/ServiceWifiResources/res/values-ar/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"‏يمكنك إيقاف Wi-Fi في الإعدادات السريعة."</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"السماح"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"عدم السماح"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‏شبكة Wi‑Fi مفعَّلة في \"وضع الطيران\""</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"‏إذا واصلت تفعيل شبكة Wi‑Fi، سيتذكر هاتفك إبقاءها مفعَّلة في المرة القادمة التي تفعِّل فيها \"وضع الطيران\"."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‏تظل شبكة Wi-Fi مفعّلة"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"‏يتذكر هاتفك إبقاء شبكة Wi‑Fi مفعَّلة في \"وضع الطيران\". يمكنك إيقاف شبكة Wi‑Fi إذا لم تكن تريد مواصلة تفعيلها."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"شبكة غير متوفّرة"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"تم إيقاف معرّف <xliff:g id="SSID">%1$s</xliff:g> من قِبل المشرف."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"إغلاق"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‏شبكة Wi‑Fi مفعَّلة في \"وضع الطيران\""</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‏تظل شبكة Wi-Fi مفعّلة"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-as/strings.xml b/service/ServiceWifiResources/res/values-as/strings.xml
index 6cca27a589..02c50762de 100644
--- a/service/ServiceWifiResources/res/values-as/strings.xml
+++ b/service/ServiceWifiResources/res/values-as/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"আপুনি ক্ষিপ্ৰ ছেটিঙত ৱাই-ফাই অফ কৰিব পাৰে"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"অনুমতি দিয়ক"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"অনুমতি নিদিব"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"এয়াৰপ্লেন ম’ডত ৱাই‐ফাই অন হৈ থাকিব"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"আপুনি যদি ৱাই-ফাই অন কৰি ৰাখে, পৰৱৰ্তী সময়ত আপুনি এয়াৰপ্লেন ম’ড ব্যৱহাৰ কৰিলে আপোনাৰ ফ’নটোৱে এয়া অন কৰি ৰাখিবলৈ মনত ৰাখিব"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi অন হৈ থাকিব"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"আপোনাৰ ফ’নটোৱে এয়াৰপ্লেন ম’ডত ৱাই-ফাই অন ৰাখিবলৈ মনত ৰাখে। আপুনি যদি ৱাই-ফাই অন হৈ থকাটো নিবিচাৰে, তেন্তে ইয়াক অফ কৰক।"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"উপলব্ধ নোহোৱা নেটৱৰ্ক"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"আপোনাৰ প্ৰশাসকে <xliff:g id="SSID">%1$s</xliff:g> অক্ষম কৰিছে।"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"বন্ধ কৰক"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"এয়াৰপ্লেন ম’ডত ৱাই‐ফাই অন হৈ থাকিব"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi অন হৈ থাকিব"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-az/strings.xml b/service/ServiceWifiResources/res/values-az/strings.xml
index 3938db2f13..279e48205b 100644
--- a/service/ServiceWifiResources/res/values-az/strings.xml
+++ b/service/ServiceWifiResources/res/values-az/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Sürətli Ayarlarda Wi‑Fi\'ı deaktiv edə bilərsiniz"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"İcazə verin"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"İcazə verməyin"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Təyyarə rejimində Wi‑Fi aktiv qalsın"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Wi‑Fi\'ı aktiv saxlasanız, növbəti dəfə təyyarə rejimində olduqda telefonunuz onu aktiv saxlayacaq"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi aktiv qalacaq"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefonunuz təyyarə rejimində Wi‑Fi\'ı aktiv saxlayacaq. Aktiv qalmasını istəmirsinizsə, Wi‑Fi\'ı deaktiv edin."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Əlçatan Şəbəkə"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> administratorunuz tərəfindən deaktiv edilib."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Bağlayın"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Təyyarə rejimində Wi‑Fi aktiv qalsın"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi aktiv qalacaq"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml b/service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml
index e77f0c579a..7dcc6a9a14 100644
--- a/service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml
+++ b/service/ServiceWifiResources/res/values-b+sr+Latn/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Možete da isključite WiFi u Brzim podešavanjima"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Dozvoli"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Ne dozvoli"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WiFi je uključen u režimu rada u avionu"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ako odlučite da ne isključujete WiFi, telefon će zapamtiti da ga ne isključuje sledeći put kada budete u režimu rada u avionu"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WiFi ostaje uključen"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefon pamti da ne treba da isključuje WiFi u režimu rada u avionu. Isključite WiFi ako ne želite da ostane uključen."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Nedostupna mreža"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Administrator je onemogućio <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Zatvori"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WiFi je uključen u režimu rada u avionu"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WiFi ostaje uključen"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-be/strings.xml b/service/ServiceWifiResources/res/values-be/strings.xml
index 04758ca32f..874e8a2364 100644
--- a/service/ServiceWifiResources/res/values-be/strings.xml
+++ b/service/ServiceWifiResources/res/values-be/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Вы можаце выключыць сетку Wi‑Fi у Хуткіх наладах"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Дазволіць"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Не дазваляць"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"У рэжыме палёту сетка Wi‑Fi застанецца ўключанай"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Калі вы не выключыце сетку Wi‑Fi, падчас наступнага пераходу ў рэжым палёту тэлефон будзе захоўваць яе ўключанай"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Сетка Wi‑Fi застаецца ўключанай"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"На тэлефоне ў рэжыме палёту сетка Wi‑Fi будзе заставацца ўключанай, але вы можаце выключыць яе."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Недаступная сетка"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Сетка \"<xliff:g id="SSID">%1$s</xliff:g>\" адключана вашым адміністратарам."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Закрыць"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"У рэжыме палёту сетка Wi‑Fi застанецца ўключанай"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Сетка Wi‑Fi застаецца ўключанай"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-bg/strings.xml b/service/ServiceWifiResources/res/values-bg/strings.xml
index 020583b05a..e4da9d56f2 100644
--- a/service/ServiceWifiResources/res/values-bg/strings.xml
+++ b/service/ServiceWifiResources/res/values-bg/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Можете да изключите Wi‑Fi от бързите настройки"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Разрешаване"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Забраняване"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Включване на Wi‑Fi в самолетния режим"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ако не изключите функцията за Wi‑Fi, телефонът ви ще я остави активна следващия път, когато използвате самолетния режим"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi няма да се изключи"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Функцията за Wi‑Fi ще бъде включена, докато телефонът ви е в самолетен режим. Ако не искате това, изключете я."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Няма достъп до мрежата"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Функцията <xliff:g id="SSID">%1$s</xliff:g> е деактивирана от администратора ви."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Затваряне"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Включване на Wi‑Fi в самолетния режим"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi няма да се изключи"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-bn/strings.xml b/service/ServiceWifiResources/res/values-bn/strings.xml
index 0d23bf34ba..f79fc4a6e3 100644
--- a/service/ServiceWifiResources/res/values-bn/strings.xml
+++ b/service/ServiceWifiResources/res/values-bn/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"\'দ্রুত সেটিংস\' মেনু থেকে আপনি ওয়াই-ফাই বন্ধ করতে পারবেন"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"অনুমতি দিন"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"অনুমতি দেবেন না"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"\'বিমান মোড\'-এ ওয়াই-ফাই চালু থাকে"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"আপনি ওয়াই-ফাই চালু রাখলে, আপনি \'বিমান\' মোডে থাকলে পরবর্তী সময় আপনার ফোন এটি চালু রাখার জন্য মনে রাখবে"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"ওয়াই-ফাই চালু থাকে"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"\'বিমান মোড\'-এ থাকাকালীন আপনার ফোন ওয়াই-ফাই চালু রাখে। আপনি এটি চালু না রাখতে চাইলে ওয়াই-ফাই বন্ধ করুন।"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"নেটওয়ার্ক উপলভ্য নয়"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"আপনার অ্যাডমিনিস্ট্রেটর <xliff:g id="SSID">%1$s</xliff:g> বন্ধ করে দিয়েছেন।"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"বন্ধ করুন"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"\'বিমান মোড\'-এ ওয়াই-ফাই চালু থাকে"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"ওয়াই-ফাই চালু থাকে"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-bs/strings.xml b/service/ServiceWifiResources/res/values-bs/strings.xml
index ac272e8b1b..eb54553f5e 100644
--- a/service/ServiceWifiResources/res/values-bs/strings.xml
+++ b/service/ServiceWifiResources/res/values-bs/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"WiFi možete isključiti u Brzim postavkama"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Dozvoli"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Nemoj dozvoliti"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WiFi je uključen u načinu rada u avionu"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ako ostavite WiFi uključen, telefon će zapamtiti da ga ostavi uključenog sljedeći put kada budete u načinu rada u avionu"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WiFi ostaje uključen"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefon pamti da zadrži WiFi u načinu rada u avionu. Isključite WiFi ako ne želite da ostane uključen."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Nedostupna mreža"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Administrator je onemogućio <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Zatvori"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WiFi je uključen u načinu rada u avionu"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WiFi ostaje uključen"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ca/strings.xml b/service/ServiceWifiResources/res/values-ca/strings.xml
index 0e45b307d1..f877622197 100644
--- a/service/ServiceWifiResources/res/values-ca/strings.xml
+++ b/service/ServiceWifiResources/res/values-ca/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Pots desactivar la Wi‑Fi a la configuració ràpida"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Permet"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"No permetis"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi activada en mode d\'avió"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Si tens activada la Wi‑Fi, el telèfon recordarà mantenir-la així la pròxima vegada que utilitzis el mode d\'avió"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"La Wi‑Fi es manté activada"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"El telèfon recorda mantenir la Wi‑Fi activada en mode d\'avió. Desactiva la Wi‑Fi si no vols que es quedi activada."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Xarxa no disponible"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"L\'administrador ha desactivat <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Tanca"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi activada en mode d\'avió"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"La Wi‑Fi es manté activada"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-cs/strings.xml b/service/ServiceWifiResources/res/values-cs/strings.xml
index 895cbfc7a9..97bdde85a3 100644
--- a/service/ServiceWifiResources/res/values-cs/strings.xml
+++ b/service/ServiceWifiResources/res/values-cs/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Wi‑Fi můžete vypnout v Rychlém nastavení"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Povolit"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Nepovolovat"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Zapnutá Wi-Fi v režimu Letadlo"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Pokud Wi-Fi necháte zapnutou, telefon si zapamatuje, že ji má příště v režimu Letadlo ponechat zapnutou"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi zůstane zapnutá"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefon si pamatuje, že má v režimu Letadlo ponechat zapnutou Wi-Fi. Pokud nechcete, aby Wi-Fi zůstala zapnutá, vypněte ji."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Nedostupná síť"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Funkce <xliff:g id="SSID">%1$s</xliff:g> byla deaktivována administrátorem."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Zavřít"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Zapnutá Wi-Fi v režimu Letadlo"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi zůstane zapnutá"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-da/strings.xml b/service/ServiceWifiResources/res/values-da/strings.xml
index 570662b0af..9a598594fc 100644
--- a/service/ServiceWifiResources/res/values-da/strings.xml
+++ b/service/ServiceWifiResources/res/values-da/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Du kan deaktivere Wi‑Fi via kvikmenuen"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Tillad"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Tillad ikke"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi aktiveret i flytilstand"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Hvis du holder Wi-Fi aktiveret, sørger din telefon for, at Wi-Fi forbliver aktiveret, næste gang du sætter den til flytilstand"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi forbliver aktiv"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Din telefon holder Wi-Fi aktiveret i flytilstand. Deaktiver Wi-Fi, hvis du ikke vil have, at det forbliver aktiveret."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Utilgængeligt netværk"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> er blevet deaktiveret af din administrator."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Luk"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi aktiveret i flytilstand"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi forbliver aktiv"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-de/strings.xml b/service/ServiceWifiResources/res/values-de/strings.xml
index f98966269f..e19de9096a 100644
--- a/service/ServiceWifiResources/res/values-de/strings.xml
+++ b/service/ServiceWifiResources/res/values-de/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Das WLAN kannst du in den Schnelleinstellungen deaktivieren"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Zulassen"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Nicht zulassen"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WLAN im Flugzeugmodus"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Wenn das WLAN aktiviert bleibt, lässt es dein Smartphone eingeschaltet, wenn du das nächste Mal in den Flugmodus wechselst"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WLAN bleibt eingeschaltet"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Dein Smartphone lässt das WLAN im Flugmodus eingeschaltet. Schalte das WLAN aus, wenn du das nicht möchtest."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Nicht verfügbares Netzwerk"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Die Funktion „<xliff:g id="SSID">%1$s</xliff:g>“ wurde von deinem Administrator deaktiviert."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Schließen"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WLAN im Flugzeugmodus"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WLAN bleibt eingeschaltet"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-el/strings.xml b/service/ServiceWifiResources/res/values-el/strings.xml
index 6ff37212db..114f9949fb 100644
--- a/service/ServiceWifiResources/res/values-el/strings.xml
+++ b/service/ServiceWifiResources/res/values-el/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Μπορείτε να απενεργοποιήσετε το Wi‑Fi από τις Γρήγορες ρυθμίσεις"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Να επιτρέπεται"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Να μην επιτρέπεται"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ενεργό σε λειτουργία πτήσης"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Αν διατηρήσετε το Wi‑Fi ενεργοποιημένο, το τηλέφωνό σας θα θυμάται να το διατηρήσει ενεργοποιημένο την επόμενη φορά που θα βρεθεί σε λειτουργία πτήσης"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Το Wi‑Fi παραμένει ενεργό"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Το τηλέφωνο θυμάται να διατηρεί ενεργοποιημένο το Wi‑Fi σε λειτουργία πτήσης. Απενεργοποιήστε το Wi‑Fi, αν δεν επιθυμείτε να είναι ενεργοποιημένο."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Μη διαθέσιμο δίκτυο"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Το <xliff:g id="SSID">%1$s</xliff:g> έχει απενεργοποιηθεί από τον διαχειριστή σας."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Κλείσιμο"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ενεργό σε λειτουργία πτήσης"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Το Wi‑Fi παραμένει ενεργό"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-en-rAU/strings.xml b/service/ServiceWifiResources/res/values-en-rAU/strings.xml
index 61a990664d..7928067642 100644
--- a/service/ServiceWifiResources/res/values-en-rAU/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rAU/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"You can turn off Wi‑Fi in Quick Settings"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Allow"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Don\'t allow"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi on in aeroplane mode"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"If you keep Wi‑Fi on, your phone will remember to keep it on the next time that you\'re in aeroplane mode"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi stays on"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Your phone remembers to keep Wi‑Fi on in aeroplane mode. Turn off Wi‑Fi if you don\'t want it to stay on."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Unavailable network"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> is disabled by your administrator."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Close"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi on in aeroplane mode"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi stays on"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-en-rCA/strings.xml b/service/ServiceWifiResources/res/values-en-rCA/strings.xml
index 057cdc7453..2ed55cbe01 100644
--- a/service/ServiceWifiResources/res/values-en-rCA/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rCA/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"You can turn off Wi‑Fi in Quick Settings"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Allow"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Don\'t allow"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi on in airplane mode"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"If you keep Wi‑Fi on, your phone will remember to keep it on the next time you\'re in airplane mode"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi stays on"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Your phone remembers to keep Wi‑Fi on in airplane mode. Turn off Wi‑Fi if you don\'t want it to stay on."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Unavailable Network"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> is disabled by your administrator."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Close"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi on in airplane mode"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi stays on"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-en-rGB/strings.xml b/service/ServiceWifiResources/res/values-en-rGB/strings.xml
index 61a990664d..7928067642 100644
--- a/service/ServiceWifiResources/res/values-en-rGB/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rGB/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"You can turn off Wi‑Fi in Quick Settings"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Allow"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Don\'t allow"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi on in aeroplane mode"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"If you keep Wi‑Fi on, your phone will remember to keep it on the next time that you\'re in aeroplane mode"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi stays on"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Your phone remembers to keep Wi‑Fi on in aeroplane mode. Turn off Wi‑Fi if you don\'t want it to stay on."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Unavailable network"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> is disabled by your administrator."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Close"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi on in aeroplane mode"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi stays on"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-en-rIN/strings.xml b/service/ServiceWifiResources/res/values-en-rIN/strings.xml
index 61a990664d..7928067642 100644
--- a/service/ServiceWifiResources/res/values-en-rIN/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rIN/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"You can turn off Wi‑Fi in Quick Settings"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Allow"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Don\'t allow"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi on in aeroplane mode"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"If you keep Wi‑Fi on, your phone will remember to keep it on the next time that you\'re in aeroplane mode"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi stays on"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Your phone remembers to keep Wi‑Fi on in aeroplane mode. Turn off Wi‑Fi if you don\'t want it to stay on."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Unavailable network"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> is disabled by your administrator."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Close"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi on in aeroplane mode"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi stays on"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-en-rXC/strings.xml b/service/ServiceWifiResources/res/values-en-rXC/strings.xml
index f1a9c7ef06..387326a64a 100644
--- a/service/ServiceWifiResources/res/values-en-rXC/strings.xml
+++ b/service/ServiceWifiResources/res/values-en-rXC/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎You can turn off Wi‑Fi in Quick Settings‎‏‎‎‏‎"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎Allow‎‏‎‎‏‎"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎Don\'t allow‎‏‎‎‏‎"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎Wi‑Fi on in airplane mode‎‏‎‎‏‎"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎If you keep Wi‑Fi on, your phone will remember to keep it on the next time you\'re in airplane mode‎‏‎‎‏‎"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎Wi‑Fi stays on‎‏‎‎‏‎"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎Your phone remembers to keep Wi‑Fi on in airplane mode. Turn off Wi‑Fi if you don\'t want it to stay on.‎‏‎‎‏‎"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎Unavailable Network‎‏‎‎‏‎"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="SSID">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is disabled by your administrator.‎‏‎‎‏‎"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎Close‎‏‎‎‏‎"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎Wi‑Fi on in airplane mode‎‏‎‎‏‎"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎Wi‑Fi stays on‎‏‎‎‏‎"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-es-rUS/strings.xml b/service/ServiceWifiResources/res/values-es-rUS/strings.xml
index f8af29acaa..47d90767ad 100644
--- a/service/ServiceWifiResources/res/values-es-rUS/strings.xml
+++ b/service/ServiceWifiResources/res/values-es-rUS/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Puedes desactivar el Wi‑Fi en la Configuración rápida"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Permitir"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"No permitir"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi activado en modo de avión"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Si mantienes el Wi-Fi activado, tu teléfono recordará mantenerlo activado la próxima vez que actives el modo de avión"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"El Wi-Fi permanece activado"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"El teléfono dejará activado el Wi-Fi en el modo de avión. Desactiva el Wi-Fi si no quieres permanecer conectado."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Red no disponible"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Tu administrador inhabilitó <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Cerrar"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi activado en modo de avión"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"El Wi-Fi permanece activado"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-es/strings.xml b/service/ServiceWifiResources/res/values-es/strings.xml
index 29464d4922..1e3005e397 100644
--- a/service/ServiceWifiResources/res/values-es/strings.xml
+++ b/service/ServiceWifiResources/res/values-es/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Puedes desactivar la Wi‑Fi en los ajustes rápidos"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Permitir"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"No permitir"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi activado en modo Avión"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Si dejas el Wi-Fi activado, tu teléfono se acordará de dejarlo así la próxima vez que uses el modo Avión"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"El Wi‑Fi se mantiene activado"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Tu teléfono dejará el Wi-Fi activado en modo Avión. Desactiva el Wi-Fi si no quieres que se quede activado."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Red no disponible"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Tu administrador ha inhabilitado <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Cerrar"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi activado en modo Avión"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"El Wi‑Fi se mantiene activado"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-et/strings.xml b/service/ServiceWifiResources/res/values-et/strings.xml
index 2a28aa6cd6..5731347c6f 100644
--- a/service/ServiceWifiResources/res/values-et/strings.xml
+++ b/service/ServiceWifiResources/res/values-et/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"WiFi saab välja lülitada kiirseadetes"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Luba"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Ära luba"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WiFi on lennukirežiimis sisse lülitatud"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Kui hoiate WiFi sisselülitatuna, jätab telefon teie valiku meelde ja kasutab seda järgmisel korral lennukirežiimi aktiveerimisel."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WiFi jääb sisselülitatuks"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Teie telefon hoiab WiFi lennukirežiimis sisselülitatuna. Lülitage WiFi välja, kui te ei soovi, et see oleks sisse lülitatud."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Võrk ei ole saadaval"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Administraator on funktsiooni <xliff:g id="SSID">%1$s</xliff:g> keelanud."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Sule"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WiFi on lennukirežiimis sisse lülitatud"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WiFi jääb sisselülitatuks"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-eu/strings.xml b/service/ServiceWifiResources/res/values-eu/strings.xml
index 08ca5d0cb4..c069373bc2 100644
--- a/service/ServiceWifiResources/res/values-eu/strings.xml
+++ b/service/ServiceWifiResources/res/values-eu/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Ezarpen bizkorrak erabil ditzakezu wifia desaktibatzeko"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Eman baimena"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Ez eman baimenik"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wifia aktibatuta hegaldi moduan"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Wifia aktibatuta utziz gero, hura aktibatuta mantentzeaz gogoratuko da telefonoa hegaldi modua erabiltzen duzun hurrengoan"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wifia aktibatuta mantentzen da"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Hegaldi moduan, wifia aktibatuta mantentzeaz gogoratzen da telefonoa. Halakorik nahi ez baduzu, desaktiba ezazu zuk zeuk."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Sarea ez dago erabilgarri"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Administratzaileak desgaitu du <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Itxi"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wifia aktibatuta hegaldi moduan"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wifia aktibatuta mantentzen da"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-fa/strings.xml b/service/ServiceWifiResources/res/values-fa/strings.xml
index 1688041b0e..9256b778ed 100644
--- a/service/ServiceWifiResources/res/values-fa/strings.xml
+++ b/service/ServiceWifiResources/res/values-fa/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"‏می‌توانید Wi‑Fi را در «تنظیمات فوری» خاموش کنید"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"اجازه دادن"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"اجازه ندادن"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‏‫Wi‑Fi در «حالت هواپیما» روشن باشد"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"‏اگر Wi-Fi را روشن نگه دارید، تلفنتان به‌یاد خواهد داشت تا دفعه بعدی که در «حالت هواپیما» هستید آن را روشن نگه دارد"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‏‫Wi-Fi روشن بماند"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"‏تلفنتان به‌یاد می‌آورد که Wi-Fi را در حالت هواپیما روشن نگه دارد. اگر نمی‌خواهید Wi-Fi روشن بماند، آن را خاموش کنید."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"شبکه غیرقابل‌دسترس"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"سرپرست شما <xliff:g id="SSID">%1$s</xliff:g> را غیرفعال کرده است."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"بستن"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‏‫Wi‑Fi در «حالت هواپیما» روشن باشد"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‏‫Wi-Fi روشن بماند"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-fi/strings.xml b/service/ServiceWifiResources/res/values-fi/strings.xml
index 698d951763..754ed048b6 100644
--- a/service/ServiceWifiResources/res/values-fi/strings.xml
+++ b/service/ServiceWifiResources/res/values-fi/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Voit laittaa Wi-Fi-yhteyden pois päältä pika-asetuksista"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Salli"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Älä salli"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi päällä lentokonetilassa"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Jos pidät Wi-Fi-yhteyden päällä, puhelin pitää sen päällä, kun seuraavan kerran olet lentokonetilassa"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi pysyy päällä"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Puhelimen Wi-Fi-yhteys pysyy päällä lentokonetilassa. Voit halutessasi laittaa Wi-Fi-yhteyden pois päältä."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Verkko ei ole käytettävissä"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> on järjestelmänvalvojan käytöstä poistama."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Sulje"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi päällä lentokonetilassa"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi pysyy päällä"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-fr-rCA/strings.xml b/service/ServiceWifiResources/res/values-fr-rCA/strings.xml
index cc081880f5..18c75c2260 100644
--- a/service/ServiceWifiResources/res/values-fr-rCA/strings.xml
+++ b/service/ServiceWifiResources/res/values-fr-rCA/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Vous pouvez désactiver le Wi-Fi dans les Paramètres rapides"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Autoriser"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Ne pas autoriser"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi activé en mode Avion"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Si vous laissez le Wi-Fi activé, votre téléphone se rappellera qu\'il doit le laisser activé la prochaine fois que vous serez en mode Avion"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Le Wi‑Fi reste activé"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Votre téléphone se rappelle de garder le Wi-Fi activé en mode Avion. Désactivez le Wi-Fi si vous ne voulez pas qu\'il reste allumé."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Réseau indisponible"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Fonctionnalité <xliff:g id="SSID">%1$s</xliff:g> désactivée par votre administrateur."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Fermer"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi activé en mode Avion"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Le Wi‑Fi reste activé"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-fr/strings.xml b/service/ServiceWifiResources/res/values-fr/strings.xml
index 1701a10937..4affffb978 100644
--- a/service/ServiceWifiResources/res/values-fr/strings.xml
+++ b/service/ServiceWifiResources/res/values-fr/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Vous pouvez désactiver le Wi‑Fi dans \"Réglages rapides\""</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Autoriser"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Ne pas autoriser"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi activé en mode Avion"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Si vous laissez le Wi-Fi activé, votre téléphone s\'en souviendra et le Wi-Fi restera activé la prochaine fois que vous serez en mode Avion"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Le Wi‑Fi reste activé"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Le Wi‑Fi de votre téléphone restera activé en mode Avion. Désactivez le Wi-Fi si ce paramètre ne vous convient pas."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Réseau indisponible"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> est désactivé par votre administrateur."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Fermer"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi activé en mode Avion"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Le Wi‑Fi reste activé"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-gl/strings.xml b/service/ServiceWifiResources/res/values-gl/strings.xml
index 6f0f6055e8..802b08b1d3 100644
--- a/service/ServiceWifiResources/res/values-gl/strings.xml
+++ b/service/ServiceWifiResources/res/values-gl/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Podes desactivar a wifi en Configuración rápida"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Permitir"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Non permitir"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"A wifi está activada no modo avión"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Se mantés a wifi activada, o teléfono lembrará que ten que deixala nese estado a próxima vez que esteas no modo avión"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"A wifi permanece activada"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"O teléfono lembrará manter a wifi activada no modo avión. Desactívaa se non queres que permaneza activada."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Rede non dispoñible"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"O teu administrador desactivou a rede <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Pechar"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"A wifi está activada no modo avión"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"A wifi permanece activada"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-gu/strings.xml b/service/ServiceWifiResources/res/values-gu/strings.xml
index e662e3f22d..6f54c062e1 100644
--- a/service/ServiceWifiResources/res/values-gu/strings.xml
+++ b/service/ServiceWifiResources/res/values-gu/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"તમે ઝડપી સેટિંગમાં જઈને વાઇ-ફાઇ બંધ કરી શકો છો"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"મંજૂરી આપો"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"મંજૂરી આપશો નહીં"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"એરપ્લેન મોડમાં વાઇ-ફાઇ ચાલુ રહેશે"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"જો તમે વાઇ-ફાઇ ચાલુ રાખો, તો તમે જ્યારે આગલી વખતે એરપ્લેન મોડ પર જશો, ત્યારે તમારો ફોન તેને ચાલુ રાખવાનું યાદ રાખશે"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"વાઇ-ફાઇ ચાલુ રહેશે"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"તમારો ફોન વાઇ-ફાઇને એરપ્લેન મોડમાં ચાલુ રાખવાનું યાદ રાખે છે. જો તમે વાઇ-ફાઇ ચાલુ રાખવા માગતા ન હો, તો તેને બંધ કરો."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"નેટવર્ક ઉપલબ્ધ નથી"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g>ને તમારા ઍડમિનિસ્ટ્રેટર દ્વારા બંધ કરવામાં આવ્યું છે."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"બંધ કરો"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"એરપ્લેન મોડમાં વાઇ-ફાઇ ચાલુ રહેશે"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"વાઇ-ફાઇ ચાલુ રહેશે"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-hi/strings.xml b/service/ServiceWifiResources/res/values-hi/strings.xml
index dc0411c165..32fca99e29 100644
--- a/service/ServiceWifiResources/res/values-hi/strings.xml
+++ b/service/ServiceWifiResources/res/values-hi/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"\'फटाफट सेटिंग\' में जाकर, वाई-फ़ाई बंद किया जा सकता है"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"अनुमति दें"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"अनुमति न दें"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"हवाई जहाज़ मोड में वाई-फ़ाई चालू रहेगा"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"वाई-फ़ाई चालू रखने पर आपका फ़ोन, अगली बार हवाई जहाज़ मोड चालू होने पर भी वाई-फ़ाई चालू रखेगा"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"वाई-फ़ाई चालू रहेगा"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"हवाई जहाज़ मोड में भी आपका फ़ोन वाई-फ़ाई चालू रखता है. अगर वाई-फ़ाई चालू नहीं रखना है, तो उसे बंद कर दें."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"नेटवर्क उपलब्ध नहीं है"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"आपके एडमिन ने <xliff:g id="SSID">%1$s</xliff:g> को बंद किया हुआ है."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"बंद करें"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"हवाई जहाज़ मोड में वाई-फ़ाई चालू रहेगा"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"वाई-फ़ाई चालू रहेगा"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-hr/strings.xml b/service/ServiceWifiResources/res/values-hr/strings.xml
index c41836c5d7..efc69d0e94 100644
--- a/service/ServiceWifiResources/res/values-hr/strings.xml
+++ b/service/ServiceWifiResources/res/values-hr/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Wi‑Fi možete isključiti u brzim postavkama"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Dopusti"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Nemoj dopustiti"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi je uključen u načinu rada u zrakoplovu"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ako Wi-Fi ostane uključen, telefon će zapamtiti da treba ostati uključen u načinu rada u zrakoplovu"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi ostaje uključen"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefon će zapamtiti da Wi‑Fi treba ostati uključen u načinu rada u zrakoplovu. Isključite Wi-Fi ako ne želite da ostane uključen."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Mreža nije dostupna"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Značajku <xliff:g id="SSID">%1$s</xliff:g> onemogućio je vaš administrator."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Zatvori"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi je uključen u načinu rada u zrakoplovu"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi ostaje uključen"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-hu/strings.xml b/service/ServiceWifiResources/res/values-hu/strings.xml
index 438c32d3f1..26224decf8 100644
--- a/service/ServiceWifiResources/res/values-hu/strings.xml
+++ b/service/ServiceWifiResources/res/values-hu/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"A Wi‑Fi-t a Gyorsbeállításokban kapcsolhatja ki"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Engedélyezés"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Tiltás"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"A Wi‑Fi bekapcsolva marad Repülős üzemmódban"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ha bekapcsolva tartja a Wi-Fi-t, a telefon emlékezni fog arra, hogy a következő alkalommal, amikor Repülős üzemmódban van, bekapcsolva tartsa a funkciót"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"A Wi‑Fi bekapcsolva marad"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"A telefon bekapcsolva tartja a Wi‑Fi-t Repülős üzemmódban. Kapcsolja ki a Wi-Fi-t, ha nem szeretné, hogy bekapcsolva maradjon."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Hozzáférhetetlen hálózat"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> letiltva a rendszergazda által."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Bezárás"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"A Wi‑Fi bekapcsolva marad Repülős üzemmódban"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"A Wi‑Fi bekapcsolva marad"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-hy/strings.xml b/service/ServiceWifiResources/res/values-hy/strings.xml
index 8c3d758bd5..282b0f7382 100644
--- a/service/ServiceWifiResources/res/values-hy/strings.xml
+++ b/service/ServiceWifiResources/res/values-hy/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Wi‑Fi-ը կարող եք անջատել Արագ կարգավորումներում"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Թույլատրել"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Չթույլատրել"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Ավիառեժիմում Wi‑Fi-ը միացված կլինի"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Եթե Wi-Fi-ը միացված թողնեք, հաջորդ անգամ այն ավտոմատ միացված կմնա ավիառեժիմում"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi-ը մնում է միացված"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Ավիառեժիմում Wi‑Fi-ը միացված կմնա։ Ցանկության դեպքում կարող եք անջատել Wi-Fi-ը։"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Անհասանելի ցանց"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Ադմինիստրատորն անջատել է <xliff:g id="SSID">%1$s</xliff:g> գործառույթը։"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Փակել"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Ավիառեժիմում Wi‑Fi-ը միացված կլինի"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi-ը մնում է միացված"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-in/strings.xml b/service/ServiceWifiResources/res/values-in/strings.xml
index 6ba3e6e5e9..0515dc6ee1 100644
--- a/service/ServiceWifiResources/res/values-in/strings.xml
+++ b/service/ServiceWifiResources/res/values-in/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Anda dapat menonaktifkan Wi‑Fi di Setelan Cepat"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Izinkan"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Jangan izinkan"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi aktif dalam mode pesawat"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Jika Wi-Fi tetap diaktifkan, ponsel akan ingat untuk tetap mengaktifkannya saat berikutnya ponsel Anda disetel ke mode pesawat"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi tetap aktif"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Ponsel akan ingat untuk tetap mengaktifkan Wi-Fi dalam mode pesawat. Nonaktifkan jika Anda tidak ingin Wi-Fi terus aktif."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Jaringan Tidak Tersedia"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> dinonaktifkan oleh administrator Anda."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Tutup"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi aktif dalam mode pesawat"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi tetap aktif"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-is/strings.xml b/service/ServiceWifiResources/res/values-is/strings.xml
index 575a11580f..f12cee7c04 100644
--- a/service/ServiceWifiResources/res/values-is/strings.xml
+++ b/service/ServiceWifiResources/res/values-is/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Þú getur slökkt á WiFi í flýtistillingum"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Leyfa"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Ekki leyfa"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Kveikt á Wi‑Fi í flugstillingu"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ef þú hefur kveikt á Wi-Fi mun síminn muna að hafa kveikt á því næst þegar þú stillir á flugstillingu"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Áfram kveikt á Wi‑Fi"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Síminn man að hafa kveikt á Wi-Fi í flugstillingu. Slökktu á Wi-Fi ef þú vilt ekki hafa kveikt á því."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Netkerfi ekki tiltækt"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Stjórnandinn hefur slökkt á <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Loka"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Kveikt á Wi‑Fi í flugstillingu"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Áfram kveikt á Wi‑Fi"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-it/strings.xml b/service/ServiceWifiResources/res/values-it/strings.xml
index 651d0e55f5..2ddce7387a 100644
--- a/service/ServiceWifiResources/res/values-it/strings.xml
+++ b/service/ServiceWifiResources/res/values-it/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Puoi disattivare il Wi‑Fi nelle Impostazioni rapide"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Consenti"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Non consentire"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi attivo in modalità aereo"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Se tieni attivo il Wi-fi, il telefono ricorderà di mantenerlo attivo la prossima volta che sarai in modalità aereo"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Il Wi-Fi rimane attivo"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Il telefono ricorda di mantenere attivo il Wi‑Fi in modalità aereo. Disattiva il Wi-Fi se non vuoi che resti attivo."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Rete non disponibile"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"L\'amministratore ha disattivato la funzionalità <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Chiudi"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi attivo in modalità aereo"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Il Wi-Fi rimane attivo"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-iw/strings.xml b/service/ServiceWifiResources/res/values-iw/strings.xml
index 1b6dcc6cb4..12cd714240 100644
--- a/service/ServiceWifiResources/res/values-iw/strings.xml
+++ b/service/ServiceWifiResources/res/values-iw/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"‏אפשר לכבות את ה-Wi-Fi בהגדרות המהירות"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"אישור"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"אין אישור"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‏Wi‑Fi מופעל במצב טיסה"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"‏אם חיבור ה-Wi‑Fi נשאר מופעל, הטלפון יזכור להשאיר אותו מופעל בפעם הבאה שהוא יועבר למצב טיסה"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‏חיבור ה-Wi‑Fi יישאר מופעל"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"‏חיבור ה-Wi‑Fi בטלפון יישאר מופעל במצב טיסה. אפשר להשבית את ה-Wi-Fi אם לא רוצים שהוא יפעל."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"רשת לא זמינה"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"האדמין השבית את <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"סגירה"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‏Wi‑Fi מופעל במצב טיסה"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‏חיבור ה-Wi‑Fi יישאר מופעל"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ja/strings.xml b/service/ServiceWifiResources/res/values-ja/strings.xml
index c4054439e9..f3613231f3 100644
--- a/service/ServiceWifiResources/res/values-ja/strings.xml
+++ b/service/ServiceWifiResources/res/values-ja/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"クイック設定で Wi‑Fi を OFF にできます"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"許可"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"許可しない"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"機内モードで Wi-Fi を ON"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Wi-Fi を ON にしておくと、次に機内モードになったときも ON のままになります"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi を ON のままにする"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"機内モードでも、スマートフォンの Wi-Fi は ON のままになります。Wi-Fi を ON にしたくない場合は OFF にしてください。"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"使用できないネットワーク"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> は管理者によって無効にされています。"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"閉じる"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"機内モードで Wi-Fi を ON"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi を ON のままにする"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ka/strings.xml b/service/ServiceWifiResources/res/values-ka/strings.xml
index e643cf6a14..cd6bc0944b 100644
--- a/service/ServiceWifiResources/res/values-ka/strings.xml
+++ b/service/ServiceWifiResources/res/values-ka/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"შეგიძლიათ, გამორთოთ Wi-Fi სწრაფი პარამეტრებიდან"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"დაშვება"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"აკრძალვა"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ჩართულია თვითმფრინავის რეჟიმში"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"თუ Wi‑Fi-ს ჩართულს დატოვებთ, თქვენი ტელეფონი დაიმახსოვრებს და ჩართულს დატოვებს, როდესაც შემდგომში თვითმფრინავის რეჟიმში იქნებით"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi კვლავ ჩართულია"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"თქვენს ტელეფონს ემახსოვრება, რომ Wi‑Fi ჩართული უნდა იყოს თვითმფრინავის რეჟიმში. Wi‑Fi if-ის გამორთვა, თუ არ გსურთ ჩართული დატოვოთ."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"ქსელი მიუწვდომელია"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> გათიშულია თქვენი ადმინისტრატორის მიერ."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"დახურვა"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ჩართულია თვითმფრინავის რეჟიმში"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi კვლავ ჩართულია"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-kk/strings.xml b/service/ServiceWifiResources/res/values-kk/strings.xml
index af1817ef49..e4b82af8cf 100644
--- a/service/ServiceWifiResources/res/values-kk/strings.xml
+++ b/service/ServiceWifiResources/res/values-kk/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Wi‑Fi-ды \"Жылдам параметрлер\" бөлімінде өшіре аласыз."</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Рұқсат беру"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Рұқсат бермеу"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ұшақ режимінде қосулы болады"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Wi‑Fi қосулы болса, ол келесіде телефондағы ұшақ режимінде қосулы болады."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi қосулы тұрады"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Телефондағы Wi‑Fi ұшақ режимінде қосулы болады. Wi‑Fi желісінің қосулы тұрғанын қаламасаңыз, оны өшіріңіз."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Қолжетімсіз желі"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> әкімші тарапынан өшірілді."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Жабу"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ұшақ режимінде қосулы болады"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi қосулы тұрады"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-km/strings.xml b/service/ServiceWifiResources/res/values-km/strings.xml
index 6e6ea9a651..60236be653 100644
--- a/service/ServiceWifiResources/res/values-km/strings.xml
+++ b/service/ServiceWifiResources/res/values-km/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"អ្នកអាច​បិទ Wi‑Fi នៅក្នុង​ការកំណត់រហ័ស"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"អនុញ្ញាត"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"មិនអនុញ្ញាត"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"បើក ​​Wi-Fi នៅក្នុងមុខងារពេល​ជិះ​យន្តហោះ"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"ប្រសិនបើអ្នកបន្តបើក Wi‑Fi នោះទូរសព្ទរបស់អ្នកនឹងចាំថាត្រូវបន្តបើកវា នៅលើកក្រោយដែលអ្នកស្ថិតក្នុងមុខងារពេលជិះយន្តហោះ"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi នៅ​តែ​បើក"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"ទូរសព្ទរបស់អ្នកចាំថាត្រូវបន្តបើក Wi-Fi នៅក្នុងមុខងារពេលជិះយន្តហោះ។ បិទ Wi‑Fi ប្រសិនបើអ្នកមិនចង់ឱ្យវាបន្តបើក។"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"បណ្ដាញ​មិន​អាច​ប្រើ​បាន"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> ត្រូវបានបិទ​ដោយអ្នកគ្រប់គ្រង​របស់អ្នក។"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"បិទ"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"បើក ​​Wi-Fi នៅក្នុងមុខងារពេល​ជិះ​យន្តហោះ"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi នៅ​តែ​បើក"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-kn/strings.xml b/service/ServiceWifiResources/res/values-kn/strings.xml
index 34e8d407c0..bac4a72928 100644
--- a/service/ServiceWifiResources/res/values-kn/strings.xml
+++ b/service/ServiceWifiResources/res/values-kn/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳಲ್ಲಿ ನೀವು ವೈ-ಫೈ ಅನ್ನು ಆಫ್ ಮಾಡಬಹುದು"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"ಅನುಮತಿಸಿ"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"ಅನುಮತಿಸಬೇಡಿ"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ವೈ-ಫೈ ಆನ್ ಆಗಿದೆ"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"ನೀವು ವೈ-ಫೈ ಆನ್ ಮಾಡಿದರೆ, ಮುಂದಿನ ಬಾರಿ ನೀವು ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿರುವಾಗ ಅದನ್ನು ಆನ್ ಮಾಡಲು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"ವೈ-ಫೈ ಆನ್ ಇರುತ್ತದೆ"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"ವೈ-ಫೈ ಅನ್ನು ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಇರಿಸಿಕೊಳ್ಳಲು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿನಲ್ಲಿರಿಸಿಕೊಳ್ಳುತ್ತದೆ. ವೈ-ಫೈ ಆನ್ ಆಗಿರಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಅದನ್ನು ಆಫ್ ಮಾಡಿ."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"ನೆಟ್‌ವರ್ಕ್ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> ಅನ್ನು ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"ಮುಚ್ಚಿರಿ"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ವೈ-ಫೈ ಆನ್ ಆಗಿದೆ"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"ವೈ-ಫೈ ಆನ್ ಇರುತ್ತದೆ"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ko/strings.xml b/service/ServiceWifiResources/res/values-ko/strings.xml
index 98b5dc6728..656cf1b5c8 100644
--- a/service/ServiceWifiResources/res/values-ko/strings.xml
+++ b/service/ServiceWifiResources/res/values-ko/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"빠른 설정에서 Wi‑Fi를 끌 수 있습니다."</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"허용"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"허용 안함"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"비행기 모드에서 Wi-Fi 사용"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Wi-Fi를 켜진 상태로 유지하면 다음에 비행기 모드를 사용할 때도 Wi-Fi 연결이 유지됩니다."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi가 켜진 상태로 유지됨"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"휴대전화가 비행기 모드에서 Wi-Fi를 켜진 상태로 유지합니다. 유지하지 않으려면 Wi-Fi를 사용 중지하세요."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"사용할 수 없는 네트워크"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g>이(가) 관리자에 의해 사용 중지되었습니다."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"닫기"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"비행기 모드에서 Wi-Fi 사용"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi가 켜진 상태로 유지됨"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ky/strings.xml b/service/ServiceWifiResources/res/values-ky/strings.xml
index ce19b53812..0f0a12333c 100644
--- a/service/ServiceWifiResources/res/values-ky/strings.xml
+++ b/service/ServiceWifiResources/res/values-ky/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Wi‑Fi\'ды Ыкчам жөндөөлөрдөн өчүрсөңүз болот"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Уруксат берүү"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Тыюу салуу"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi учак режиминде күйгүзүлөт"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Эгер Wi-Fi күйүк бойдон калса, кийинки жолу учак режимине өткөнүңүздө телефонуңуз аны эстеп калат"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi күйгөн бойдон калат"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Телефонуңуз учак режиминде Wi‑Fi\'га туташкан бойдон калат. Кааласаңыз, Wi‑Fi\'ды өчүрүп койсоңуз болот."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Жеткиликсиз тармак"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> администраторуңуз тарабынан өчүрүлдү."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Жабуу"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi учак режиминде күйгүзүлөт"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi күйгөн бойдон калат"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-lo/strings.xml b/service/ServiceWifiResources/res/values-lo/strings.xml
index d580e25f51..aa19a5acf9 100644
--- a/service/ServiceWifiResources/res/values-lo/strings.xml
+++ b/service/ServiceWifiResources/res/values-lo/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"ທ່ານສາມາດປິດ Wi‑Fi ໄດ້ໃນການ​ຕັ້ງ​ຄ່າ​ດ່ວນ"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"ອະນຸຍາດ"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"ບໍ່ອະນຸຍາດ"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ເປີດຢູ່ໃນໂໝດຢູ່ໃນຍົນ"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"ຫາກທ່ານເປີດ Wi‑Fi ໄວ້, ໂທລະສັບຂອງທ່ານຈະຈື່ວ່າຕ້ອງເປີດ Wi‑Fi ໃນເທື່ອຕໍ່ໄປທີ່ທ່ານຢູ່ໃນໂໝດຢູ່ໃນຍົນ"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi ເປີດຢູ່"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"ໂທລະສັບຂອງທ່ານຈື່ວ່າຈະຕ້ອງເປີດ Wi-Fi ໄວ້ໃນໂໝດຢູ່ໃນຍົນ. ປິດ Wi‑Fi ຫາກທ່ານບໍ່ຕ້ອງການໃຫ້ເປີດມັນໄວ້."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"ບໍ່ສາມາດໃຊ້ເຄືອຂ່າຍໄດ້"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"ປິດ"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ເປີດຢູ່ໃນໂໝດຢູ່ໃນຍົນ"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi ເປີດຢູ່"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-lt/strings.xml b/service/ServiceWifiResources/res/values-lt/strings.xml
index 36db1ef849..25a48d4937 100644
--- a/service/ServiceWifiResources/res/values-lt/strings.xml
+++ b/service/ServiceWifiResources/res/values-lt/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"„Wi‑Fi“ galite išjungti sparčiuosiuose nustatymuose"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Leisti"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Neleisti"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"„Wi‑Fi“ ryšys įjungtas lėktuvo režimu"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Jei paliksite „Wi‑Fi“ ryšį įjungtą, telefonas, prisimins palikti jį įjungtą, kai kitą kartą įjungsite lėktuvo režimą"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"„Wi‑Fi“ lieka įjungtas"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefonas prisimena, kad lėktuvo režimu reikia palikti įjungtą „Wi‑Fi“ ryšį. Išjunkite „Wi‑Fi“, jei nenorite, kad jis liktų įjungtas."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Nepasiekiamas tinklas"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"„<xliff:g id="SSID">%1$s</xliff:g>“ išjungė administratorius."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Uždaryti"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"„Wi‑Fi“ ryšys įjungtas lėktuvo režimu"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"„Wi‑Fi“ lieka įjungtas"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-lv/strings.xml b/service/ServiceWifiResources/res/values-lv/strings.xml
index abd4905744..5fcff98237 100644
--- a/service/ServiceWifiResources/res/values-lv/strings.xml
+++ b/service/ServiceWifiResources/res/values-lv/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Varat izslēgt Wi-Fi savienojumu ātrajos iestatījumos."</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Atļaut"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Neatļaut"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ieslēgts lidojuma režīmā"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ja Wi‑Fi savienojums paliks ieslēgts, tālrunī tas paliks ieslēgts arī nākamreiz, kad ieslēgsiet lidojuma režīmu."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi joprojām ieslēgts"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Tālrunī joprojām būs ieslēgts Wi-Fi savienojums lidojuma režīmā. Izslēdziet Wi‑Fi savienojumu, ja nevēlaties, lai tas paliktu ieslēgts."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Nepieejams tīkls"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Administrators atspējoja tīklu <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Aizvērt"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ieslēgts lidojuma režīmā"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi joprojām ieslēgts"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-mk/strings.xml b/service/ServiceWifiResources/res/values-mk/strings.xml
index 8abed0719d..6827cbfdcb 100644
--- a/service/ServiceWifiResources/res/values-mk/strings.xml
+++ b/service/ServiceWifiResources/res/values-mk/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Може да го исклучите Wi‑Fi во „Брзи поставки“"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Дозволи"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Не дозволувај"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi е вклучено во авионски режим"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ако го оставите Wi‑Fi вклучено, телефонот ќе запомни да го остави вклучено до следниот пат кога ќе бидете во авионски режим"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi останува вклучено"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Телефонот помни да го остави Wi‑Fi вклучено во авионски режим. Исклучете го Wi‑Fi ако не сакате да остане вклучено."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Недостапна мрежа"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> е оневозможенa од вашиот администратор."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Затвори"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi е вклучено во авионски режим"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi останува вклучено"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ml/strings.xml b/service/ServiceWifiResources/res/values-ml/strings.xml
index da1ed6d4aa..b4c84577b7 100644
--- a/service/ServiceWifiResources/res/values-ml/strings.xml
+++ b/service/ServiceWifiResources/res/values-ml/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"ദ്രുത ക്രമീകരണത്തിൽ നിങ്ങൾക്ക് വൈഫൈ ഓഫാക്കാൻ കഴിയും"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"അനുവദിക്കുക"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"അനുവദിക്കരുത്"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ഫ്ലൈറ്റ് മോഡിൽ വൈഫൈ ഓണാണ്"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"വൈഫൈ ഓണാക്കി വച്ചാൽ, അടുത്ത തവണ നിങ്ങൾ ഫ്ലൈറ്റ് മോഡിൽ ആയിരിക്കുമ്പോൾ നിങ്ങളുടെ ഫോൺ അത് ഓണാക്കി വയ്ക്കാൻ ഓർക്കും"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"വൈഫൈ ഓണായിരിക്കും"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"ഫ്ലൈറ്റ് മോഡിലായിരിക്കുമ്പോൾ വൈഫൈ ഓണാക്കി വയ്ക്കാൻ നിങ്ങളുടെ ഫോൺ ഓർമ്മിക്കും. വൈഫൈ ഓണാക്കി വയ്ക്കാൻ താൽപ്പര്യമില്ലെങ്കിൽ അത് ഓഫാക്കുക."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"ലഭ്യമല്ലാത്ത നെറ്റ്‌വർക്ക്"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> നിങ്ങളുടെ അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"അടയ്ക്കുക"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ഫ്ലൈറ്റ് മോഡിൽ വൈഫൈ ഓണാണ്"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"വൈഫൈ ഓണായിരിക്കും"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-mn/strings.xml b/service/ServiceWifiResources/res/values-mn/strings.xml
index c940864362..2698812cc2 100644
--- a/service/ServiceWifiResources/res/values-mn/strings.xml
+++ b/service/ServiceWifiResources/res/values-mn/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Та Wi-Fi-г Шуурхай тохиргоо хэсэгт унтраах боломжтой"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Зөвшөөр"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Бүү зөвшөөр"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi нислэгийн горимд асаалттай"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Хэрэв та Wi-Fi-аа асаалттай байлгавал таныг дараагийн удаа нислэгийн горимд байх үед утас тань үүнийг асаалттай байлгахыг санана"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi асаалттай байна"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Таны утас Wi-Fi-г нислэгийн горимд асаалттай байлгахыг санана. Хэрэв та үүнийг асаалттай байлгахыг хүсэхгүй байвал Wi-Fi-г унтраана уу."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Боломжгүй сүлжээ"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g>-г танай администратор идэвхгүй болгосон."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Хаах"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi нислэгийн горимд асаалттай"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi асаалттай байна"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-mr/strings.xml b/service/ServiceWifiResources/res/values-mr/strings.xml
index c285271d66..edfa021713 100644
--- a/service/ServiceWifiResources/res/values-mr/strings.xml
+++ b/service/ServiceWifiResources/res/values-mr/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"तुम्ही क्विक सेटिंग्ज मध्ये वाय-फाय बंद करू शकता"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"अनुमती द्या"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"अनुमती देऊ नका"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"विमान मोडमध्ये वाय-फाय सुरू आहे"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"तुम्ही वाय-फाय सुरू ठेवल्यास, पुढील वेळी विमान मोडमध्ये असाल, तेव्हा तुमचा फोन ते सुरू ठेवण्याचे लक्षात ठेवेल"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"वाय-फाय सुरू राहते"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"तुमचा फोन विमान मोडमध्ये वाय-फाय सुरू ठेवण्याचे लक्षात ठेवतो. तुम्हाला सुरू ठेवायचे नसल्यास, वाय-फाय बंद करा."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"उपलब्ध नसलेले नेटवर्क"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"तुमच्या अ‍ॅडमिनिस्ट्रेटर ने <xliff:g id="SSID">%1$s</xliff:g> बंद केले आहे."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"बंद करा"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"विमान मोडमध्ये वाय-फाय सुरू आहे"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"वाय-फाय सुरू राहते"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ms/strings.xml b/service/ServiceWifiResources/res/values-ms/strings.xml
index 930c49d16b..ed211b1901 100644
--- a/service/ServiceWifiResources/res/values-ms/strings.xml
+++ b/service/ServiceWifiResources/res/values-ms/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Anda boleh mematikan Wi‑Fi dalam Tetapan Pantas"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Benarkan"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Jangan benarkan"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi dihidupkan dalam mod pesawat"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Jika anda terus menghidupkan Wi-Fi, telefon anda akan ingat untuk membiarkan Wi-Fi hidup pada kali seterusnya telefon anda berada dalam mod pesawat"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi terus dihidupkan"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefon anda diingatkan untuk terus menghidupkan Wi-Fi dalam mod pesawat. Matikan Wi‑Fi jika anda tidak mahu Wi‑Fi sentiasa hidup."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Rangkaian Tidak Tersedia"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> dilumpuhkan oleh pentadbir anda."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Tutup"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi dihidupkan dalam mod pesawat"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi terus dihidupkan"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-my/strings.xml b/service/ServiceWifiResources/res/values-my/strings.xml
index 9fc959273c..c31355f88a 100644
--- a/service/ServiceWifiResources/res/values-my/strings.xml
+++ b/service/ServiceWifiResources/res/values-my/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"‘အမြန် ဆက်တင်များ’ တွင် Wi‑Fi ပိတ်နိုင်သည်"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"ခွင့်ပြုရန်"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"ခွင့်မပြုပါ"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"လေယာဉ်ပျံမုဒ်တွင် Wi‑Fi ပွင့်နေသည်"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Wi‑Fi ဆက်ဖွင့်ထားပါက နောက်တစ်ကြိမ်လေယာဉ်ပျံမုဒ် သုံးချိန်တွင် ၎င်းဆက်ဖွင့်ရန် သင့်ဖုန်းက မှတ်ထားမည်။"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi ဆက်ပွင့်နေသည်"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"လေယာဉ်ပျံမုဒ်သုံးစဉ် Wi-Fi ဆက်ဖွင့်ထားရန် သင့်ဖုန်းက မှတ်မိသည်။ Wi‑Fi ဆက်ဖွင့်မထားလိုပါက ပိတ်နိုင်သည်။"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"ကွန်ရက်မရနိုင်ပါ"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"သင့်စီမံခန့်ခွဲသူက <xliff:g id="SSID">%1$s</xliff:g> ကို ပိတ်ထားသည်။"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"ပိတ်ရန်"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"လေယာဉ်ပျံမုဒ်တွင် Wi‑Fi ပွင့်နေသည်"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi ဆက်ပွင့်နေသည်"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-nb/strings.xml b/service/ServiceWifiResources/res/values-nb/strings.xml
index b9188a6373..dc7cd5ceb2 100644
--- a/service/ServiceWifiResources/res/values-nb/strings.xml
+++ b/service/ServiceWifiResources/res/values-nb/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Du kan slå av Wi‑Fi i hurtiginnstillingene"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Tillat"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Ikke tillat"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wifi på i flymodus"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Hvis du lar wifi være på, husker telefonen dette til den neste gangen du bruker flymodus"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wifi holdes på"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefonen husker å la wifi være påslått i flymodus. Du kan slå av wifi hvis du ikke vil la det være på."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Utilgjengelig nettverk"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Administratoren din har deaktivert <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Lukk"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wifi på i flymodus"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wifi holdes på"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ne/strings.xml b/service/ServiceWifiResources/res/values-ne/strings.xml
index b9e72840f5..fedf745227 100644
--- a/service/ServiceWifiResources/res/values-ne/strings.xml
+++ b/service/ServiceWifiResources/res/values-ne/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"तपाईं द्रुत सेटिङहरूमा गएर Wi‑Fi अफ गर्न सक्नुहुन्छ"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"अनुमति दिनुहोस्"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"अनुमति नदिनुहोस्"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"हवाइजहाज मोडमा Wi-Fi अन रहन्छ"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"तपाईंले Wi‑Fi अन राख्नुभयो भने तपाईंले फेरि हवाइजहाज मोड सेट गर्दा फोनले Wi-Fi अन राख्नु पर्ने कुरा याद राख्छ"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi अन रहन्छ"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"हवाइजहाज मोडमा पनि तपाईंको फोनमा Wi-Fi अन नै रहने छ। तपाईं Wi‑Fi अन भइनरहोस् भन्ने चाहनुहुन्छ भने अफ गर्नुहोस्।"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"नेटवर्क उपलब्ध छैन"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"तपाईंका एड्मिनले <xliff:g id="SSID">%1$s</xliff:g> अफ गर्नुभएको छ।"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"बन्द गर्नुहोस्"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"हवाइजहाज मोडमा Wi-Fi अन रहन्छ"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi अन रहन्छ"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-nl/strings.xml b/service/ServiceWifiResources/res/values-nl/strings.xml
index 53fc90e0e6..3f76368e65 100644
--- a/service/ServiceWifiResources/res/values-nl/strings.xml
+++ b/service/ServiceWifiResources/res/values-nl/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Je kunt wifi uitzetten via Snelle instellingen"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Toestaan"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Niet toestaan"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wifi aan in vliegtuigmodus"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Als je wifi laat aanstaan, onthoudt je telefoon dit en blijft de wifi aanstaan als je de vliegtuigmodus weer aanzet"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wifi blijft aan"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"De wifi op je telefoon blijft aan in de vliegtuigmodus. Zet wifi uit als je niet wilt dat dit aan blijft."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Niet-beschikbaar netwerk"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> is uitgezet door je beheerder."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Sluiten"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wifi aan in vliegtuigmodus"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wifi blijft aan"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-or/strings.xml b/service/ServiceWifiResources/res/values-or/strings.xml
index f210f4c2f6..02e25164a5 100644
--- a/service/ServiceWifiResources/res/values-or/strings.xml
+++ b/service/ServiceWifiResources/res/values-or/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"ଆପଣ କ୍ୱିକ ସେଟିଂସରେ ୱାଇ-ଫାଇ ବନ୍ଦ କରିପାରିବେ"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ଏୟାରପ୍ଲେନ ମୋଡରେ ୱାଇ-ଫାଇ ଚାଲୁ ଅଛି"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"ଯଦି ଆପଣ ୱାଇ-ଫାଇ ଚାଲୁ ରଖନ୍ତି, ତେବେ ଆପଣ ପରବର୍ତ୍ତୀ ଥର ଏୟାରପ୍ଲେନ ମୋଡରେ ଥିବା ସମୟରେ ଆପଣଙ୍କ ଫୋନ ଏହାକୁ ଚାଲୁ ରଖିବାକୁ ମନେ ରଖିବ"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"ୱାଇ-ଫାଇ ଚାଲୁ ରହିବ"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"ଆପଣଙ୍କ ଫୋନ ଏୟାରପ୍ଲେନ ମୋଡରେ ୱାଇ-ଫାଇ ଚାଲୁ ରଖିବାକୁ ମନେ ରଖେ। ଯଦି ଆପଣ ୱାଇ-ଫାଇ ଚାଲୁ ରଖିବାକୁ ଚାହାଁନ୍ତି ନାହିଁ ତେବେ ୱାଇ-ଫାଇ ବନ୍ଦ କରନ୍ତୁ।"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"ଅନୁପଲବ୍ଧ ନେଟୱାର୍କ"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g>କୁ ଆପଣଙ୍କ ଆଡମିନିଷ୍ଟ୍ରେଟରଙ୍କ ଦ୍ୱାରା ଅକ୍ଷମ କରାଯାଇଛି।"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"ବନ୍ଦ କରନ୍ତୁ"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ଏୟାରପ୍ଲେନ ମୋଡରେ ୱାଇ-ଫାଇ ଚାଲୁ ଅଛି"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"ୱାଇ-ଫାଇ ଚାଲୁ ରହିବ"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-pa/strings.xml b/service/ServiceWifiResources/res/values-pa/strings.xml
index 46b352de09..23fe0f388a 100644
--- a/service/ServiceWifiResources/res/values-pa/strings.xml
+++ b/service/ServiceWifiResources/res/values-pa/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"ਤੁਸੀਂ ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਵਾਈ-ਫਾਈ ਨੂੰ ਬੰਦ ਕਰ ਸਕਦੇ ਹੋ"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"ਆਗਿਆ ਦਿਓ"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"ਆਗਿਆ ਨਾ ਦਿਓ"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਵਾਈ-ਫਾਈ ਚਾਲੂ ਹੈ"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"ਜੇ ਤੁਸੀਂ ਵਾਈ-ਫਾਈ ਨੂੰ ਚਾਲੂ ਰੱਖਦੇ ਹੋ, ਤਾਂ ਅਗਲੀ ਵਾਰ ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਹੋਣ \'ਤੇ ਤੁਹਾਡਾ ਫ਼ੋਨ ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖੇਗਾ"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"ਵਾਈ-ਫਾਈ ਚਾਲੂ ਰਹੇਗਾ"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਵਾਈ-ਫਾਈ ਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇਸਨੂੰ ਚਾਲੂ ਨਹੀਂ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਵਾਈ-ਫਾਈ ਨੂੰ ਬੰਦ ਕਰੋ।"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ <xliff:g id="SSID">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ।"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"ਬੰਦ ਕਰੋ"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਵਾਈ-ਫਾਈ ਚਾਲੂ ਹੈ"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"ਵਾਈ-ਫਾਈ ਚਾਲੂ ਰਹੇਗਾ"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-pl/strings.xml b/service/ServiceWifiResources/res/values-pl/strings.xml
index 6a13a74fd2..78c38fbc66 100644
--- a/service/ServiceWifiResources/res/values-pl/strings.xml
+++ b/service/ServiceWifiResources/res/values-pl/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Możesz wyłączyć Wi‑Fi w Szybkich ustawieniach"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Zezwól"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Nie zezwalaj"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi włączone w trybie samolotowym"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Jeśli pozostawisz funkcję Wi‑Fi włączoną, telefon zachowa się podobnie przy kolejnym przejściu w tryb samolotowy"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi pozostanie włączone"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Wi-Fi na telefonie pozostaje włączone w trybie samolotowym. Wyłącz Wi‑Fi, jeśli nie chcesz, aby ta funkcja pozostała uruchomiona."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Niedostępna sieć"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Administrator wyłączył sieć <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Zamknij"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi włączone w trybie samolotowym"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi pozostanie włączone"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-pt-rBR/strings.xml b/service/ServiceWifiResources/res/values-pt-rBR/strings.xml
index 6b044eac0e..c5edab3235 100644
--- a/service/ServiceWifiResources/res/values-pt-rBR/strings.xml
+++ b/service/ServiceWifiResources/res/values-pt-rBR/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"É possível desativar o Wi-Fi nas Configurações rápidas"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Permitir"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Não permitir"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi ativado no modo avião"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Se você escolher manter o Wi‑Fi ligado, na próxima vez que você estiver em modo avião, o Wi-Fi do smartphone vai continuar ativado"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"O Wi-Fi fica ativado"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"O smartphone vai manter o Wi-Fi ligado no modo avião. Desligue o Wi‑Fi se você não quer que ele fique ativado."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Rede indisponível"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"O recurso <xliff:g id="SSID">%1$s</xliff:g> foi desativado pelo administrador."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Fechar"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi ativado no modo avião"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"O Wi-Fi fica ativado"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-pt-rPT/strings.xml b/service/ServiceWifiResources/res/values-pt-rPT/strings.xml
index 4ee0be601f..7ece8a8688 100644
--- a/service/ServiceWifiResources/res/values-pt-rPT/strings.xml
+++ b/service/ServiceWifiResources/res/values-pt-rPT/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Pode desativar o Wi‑Fi nas Definições rápidas"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Permitir"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Não permitir"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ativado no modo de avião"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Se mantiver o Wi‑Fi ativado, o telemóvel vai lembrar-se de o manter ativado da próxima vez que estiver no modo de avião"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"O Wi‑Fi mantém-se ativado"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"O seu telemóvel mantém o Wi-Fi ativado no modo de avião. Desative o Wi-Fi se não quiser que fique ativado."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Rede indisponível"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"O administrador desativou a funcionalidade <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Fechar"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi ativado no modo de avião"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"O Wi‑Fi mantém-se ativado"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-pt/strings.xml b/service/ServiceWifiResources/res/values-pt/strings.xml
index 6b044eac0e..c5edab3235 100644
--- a/service/ServiceWifiResources/res/values-pt/strings.xml
+++ b/service/ServiceWifiResources/res/values-pt/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"É possível desativar o Wi-Fi nas Configurações rápidas"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Permitir"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Não permitir"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi ativado no modo avião"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Se você escolher manter o Wi‑Fi ligado, na próxima vez que você estiver em modo avião, o Wi-Fi do smartphone vai continuar ativado"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"O Wi-Fi fica ativado"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"O smartphone vai manter o Wi-Fi ligado no modo avião. Desligue o Wi‑Fi se você não quer que ele fique ativado."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Rede indisponível"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"O recurso <xliff:g id="SSID">%1$s</xliff:g> foi desativado pelo administrador."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Fechar"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi-Fi ativado no modo avião"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"O Wi-Fi fica ativado"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ro/strings.xml b/service/ServiceWifiResources/res/values-ro/strings.xml
index bed936e8b9..8d50f9d424 100644
--- a/service/ServiceWifiResources/res/values-ro/strings.xml
+++ b/service/ServiceWifiResources/res/values-ro/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Poți dezactiva conexiunea Wi‑Fi din Setările rapide"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Permite"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Nu permite"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi activat în modul Avion"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Dacă păstrezi Wi‑Fi activat, telefonul tău va reține să-l păstreze activat data viitoare când ești în modul Avion"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Funcția Wi‑Fi rămâne activată"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefonul reține să păstreze funcția Wi-Fi activată în modul Avion. Dezactivează Wi‑Fi dacă nu vrei să rămână activat."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Rețea indisponibilă"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Administratorul a dezactivat <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Închide"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi activat în modul Avion"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Funcția Wi‑Fi rămâne activată"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ru/strings.xml b/service/ServiceWifiResources/res/values-ru/strings.xml
index 7179dd51ae..0ee529a173 100644
--- a/service/ServiceWifiResources/res/values-ru/strings.xml
+++ b/service/ServiceWifiResources/res/values-ru/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Отключить Wi‑Fi можно в быстрых настройках."</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Разрешить"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Не разрешать"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi будет включен в режиме полета"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Если не отключить функцию Wi-Fi, в следующий раз она останется включенной в режиме полета."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Функция Wi‑Fi остается включенной"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Функция Wi‑Fi останется включенной в режиме полета. Вы можете отключить ее, если хотите."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Сеть недоступна"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Администратор отключил функцию \"<xliff:g id="SSID">%1$s</xliff:g>\"."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Закрыть"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi будет включен в режиме полета"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Функция Wi‑Fi остается включенной"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-si/strings.xml b/service/ServiceWifiResources/res/values-si/strings.xml
index ea269f6d6b..abcbca427d 100644
--- a/service/ServiceWifiResources/res/values-si/strings.xml
+++ b/service/ServiceWifiResources/res/values-si/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"ඔබට ඉක්මන් සැකසීම් තුළ Wi‑Fi ක්‍රියාවිරහිත කළ හැකිය"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"ඉඩ දෙන්න"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"ඉඩ නොදෙන්න"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ගුවන්යානා ප්‍රකාරය තුළ Wi‑Fi සක්‍රීයයි"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"ඔබ Wi‑Fi ක්‍රියාත්මක කර තබා ගන්නේ නම්, ඔබ අහස්යානා ආකාරයේ සිටින මීළඟ වතාවේ එය ක්‍රියාත්මක කිරීමට ඔබේ දුරකථනයට මතක තිබෙනු ඇත."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi ක්‍රියාත්මකව පවතී"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"ඔබේ දුරකථනය අහස්යානා ආකාරයේ දී Wi‑Fi ක්‍රියාත්මකව තබා ගැනීමට මතක තබා ගනියි. ඔබට Wi‑Fi ක්‍රියාත්මක වීමට අවශ්‍ය නොවේ නම් එය ක්‍රියාවිරහිත කරන්න."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"ලබා ගත නොහැකි ජාලය"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> ඔබේ පරිපාලක විසින් අබල කර ඇත."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"වසන්න"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"ගුවන්යානා ප්‍රකාරය තුළ Wi‑Fi සක්‍රීයයි"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi ක්‍රියාත්මකව පවතී"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-sk/strings.xml b/service/ServiceWifiResources/res/values-sk/strings.xml
index 8d00f9019c..1f8484ec99 100644
--- a/service/ServiceWifiResources/res/values-sk/strings.xml
+++ b/service/ServiceWifiResources/res/values-sk/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Wi‑Fi môžete vypnúť v rýchlych nastaveniach"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Povoliť"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Nepovoliť"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Sieť Wi‑Fi bude v režime v lietadle zapnutá"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ak ponecháte sieť Wi‑Fi zapnutú, váš telefón si zapamätá, že ju má ponechať zapnutú pri ďalšom aktivovaní režimu v lietadle"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Pripojenie Wi‑Fi zostane zapnuté"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefón si zapamätá, aby v režime v lietadle nevypínal sieť Wi‑Fi. Vypnite ju, ak nechcete, aby zostala zapnutá."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Nedostupná sieť"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Funkcia <xliff:g id="SSID">%1$s</xliff:g> je deaktivovaná správcom."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Zavrieť"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Sieť Wi‑Fi bude v režime v lietadle zapnutá"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Pripojenie Wi‑Fi zostane zapnuté"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-sl/strings.xml b/service/ServiceWifiResources/res/values-sl/strings.xml
index ab763ba559..9d3ea17e9a 100644
--- a/service/ServiceWifiResources/res/values-sl/strings.xml
+++ b/service/ServiceWifiResources/res/values-sl/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Wi‑Fi lahko izklopite v hitrih nastavitvah."</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Dovoli"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Ne dovoli"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi je vklopljen v načinu za letalo."</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Če pustite Wi-Fi vklopljen, bo telefon ob naslednjem preklopu na način za letalo pustil Wi-Fi vklopljen."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi ostane vklopljen"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefon v načinu za letalo pusti Wi-Fi vklopljen. Če ne želite, da ostane vklopljen, izklopite vmesnik Wi‑Fi."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Omrežje ni na voljo"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Omrežje <xliff:g id="SSID">%1$s</xliff:g> je onemogočil skrbnik."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Zapri"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi je vklopljen v načinu za letalo."</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi ostane vklopljen"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-sq/strings.xml b/service/ServiceWifiResources/res/values-sq/strings.xml
index bd22a68f83..11632fe88e 100644
--- a/service/ServiceWifiResources/res/values-sq/strings.xml
+++ b/service/ServiceWifiResources/res/values-sq/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Mund ta çaktivizosh Wi-Fi te \"Cilësimet e shpejta\""</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Lejo"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Mos lejo"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi është në modalitetin e aeroplanit"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Nëse e mban Wi-Fi të aktivizuar, telefoni yt do të kujtohet ta mbajë atë të aktivizuar herën tjetër që të jesh në modalitetin e aeroplanit"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi qëndron aktiv"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefoni yt kujtohet që ta mbajë Wi-Fi të aktivizuar në modalitetin e aeroplanit. Çaktivizo Wi‑Fi nëse nuk dëshiron që të qëndrojë e aktivizuar."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Rrjeti i padisponueshëm"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> është çaktivizuar nga administratori yt."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Mbyll"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi është në modalitetin e aeroplanit"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi qëndron aktiv"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-sr/strings.xml b/service/ServiceWifiResources/res/values-sr/strings.xml
index 4f514c9612..6bdf104afb 100644
--- a/service/ServiceWifiResources/res/values-sr/strings.xml
+++ b/service/ServiceWifiResources/res/values-sr/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Можете да искључите WiFi у Брзим подешавањима"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Дозволи"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Не дозволи"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WiFi је укључен у режиму рада у авиону"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Ако одлучите да не искључујете WiFi, телефон ће запамтити да га не искључује следећи пут када будете у режиму рада у авиону"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WiFi остаје укључен"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Телефон памти да не треба да искључује WiFi у режиму рада у авиону. Искључите WiFi ако не желите да остане укључен."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Недоступна мрежа"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Администратор је онемогућио <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Затвори"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"WiFi је укључен у режиму рада у авиону"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WiFi остаје укључен"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-sv/strings.xml b/service/ServiceWifiResources/res/values-sv/strings.xml
index 337363185f..57c31282a6 100644
--- a/service/ServiceWifiResources/res/values-sv/strings.xml
+++ b/service/ServiceWifiResources/res/values-sv/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Du kan stänga av wifi i snabbinställningarna"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Tillåt"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Tillåt inte"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wifi är aktiverat i flygplansläget"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Om du håller wifi aktiverat kommer telefonen ihåg att hålla det aktiverat nästa gång du använder flygplansläge."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wifi inaktiveras inte"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefonen håller wifi aktiverat i flygplansläge. Inaktivera wifi om du inte vill att wifi ska hållas aktiverat."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Otillgängligt nätverk"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> har inaktiverats av administratören."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Stäng"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wifi är aktiverat i flygplansläget"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wifi inaktiveras inte"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-sw/strings.xml b/service/ServiceWifiResources/res/values-sw/strings.xml
index 5d4dee3f8c..aa007edafe 100644
--- a/service/ServiceWifiResources/res/values-sw/strings.xml
+++ b/service/ServiceWifiResources/res/values-sw/strings.xml
@@ -160,13 +160,13 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Unaweza kuzima Wi-Fi kwenye Mipangilio ya Haraka"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Ruhusu"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Usiruhusu"</string>
- <string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Mtandao Haupatikani"</string>
- <string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> umezimwa na msimamizi wako."</string>
- <string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Funga"</string>
<string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi itawashwa katika hali ya ndegeni"</string>
<!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
<skip />
<string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi itaendelea kuwaka"</string>
<!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
<skip />
+ <string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Mtandao Haupatikani"</string>
+ <string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> umezimwa na msimamizi wako."</string>
+ <string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Funga"</string>
</resources>
diff --git a/service/ServiceWifiResources/res/values-ta/strings.xml b/service/ServiceWifiResources/res/values-ta/strings.xml
index d385417da4..e2dc6c6572 100644
--- a/service/ServiceWifiResources/res/values-ta/strings.xml
+++ b/service/ServiceWifiResources/res/values-ta/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"விரைவு அமைப்புகளில் நீங்கள் வைஃபையை முடக்கிக்கொள்ளலாம்"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"அனுமதி"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"அனுமதிக்க வேண்டாம்"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"விமானப் பயன்முறையில் வைஃபை இயக்கத்திலேயே இருக்கும்"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"வைஃபையை இயக்கத்தில் வைத்திருந்தால், அடுத்த முறை நீங்கள் விமானப் பயன்முறையைப் பயன்படுத்தும்போது உங்கள் மொபைல் வைஃபையை இயக்கத்தில் வைக்கும்"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"வைஃபை இயக்கத்திலேயே இருக்கும்"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"உங்கள் மொபைல் விமானப் பயன்முறையில் இருக்கும்போது வைஃபையை இயக்கத்திலேயே வைத்திருக்கும். வைஃபையைப் பயன்படுத்த விரும்பவில்லை என்றால் அதை முடக்கவும்."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"நெட்வொர்க் கிடைக்கவில்லை"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> உங்கள் நிர்வாகியால் முடக்கப்பட்டுள்ளது."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"மூடுக"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"விமானப் பயன்முறையில் வைஃபை இயக்கத்திலேயே இருக்கும்"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"வைஃபை இயக்கத்திலேயே இருக்கும்"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-te/strings.xml b/service/ServiceWifiResources/res/values-te/strings.xml
index 47f53eda42..3e1a882606 100644
--- a/service/ServiceWifiResources/res/values-te/strings.xml
+++ b/service/ServiceWifiResources/res/values-te/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"మీరు క్విక్ సెట్టింగ్‌లలో Wi‑Fiని ఆఫ్ చేయవచ్చు"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"అనుమతించండి"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"అనుమతించవద్దు"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"విమానం మోడ్‌లో Wi‑Fi ఆన్ చేయబడింది"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"మీరు Wi‑Fiని ఆన్‌లో ఉంచినట్లయితే, మీరు తదుపరిసారి విమానం మోడ్‌లో ఉన్నప్పుడు దాన్ని ఆన్‌లో ఉంచాలని మీ ఫోన్ గుర్తుంచుకుంటుంది"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi ఆన్‌లోనే ఉంటుంది"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"మీ ఫోన్ విమానం మోడ్‌లో Wi‑Fiని ఆన్‌లో ఉంచాలని గుర్తుంచుకుంటుంది. Wi‑Fi ఆన్‌లో ఉండకూడదనుకుంటే దాన్ని ఆఫ్ చేయండి."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"నెట్‌వర్క్ అందుబాటులో లేదు"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g>ను మీ అడ్మినిస్ట్రేటర్ డిజేబుల్ చేశారు."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"మూసివేయండి"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"విమానం మోడ్‌లో Wi‑Fi ఆన్ చేయబడింది"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi ఆన్‌లోనే ఉంటుంది"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-th/strings.xml b/service/ServiceWifiResources/res/values-th/strings.xml
index 38355e7c44..0cdd9c2c42 100644
--- a/service/ServiceWifiResources/res/values-th/strings.xml
+++ b/service/ServiceWifiResources/res/values-th/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"คุณปิด Wi‑Fi ได้ในการตั้งค่าด่วน"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"อนุญาต"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"ไม่อนุญาต"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi จะเปิดในโหมดบนเครื่องบิน"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"หากเปิด Wi-Fi ไว้ โทรศัพท์จะจำว่าต้องเปิด Wi-Fi ในครั้งถัดไปที่คุณอยู่ในโหมดบนเครื่องบิน"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi เปิดอยู่"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"โทรศัพท์จำว่าจะต้องเปิด Wi-Fi ในโหมดบนเครื่องบิน ปิด Wi-Fi หากคุณไม่ต้องการให้เปิดไว้"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"เครือข่ายไม่พร้อมใช้งาน"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"ผู้ดูแลระบบปิดใช้ <xliff:g id="SSID">%1$s</xliff:g>"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"ปิด"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi จะเปิดในโหมดบนเครื่องบิน"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi-Fi เปิดอยู่"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-tl/strings.xml b/service/ServiceWifiResources/res/values-tl/strings.xml
index 8ab7d880ba..ac0be04d6f 100644
--- a/service/ServiceWifiResources/res/values-tl/strings.xml
+++ b/service/ServiceWifiResources/res/values-tl/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Puwede mong i-off ang Wi‑Fi sa Mga Mabilisang Setting"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Payagan"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Huwag payagan"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"I-on ang Wi‑Fi habang nasa airplane mode"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Kung papanatilihin mong naka-on ang Wi‑Fi, tatandaan ng iyong telepono na panatilihin itong naka-on sa susunod na nasa airplane mode ka"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Mananatiling naka-on ang Wi‑Fi"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Tinatandaan ng iyong telepono na panatilihing naka-on ang Wi-Fi habang nasa airplane mode. I-off ang Wi‑Fi kung ayaw mo itong manatiling naka-on."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Hindi Available na Network"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Na-disable ng iyong administrator ang <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Isara"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"I-on ang Wi‑Fi habang nasa airplane mode"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Mananatiling naka-on ang Wi‑Fi"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-tr/strings.xml b/service/ServiceWifiResources/res/values-tr/strings.xml
index f8a1b6ae89..8ba171ad0b 100644
--- a/service/ServiceWifiResources/res/values-tr/strings.xml
+++ b/service/ServiceWifiResources/res/values-tr/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Kablosuz bağlantıyı Hızlı Ayarlar\'dan kapatabilirsiniz"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"İzin ver"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"İzin verme"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Uçak modundayken kablosuz bağlantı açık"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Kablosuz bağlantıyı açık tutarsanız telefonunuz, daha sonra tekrar uçak modunda olduğunuzda kablosuz bağlantıyı açık tutar"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Kablosuz bağlantı açık kalır"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefonunuz, uçak modundayken kablosuz bağlantıyı açık tutmayı hatırlar. Açık kalmasını istemiyorsanız kablosuz bağlantıyı kapatın."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Kullanılamayan Ağ"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g>, yöneticiniz tarafından devre dışı bırakıldı."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Kapat"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Uçak modundayken kablosuz bağlantı açık"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Kablosuz bağlantı açık kalır"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-uk/strings.xml b/service/ServiceWifiResources/res/values-uk/strings.xml
index 2a34dc0621..63f172c1c5 100644
--- a/service/ServiceWifiResources/res/values-uk/strings.xml
+++ b/service/ServiceWifiResources/res/values-uk/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Wi-Fi можна вимкнути у швидких налаштуваннях"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Дозволити"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Не дозволяти"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Ви ввімкнули Wi‑Fi у режимі польоту"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Якщо ви не вимкнете Wi‑Fi на телефоні, ця функція залишатиметься ввімкненою під час наступного використання режиму польоту"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi не буде вимкнено"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"У режимі польоту функція Wi‑Fi на телефоні залишатиметься ввімкненою. Якщо захочете вимкнути її, вимкніть Wi‑Fi."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Недоступна мережа"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Адміністратор вимкнув мережу <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Закрити"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Ви ввімкнули Wi‑Fi у режимі польоту"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi не буде вимкнено"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-ur/strings.xml b/service/ServiceWifiResources/res/values-ur/strings.xml
index 8f8f6f0ac2..ac5dc2976d 100644
--- a/service/ServiceWifiResources/res/values-ur/strings.xml
+++ b/service/ServiceWifiResources/res/values-ur/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"‏آپ فوری ترتیبات میں Wi-Fi آف کر سکتے ہیں"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"اجازت دیں"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"اجازت نہ دیں"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‏ہوائی جہاز وضع میں Wi‑Fi آن ہے"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"‏اگر آپ Wi-Fi کو آن رکھتے ہیں تو آپ کا فون آپ کے اگلی مرتبہ ہوائی جہاز وضع میں ہونے پر اسے آن رکھنا یاد رکھے گا"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‏Wi‑Fi آن رہتا ہے"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"‏آپ کا فون ہوائی جہاز وضع میں Wi‑Fi کو آن رکھنا یاد رکھتا ہے۔ اگر آپ نہیں چاہتے ہیں کہ Wi-Fi آن رہے تو اسے آف کریں۔"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"غیر دستیاب نیٹ ورک"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> کو آپ کے منتظم کے ذریعے مسدود کر دیا گیا ہے۔"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"بند کریں"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"‏ہوائی جہاز وضع میں Wi‑Fi آن ہے"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"‏Wi‑Fi آن رہتا ہے"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-uz/strings.xml b/service/ServiceWifiResources/res/values-uz/strings.xml
index e62ec1e76d..e16b3cc37e 100644
--- a/service/ServiceWifiResources/res/values-uz/strings.xml
+++ b/service/ServiceWifiResources/res/values-uz/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Tezkor sozlamalar orqali Wi-Fi aloqani faolsizlantirish mumkin"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Ruxsat berish"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Rad etish"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi parvoz rejimida yoniq"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Wi-Fi yoniq qolsa, telefon keyingi safar parvoz rejimida ham uni yoniq qoldiradi."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi yoniq turadi"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Telefoningiz parvoz rejimida Wi‑Fi yoqilganini eslab qoladi. Yoniq qolmasligi uchun Wi-Fi aloqasini oʻchiring."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Tarmoq mavjud emas"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> administrator tomonidan faolsizlantirilgan."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Yopish"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi parvoz rejimida yoniq"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi yoniq turadi"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-vi/strings.xml b/service/ServiceWifiResources/res/values-vi/strings.xml
index 1470d42809..7336092071 100644
--- a/service/ServiceWifiResources/res/values-vi/strings.xml
+++ b/service/ServiceWifiResources/res/values-vi/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Bạn có thể tắt Wi-Fi trong phần Cài đặt nhanh"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Cho phép"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Không cho phép"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi bật ở chế độ trên máy bay"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Nếu bạn không tắt Wi‑Fi, điện thoại sẽ luôn bật Wi‑Fi vào lần tiếp theo bạn dùng chế độ trên máy bay"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi ‑ Fi luôn được bật"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Điện thoại của bạn sẽ luôn bật Wi-Fi ở chế độ trên máy bay. Nếu không muốn như vậy thì bạn có thể tắt Wi-Fi."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Không có kết nối mạng"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"Quản trị viên của bạn đã tắt tính năng <xliff:g id="SSID">%1$s</xliff:g>."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Đóng"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"Wi‑Fi bật ở chế độ trên máy bay"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi ‑ Fi luôn được bật"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-zh-rCN/strings.xml b/service/ServiceWifiResources/res/values-zh-rCN/strings.xml
index 24f5cb288f..623a33c397 100644
--- a/service/ServiceWifiResources/res/values-zh-rCN/strings.xml
+++ b/service/ServiceWifiResources/res/values-zh-rCN/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"您可以在“快捷设置”中关闭 WLAN"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"允许"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"不允许"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"飞行模式时开启 WLAN"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"如果您不关闭 WLAN,那么您下次进入飞行模式时手机将记住保持 WLAN 开启"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WLAN 保持开启状态"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"在飞行模式下手机将记住保持 WLAN 开启。如果您不想让 WLAN 保持开启,请将其关闭。"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"网络无法使用"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"<xliff:g id="SSID">%1$s</xliff:g> 已被您的管理员停用。"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"关闭"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"飞行模式时开启 WLAN"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"WLAN 保持开启状态"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-zh-rHK/strings.xml b/service/ServiceWifiResources/res/values-zh-rHK/strings.xml
index f4f56b7f8d..19e43dd644 100644
--- a/service/ServiceWifiResources/res/values-zh-rHK/strings.xml
+++ b/service/ServiceWifiResources/res/values-zh-rHK/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"您可以在「快速設定」中關閉 Wi-Fi"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"允許"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"不允許"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"在飛行模式下開啟 Wi-Fi"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"如果您不關閉 Wi-Fi,下次手機進入飛行模式時,Wi-Fi 將保持開啟"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"保持 Wi-Fi 連線"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"手機會記得在飛行模式下保持 Wi-Fi 開啟。如果您不希望保持開啟,請關閉 Wi-Fi。"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"無法使用網絡"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"您的管理員已停用「<xliff:g id="SSID">%1$s</xliff:g>」。"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"關閉"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"在飛行模式下開啟 Wi-Fi"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"保持 Wi-Fi 連線"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-zh-rTW/strings.xml b/service/ServiceWifiResources/res/values-zh-rTW/strings.xml
index c941f23239..b579adfe0c 100644
--- a/service/ServiceWifiResources/res/values-zh-rTW/strings.xml
+++ b/service/ServiceWifiResources/res/values-zh-rTW/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"你可以透過快速設定關閉 Wi-Fi"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"允許"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"不允許"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"在飛航模式下保持 Wi-Fi 開啟狀態"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"如果你不關閉 Wi-Fi,下次手機進入飛航模式時,Wi-Fi 將保持開啟"</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi 會保持開啟狀態"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"手機會記得在飛航模式下保持 Wi-Fi 開啟。如果不要保持開啟,請關閉 Wi-Fi。"</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"網路無法使用"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"你的系統管理員已停用 <xliff:g id="SSID">%1$s</xliff:g>。"</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"關閉"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"在飛航模式下保持 Wi-Fi 開啟狀態"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"Wi‑Fi 會保持開啟狀態"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values-zu/strings.xml b/service/ServiceWifiResources/res/values-zu/strings.xml
index 69f841ce72..7b2596923b 100644
--- a/service/ServiceWifiResources/res/values-zu/strings.xml
+++ b/service/ServiceWifiResources/res/values-zu/strings.xml
@@ -160,13 +160,11 @@
<string name="wifi_enable_request_dialog_message" msgid="6395169178524938278">"Ungavala i-Wi-Fi Kumasethingi Asheshayo"</string>
<string name="wifi_enable_request_dialog_positive_button" msgid="6050832555821470466">"Vumela"</string>
<string name="wifi_enable_request_dialog_negative_button" msgid="4754219902374918882">"Ungavumeli"</string>
+ <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"I-Wi‑Fi ivuliwe kumodi yendiza"</string>
+ <string name="wifi_enabled_apm_first_time_message" msgid="5443101896157496353">"Uma ugcina i-Wi‑Fi ivuliwe, ifoni yakho izokhumbula ukuyigcina ivuliwe ngesikhathi esilandelayo uma ukumodi yendiza."</string>
+ <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"I-Wi‑Fi ihlala ivuliwe"</string>
+ <string name="apm_enabled_first_time_message" msgid="4753441005253327841">"Ifoni yakho ikhumbula ukugcina i-Wi‑Fi ivuliwe kumodi yendiza. Vala i-Wi-Fi uma ungafuni ukuthi ihlale ivuliwe."</string>
<string name="wifi_network_disabled_by_admin_title" msgid="9057697656855227293">"Inethiwekhi Engatholakali"</string>
<string name="wifi_network_disabled_by_admin_message" msgid="7830360441333155462">"I-<xliff:g id="SSID">%1$s</xliff:g> ikhutshazwe umlawuli wakho."</string>
<string name="wifi_network_disabled_by_admin_button" msgid="3350310756265122689">"Vala"</string>
- <string name="wifi_enabled_apm_first_time_title" msgid="4814302384637588804">"I-Wi‑Fi ivuliwe kumodi yendiza"</string>
- <!-- no translation found for wifi_enabled_apm_first_time_message (5443101896157496353) -->
- <skip />
- <string name="apm_enabled_first_time_title" msgid="2534167413190488009">"I-Wi‑Fi ihlala ivuliwe"</string>
- <!-- no translation found for apm_enabled_first_time_message (4753441005253327841) -->
- <skip />
</resources>
diff --git a/service/ServiceWifiResources/res/values/config.xml b/service/ServiceWifiResources/res/values/config.xml
index a5dcb90705..d3107151b9 100644
--- a/service/ServiceWifiResources/res/values/config.xml
+++ b/service/ServiceWifiResources/res/values/config.xml
@@ -134,8 +134,10 @@
config_wifiFrameworkUnmeteredNetworkBonus. -->
<integer translatable="false" name="config_wifiScoringBucketStepSize">500</integer>
- <!-- The duration in minutes to strongly favor the last-selected network over other options. -->
+ <!-- The duration in minutes to strongly favor the last-selected non-metered network over other options. -->
<integer translatable="false" name="config_wifiFrameworkLastSelectionMinutes">480</integer>
+ <!-- The duration in minutes to strongly favor the last-selected metered network over other options. -->
+ <integer translatable="false" name="config_wifiFrameworkLastMeteredSelectionMinutes">120</integer>
<!-- Integer specifying the min packet Tx/Rx rates in packets per second to be considered
active traffic so that network selection and scan could be skipped-->
@@ -550,6 +552,24 @@
<integer translatable="false" name="config_wifiDisableReasonAuthenticationFailureThreshold"> 3 </integer>
<integer translatable="false" name="config_wifiDisableReasonDhcpFailureThreshold"> 2 </integer>
<integer translatable="false" name="config_wifiDisableReasonNetworkNotFoundThreshold"> 2 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonNoInternetTemporaryThreshold"> 1 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonAuthenticationNoCredentialsThreshold"> 3 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonNoInternetPermanentThreshold"> 1 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonByWrongPasswordThreshold"> 1 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonAuthenticationNoSubscriptionThreshold"> 1 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonConsecutiveFailuresThreshold"> 1 </integer>
+
+ <!-- Base duration to set a network disabled after validation failure happen-->
+ <integer translatable="false" name="config_wifiDisableReasonAssociationRejectionDurationMs"> 300000 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonAuthenticationFailureDurationMs"> 300000 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonDhcpFailureDurationMs"> 300000 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonNetworkNotFoundDurationMs"> 300000 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonNoInternetTemporaryDurationMs"> 600000 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonAuthenticationNoCredentialsDurationMs"> -1 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonNoInternetPermanentDurationMs"> -1 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonByWrongPasswordDurationMs"> -1 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonAuthenticationNoSubscriptionDurationMs"> -1 </integer>
+ <integer translatable="false" name="config_wifiDisableReasonConsecutiveFailuresDurationMs"> 300000 </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.-->
@@ -571,6 +591,9 @@
config_wifiBssidBlocklistMonitorFailureStreakCap is set to 7-->
<integer translatable="false" name="config_wifiBssidBlocklistMonitorBaseBlockDurationMs"> 300000 </integer>
+ <!-- Base duration to block a bssid after validation failure happen-->
+ <integer translatable="false" name="config_wifiBssidBlocklistMonitorValidationFailureBaseBlockDurationMs"> 300000 </integer>
+
<!-- Base duration to block a BSSID after the external connected scorer sets wifi as unusable.
The block duration is increased exponentially if the same BSSID is repeated marked as unusable.
ie. 0.5/1/2/4/8/16/32/64 minutes - capped at 64 minutes because the default for
@@ -838,6 +861,9 @@
<!-- Indicate the number of networks to restore in a batch. 0 : all networks in a batch -->
<integer translatable="false" name="config_wifiConfigurationRestoreNetworksBatchNum">50</integer>
+ <!-- Enables logging for any tasks running on the Wi-Fi thread which take longer than this threshold (in milliseconds) -->
+ <integer translatable="false" name="config_wifiConfigurationWifiRunnerThresholdInMs">100</integer>
+
<!-- OEM privileged WiFi admin package names. Empty by default-->
<string-array translatable="false" name="config_oemPrivilegedWifiAdminPackages">
<!-- Add package names here, example: -->
@@ -961,4 +987,7 @@
<!-- boolean indicating whether the caller thread needs to wait for destroyed listeners -->
<bool translatable="false" name ="config_wifiWaitForDestroyedListeners">false</bool>
+
+ <!-- Indicates the number of channels is allowed to set in a WifiNetworkSpecifier -->
+ <integer translatable="false" name ="config_wifiNetworkSpecifierMaxPreferredChannels">5</integer>
</resources>
diff --git a/service/ServiceWifiResources/res/values/overlayable.xml b/service/ServiceWifiResources/res/values/overlayable.xml
index 019063b6d2..44fde711c5 100644
--- a/service/ServiceWifiResources/res/values/overlayable.xml
+++ b/service/ServiceWifiResources/res/values/overlayable.xml
@@ -50,6 +50,7 @@
<item type="integer" name="config_wifiBand6GhzBonus" />
<item type="integer" name="config_wifiScoringBucketStepSize" />
<item type="integer" name="config_wifiFrameworkLastSelectionMinutes" />
+ <item type="integer" name="config_wifiFrameworkLastMeteredSelectionMinutes" />
<item type="integer" name="config_wifiFrameworkMinPacketPerSecondActiveTraffic" />
<item type="integer" name="config_wifiFrameworkMinPacketPerSecondHighTraffic" />
<item type="integer" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz" />
@@ -144,10 +145,29 @@
<item type="integer" name="config_wifiPnoScanLowRssiNetworkRetryStartDelaySec" />
<item type="integer" name="config_wifiPnoScanLowRssiNetworkRetryMaxDelaySec" />
<item type="integer" name="config_wifiConnectedHighRssiScanMinimumWindowSizeSec" />
+
<item type="integer" name="config_wifiDisableReasonAssociationRejectionThreshold" />
<item type="integer" name="config_wifiDisableReasonAuthenticationFailureThreshold" />
<item type="integer" name="config_wifiDisableReasonDhcpFailureThreshold" />
<item type="integer" name="config_wifiDisableReasonNetworkNotFoundThreshold" />
+ <item type="integer" name="config_wifiDisableReasonNoInternetTemporaryThreshold" />
+ <item type="integer" name="config_wifiDisableReasonAuthenticationNoCredentialsThreshold" />
+ <item type="integer" name="config_wifiDisableReasonNoInternetPermanentThreshold" />
+ <item type="integer" name="config_wifiDisableReasonByWrongPasswordThreshold" />
+ <item type="integer" name="config_wifiDisableReasonAuthenticationNoSubscriptionThreshold" />
+ <item type="integer" name="config_wifiDisableReasonConsecutiveFailuresThreshold" />
+
+ <item type="integer" name="config_wifiDisableReasonAssociationRejectionDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonAuthenticationFailureDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonDhcpFailureDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonNetworkNotFoundDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonNoInternetTemporaryDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonAuthenticationNoCredentialsDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonNoInternetPermanentDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonByWrongPasswordDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonAuthenticationNoSubscriptionDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonConsecutiveFailuresDurationMs" />
+
<item type="integer" name="config_wifiBssidBlocklistMonitorApUnableToHandleNewStaThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorNetworkValidationFailureThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorWrongPasswordThreshold" />
@@ -163,6 +183,7 @@
<item type="integer" name="config_wifiBssidBlocklistMonitorFailureStreakCap" />
<item type="integer" name="config_wifiBssidBlocklistAbnormalDisconnectTimeWindowMs" />
<item type="integer" name="config_wifiBssidBlocklistMonitorNoResponseThreshold" />
+ <item type="integer" name="config_wifiBssidBlocklistMonitorValidationFailureBaseBlockDurationMs" />
<item type="bool" name="config_wifiScanHiddenNetworksScanOnlyMode" />
<item type="integer" name="config_wifiHardwareSoftapMaxClientCount" />
<item type="bool" name="config_wifiIsUnusableEventMetricsEnabled" />
@@ -233,6 +254,7 @@
<item type="string" name="config_wifiCertInstallationHelpLink" />
<item type="string" name="config_wifiApmEnhancementHelpLink" />
<item type="integer" name="config_wifiConfigurationRestoreNetworksBatchNum" />
+ <item type="integer" name="config_wifiConfigurationWifiRunnerThresholdInMs" />
<item type="array" name="config_oemPrivilegedWifiAdminPackages" />
<item type="bool" name="config_wifiSoftapOweSupported" />
<item type="bool" name="config_wifiSoftapOweTransitionSupported" />
@@ -257,6 +279,7 @@
<item type="array" name="config_wifiCharsetsForSsidTranslation" />
<item type="string" name="config_wifiBugreportDeepLink" />
<item type="bool" name="config_wifiWaitForDestroyedListeners" />
+ <item type="integer" name="config_wifiNetworkSpecifierMaxPreferredChannels" />
<!-- Params from config.xml that can be overlayed -->
<!-- Params from strings.xml that can be overlayed -->
@@ -381,13 +404,13 @@
<item type="string" name="wifi_tofu_invalid_cert_chain_title" />
<item type="string" name="wifi_tofu_invalid_cert_chain_message" />
<item type="string" name="wifi_tofu_invalid_cert_chain_ok_text" />
- <item type="string" name="wifi_network_disabled_by_admin_title" />
- <item type="string" name="wifi_network_disabled_by_admin_message" />
- <item type="string" name="wifi_network_disabled_by_admin_button" />
<item type="string" name="wifi_enabled_apm_first_time_title" />
<item type="string" name="wifi_enabled_apm_first_time_message" />
<item type="string" name="apm_enabled_first_time_title" />
<item type="string" name="apm_enabled_first_time_message" />
+ <item type="string" name="wifi_network_disabled_by_admin_title" />
+ <item type="string" name="wifi_network_disabled_by_admin_message" />
+ <item type="string" name="wifi_network_disabled_by_admin_button" />
<!-- Params from strings.xml that can be overlayed -->
<!-- Params from styles.xml that can be overlayed -->
diff --git a/service/ServiceWifiResources/res/values/strings.xml b/service/ServiceWifiResources/res/values/strings.xml
index 0c47bae786..4a32500d55 100644
--- a/service/ServiceWifiResources/res/values/strings.xml
+++ b/service/ServiceWifiResources/res/values/strings.xml
@@ -242,14 +242,14 @@
<string name="wifi_enable_request_dialog_positive_button">Allow</string>
<string name="wifi_enable_request_dialog_negative_button">Don\u0027t allow</string>
- <!-- Dialog for connecting to a network with only disabled type BSSes. -->
- <string name="wifi_network_disabled_by_admin_title">Unavailable Network</string>
- <string name="wifi_network_disabled_by_admin_message"><xliff:g id="ssid">%1$s</xliff:g> is disabled by your administrator.</string>
- <string name="wifi_network_disabled_by_admin_button">Close</string>
-
<!-- Notifying the user that the device will remember Wi-Fi state in APM. -->
<string name="wifi_enabled_apm_first_time_title">Wi\u2011Fi on in airplane mode</string>
<string name="wifi_enabled_apm_first_time_message">If you keep Wi\u2011Fi on, your phone will remember to keep it on the next time you\'re in airplane mode</string>
<string name="apm_enabled_first_time_title">Wi\u2011Fi stays on</string>
<string name="apm_enabled_first_time_message">Your phone remembers to keep Wi\u2011Fi on in airplane mode. Turn off Wi\u2011Fi if you don\'t want it to stay on.</string>
+
+ <!-- Dialog for connecting to a network with only disabled type BSSes. -->
+ <string name="wifi_network_disabled_by_admin_title">Unavailable Network</string>
+ <string name="wifi_network_disabled_by_admin_message"><xliff:g id="ssid">%1$s</xliff:g> is disabled by your administrator.</string>
+ <string name="wifi_network_disabled_by_admin_button">Close</string>
</resources>
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index ff60ec7a8d..c957dcf9dd 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -30,6 +30,7 @@ import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SCAN_ONLY;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LONG_LIVED;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT;
import static com.android.server.wifi.ActiveModeManager.ROLE_SOFTAP_TETHERED;
+import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_STA_BANDS;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -39,12 +40,15 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.LocationManager;
+import android.net.Network;
import android.net.wifi.ISubsystemRestartCallback;
import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiScanner;
import android.os.BatteryStatsManager;
import android.os.Build;
import android.os.Handler;
@@ -60,14 +64,15 @@ import android.os.WorkSource;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArraySet;
+import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IState;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.ActiveModeManager.ClientConnectivityRole;
@@ -75,6 +80,7 @@ import com.android.server.wifi.ActiveModeManager.ClientInternetConnectivityRole;
import com.android.server.wifi.ActiveModeManager.ClientRole;
import com.android.server.wifi.ActiveModeManager.SoftApRole;
import com.android.server.wifi.util.ApConfigUtil;
+import com.android.server.wifi.util.NativeUtil;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.wifi.resources.R;
@@ -149,6 +155,13 @@ public class ActiveModeWarden {
@Nullable
private WorkSource mLastScanOnlyClientModeManagerRequestorWs = null;
private AtomicLong mSupportedFeatureSet = new AtomicLong(0);
+ private AtomicInteger mBandsSupported = new AtomicInteger(0);
+ // Mutex lock between service Api binder thread and Wifi main thread
+ private final Object mServiceApiLock = new Object();
+ @GuardedBy("mServiceApiLock")
+ private Network mCurrentNetwork;
+ @GuardedBy("mServiceApiLock")
+ private WifiInfo mCurrentConnectionInfo;
/**
* One of {@link WifiManager#WIFI_STATE_DISABLED},
@@ -1318,6 +1331,8 @@ public class ActiveModeWarden {
}
pw.println("STA + AP Concurrency Supported: " + mWifiNative.isStaApConcurrencySupported());
mWifiInjector.getHalDeviceManager().dump(fd, pw, args);
+ pw.println("Wifi handler thread overruns");
+ mWifiInjector.getWifiHandlerLocalLog().dump(fd, pw, args);
}
@VisibleForTesting
@@ -1482,6 +1497,12 @@ public class ActiveModeWarden {
getPrimaryClientModeManager().getInterfaceName()),
mWifiNative.isStaApConcurrencySupported(),
mWifiNative.isStaStaConcurrencySupported());
+ if (clientModeManager.getRole() == ROLE_CLIENT_PRIMARY) {
+ int band = mWifiNative.getSupportedBandsForSta(
+ clientModeManager.getInterfaceName());
+ if (band == WifiScanner.WIFI_BAND_UNSPECIFIED) band = getStaBandsFromConfigStore();
+ setBandSupported(band);
+ }
}
@Override
@@ -1512,6 +1533,7 @@ public class ActiveModeWarden {
setSupportedFeatureSet(mWifiNative.getSupportedFeatureSet(null),
mWifiNative.isStaApConcurrencySupported(),
mWifiNative.isStaStaConcurrencySupported());
+ setBandSupported(getStaBandsFromConfigStore());
}
// invoke "removed" callbacks after primary changed
invokeOnRemovedCallbacks(clientModeManager);
@@ -1633,8 +1655,8 @@ public class ActiveModeWarden {
static final int CMD_REQUEST_ADDITIONAL_CLIENT_MODE_MANAGER = BASE + 26;
static final int CMD_REMOVE_ADDITIONAL_CLIENT_MODE_MANAGER = BASE + 27;
- private final EnabledState mEnabledState = new EnabledState();
- private final DisabledState mDisabledState = new DisabledState();
+ private final EnabledState mEnabledState;
+ private final DisabledState mDisabledState;
private boolean mIsInEmergencyCall = false;
private boolean mIsInEmergencyCallbackMode = false;
@@ -1642,8 +1664,11 @@ public class ActiveModeWarden {
WifiController() {
super(TAG, mLooper);
-
- DefaultState defaultState = new DefaultState();
+ final int threshold = mContext.getResources().getInteger(
+ R.integer.config_wifiConfigurationWifiRunnerThresholdInMs);
+ DefaultState defaultState = new DefaultState(threshold);
+ mEnabledState = new EnabledState(threshold);
+ mDisabledState = new DisabledState(threshold);
addState(defaultState); {
addState(mDisabledState, defaultState);
addState(mEnabledState, defaultState);
@@ -1714,6 +1739,10 @@ public class ActiveModeWarden {
return "CMD_UPDATE_AP_CONFIG";
case CMD_WIFI_TOGGLED:
return "CMD_WIFI_TOGGLED";
+ case RunnerState.STATE_ENTER_CMD:
+ return "Enter";
+ case RunnerState.STATE_EXIT_CMD:
+ return "Exit";
default:
return "what:" + what;
}
@@ -1762,7 +1791,11 @@ public class ActiveModeWarden {
return recoveryDelayMillis;
}
- abstract class BaseState extends State {
+ abstract class BaseState extends RunnerState {
+ BaseState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
@VisibleForTesting
boolean isInEmergencyMode() {
return mIsInEmergencyCall || mIsInEmergencyCallbackMode;
@@ -1887,7 +1920,21 @@ public class ActiveModeWarden {
}
@Override
- public final boolean processMessage(Message msg) {
+ public void enterImpl() {
+ }
+
+ @Override
+ public void exitImpl() {
+ }
+
+ @Override
+ String getMessageLogRec(int what) {
+ return ActiveModeWarden.class.getSimpleName() + "."
+ + DefaultState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public final boolean processMessageImpl(Message msg) {
// potentially enter emergency mode
if (msg.what == CMD_EMERGENCY_CALL_STATE_CHANGED
|| msg.what == CMD_EMERGENCY_MODE_CHANGED) {
@@ -1908,9 +1955,27 @@ public class ActiveModeWarden {
protected abstract boolean processMessageFiltered(Message msg);
}
- class DefaultState extends State {
+ class DefaultState extends RunnerState {
+ DefaultState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public boolean processMessage(Message msg) {
+ String getMessageLogRec(int what) {
+ return ActiveModeWarden.class.getSimpleName() + "."
+ + DefaultState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ void enterImpl() {
+ }
+
+ @Override
+ void exitImpl() {
+ }
+
+ @Override
+ public boolean processMessageImpl(Message msg) {
switch (msg.what) {
case CMD_SCAN_ALWAYS_MODE_CHANGED:
case CMD_EMERGENCY_SCAN_STATE_CHANGED:
@@ -2004,19 +2069,23 @@ public class ActiveModeWarden {
}
class DisabledState extends BaseState {
+ DisabledState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
log("DisabledState.enter()");
- super.enter();
+ super.enterImpl();
if (hasAnyModeManager()) {
Log.e(TAG, "Entered DisabledState, but has active mode managers");
}
}
@Override
- public void exit() {
+ public void exitImpl() {
log("DisabledState.exit()");
- super.exit();
+ super.exitImpl();
}
@Override
@@ -2094,10 +2163,14 @@ public class ActiveModeWarden {
private boolean mIsDisablingDueToAirplaneMode;
+ EnabledState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
log("EnabledState.enter()");
- super.enter();
+ super.enterImpl();
if (!hasAnyModeManager()) {
Log.e(TAG, "Entered EnabledState, but no active mode managers");
}
@@ -2105,12 +2178,12 @@ public class ActiveModeWarden {
}
@Override
- public void exit() {
+ public void exitImpl() {
log("EnabledState.exit()");
if (hasAnyModeManager()) {
Log.e(TAG, "Exiting EnabledState, but has active mode managers");
}
- super.exit();
+ super.exitImpl();
}
@Nullable
@@ -2401,7 +2474,8 @@ public class ActiveModeWarden {
? null : connectedOrConnectingWifiConfiguration.SSID;
Log.v(TAG, connectedOrConnectingBssid + " " + connectedOrConnectingSsid);
return Objects.equals(ssid, connectedOrConnectingSsid)
- && Objects.equals(bssid, connectedOrConnectingBssid);
+ && (Objects.equals(bssid, connectedOrConnectingBssid)
+ || clientModeManager.isAffiliatedLinkBssid(NativeUtil.getMacAddressOrNull(bssid)));
}
/**
@@ -2485,4 +2559,80 @@ public class ActiveModeWarden {
public long getSupportedFeatureSet() {
return mSupportedFeatureSet.get();
}
+
+ /**
+ * Check if a band is supported as STA
+ * @param band Wifi band
+ * @return true if supported
+ */
+ public boolean isBandSupportedForSta(@WifiScanner.WifiBand int band) {
+ return (mBandsSupported.get() & band) != 0;
+ }
+
+ private void setBandSupported(@WifiScanner.WifiBand int bands) {
+ mBandsSupported.set(bands);
+ saveStaBandsToConfigStoreIfNecessary(bands);
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "setBandSupported 0x" + Long.toHexString(mBandsSupported.get()));
+ }
+ }
+
+ /**
+ * Get the current default Wifi network.
+ * @return the default Wifi network
+ */
+ public Network getCurrentNetwork() {
+ synchronized (mServiceApiLock) {
+ return mCurrentNetwork;
+ }
+ }
+
+ /**
+ * Set the current default Wifi network. Called from ClientModeImpl.
+ * @param network the default Wifi network
+ */
+ protected void setCurrentNetwork(Network network) {
+ synchronized (mServiceApiLock) {
+ mCurrentNetwork = network;
+ }
+ }
+
+ /**
+ * Get the current Wifi network connection info.
+ * @return the default Wifi network connection info
+ */
+ public WifiInfo getConnectionInfo() {
+ synchronized (mServiceApiLock) {
+ return mCurrentConnectionInfo;
+ }
+ }
+
+ /**
+ * Update the current connection information.
+ */
+ public void updateCurrentConnectionInfo() {
+ synchronized (mServiceApiLock) {
+ mCurrentConnectionInfo = getPrimaryClientModeManager().getConnectionInfo();
+ }
+ }
+
+ /**
+ * Save the supported bands for STA from WiFi HAL to config store.
+ * @param bands bands supported
+ */
+ private void saveStaBandsToConfigStoreIfNecessary(int bands) {
+ if (bands != getStaBandsFromConfigStore()) {
+ mWifiInjector.getSettingsConfigStore().put(WIFI_NATIVE_SUPPORTED_STA_BANDS, bands);
+ Log.i(TAG, "Supported STA bands is updated in config store: " + bands);
+ }
+ }
+
+ /**
+ * Get the supported STA bands from cache/config store
+ * @return bands supported
+ */
+ private int getStaBandsFromConfigStore() {
+ return mWifiInjector.getSettingsConfigStore().get(WIFI_NATIVE_SUPPORTED_STA_BANDS);
+ }
+
}
diff --git a/service/java/com/android/server/wifi/ClientMode.java b/service/java/com/android/server/wifi/ClientMode.java
index dfef172c61..66dd151a30 100644
--- a/service/java/com/android/server/wifi/ClientMode.java
+++ b/service/java/com/android/server/wifi/ClientMode.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.DhcpResultsParcelable;
+import android.net.MacAddress;
import android.net.Network;
import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.WifiAnnotations;
@@ -91,11 +92,19 @@ public interface ClientMode {
*/
void onBluetoothConnectionStateChanged();
- WifiInfo syncRequestConnectionInfo();
+ /**
+ * Get current Wifi connection information
+ * @return Wifi info
+ */
+ WifiInfo getConnectionInfo();
boolean syncQueryPasspointIcon(long bssid, String fileName);
- Network syncGetCurrentNetwork();
+ /**
+ * Get the current Wifi network information
+ * @return network
+ */
+ Network getCurrentNetwork();
DhcpResultsParcelable syncGetDhcpResultsParcelable();
@@ -298,4 +307,11 @@ public interface ClientMode {
* update the capabilities
*/
void updateCapabilities();
+
+ /**
+ * Check if BSSID belongs to any of the affiliated link BSSID's.
+ * @param bssid BSSID of the AP
+ * @return true if BSSID matches to one of the affiliated link BSSIDs, false otherwise.
+ */
+ boolean isAffiliatedLinkBssid(MacAddress bssid);
}
diff --git a/service/java/com/android/server/wifi/ClientModeDefaults.java b/service/java/com/android/server/wifi/ClientModeDefaults.java
index 33c3b7a0b3..b18fc07439 100644
--- a/service/java/com/android/server/wifi/ClientModeDefaults.java
+++ b/service/java/com/android/server/wifi/ClientModeDefaults.java
@@ -18,6 +18,7 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.net.DhcpResultsParcelable;
+import android.net.MacAddress;
import android.net.Network;
import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.WifiConfiguration;
@@ -78,7 +79,7 @@ public interface ClientModeDefaults extends ClientMode {
default void onBluetoothConnectionStateChanged() { }
- default WifiInfo syncRequestConnectionInfo() {
+ default WifiInfo getConnectionInfo() {
return new WifiInfo();
}
@@ -86,7 +87,7 @@ public interface ClientModeDefaults extends ClientMode {
return false;
}
- default Network syncGetCurrentNetwork() {
+ default Network getCurrentNetwork() {
return null;
}
@@ -227,4 +228,9 @@ public interface ClientModeDefaults extends ClientMode {
@Override
default void updateCapabilities() { }
+
+ @Override
+ default boolean isAffiliatedLinkBssid(MacAddress bssid) {
+ return false;
+ }
}
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 05eb8230a1..8fd71c5fb7 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -25,8 +25,10 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_TRUST_ON_FIRST_USE;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_LOCAL_ONLY;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
+import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SCAN_ONLY;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LONG_LIVED;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT;
+import static com.android.server.wifi.WifiSettingsConfigStore.SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STA_FACTORY_MAC_ADDRESS;
import static com.android.server.wifi.proto.WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__SUPPLICANT_DISCONNECTED;
@@ -35,6 +37,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AlarmManager;
+import android.app.BroadcastOptions;
import android.app.admin.SecurityLog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -288,7 +291,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
private boolean mCurrentConnectionDetectedCaptivePortal;
private String getTag() {
- return TAG + "[" + (mInterfaceName == null ? "unknown" : mInterfaceName) + "]";
+ return TAG + "[" + mId + ":" + (mInterfaceName == null ? "unknown" : mInterfaceName) + "]";
}
private void processRssiThreshold(byte curRssi, int reason,
@@ -338,7 +341,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
@NonNull
private DhcpResultsParcelable mDhcpResultsParcelable = new DhcpResultsParcelable();
- // NOTE: Do not return to clients - see syncRequestConnectionInfo()
+ // NOTE: Do not return to clients - see getConnectionInfo()
private final ExtendedWifiInfo mWifiInfo;
// TODO : remove this member. It should be possible to only call sendNetworkChangeBroadcast when
// the state actually changed, and to deduce the state of the agent from the state of the
@@ -538,6 +541,9 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
/* used to indicated RSSI threshold breach in hw */
static final int CMD_RSSI_THRESHOLD_BREACHED = BASE + 164;
+ /* Used to time out the creation of an IpClient instance. */
+ static final int CMD_IPCLIENT_STARTUP_TIMEOUT = BASE + 165;
+
/**
* Used to handle messages bounced between ClientModeImpl and IpClient.
*/
@@ -573,7 +579,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
/* Start connection to FILS AP*/
static final int CMD_START_FILS_CONNECTION = BASE + 262;
- static final int CMD_CONNECTABLE_STATE_SETUP = BASE + 300;
+ static final int CMD_IPCLIENT_CREATED = BASE + 300;
@VisibleForTesting
static final int CMD_ACCEPT_EAP_SERVER_CERTIFICATE = BASE + 301;
@@ -601,21 +607,23 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
int mRunningBeaconCount = 0;
/* Parent state where connections are allowed */
- private State mConnectableState = new ConnectableState();
+ private State mConnectableState;
/* Connecting/Connected to an access point */
- private State mConnectingOrConnectedState = new ConnectingOrConnectedState();
+ private State mConnectingOrConnectedState;
/* Connecting to an access point */
- private State mL2ConnectingState = new L2ConnectingState();
+ private State mL2ConnectingState;
/* Connected at 802.11 (L2) level */
- private State mL2ConnectedState = new L2ConnectedState();
+ private State mL2ConnectedState;
+ /* Waiting for IpClient recreation completes */
+ private State mWaitBeforeL3ProvisioningState;
/* fetching IP after connection to access point (assoc+auth complete) */
- private State mL3ProvisioningState = new L3ProvisioningState();
+ private State mL3ProvisioningState;
/* Connected with IP addr */
- private State mL3ConnectedState = new L3ConnectedState();
+ private State mL3ConnectedState;
/* Roaming */
- private State mRoamingState = new RoamingState();
+ private State mRoamingState;
/* Network is not connected, supplicant assoc+auth is not complete */
- private State mDisconnectedState = new DisconnectedState();
+ private State mDisconnectedState;
/*
* FILS connection related variables.
@@ -862,10 +870,23 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mInterfaceName,
getHandler());
+ final int threshold = mContext.getResources().getInteger(
+ R.integer.config_wifiConfigurationWifiRunnerThresholdInMs);
+ mConnectableState = new ConnectableState(threshold);
+ mConnectingOrConnectedState = new ConnectingOrConnectedState(threshold);
+ mL2ConnectingState = new L2ConnectingState(threshold);
+ mL2ConnectedState = new L2ConnectedState(threshold);
+ mWaitBeforeL3ProvisioningState = new WaitBeforeL3ProvisioningState(threshold);
+ mL3ProvisioningState = new L3ProvisioningState(threshold);
+ mL3ConnectedState = new L3ConnectedState(threshold);
+ mRoamingState = new RoamingState(threshold);
+ mDisconnectedState = new DisconnectedState(threshold);
+
addState(mConnectableState); {
addState(mConnectingOrConnectedState, mConnectableState); {
addState(mL2ConnectingState, mConnectingOrConnectedState);
addState(mL2ConnectedState, mConnectingOrConnectedState); {
+ addState(mWaitBeforeL3ProvisioningState, mL2ConnectedState);
addState(mL3ProvisioningState, mL2ConnectedState);
addState(mL3ConnectedState, mL2ConnectedState);
addState(mRoamingState, mL2ConnectedState);
@@ -883,6 +904,8 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// update with initial role for ConcreteClientModeManager
onRoleChanged();
+ // Update current connection wifiInfo
+ updateCurrentConnectionInfo();
}
private static final int[] WIFI_MONITOR_EVENTS = {
@@ -995,29 +1018,33 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
@Override
public void onIpClientCreated(IIpClient ipClient) {
+ if (mIpClientCallbacks != this) return;
// IpClient may take a very long time (many minutes) to start at boot time. But after
// that IpClient should start pretty quickly (a few seconds).
// Blocking wait for 5 seconds first (for when the wait is short)
// If IpClient is still not ready after blocking wait, async wait (for when wait is
// long). Will drop all connection requests until IpClient is ready. Other requests
// will still be processed.
- sendMessageAtFrontOfQueue(CMD_CONNECTABLE_STATE_SETUP,
+ sendMessageAtFrontOfQueue(CMD_IPCLIENT_CREATED,
new IpClientManager(ipClient, getName()));
mWaitForCreationCv.open();
}
@Override
public void onPreDhcpAction() {
+ if (mIpClientCallbacks != this) return;
sendMessage(CMD_PRE_DHCP_ACTION);
}
@Override
public void onPostDhcpAction() {
+ if (mIpClientCallbacks != this) return;
sendMessage(CMD_POST_DHCP_ACTION);
}
@Override
public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) {
+ if (mIpClientCallbacks != this) return;
if (dhcpResults != null) {
sendMessage(CMD_IPV4_PROVISIONING_SUCCESS, dhcpResults);
} else {
@@ -1027,6 +1054,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
@Override
public void onProvisioningSuccess(LinkProperties newLp) {
+ if (mIpClientCallbacks != this) return;
addPasspointInfoToLinkProperties(newLp);
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL);
sendMessage(CMD_UPDATE_LINKPROPERTIES, newLp);
@@ -1035,54 +1063,64 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
@Override
public void onProvisioningFailure(LinkProperties newLp) {
+ if (mIpClientCallbacks != this) return;
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST);
sendMessage(CMD_IP_CONFIGURATION_LOST);
}
@Override
public void onLinkPropertiesChange(LinkProperties newLp) {
+ if (mIpClientCallbacks != this) return;
addPasspointInfoToLinkProperties(newLp);
sendMessage(CMD_UPDATE_LINKPROPERTIES, newLp);
}
@Override
public void onReachabilityLost(String logMsg) {
+ if (mIpClientCallbacks != this) return;
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_CMD_IP_REACHABILITY_LOST);
sendMessage(CMD_IP_REACHABILITY_LOST, logMsg);
}
@Override
public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) {
+ if (mIpClientCallbacks != this) return;
sendMessage(CMD_IP_REACHABILITY_FAILURE, lossInfo);
}
@Override
public void installPacketFilter(byte[] filter) {
+ if (mIpClientCallbacks != this) return;
sendMessage(CMD_INSTALL_PACKET_FILTER, filter);
}
@Override
public void startReadPacketFilter() {
+ if (mIpClientCallbacks != this) return;
sendMessage(CMD_READ_PACKET_FILTER);
}
@Override
public void setFallbackMulticastFilter(boolean enabled) {
+ if (mIpClientCallbacks != this) return;
sendMessage(CMD_SET_FALLBACK_PACKET_FILTERING, enabled);
}
@Override
public void setNeighborDiscoveryOffload(boolean enabled) {
+ if (mIpClientCallbacks != this) return;
sendMessage(CMD_CONFIG_ND_OFFLOAD, (enabled ? 1 : 0));
}
@Override
public void onPreconnectionStart(List<Layer2PacketParcelable> packets) {
+ if (mIpClientCallbacks != this) return;
sendMessage(CMD_START_FILS_CONNECTION, 0, 0, packets);
}
@Override
public void onQuit() {
+ if (mIpClientCallbacks != this) return;
mWaitForStopCv.open();
}
@@ -1199,6 +1237,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
Log.i(getTag(), "Network marked metered=" + isMetered
+ " trusted=" + newConfig.trusted + ", triggering capabilities update");
updateCapabilities(newConfig);
+ updateCurrentConnectionInfo();
}
@Override
@@ -1533,6 +1572,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiInfo.updatePacketRates(mTxPkts, mRxPkts, mLastLinkLayerStatsUpdate);
}
mWifiMetrics.incrementWifiLinkLayerUsageStats(mInterfaceName, stats);
+ updateCurrentConnectionInfo();
return stats;
}
@@ -1647,7 +1687,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
public boolean isConnecting() {
IState state = getCurrentState();
return state == mL2ConnectingState || state == mL2ConnectedState
- || state == mL3ProvisioningState;
+ || state == mWaitBeforeL3ProvisioningState || state == mL3ProvisioningState;
}
@Override
@@ -1691,11 +1731,10 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
* thread, will execute synchronously).
*
* @return a {@link WifiInfo} object containing information about the current connection
- * TODO (b/173551144): Change to direct call. Let callers use WifiThreadRunner if necessary.
*/
@Override
- public WifiInfo syncRequestConnectionInfo() {
- return mWifiThreadRunner.call(() -> new WifiInfo(mWifiInfo), new WifiInfo());
+ public WifiInfo getConnectionInfo() {
+ return new WifiInfo(mWifiInfo);
}
/**
@@ -1862,30 +1901,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
/**
- * Should only be used internally.
- * External callers should use {@link #syncGetCurrentNetwork()}.
- */
- private Network getCurrentNetwork() {
- if (mNetworkAgent != null) {
- return mNetworkAgent.getNetwork();
- } else {
- return null;
- }
- }
-
- /**
* Get Network object of currently connected wifi network, or null if not connected.
* @return Network object of current wifi network
*/
- public Network syncGetCurrentNetwork() {
- return mWifiThreadRunner.call(
- () -> {
- if (getCurrentState() == mL3ConnectedState
- || getCurrentState() == mRoamingState) {
- return getCurrentNetwork();
- }
- return null;
- }, null);
+ public Network getCurrentNetwork() {
+ if (getCurrentState() != mL3ConnectedState
+ && getCurrentState() != mRoamingState) return null;
+ return (mNetworkAgent != null) ? mNetworkAgent.getNetwork() : null;
}
/**
@@ -2310,6 +2332,8 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
return "CMD_IP_REACHABILITY_LOST";
case CMD_IP_REACHABILITY_FAILURE:
return "CMD_IP_REACHABILITY_FAILURE";
+ case CMD_IPCLIENT_STARTUP_TIMEOUT:
+ return "CMD_IPCLIENT_STARTUP_TIMEOUT";
case CMD_IPV4_PROVISIONING_FAILURE:
return "CMD_IPV4_PROVISIONING_FAILURE";
case CMD_IPV4_PROVISIONING_SUCCESS:
@@ -2366,6 +2390,8 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
return "CMD_UNWANTED_NETWORK";
case CMD_UPDATE_LINKPROPERTIES:
return "CMD_UPDATE_LINKPROPERTIES";
+ case CMD_IPCLIENT_CREATED:
+ return "CMD_IPCLIENT_CREATED";
case CMD_ACCEPT_EAP_SERVER_CERTIFICATE:
return "CMD_ACCEPT_EAP_SERVER_CERTIFICATE";
case CMD_REJECT_EAP_SERVER_CERTIFICATE:
@@ -2420,6 +2446,10 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
return "NETWORK_NOT_FOUND_EVENT";
case WifiMonitor.TOFU_ROOT_CA_CERTIFICATE:
return "TOFU_ROOT_CA_CERTIFICATE";
+ case RunnerState.STATE_ENTER_CMD:
+ return "Enter";
+ case RunnerState.STATE_EXIT_CMD:
+ return "Exit";
default:
return "what:" + what;
}
@@ -2627,6 +2657,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
* Increment various performance metrics
*/
mWifiMetrics.handlePollResult(mInterfaceName, mWifiInfo);
+ updateCurrentConnectionInfo();
return stats;
}
@@ -2668,6 +2699,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiInfo.setSuccessfulRxPacketsPerSecond(0);
mWifiScoreReport.reset();
mLastLinkLayerStats = null;
+ updateCurrentConnectionInfo();
}
private void updateLinkProperties(LinkProperties newLp) {
@@ -2724,10 +2756,18 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
+ final BroadcastOptions opts;
+ if (SdkLevel.isAtLeastU()) {
+ opts = BroadcastOptions.makeBasic();
+ opts.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
+ } else {
+ opts = null;
+ }
mBroadcastQueue.queueOrSendBroadcast(
mClientModeManager,
() -> mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
- android.Manifest.permission.ACCESS_WIFI_STATE));
+ android.Manifest.permission.ACCESS_WIFI_STATE,
+ opts == null ? null : opts.toBundle()));
}
private void sendLinkConfigurationChangedBroadcast() {
@@ -2855,6 +2895,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiInfo.setApMloLinkId(MloLink.INVALID_MLO_LINK_ID);
mWifiInfo.setAffiliatedMloLinks(Collections.emptyList());
}
+ updateCurrentConnectionInfo();
}
private SupplicantState handleSupplicantStateChange(StateChangeResult stateChangeResult) {
@@ -2877,6 +2918,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiInfo.setInformationElements(findMatchingInfoElements(stateChangeResult.bssid));
} else {
// Reset parameters according to WifiInfo.reset()
+ mWifiBlocklistMonitor.removeAffiliatedBssids(mWifiInfo.getBSSID());
mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
mWifiInfo.setBSSID(null);
mWifiInfo.setSSID(null);
@@ -2913,9 +2955,34 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
}
mWifiScoreCard.noteSupplicantStateChanged(mWifiInfo);
+ updateCurrentConnectionInfo();
return state;
}
+ private void handleNetworkConnectionEventInfo(
+ WifiConfiguration config, NetworkConnectionEventInfo connectionInfo) {
+ if (connectionInfo == null) return;
+
+ mWifiInfo.setBSSID(connectionInfo.bssid);
+ mWifiInfo.setNetworkId(connectionInfo.networkId);
+
+ if (config != null && connectionInfo.keyMgmtMask != null) {
+ // Besides allowed key management, pmf and wep keys are necessary to
+ // identify WPA3 Enterprise and WEP, so the original configuration
+ // is still necessary.
+ WifiConfiguration tmp = new WifiConfiguration(config);
+ tmp.setSecurityParams(connectionInfo.keyMgmtMask);
+ mWifiInfo.setCurrentSecurityType(tmp.getDefaultSecurityParams().getSecurityType());
+ // Update the last used security params.
+ config.getNetworkSelectionStatus().setLastUsedSecurityParams(
+ tmp.getDefaultSecurityParams());
+ mWifiConfigManager.setNetworkLastUsedSecurityParams(config.networkId,
+ tmp.getDefaultSecurityParams());
+ Log.i(getTag(), "Update current security type to " + mWifiInfo.getCurrentSecurityType()
+ + " from network connection event.");
+ }
+ }
+
private void updateWifiInfoWhenConnected(@NonNull WifiConfiguration config) {
mWifiInfo.setEphemeral(config.ephemeral);
mWifiInfo.setTrusted(config.trusted);
@@ -2932,11 +2999,76 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
SecurityParams securityParams = config.getNetworkSelectionStatus()
.getLastUsedSecurityParams();
if (securityParams != null) {
+ Log.i(getTag(), "Update current security type to " + securityParams.getSecurityType());
mWifiInfo.setCurrentSecurityType(securityParams.getSecurityType());
} else {
mWifiInfo.clearCurrentSecurityType();
Log.e(TAG, "Network connection candidate with no security parameters");
}
+ updateCurrentConnectionInfo();
+ }
+
+ /**
+ * Update mapping of affiliated BSSID in blocklist. Called when there is a change in MLO links.
+ */
+ private void updateBlockListAffiliatedBssids() {
+ /**
+ * getAffiliatedMloLinks() returns a list of MloLink objects for all the links
+ * advertised by AP-MLD including the associated link. Update mWifiBlocklistMonitor
+ * with all affiliated AP link MAC addresses, excluding the associated link, indexed
+ * with associated AP link MAC address (BSSID).
+ * For e.g.
+ * link1_bssid -> affiliated {link2_bssid, link3_bssid}
+ * Above mapping is used to block list all affiliated links when associated link is
+ * block listed.
+ */
+ List<String> affiliatedBssids = new ArrayList<>();
+ for (MloLink link : mWifiInfo.getAffiliatedMloLinks()) {
+ if (!Objects.equals(mWifiInfo.getBSSID(), link.getApMacAddress().toString())) {
+ affiliatedBssids.add(link.getApMacAddress().toString());
+ }
+ }
+ mWifiBlocklistMonitor.setAffiliatedBssids(mWifiInfo.getBSSID(), affiliatedBssids);
+ }
+
+ /**
+ * Clear MLO link states to UNASSOCIATED.
+ */
+ private void clearMloLinkStates() {
+ for (MloLink link : mWifiInfo.getAffiliatedMloLinks()) {
+ link.setState(MloLink.MLO_LINK_STATE_UNASSOCIATED);
+ }
+ }
+
+ /**
+ * Update the MLO link states to ACTIVE or IDLE depending on any traffic stream is mapped to the
+ * link.
+ *
+ * @param info MLO link object from HAL.
+ */
+ private void updateMloLinkStates(@Nullable WifiNative.ConnectionMloLinksInfo info) {
+ if (info == null) return;
+ for (int i = 0; i < info.links.length; i++) {
+ mWifiInfo.updateMloLinkState(info.links[i].getLinkId(),
+ info.links[i].isAnyTidMapped() ? MloLink.MLO_LINK_STATE_ACTIVE
+ : MloLink.MLO_LINK_STATE_IDLE);
+ }
+ }
+ /**
+ * Update the MLO link states to ACTIVE or IDLE depending on any traffic stream is mapped to the
+ * link. Also, update the link MAC address.
+ *
+ * @param info MLO link object from HAL.
+ */
+ private void updateMloLinkAddrAndStates(@Nullable WifiNative.ConnectionMloLinksInfo info) {
+ if (info == null) return;
+ for (int i = 0; i < info.links.length; i++) {
+ mWifiInfo.updateMloLinkStaAddress(info.links[i].getLinkId(),
+ info.links[i].getMacAddress());
+ mWifiInfo.updateMloLinkState(info.links[i].getLinkId(),
+ info.links[i].isAnyTidMapped() ? MloLink.MLO_LINK_STATE_ACTIVE
+ : MloLink.MLO_LINK_STATE_IDLE);
+ }
}
private void updateWifiInfoLinkParamsAfterAssociation() {
@@ -2951,16 +3083,8 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(mInterfaceName,
maxTxLinkSpeedMbps, maxRxLinkSpeedMbps);
if (mLastConnectionCapabilities.wifiStandard == ScanResult.WIFI_STANDARD_11BE) {
- WifiNative.ConnectionMloLinksInfo info =
- mWifiNative.getConnectionMloLinksInfo(mInterfaceName);
- if (info != null) {
- for (int i = 0; i < info.links.length; i++) {
- mWifiInfo.updateMloLinkStaAddress(info.links[i].linkId,
- info.links[i].staMacAddress);
- mWifiInfo.updateMloLinkState(
- info.links[i].linkId, MloLink.MLO_LINK_STATE_ACTIVE);
- }
- }
+ updateMloLinkAddrAndStates(mWifiNative.getConnectionMloLinksInfo(mInterfaceName));
+ updateBlockListAffiliatedBssids();
}
if (mVerboseLoggingEnabled) {
StringBuilder sb = new StringBuilder();
@@ -2969,6 +3093,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
.append(" maxRxSpeed: ").append(maxRxLinkSpeedMbps)
.toString());
}
+ updateCurrentConnectionInfo();
}
/**
@@ -2978,7 +3103,8 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
if (mIpClient != null) {
Pair<String, String> p = mWifiScoreCard.getL2KeyAndGroupHint(mWifiInfo);
if (!p.equals(mLastL2KeyAndGroupHint)) {
- final MacAddress currentBssid = getMacAddressFromBssidString(mWifiInfo.getBSSID());
+ final MacAddress currentBssid =
+ NativeUtil.getMacAddressOrNull(mWifiInfo.getBSSID());
final Layer2Information l2Information = new Layer2Information(
p.first, p.second, currentBssid);
// Update current BSSID on IpClient side whenever l2Key and groupHint
@@ -3048,6 +3174,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiScoreReport.stopConnectedNetworkScorer();
/* Reset data structures */
mWifiScoreReport.reset();
+ mWifiBlocklistMonitor.removeAffiliatedBssids(mWifiInfo.getBSSID());
mWifiInfo.reset();
/* Reset roaming parameters */
mIsAutoRoaming = false;
@@ -3076,6 +3203,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
if (!newConnectionInProgress) {
mIsUserSelected = false;
}
+ updateCurrentConnectionInfo();
}
void handlePreDhcpSetup() {
@@ -3454,6 +3582,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
updateCapabilities();
+ updateCurrentConnectionInfo();
}
private void handleSuccessfulIpConfiguration() {
@@ -3498,6 +3627,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
* disconnect thru supplicant, we will let autojoin retry connecting to the network
*/
mWifiNative.disconnect(mInterfaceName);
+ updateCurrentConnectionInfo();
}
private void handleIpReachabilityLost() {
@@ -3507,6 +3637,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// Disconnect via supplicant, and let autojoin retry connecting to the network.
mWifiNative.disconnect(mInterfaceName);
+ updateCurrentConnectionInfo();
}
private void handleIpReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) {
@@ -3559,10 +3690,11 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mQosPolicyRequestHandler.setNetworkAgent(mNetworkAgent);
}
- transitionTo(mL3ProvisioningState);
+ transitionTo(mWaitBeforeL3ProvisioningState);
} else {
logd("Invalid failure reason from onIpReachabilityFailure");
}
+ updateCurrentConnectionInfo();
}
private NetworkAgentConfig getNetworkAgentConfigInternal(WifiConfiguration config) {
@@ -3694,7 +3826,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
return;
}
String currentMacString = mWifiNative.getMacAddress(mInterfaceName);
- MacAddress currentMac = getMacAddressFromBssidString(currentMacString);
+ MacAddress currentMac = NativeUtil.getMacAddressOrNull(currentMacString);
MacAddress newMac = mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config,
isSecondaryInternet() && mClientModeManager.isSecondaryInternetDbsAp());
if (!WifiConfiguration.isValidMacAddressForRandomization(newMac)) {
@@ -3802,6 +3934,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// Retrieve and store the factory MAC address (on first bootup).
retrieveFactoryMacAddressAndStoreIfNecessary();
+ updateCurrentConnectionInfo();
}
/**
@@ -3814,13 +3947,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiDiagnostics.stopLogging(mInterfaceName);
mMboOceController.disable();
- if (mIpClient != null && mIpClient.shutdown()) {
- // Block to make sure IpClient has really shut down, lest cleanup
- // race with, say, bringup code over in tethering.
- mIpClientCallbacks.awaitShutdown();
- mIpClientCallbacks = null;
- mIpClient = null;
- }
+ maybeShutdownIpclient();
deregisterForWifiMonitorEvents(); // uses mInterfaceName, must call before nulling out
// TODO: b/79504296 This broadcast has been deprecated and should be removed
sendSupplicantConnectionChangedBroadcast(false);
@@ -3830,6 +3957,9 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
* Helper method called when a L3 connection is successfully established to a network.
*/
void registerConnected() {
+ if (isPrimary()) {
+ mWifiInjector.getActiveModeWarden().setCurrentNetwork(getCurrentNetwork());
+ }
if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
WifiConfiguration config = getConnectedWifiConfigurationInternal();
boolean shouldSetUserConnectChoice = config != null
@@ -3849,6 +3979,11 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
void registerDisconnected() {
+ // The role of the ClientModeManager may have been changed to scan only before handling
+ // the network disconnect.
+ if (isPrimary() || mClientModeManager.getRole() == ROLE_CLIENT_SCAN_ONLY) {
+ mWifiInjector.getActiveModeWarden().setCurrentNetwork(getCurrentNetwork());
+ }
if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
mWifiConfigManager.updateNetworkAfterDisconnect(mLastNetworkId);
}
@@ -3935,17 +4070,8 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
return scanDetailCache.getScanResult(bssid);
}
- private MacAddress getMacAddressFromBssidString(@Nullable String bssidStr) {
- try {
- return (bssidStr != null) ? MacAddress.fromString(bssidStr) : null;
- } catch (IllegalArgumentException e) {
- Log.e(getTag(), "Invalid BSSID format: " + bssidStr);
- return null;
- }
- }
-
private MacAddress getCurrentBssidInternalMacAddress() {
- return getMacAddressFromBssidString(mLastBssid);
+ return NativeUtil.getMacAddressOrNull(mLastBssid);
}
private void connectToNetwork(WifiConfiguration config) {
@@ -3968,11 +4094,31 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
}
+ private void makeIpClient() {
+ mIpClientCallbacks = new IpClientCallbacksImpl();
+ mFacade.makeIpClient(mContext, mInterfaceName, mIpClientCallbacks);
+ mIpClientCallbacks.awaitCreation();
+ }
+
+ private void maybeShutdownIpclient() {
+ if (mIpClient == null) return;
+ if (!mIpClient.shutdown()) {
+ logd("Fail to shut down IpClient");
+ return;
+ }
+
+ // Block to make sure IpClient has really shut down, lest cleanup
+ // race with, say, bringup code over in tethering.
+ mIpClientCallbacks.awaitShutdown();
+ mIpClientCallbacks = null;
+ mIpClient = null;
+ }
+
/********************************************************
* HSM states
*******************************************************/
- class ConnectableState extends State {
+ class ConnectableState extends RunnerState {
private boolean mIsScreenStateChangeReceiverRegistered = false;
BroadcastReceiver mScreenStateChangeReceiver = new BroadcastReceiver() {
@Override
@@ -3986,17 +4132,18 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
};
+ ConnectableState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
Log.d(getTag(), "entering ConnectableState: ifaceName = " + mInterfaceName);
setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
mWifiStateTracker.updateState(mInterfaceName, WifiStateTracker.INVALID);
- mIpClientCallbacks = new IpClientCallbacksImpl();
- Log.d(getTag(), "Start makeIpClient ifaceName = " + mInterfaceName);
- mFacade.makeIpClient(mContext, mInterfaceName, mIpClientCallbacks);
- mIpClientCallbacks.awaitCreation();
+ makeIpClient();
}
private void continueEnterSetup(IpClientManager ipClientManager) {
@@ -4026,10 +4173,11 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiMetrics.setWifiState(mInterfaceName, WifiMetricsProto.WifiLog.WIFI_DISCONNECTED);
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_WIFI_ENABLED);
mWifiScoreCard.noteSupplicantStateChanged(mWifiInfo);
+ updateCurrentConnectionInfo();
}
@Override
- public void exit() {
+ public void exitImpl() {
// Inform metrics that Wifi is being disabled (Toggled, airplane enabled, etc)
mWifiMetrics.setWifiState(mInterfaceName, WifiMetricsProto.WifiLog.WIFI_DISABLED);
mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_WIFI_DISABLED);
@@ -4047,9 +4195,15 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ClientModeImpl.class.getSimpleName() + "."
+ + ConnectableState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
switch (message.what) {
- case CMD_CONNECTABLE_STATE_SETUP:
+ case CMD_IPCLIENT_CREATED:
if (mIpClient != null) {
loge("Setup connectable state again when IpClient is ready?");
} else {
@@ -4149,6 +4303,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
String currentMacAddress = mWifiNative.getMacAddress(mInterfaceName);
mWifiInfo.setMacAddress(currentMacAddress);
+ updateCurrentConnectionInfo();
Log.i(getTag(), "Connecting with " + currentMacAddress + " as the mac address");
mTargetWifiConfiguration = config;
@@ -4555,7 +4710,9 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
if (!uids.isEmpty()
&& !mWifiConnectivityManager.hasMultiInternetConnection()) {
// Remove internet capability.
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ if (!mNetworkFactory.shouldHaveInternetCapabilities()) {
+ builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ }
if (SdkLevel.isAtLeastS()) {
builder.setUids(getUidRangeSet(uids));
} else {
@@ -4660,6 +4817,22 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
updateCapabilities(getConnectedWifiConfigurationInternal());
}
+ /**
+ * Check if BSSID belongs to any of the affiliated link BSSID's.
+ * @param bssid BSSID of the AP.
+ * @return true if BSSID matches to one of the affiliated link BSSIDs, false otherwise.
+ */
+ public boolean isAffiliatedLinkBssid(@NonNull MacAddress bssid) {
+ List<MloLink> links = mWifiInfo.getAffiliatedMloLinks();
+ for (MloLink link: links) {
+ if (link.getApMacAddress().equals(bssid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
private void updateCapabilities(WifiConfiguration currentWifiConfiguration) {
updateCapabilities(getCapabilities(currentWifiConfiguration, getConnectedBssidInternal()));
}
@@ -4867,15 +5040,19 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
sendMessage(CMD_NETWORK_STATUS, status);
}
- class ConnectingOrConnectedState extends State {
+ class ConnectingOrConnectedState extends RunnerState {
+ ConnectingOrConnectedState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
if (mVerboseLoggingEnabled) Log.v(getTag(), "Entering ConnectingOrConnectedState");
mCmiMonitor.onConnectionStart(mClientModeManager);
}
@Override
- public void exit() {
+ public void exitImpl() {
if (mVerboseLoggingEnabled) Log.v(getTag(), "Exiting ConnectingOrConnectedState");
mCmiMonitor.onConnectionEnd(mClientModeManager);
@@ -4892,9 +5069,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
Log.e(getTag(), "Failed to set random MAC address on disconnect");
}
}
+ if (mWifiInfo.getBSSID() != null) {
+ mWifiBlocklistMonitor.removeAffiliatedBssids(mWifiInfo.getBSSID());
+ }
mWifiInfo.reset();
mWifiInfo.setSupplicantState(SupplicantState.DISCONNECTED);
mWifiScoreCard.noteSupplicantStateChanged(mWifiInfo);
+ updateCurrentConnectionInfo();
// For secondary client roles, they should stop themselves upon disconnection.
// - Primary role shouldn't because it is persistent, and should try connecting to other
@@ -4918,7 +5099,14 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ClientModeImpl.class.getSimpleName() + "."
+ + ConnectingOrConnectedState.class.getSimpleName() + "." + getWhatToString(
+ what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
boolean handleStatus = HANDLED;
switch (message.what) {
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: {
@@ -5010,8 +5198,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
sendMessage(CMD_DISCONNECT, StaEvent.DISCONNECT_UNKNOWN_NETWORK);
break;
}
- mWifiInfo.setBSSID(mLastBssid);
- mWifiInfo.setNetworkId(mLastNetworkId);
+ handleNetworkConnectionEventInfo(config, connectionInfo);
mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName));
ScanDetailCache scanDetailCache =
@@ -5090,6 +5277,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiInfo.setNetworkKey(config.getNetworkKeyFromSecurityType(
mWifiInfo.getCurrentSecurityType()));
updateLayer2Information();
+ updateCurrentConnectionInfo();
transitionTo(mL3ProvisioningState);
break;
}
@@ -5250,9 +5438,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
}
- class L2ConnectingState extends State {
+ class L2ConnectingState extends RunnerState {
+ L2ConnectingState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
if (mVerboseLoggingEnabled) Log.v(getTag(), "Entering L2ConnectingState");
// Make sure we connect: we enter this state prior to connecting to a new
// network. In some cases supplicant ignores the connect requests (it might not
@@ -5265,7 +5457,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public void exit() {
+ public void exitImpl() {
if (mVerboseLoggingEnabled) Log.v(getTag(), "Exiting L2ConnectingState");
// Cancel any pending CMD_CONNECTING_WATCHDOG_TIMER since this is only valid in
// L2ConnectingState anyway.
@@ -5273,7 +5465,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ClientModeImpl.class.getSimpleName() + "."
+ + L2ConnectingState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
boolean handleStatus = HANDLED;
switch (message.what) {
case WifiMonitor.NETWORK_NOT_FOUND_EVENT:
@@ -5490,6 +5688,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
config.getNetworkKeyFromSecurityType(
mWifiInfo.getCurrentSecurityType()));
}
+ updateCurrentConnectionInfo();
}
sendNetworkChangeBroadcast(
WifiInfo.getDetailedStateOf(stateChangeResult.state));
@@ -5592,7 +5791,11 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
}
- class L2ConnectedState extends State {
+ class L2ConnectedState extends RunnerState {
+ L2ConnectedState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
class RssiEventHandler implements WifiNative.WifiRssiEventHandler {
@Override
public void onRssiThresholdBreached(byte curRssi) {
@@ -5606,7 +5809,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
RssiEventHandler mRssiEventHandler = new RssiEventHandler();
@Override
- public void enter() {
+ public void enterImpl() {
mRssiPollToken++;
if (mEnableRssiPolling) {
if (isPrimary()) {
@@ -5651,7 +5854,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public void exit() {
+ public void exitImpl() {
// This is handled by receiving a NETWORK_DISCONNECTION_EVENT in ConnectableState
// Bug: 15347363
// For paranoia's sake, call handleNetworkDisconnect
@@ -5672,7 +5875,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ClientModeImpl.class.getSimpleName() + "."
+ + L2ConnectedState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
boolean handleStatus = HANDLED;
switch (message.what) {
@@ -5775,11 +5984,12 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
case WifiMonitor.NETWORK_CONNECTION_EVENT: {
NetworkConnectionEventInfo connectionInfo =
(NetworkConnectionEventInfo) message.obj;
- mWifiInfo.setBSSID(connectionInfo.bssid);
mLastNetworkId = connectionInfo.networkId;
- mWifiInfo.setNetworkId(mLastNetworkId);
+ handleNetworkConnectionEventInfo(
+ getConnectedWifiConfigurationInternal(), connectionInfo);
mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName));
updateLayer2Information();
+ updateCurrentConnectionInfo();
if (!Objects.equals(mLastBssid, connectionInfo.bssid)) {
mLastBssid = connectionInfo.bssid;
sendNetworkChangeBroadcastWithCurrentState();
@@ -5875,6 +6085,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
sendNetworkChangeBroadcastWithCurrentState();
mMultiInternetManager.notifyBssidAssociatedEvent(mClientModeManager);
+ updateCurrentConnectionInfo();
}
break;
}
@@ -5882,6 +6093,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
case CMD_RSSI_THRESHOLD_BREACHED: {
byte currRssi = (byte) message.arg1;
processRssiThreshold(currRssi, message.what, mRssiEventHandler);
+ updateCurrentConnectionInfo();
break;
}
case CMD_STOP_RSSI_MONITORING_OFFLOAD: {
@@ -5962,6 +6174,32 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
break;
}
+ case WifiMonitor.MLO_LINKS_INFO_CHANGED:
+ WifiMonitor.MloLinkInfoChangeReason reason =
+ (WifiMonitor.MloLinkInfoChangeReason) message.obj;
+ WifiNative.ConnectionMloLinksInfo newInfo =
+ mWifiNative.getConnectionMloLinksInfo(mInterfaceName);
+ if (reason == WifiMonitor.MloLinkInfoChangeReason.TID_TO_LINK_MAP) {
+ // Traffic stream mapping changed. Update link states.
+ updateMloLinkStates(newInfo);
+ // There is a change in link capabilities. Will trigger android.net
+ // .ConnectivityManager.NetworkCallback.onCapabilitiesChanged().
+ updateCapabilities();
+ } else if (reason
+ == WifiMonitor.MloLinkInfoChangeReason.MULTI_LINK_RECONFIG_AP_REMOVAL) {
+ // Link is removed. Set removed link state to MLO_LINK_STATE_UNASSOCIATED.
+ // Also update block list mapping, as there is a change in affiliated
+ // BSSIDs.
+ clearMloLinkStates();
+ updateMloLinkStates(newInfo);
+ updateBlockListAffiliatedBssids();
+ // There is a change in link capabilities. Will trigger android.net
+ // .ConnectivityManager.NetworkCallback.onCapabilitiesChanged().
+ updateCapabilities();
+ } else {
+ logw("MLO_LINKS_INFO_CHANGED with UNKNOWN reason");
+ }
+ break;
default: {
handleStatus = NOT_HANDLED;
break;
@@ -6054,9 +6292,82 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
return triggerType;
}
- class L3ProvisioningState extends State {
+ // Before transition to L3ProvisioningState, always shut down the current IpClient
+ // instance and recreate a new IpClient and IpClientCallbacks instance, defer received
+ // messages in this state except CMD_IPCLIENT_CREATED, recreation of a new IpClient
+ // guarantees the out-of-date callbacks will be ignored, otherwise, it's not easy to
+ // differentiate callbacks which comes from new IpClient or legacy IpClient. So far
+ // only transit to this state iff IP reachability gets lost post roam.
+ class WaitBeforeL3ProvisioningState extends RunnerState {
+ WaitBeforeL3ProvisioningState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
+ @Override
+ public void enterImpl() {
+ // Recreate a new IpClient instance.
+ maybeShutdownIpclient();
+ makeIpClient();
+
+ // Given that {@link IpClientCallbacks#awaitCreation} is invoked when making a
+ // IpClient instance, which waits for {@link IPCLIENT_STARTUP_TIMEOUT_MS}.
+ // If await IpClient recreation times out, then send timeout message to proceed
+ // to Disconnected state, otherwise, we will never exit this state.
+ sendMessage(CMD_IPCLIENT_STARTUP_TIMEOUT);
+ }
+
@Override
- public void enter() {
+ public void exitImpl() {
+ removeMessages(CMD_IPCLIENT_STARTUP_TIMEOUT);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
+ switch(message.what) {
+ case CMD_IPCLIENT_CREATED: {
+ mIpClient = (IpClientManager) message.obj;
+ transitionTo(mL3ProvisioningState);
+ break;
+ }
+
+ case CMD_IPCLIENT_STARTUP_TIMEOUT: {
+ Log.e(getTag(), "Fail to create an IpClient instance within "
+ + IPCLIENT_STARTUP_TIMEOUT_MS + "ms");
+ handleNetworkDisconnect(false,
+ WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__TIMEOUT);
+ transitionTo(mDisconnectedState);
+ break;
+ }
+
+ default:
+ // Do not process any other messages except CMD_IPCLIENT_CREATED and
+ // CMD_IPCLIENT_STARTUP_TIMEOUT. This means that this state can be very
+ // simple because it does not need to worry about messasge ordering.
+ // Re-creating IpClient should only take a few milliseconds, but in the
+ // worst case, this will result in the state machine not processing any
+ // messages for IPCLIENT_STARTUP_TIMEOUT_MS.
+ deferMessage(message);
+ }
+
+ logStateAndMessage(message, this);
+ return HANDLED;
+ }
+
+ @Override
+ String getMessageLogRec(int what) {
+ return ClientModeImpl.class.getSimpleName() + "."
+ + WaitBeforeL3ProvisioningState.class.getSimpleName() + "."
+ + getWhatToString(what);
+ }
+ }
+
+ class L3ProvisioningState extends RunnerState {
+ L3ProvisioningState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
+ @Override
+ public void enterImpl() {
if (mInsecureEapNetworkHandler.startUserApprovalIfNecessary(mIsUserSelected)) {
return;
}
@@ -6065,7 +6376,17 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public boolean processMessage(Message message) {
+ public void exitImpl() {
+ }
+
+ @Override
+ String getMessageLogRec(int what) {
+ return ClientModeImpl.class.getSimpleName() + "."
+ + L3ProvisioningState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
boolean handleStatus = HANDLED;
switch(message.what) {
@@ -6129,7 +6450,6 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// Get Link layer stats so as we get fresh tx packet counters
getWifiLinkLayerStats();
}
-
}
/**
@@ -6149,10 +6469,15 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
sendNetworkChangeBroadcast(DetailedState.CONNECTED);
}
- class RoamingState extends State {
+ class RoamingState extends RunnerState {
boolean mAssociated;
+
+ RoamingState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
if (mVerboseLoggingEnabled) {
log("RoamingState Enter mScreenOn=" + mScreenOn);
}
@@ -6164,8 +6489,19 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mRoamWatchdogCount, 0), ROAM_GUARD_TIMER_MSEC);
mAssociated = false;
}
+
+ @Override
+ public void exitImpl() {
+ }
+
+ @Override
+ String getMessageLogRec(int what) {
+ return ClientModeImpl.class.getSimpleName() + "." + RoamingState.class.getSimpleName()
+ + "." + getWhatToString(what);
+ }
+
@Override
- public boolean processMessage(Message message) {
+ public boolean processMessageImpl(Message message) {
boolean handleStatus = HANDLED;
switch (message.what) {
@@ -6239,11 +6575,11 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
(NetworkConnectionEventInfo) message.obj;
mLastNetworkId = connectionInfo.networkId;
mLastBssid = connectionInfo.bssid;
- mWifiInfo.setBSSID(mLastBssid);
- mWifiInfo.setNetworkId(mLastNetworkId);
+ handleNetworkConnectionEventInfo(
+ getConnectedWifiConfigurationInternal(), connectionInfo);
updateLayer2Information();
sendNetworkChangeBroadcastWithCurrentState();
-
+ updateCurrentConnectionInfo();
// Successful framework roam! (probably)
mWifiBlocklistMonitor.handleBssidConnectionSuccess(mLastBssid,
mWifiInfo.getSSID());
@@ -6309,9 +6645,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
}
- class L3ConnectedState extends State {
+ class L3ConnectedState extends RunnerState {
+ L3ConnectedState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
if (mVerboseLoggingEnabled) {
log("Enter ConnectedState mScreenOn=" + mScreenOn);
}
@@ -6344,9 +6684,17 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// too many places to record L3 failure with too many failure reasons.
// So only record success here.
mWifiMetrics.noteFirstL3ConnectionAfterBoot(true);
+ updateCurrentConnectionInfo();
}
+
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ClientModeImpl.class.getSimpleName() + "."
+ + L3ConnectedState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
boolean handleStatus = HANDLED;
switch (message.what) {
@@ -6560,7 +6908,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public void exit() {
+ public void exitImpl() {
logd("ClientModeImpl: Leaving Connected state");
mWifiConnectivityManager.handleConnectionStateChanged(
mClientModeManager,
@@ -6570,9 +6918,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
}
- class DisconnectedState extends State {
+ class DisconnectedState extends RunnerState {
+ DisconnectedState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
Log.i(getTag(), "disconnectedstate enter");
// We don't scan frequently if this is a temporary disconnect
// due to p2p
@@ -6598,7 +6950,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ClientModeImpl.class.getSimpleName() + "."
+ + DisconnectedState.class.getSimpleName() + "." + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
boolean handleStatus = HANDLED;
switch (message.what) {
@@ -6632,7 +6990,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
@Override
- public void exit() {
+ public void exitImpl() {
mWifiConnectivityManager.handleConnectionStateChanged(
mClientModeManager,
WifiConnectivityManager.WIFI_STATE_TRANSITIONING);
@@ -6807,9 +7165,6 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
* a factory MAC address stored in config store, retrieve it now and store it.
*
* Note:
- * <li> This is needed to ensure that we use the same MAC address for connecting to
- * networks with MAC randomization disabled regardless of whether the connection is
- * occurring on "wlan0" or "wlan1" due to STA + STA. </li>
* <li> Retries added to deal with any transient failures when invoking
* {@link WifiNative#getStaFactoryMacAddress(String)}.
*/
@@ -6819,20 +7174,26 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiGlobals.isSaveFactoryMacToConfigStoreEnabled();
if (saveFactoryMacInConfigStore) {
// Already present, just return.
- String factoryMacAddressStr = mSettingsConfigStore.get(WIFI_STA_FACTORY_MAC_ADDRESS);
+ String factoryMacAddressStr = mSettingsConfigStore.get(isPrimary()
+ ? WIFI_STA_FACTORY_MAC_ADDRESS : SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS);
if (factoryMacAddressStr != null) return MacAddress.fromString(factoryMacAddressStr);
}
MacAddress factoryMacAddress = mWifiNative.getStaFactoryMacAddress(mInterfaceName);
if (factoryMacAddress == null) {
// the device may be running an older HAL (version < 1.3).
- Log.w(TAG, "Failed to retrieve factory MAC address");
+ Log.w(TAG, (isPrimary() ? "Primary" : "Secondary")
+ + " failed to retrieve factory MAC address");
return null;
}
if (saveFactoryMacInConfigStore) {
- mSettingsConfigStore.put(WIFI_STA_FACTORY_MAC_ADDRESS, factoryMacAddress.toString());
- Log.i(TAG, "Factory MAC address stored in config store: " + factoryMacAddress);
- }
- Log.i(TAG, "Factory MAC address retrieved: " + factoryMacAddress);
+ mSettingsConfigStore.put(isPrimary()
+ ? WIFI_STA_FACTORY_MAC_ADDRESS : SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS,
+ factoryMacAddress.toString());
+ Log.i(TAG, (isPrimary() ? "Primary" : "Secondary")
+ + " factory MAC address stored in config store: " + factoryMacAddress);
+ }
+ Log.i(TAG, (isPrimary() ? "Primary" : "Secondary")
+ + " factory MAC address retrieved: " + factoryMacAddress);
return factoryMacAddress;
}
@@ -7217,11 +7578,11 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
scanResultInfo = new ProvisioningConfiguration.ScanResultInfo(scanResult.SSID,
scanResult.BSSID, ies);
}
-
+ final Network network = (mNetworkAgent != null) ? mNetworkAgent.getNetwork() : null;
if (!isUsingStaticIp) {
prov = new ProvisioningConfiguration.Builder()
.withPreDhcpAction()
- .withNetwork(getCurrentNetwork())
+ .withNetwork(network)
.withDisplayName(config.SSID)
.withScanResultInfo(scanResultInfo)
.withLayer2Information(layer2Info);
@@ -7229,7 +7590,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
StaticIpConfiguration staticIpConfig = config.getStaticIpConfiguration();
prov = new ProvisioningConfiguration.Builder()
.withStaticConfiguration(staticIpConfig)
- .withNetwork(getCurrentNetwork())
+ .withNetwork(network)
.withDisplayName(config.SSID)
.withLayer2Information(layer2Info);
}
@@ -7596,6 +7957,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
sendNetworkChangeBroadcast(DetailedState.CONNECTING);
mWifiInfo.setFrequency(scanResult.frequency);
mWifiInfo.setBSSID(associatedBssid);
+ updateCurrentConnectionInfo();
return true;
}
@@ -7670,4 +8032,10 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
}
}
+
+ private void updateCurrentConnectionInfo() {
+ if (isPrimary()) {
+ mWifiInjector.getActiveModeWarden().updateCurrentConnectionInfo();
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/ConcreteClientModeManager.java b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
index 7f6bbc0b72..5186018dcc 100644
--- a/service/java/com/android/server/wifi/ConcreteClientModeManager.java
+++ b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
@@ -26,6 +26,7 @@ import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.DhcpResultsParcelable;
+import android.net.MacAddress;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
@@ -178,7 +179,8 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
private String getTag() {
- return TAG + "[" + (mClientInterfaceName == null ? "unknown" : mClientInterfaceName) + "]";
+ return TAG + "[" + mId + ":" + (mClientInterfaceName == null ? "unknown"
+ : mClientInterfaceName) + "]";
}
/**
@@ -714,10 +716,10 @@ public class ConcreteClientModeManager implements ClientModeManager {
public static final int CMD_INTERFACE_DESTROYED = 4;
public static final int CMD_INTERFACE_DOWN = 5;
public static final int CMD_SWITCH_TO_SCAN_ONLY_MODE_CONTINUE = 6;
- private final State mIdleState = new IdleState();
- private final State mStartedState = new StartedState();
- private final State mScanOnlyModeState = new ScanOnlyModeState();
- private final State mConnectModeState = new ConnectModeState();
+ private final State mIdleState;
+ private final State mStartedState;
+ private final State mScanOnlyModeState;
+ private final State mConnectModeState;
// Workaround since we cannot use transitionTo(mScanOnlyModeState, RoleChangeInfo)
private RoleChangeInfo mScanRoleChangeInfoToSetOnTransition = null;
// Workaround since we cannot use transitionTo(mConnectModeState, RoleChangeInfo)
@@ -743,6 +745,8 @@ public class ConcreteClientModeManager implements ClientModeManager {
mClientModeImpl.handleIfaceDestroyed();
}
+ // set it to null since the interface had been destroyed
+ mClientInterfaceName = null;
sendMessage(CMD_INTERFACE_DESTROYED);
}
}
@@ -764,7 +768,12 @@ public class ConcreteClientModeManager implements ClientModeManager {
ClientModeStateMachine(Looper looper) {
super(TAG, looper);
-
+ final int threshold = mContext.getResources().getInteger(
+ R.integer.config_wifiConfigurationWifiRunnerThresholdInMs);
+ mIdleState = new IdleState(threshold);
+ mStartedState = new StartedState(threshold);
+ mScanOnlyModeState = new ScanOnlyModeState(threshold);
+ mConnectModeState = new ConnectModeState(threshold);
// CHECKSTYLE:OFF IndentationCheck
addState(mIdleState);
addState(mStartedState, mIdleState);
@@ -834,6 +843,10 @@ public class ConcreteClientModeManager implements ClientModeManager {
return "CMD_INTERFACE_DOWN";
case CMD_SWITCH_TO_SCAN_ONLY_MODE_CONTINUE:
return "CMD_SWITCH_TO_SCAN_ONLY_MODE_CONTINUE";
+ case RunnerState.STATE_ENTER_CMD:
+ return "Enter";
+ case RunnerState.STATE_EXIT_CMD:
+ return "Exit";
default:
return "what:" + what;
}
@@ -865,11 +878,17 @@ public class ConcreteClientModeManager implements ClientModeManager {
private void setRoleInternalAndInvokeCallback(@NonNull RoleChangeInfo roleChangeInfo) {
if (roleChangeInfo.role == mRole) return;
if (mRole == null) {
- Log.v(getTag(), "ClientModeManager started in role: " + roleChangeInfo);
+ if (mVerboseLoggingEnabled) {
+ Log.v(getTag(), "CurState:" + getCurrentStateName()
+ + ", clientModeManager started in role: " + roleChangeInfo);
+ }
setRoleInternal(roleChangeInfo);
mModeListener.onStarted(ConcreteClientModeManager.this);
} else {
- Log.v(getTag(), "ClientModeManager role changed: " + roleChangeInfo);
+ if (mVerboseLoggingEnabled) {
+ Log.v(getTag(), "CurState:" + getCurrentStateName()
+ + ", clientModeManager role changed: " + roleChangeInfo);
+ }
setRoleInternal(roleChangeInfo);
reset();
mModeListener.onRoleChanged(ConcreteClientModeManager.this);
@@ -879,26 +898,43 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
}
- private class IdleState extends State {
+ private class IdleState extends RunnerState {
+ IdleState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
Log.d(getTag(), "entering IdleState");
mClientInterfaceName = null;
mIfaceIsUp = false;
}
@Override
- public void exit() {
+ public void exitImpl() {
// Sometimes the wifi handler thread may become blocked that the statemachine
// will exit in the IdleState without first entering StartedState. Trigger a
// cleanup here in case the above sequence happens. This the statemachine was
// started normally this will will not send a duplicate broadcast since mIsStopped
// will get set to false the first time the exit happens.
cleanupOnQuitIfApplicable();
+ Log.d(getTag(), "IdleState.exit()");
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ConcreteClientModeManager.class.getSimpleName() + "."
+ + IdleState.class.getSimpleName() + "."
+ + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(getTag(),
+ getName() + " cmd = " + getWhatToString(message.what) + " "
+ + message.toString());
+ }
switch (message.what) {
case CMD_START:
// Always start in scan mode first.
@@ -923,14 +959,17 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
break;
default:
- Log.d(getTag(), "received an invalid message: " + message);
+ Log.d(getTag(), getName() + ", received an invalid message: " + message);
return NOT_HANDLED;
}
return HANDLED;
}
}
- private class StartedState extends State {
+ private class StartedState extends RunnerState {
+ StartedState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
private void onUpChanged(boolean isUp) {
if (isUp == mIfaceIsUp) {
@@ -939,7 +978,7 @@ public class ConcreteClientModeManager implements ClientModeManager {
mIfaceIsUp = isUp;
if (!isUp) {
// if the interface goes down we should exit and go back to idle state.
- Log.d(getTag(), "interface down!");
+ Log.d(getTag(), getName() + ", interface down!");
mStateMachine.sendMessage(CMD_INTERFACE_DOWN);
}
if (mClientModeImpl != null) {
@@ -948,7 +987,7 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- public void enter() {
+ public void enterImpl() {
Log.d(getTag(), "entering StartedState");
mIfaceIsUp = false;
mIsStopped = false;
@@ -956,7 +995,19 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ConcreteClientModeManager.class.getSimpleName() + "."
+ + StartedState.class.getSimpleName() + "."
+ + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(getTag(),
+ getName() + " cmd = " + getWhatToString(message.what) + " "
+ + message.toString());
+ }
switch (message.what) {
case CMD_START:
// Already started, ignore this command.
@@ -998,8 +1049,9 @@ public class ConcreteClientModeManager implements ClientModeManager {
break;
}
case CMD_INTERFACE_DOWN:
- Log.e(getTag(), "Detected an interface down, reporting failure to "
- + "SelfRecovery");
+ Log.e(getTag(),
+ getName() + ", detected an interface down, reporting failure to "
+ + "SelfRecovery");
mSelfRecovery.trigger(SelfRecovery.REASON_STA_IFACE_DOWN);
// once interface down, nothing else to do... stop the state machine
captureObituaryAndQuitNow();
@@ -1009,7 +1061,7 @@ public class ConcreteClientModeManager implements ClientModeManager {
onUpChanged(isUp);
break;
case CMD_INTERFACE_DESTROYED:
- Log.e(getTag(), "interface destroyed - client mode stopping");
+ Log.e(getTag(), getName() + ", interface destroyed - client mode stopping");
mClientInterfaceName = null;
// once interface destroyed, nothing else to do... stop the state machine
captureObituaryAndQuitNow();
@@ -1024,22 +1076,26 @@ public class ConcreteClientModeManager implements ClientModeManager {
* Clean up state, unregister listeners and update wifi state.
*/
@Override
- public void exit() {
+ public void exitImpl() {
if (mClientInterfaceName != null) {
mWifiNative.teardownInterface(mClientInterfaceName);
mClientInterfaceName = null;
mIfaceIsUp = false;
}
- Log.i(getTag(), "StartedState#exit(), setting mRole = null");
+ Log.i(getTag(), "StartedState.exit(), setting mRole = null");
mIsStopped = true;
cleanupOnQuitIfApplicable();
}
}
- private class ScanOnlyModeState extends State {
+ private class ScanOnlyModeState extends RunnerState {
+ ScanOnlyModeState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
Log.d(getTag(), "entering ScanOnlyModeState");
if (mClientInterfaceName != null) {
@@ -1066,7 +1122,19 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ConcreteClientModeManager.class.getSimpleName() + "."
+ + ScanOnlyModeState.class.getSimpleName() + "."
+ + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(getTag(),
+ getName() + " cmd = " + getWhatToString(message.what) + " "
+ + message.toString());
+ }
switch (message.what) {
case CMD_SWITCH_TO_SCAN_ONLY_MODE:
// Already in scan only mode, ignore this command.
@@ -1078,7 +1146,7 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- public void exit() {
+ public void exitImpl() {
mScanOnlyModeImpl = null;
mScanRoleChangeInfoToSetOnTransition = null;
@@ -1089,9 +1157,13 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
}
- private class ConnectModeState extends State {
+ private class ConnectModeState extends RunnerState {
+ ConnectModeState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
Log.d(getTag(), "entering ConnectModeState, starting ClientModeImpl");
if (mClientInterfaceName == null) {
Log.e(getTag(), "Supposed to start ClientModeImpl, but iface is null!");
@@ -1122,7 +1194,19 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return ConcreteClientModeManager.class.getSimpleName() + "."
+ + ConnectModeState.class.getSimpleName() + "."
+ + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(getTag(),
+ getName() + " cmd = " + getWhatToString(message.what) + " "
+ + message.toString());
+ }
switch (message.what) {
case CMD_SWITCH_TO_CONNECT_MODE:
RoleChangeInfo roleChangeInfo = (RoleChangeInfo) message.obj;
@@ -1136,7 +1220,7 @@ public class ConcreteClientModeManager implements ClientModeManager {
// If this call failed, the iface would be torn down.
// Thus, simply abort and let the iface down handling take care of the
// rest.
- Log.e(getTag(), "Failed to switch ClientModeManager="
+ Log.e(getTag(), getName() + ", Failed to switch ClientModeManager="
+ ConcreteClientModeManager.this + "'s requestorWs");
}
break;
@@ -1179,14 +1263,14 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- public void exit() {
+ public void exitImpl() {
updateConnectModeState(mRole, WifiManager.WIFI_STATE_DISABLED,
WifiManager.WIFI_STATE_DISABLING);
if (mClientModeImpl == null) {
Log.w(getTag(), "ConnectModeState.exit(): mClientModeImpl is already null?!");
} else {
- Log.d(getTag(), "Stopping ClientModeImpl");
+ Log.d(getTag(), "ConnectModeState.exit(): Stopping ClientModeImpl");
mClientModeImpl.stop();
mGraveyard.inter(mClientModeImpl);
mClientModeImpl = null;
@@ -1301,8 +1385,8 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- public WifiInfo syncRequestConnectionInfo() {
- return getClientMode().syncRequestConnectionInfo();
+ public WifiInfo getConnectionInfo() {
+ return getClientMode().getConnectionInfo();
}
@Override
@@ -1311,8 +1395,8 @@ public class ConcreteClientModeManager implements ClientModeManager {
}
@Override
- public Network syncGetCurrentNetwork() {
- return getClientMode().syncGetCurrentNetwork();
+ public Network getCurrentNetwork() {
+ return getClientMode().getCurrentNetwork();
}
@Override
@@ -1526,4 +1610,9 @@ public class ConcreteClientModeManager implements ClientModeManager {
public void updateCapabilities() {
getClientMode().updateCapabilities();
}
+
+ @Override
+ public boolean isAffiliatedLinkBssid(MacAddress bssid) {
+ return getClientMode().isAffiliatedLinkBssid(bssid);
+ }
}
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index b0fb6883fd..919ecd19c8 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -24,33 +24,9 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Resources;
-import android.hardware.wifi.V1_0.IWifi;
-import android.hardware.wifi.V1_0.IWifiApIface;
-import android.hardware.wifi.V1_0.IWifiChip;
-import android.hardware.wifi.V1_0.IWifiChipEventCallback;
-import android.hardware.wifi.V1_0.IWifiEventCallback;
-import android.hardware.wifi.V1_0.IWifiIface;
-import android.hardware.wifi.V1_0.IWifiNanIface;
-import android.hardware.wifi.V1_0.IWifiP2pIface;
-import android.hardware.wifi.V1_0.IWifiRttController;
-import android.hardware.wifi.V1_0.IWifiStaIface;
-import android.hardware.wifi.V1_0.IfaceType;
-import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
-import android.hardware.wifi.V1_0.WifiStatus;
-import android.hardware.wifi.V1_0.WifiStatusCode;
-import android.hardware.wifi.V1_5.WifiBand;
-import android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination;
-import android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit;
-import android.hardware.wifi.V1_6.IfaceConcurrencyType;
-import android.hardware.wifi.V1_6.WifiRadioCombination;
-import android.hardware.wifi.V1_6.WifiRadioCombinationMatrix;
-import android.hardware.wifi.V1_6.WifiRadioConfiguration;
-import android.hidl.manager.V1_0.IServiceNotification;
-import android.hidl.manager.V1_2.IServiceManager;
import android.net.wifi.WifiContext;
+import android.net.wifi.WifiScanner;
import android.os.Handler;
-import android.os.IHwBinder.DeathRecipient;
-import android.os.RemoteException;
import android.os.WorkSource;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -63,7 +39,13 @@ import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.HalDeviceManagerUtil.StaticChipInfo;
-import com.android.server.wifi.util.GeneralUtil.Mutable;
+import com.android.server.wifi.hal.WifiApIface;
+import com.android.server.wifi.hal.WifiChip;
+import com.android.server.wifi.hal.WifiHal;
+import com.android.server.wifi.hal.WifiNanIface;
+import com.android.server.wifi.hal.WifiP2pIface;
+import com.android.server.wifi.hal.WifiRttController;
+import com.android.server.wifi.hal.WifiStaIface;
import com.android.server.wifi.util.WorkSourceHelper;
import com.android.wifi.resources.R;
@@ -83,7 +65,7 @@ import java.util.Map;
import java.util.Set;
/**
- * Handles device management through the HAL (HIDL) interface.
+ * Handles device management through the HAL interface.
*/
public class HalDeviceManager {
private static final String TAG = "HalDevMgr";
@@ -94,9 +76,9 @@ public class HalDeviceManager {
private static final long CHIP_CAPABILITY_UNINITIALIZED = -1L;
private static final int DBS_24G_5G_MASK =
- (1 << WifiBand.BAND_24GHZ) | (1 << WifiBand.BAND_5GHZ);
+ WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ;
private static final int DBS_5G_6G_MASK =
- (1 << WifiBand.BAND_5GHZ) | (1 << WifiBand.BAND_6GHZ);
+ WifiScanner.WIFI_BAND_5_GHZ | WifiScanner.WIFI_BAND_6_GHZ;
private static final int START_HAL_RETRY_INTERVAL_MS = 20;
// Number of attempts a start() is re-tried. A value of 0 means no retries after a single
@@ -107,20 +89,18 @@ public class HalDeviceManager {
private final Clock mClock;
private final WifiInjector mWifiInjector;
private final Handler mEventHandler;
+ private WifiHal mWifiHal;
private WifiDeathRecipient mIWifiDeathRecipient;
- private ServiceManagerDeathRecipient mServiceManagerDeathRecipient;
- private boolean mIsBridgedSoftApSupported;
- private boolean mIsStaWithBridgedSoftApConcurrencySupported;
private boolean mWifiUserApprovalRequiredForD2dInterfacePriority;
private boolean mIsConcurrencyComboLoadedFromDriver;
private boolean mWaitForDestroyedListeners;
- private ArrayMap<IWifiIface, SoftApManager> mSoftApManagers = new ArrayMap<>();
-
- // cache the value for supporting vendor HAL or not
- private boolean mIsVendorHalSupported = false;
+ private ArrayMap<WifiHal.WifiInterface, SoftApManager> mSoftApManagers = new ArrayMap<>();
/**
* Public API for querying interfaces from the HalDeviceManager.
+ *
+ * TODO (b/256648410): Consider replacing these values with WifiChip.IFACE_TYPE_
+ * to avoid duplication.
*/
public static final int HDM_CREATE_IFACE_STA = 0;
public static final int HDM_CREATE_IFACE_AP = 1;
@@ -138,34 +118,19 @@ public class HalDeviceManager {
public @interface HdmIfaceTypeForCreation {};
public static final SparseIntArray HAL_IFACE_MAP = new SparseIntArray() {{
- put(HDM_CREATE_IFACE_STA, IfaceType.STA);
- put(HDM_CREATE_IFACE_AP, IfaceType.AP);
- put(HDM_CREATE_IFACE_AP_BRIDGE, IfaceType.AP);
- put(HDM_CREATE_IFACE_P2P, IfaceType.P2P);
- put(HDM_CREATE_IFACE_NAN, IfaceType.NAN);
- }};
-
- public static final SparseIntArray REVERSE_HAL_IFACE_MAP = new SparseIntArray() {{
- put(IfaceType.STA, HDM_CREATE_IFACE_STA);
- put(IfaceType.AP, HDM_CREATE_IFACE_AP);
- put(IfaceType.P2P, HDM_CREATE_IFACE_P2P);
- put(IfaceType.NAN, HDM_CREATE_IFACE_NAN);
+ put(HDM_CREATE_IFACE_STA, WifiChip.IFACE_TYPE_STA);
+ put(HDM_CREATE_IFACE_AP, WifiChip.IFACE_TYPE_AP);
+ put(HDM_CREATE_IFACE_AP_BRIDGE, WifiChip.IFACE_TYPE_AP);
+ put(HDM_CREATE_IFACE_P2P, WifiChip.IFACE_TYPE_P2P);
+ put(HDM_CREATE_IFACE_NAN, WifiChip.IFACE_TYPE_NAN);
}};
public static final SparseIntArray CONCURRENCY_TYPE_TO_CREATE_TYPE_MAP = new SparseIntArray() {{
- put(android.hardware.wifi.V1_6.IfaceConcurrencyType.STA, HDM_CREATE_IFACE_STA);
- put(android.hardware.wifi.V1_6.IfaceConcurrencyType.AP, HDM_CREATE_IFACE_AP);
- put(android.hardware.wifi.V1_6.IfaceConcurrencyType.AP_BRIDGED,
- HDM_CREATE_IFACE_AP_BRIDGE);
- put(android.hardware.wifi.V1_6.IfaceConcurrencyType.P2P, HDM_CREATE_IFACE_P2P);
- put(android.hardware.wifi.V1_6.IfaceConcurrencyType.NAN, HDM_CREATE_IFACE_NAN);
- }};
-
- public static final SparseIntArray IFACE_TYPE_TO_CONCURRENCY_TYPE_MAP = new SparseIntArray() {{
- put(IfaceType.STA, android.hardware.wifi.V1_6.IfaceConcurrencyType.STA);
- put(IfaceType.AP, android.hardware.wifi.V1_6.IfaceConcurrencyType.AP);
- put(IfaceType.P2P, android.hardware.wifi.V1_6.IfaceConcurrencyType.P2P);
- put(IfaceType.NAN, android.hardware.wifi.V1_6.IfaceConcurrencyType.NAN);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, HDM_CREATE_IFACE_STA);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, HDM_CREATE_IFACE_AP);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED, HDM_CREATE_IFACE_AP_BRIDGE);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, HDM_CREATE_IFACE_P2P);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, HDM_CREATE_IFACE_NAN);
}};
@@ -173,9 +138,6 @@ public class HalDeviceManager {
public HalDeviceManager(WifiContext context, Clock clock, WifiInjector wifiInjector,
Handler handler) {
Resources res = context.getResources();
- mIsBridgedSoftApSupported = res.getBoolean(R.bool.config_wifiBridgedSoftApSupported);
- mIsStaWithBridgedSoftApConcurrencySupported =
- res.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported);
mWifiUserApprovalRequiredForD2dInterfacePriority =
res.getBoolean(R.bool.config_wifiUserApprovalRequiredForD2dInterfacePriority);
mWaitForDestroyedListeners = res.getBoolean(R.bool.config_wifiWaitForDestroyedListeners);
@@ -183,7 +145,12 @@ public class HalDeviceManager {
mWifiInjector = wifiInjector;
mEventHandler = handler;
mIWifiDeathRecipient = new WifiDeathRecipient();
- mServiceManagerDeathRecipient = new ServiceManagerDeathRecipient();
+ mWifiHal = getWifiHalMockable(context, wifiInjector);
+ }
+
+ @VisibleForTesting
+ protected WifiHal getWifiHalMockable(WifiContext context, WifiInjector wifiInjector) {
+ return new WifiHal(context, wifiInjector.getSsidTranslator());
}
/**
@@ -206,6 +173,7 @@ public class HalDeviceManager {
*/
public void initialize() {
initializeInternal();
+ registerWifiHalEventCallback();
}
/**
@@ -234,7 +202,7 @@ public class HalDeviceManager {
* Returns whether the vendor HAL is supported on this device or not.
*/
public boolean isSupported() {
- return mIsVendorHalSupported;
+ return mWifiHal.isSupported();
}
/**
@@ -243,24 +211,20 @@ public class HalDeviceManager {
* the registerStatusListener() to listener for status changes.
*/
public boolean isReady() {
- return mIsReady;
+ return mWifiHal.isInitializationComplete();
}
/**
* Returns the current status of Wi-Fi: started (true) or stopped (false).
- *
- * Note: direct call to HIDL.
*/
public boolean isStarted() {
return isWifiStarted();
}
/**
- * Attempts to start Wi-Fi (using HIDL). Returns the success (true) or failure (false) or
+ * Attempts to start Wi-Fi. Returns the success (true) or failure (false) or
* the start operation. Will also dispatch any registered ManagerStatusCallback.onStart() on
* success.
- *
- * Note: direct call to HIDL.
*/
public boolean start() {
return startWifi();
@@ -268,14 +232,10 @@ public class HalDeviceManager {
/**
* Stops Wi-Fi. Will also dispatch any registeredManagerStatusCallback.onStop().
- *
- * Note: direct call to HIDL - failure is not-expected.
*/
public void stop() {
- synchronized (mLock) { // prevents race condition
- stopWifi();
- mWifi = null;
- }
+ stopWifi();
+ mWifiHal.invalidate();
}
/**
@@ -303,7 +263,7 @@ public class HalDeviceManager {
*
* @return A set of IfaceTypes constants (possibly empty, e.g. on error).
*/
- public Set<Integer> getSupportedIfaceTypes(IWifiChip chip) {
+ public Set<Integer> getSupportedIfaceTypes(WifiChip chip) {
return getSupportedIfaceTypesInternal(chip);
}
@@ -326,11 +286,11 @@ public class HalDeviceManager {
* interface using rules based on the requestor app's context.
* @return A newly created interface - or null if the interface could not be created.
*/
- public IWifiStaIface createStaIface(
+ public WifiStaIface createStaIface(
long requiredChipCapabilities,
@Nullable InterfaceDestroyedListener destroyedListener, @Nullable Handler handler,
@NonNull WorkSource requestorWs) {
- return (IWifiStaIface) createIface(HDM_CREATE_IFACE_STA, requiredChipCapabilities,
+ return (WifiStaIface) createIface(HDM_CREATE_IFACE_STA, requiredChipCapabilities,
destroyedListener, handler, requestorWs);
}
@@ -349,17 +309,16 @@ public class HalDeviceManager {
* interface using rules based on the requestor app's context.
* @return A newly created interface - or null if the interface could not be created.
*/
- public IWifiStaIface createStaIface(
+ public WifiStaIface createStaIface(
@Nullable InterfaceDestroyedListener destroyedListener, @Nullable Handler handler,
@NonNull WorkSource requestorWs) {
- return (IWifiStaIface) createStaIface(CHIP_CAPABILITY_ANY,
- destroyedListener, handler, requestorWs);
+ return createStaIface(CHIP_CAPABILITY_ANY, destroyedListener, handler, requestorWs);
}
/**
* Create AP interface if possible (see createStaIface doc).
*/
- public IWifiApIface createApIface(
+ public WifiApIface createApIface(
long requiredChipCapabilities,
@Nullable InterfaceDestroyedListener destroyedListener, @Nullable Handler handler,
@NonNull WorkSource requestorWs, boolean isBridged,
@@ -368,7 +327,7 @@ public class HalDeviceManager {
Log.e(TAG, "Cannot create AP Iface with null SoftApManager");
return null;
}
- IWifiApIface apIface = (IWifiApIface) createIface(isBridged ? HDM_CREATE_IFACE_AP_BRIDGE
+ WifiApIface apIface = (WifiApIface) createIface(isBridged ? HDM_CREATE_IFACE_AP_BRIDGE
: HDM_CREATE_IFACE_AP, requiredChipCapabilities, destroyedListener,
handler, requestorWs);
if (apIface != null) {
@@ -380,29 +339,38 @@ public class HalDeviceManager {
/**
* Create P2P interface if possible (see createStaIface doc).
*/
- public IWifiP2pIface createP2pIface(
+ public String createP2pIface(
long requiredChipCapabilities,
@Nullable InterfaceDestroyedListener destroyedListener,
@Nullable Handler handler, @NonNull WorkSource requestorWs) {
- return (IWifiP2pIface) createIface(HDM_CREATE_IFACE_P2P, requiredChipCapabilities,
- destroyedListener, handler, requestorWs);
+ WifiP2pIface iface = (WifiP2pIface) createIface(HDM_CREATE_IFACE_P2P,
+ requiredChipCapabilities, destroyedListener, handler, requestorWs);
+ if (iface == null) {
+ return null;
+ }
+ String ifaceName = getName(iface);
+ if (TextUtils.isEmpty(ifaceName)) {
+ removeIface(iface);
+ return null;
+ }
+ mWifiP2pIfaces.put(ifaceName, iface);
+ return ifaceName;
}
/**
* Create P2P interface if possible (see createStaIface doc).
*/
- public IWifiP2pIface createP2pIface(@Nullable InterfaceDestroyedListener destroyedListener,
+ public String createP2pIface(@Nullable InterfaceDestroyedListener destroyedListener,
@Nullable Handler handler, @NonNull WorkSource requestorWs) {
- return (IWifiP2pIface) createP2pIface(CHIP_CAPABILITY_ANY,
- destroyedListener, handler, requestorWs);
+ return createP2pIface(CHIP_CAPABILITY_ANY, destroyedListener, handler, requestorWs);
}
/**
* Create NAN interface if possible (see createStaIface doc).
*/
- public IWifiNanIface createNanIface(@Nullable InterfaceDestroyedListener destroyedListener,
+ public WifiNanIface createNanIface(@Nullable InterfaceDestroyedListener destroyedListener,
@Nullable Handler handler, @NonNull WorkSource requestorWs) {
- return (IWifiNanIface) createIface(HDM_CREATE_IFACE_NAN, CHIP_CAPABILITY_ANY,
+ return (WifiNanIface) createIface(HDM_CREATE_IFACE_NAN, CHIP_CAPABILITY_ANY,
destroyedListener, handler, requestorWs);
}
@@ -410,12 +378,26 @@ public class HalDeviceManager {
* Removes (releases/destroys) the given interface. Will trigger any registered
* InterfaceDestroyedListeners.
*/
- public boolean removeIface(IWifiIface iface) {
+ public boolean removeIface(WifiHal.WifiInterface iface) {
boolean success = removeIfaceInternal(iface, /* validateRttController */true);
return success;
}
- private InterfaceCacheEntry getInterfaceCacheEntry(IWifiIface iface) {
+ /**
+ * Wrapper around {@link #removeIface(WifiHal.WifiInterface)} for P2P ifaces.
+ */
+ public boolean removeP2pIface(String ifaceName) {
+ WifiP2pIface iface = mWifiP2pIfaces.get(ifaceName);
+ if (iface == null) return false;
+ if (!removeIface(iface)) {
+ Log.e(TAG, "Unable to remove p2p iface " + ifaceName);
+ return false;
+ }
+ mWifiP2pIfaces.remove(ifaceName);
+ return true;
+ }
+
+ private InterfaceCacheEntry getInterfaceCacheEntry(WifiHal.WifiInterface iface) {
String name = getName(iface);
int type = getType(iface);
if (VDBG) Log.d(TAG, "getInterfaceCacheEntry: iface(name)=" + name);
@@ -432,26 +414,26 @@ public class HalDeviceManager {
}
/**
- * Returns the IWifiChip corresponding to the specified interface (or null on error).
+ * Returns the WifiChip corresponding to the specified interface (or null on error).
*
* Note: clients must not perform chip mode changes or interface management (create/delete)
- * operations on IWifiChip directly. However, they can use the IWifiChip interface to perform
+ * operations on WifiChip directly. However, they can use the WifiChip interface to perform
* other functions - e.g. calling the debug/trace methods.
*/
- public IWifiChip getChip(IWifiIface iface) {
+ public WifiChip getChip(WifiHal.WifiInterface iface) {
synchronized (mLock) {
InterfaceCacheEntry cacheEntry = getInterfaceCacheEntry(iface);
return (cacheEntry == null) ? null : cacheEntry.chip;
}
}
- private WifiChipInfo getChipInfo(IWifiIface iface) {
+ private WifiChipInfo getChipInfo(WifiHal.WifiInterface iface) {
synchronized (mLock) {
InterfaceCacheEntry cacheEntry = getInterfaceCacheEntry(iface);
- if (null == cacheEntry) return null;
+ if (cacheEntry == null) return null;
WifiChipInfo[] chipInfos = getAllChipInfoCached();
- if (null == chipInfos) return null;
+ if (chipInfos == null) return null;
for (WifiChipInfo info: chipInfos) {
if (info.chipId == cacheEntry.chipId) {
@@ -462,14 +444,14 @@ public class HalDeviceManager {
}
}
- private boolean isDbsSupported(IWifiIface iface, int dbsMask) {
+ private boolean isDbsSupported(WifiHal.WifiInterface iface, int dbsMask) {
synchronized (mLock) {
WifiChipInfo info = getChipInfo(iface);
- if (null == info) return false;
+ if (info == null) return false;
// If there is no radio combination information, cache it.
- if (null == info.radioCombinationMatrix) {
- IWifiChip chip = getChip(iface);
- if (null == chip) return false;
+ if (info.radioCombinationMatrix == null) {
+ WifiChip chip = getChip(iface);
+ if (chip == null) return false;
info.radioCombinationMatrix = getChipSupportedRadioCombinationsMatrix(chip);
info.radioCombinationLookupTable = convertRadioCombinationMatrixToLookupTable(
@@ -484,39 +466,57 @@ public class HalDeviceManager {
}
/**
- * Indicate whether or not 2.4GHz/5GHz DBS is supported.
+ * Indicate whether 2.4GHz/5GHz DBS is supported.
*
* @param iface The interface on the chip.
* @return true if supported; false, otherwise;
*/
- public boolean is24g5gDbsSupported(IWifiIface iface) {
+ public boolean is24g5gDbsSupported(WifiHal.WifiInterface iface) {
return isDbsSupported(iface, DBS_24G_5G_MASK);
}
/**
- * Indicate whether or not 5GHz/6GHz DBS is supported.
+ * Wrapper around {@link #is24g5gDbsSupported(WifiHal.WifiInterface)} for P2P ifaces.
+ */
+ public boolean is24g5gDbsSupportedOnP2pIface(String ifaceName) {
+ WifiP2pIface iface = mWifiP2pIfaces.get(ifaceName);
+ if (iface == null) return false;
+ return is24g5gDbsSupported(iface);
+ }
+
+ /**
+ * Indicate whether 5GHz/6GHz DBS is supported.
*
* @param iface The interface on the chip.
* @return true if supported; false, otherwise;
*/
- public boolean is5g6gDbsSupported(IWifiIface iface) {
+ public boolean is5g6gDbsSupported(WifiHal.WifiInterface iface) {
return isDbsSupported(iface, DBS_5G_6G_MASK);
}
/**
+ * Wrapper around {@link #is5g6gDbsSupported(WifiHal.WifiInterface)} for P2P ifaces.
+ */
+ public boolean is5g6gDbsSupportedOnP2pIface(String ifaceName) {
+ WifiP2pIface iface = mWifiP2pIfaces.get(ifaceName);
+ if (iface == null) return false;
+ return is5g6gDbsSupported(iface);
+ }
+
+ /**
* Replace the requestorWs info for the associated info.
*
* When a new iface is requested via
- * {@link #createIface(int, InterfaceDestroyedListener, Handler, WorkSource)}, the clients
+ * {@link #createIface(int, long, InterfaceDestroyedListener, Handler, WorkSource)}, the clients
* pass in a worksource which includes all the apps that triggered the iface creation. However,
* this list of apps can change during the lifetime of the iface (as new apps request the same
* iface or existing apps release their request for the iface). This API can be invoked multiple
* times to replace the entire requestor info for the provided iface.
*
- * Note: This is is wholesale replace of the requestor info. The corresponding client is
+ * Note: This is a wholesale replacement of the requestor info. The corresponding client is
* responsible for individual add/remove of apps in the WorkSource passed in.
*/
- public boolean replaceRequestorWs(@NonNull IWifiIface iface,
+ public boolean replaceRequestorWs(@NonNull WifiHal.WifiInterface iface,
@NonNull WorkSource newRequestorWs) {
String name = getName(iface);
int type = getType(iface);
@@ -537,6 +537,24 @@ public class HalDeviceManager {
}
/**
+ * Wrapper around {@link #replaceRequestorWs(WifiHal.WifiInterface, WorkSource)} for P2P ifaces.
+ */
+ public boolean replaceRequestorWsForP2pIface(String ifaceName,
+ @NonNull WorkSource newRequestorWs) {
+ WifiP2pIface iface = mWifiP2pIfaces.get(ifaceName);
+ if (iface == null) return false;
+ return replaceRequestorWs(iface, newRequestorWs);
+ }
+
+ /**
+ * Wrapper around {@link #replaceRequestorWs(WifiHal.WifiInterface, WorkSource)} for NAN ifaces.
+ */
+ public boolean replaceRequestorWsForNanIface(@NonNull WifiNanIface iface,
+ @NonNull WorkSource newRequestorWs) {
+ return replaceRequestorWs(iface, newRequestorWs);
+ }
+
+ /**
* Register a SubsystemRestartListener to listen to the subsystem restart event from HAL.
* Use the action() to forward the event to SelfRecovery when receiving the event from HAL.
*
@@ -564,6 +582,10 @@ public class HalDeviceManager {
* an existing RTT controller is destroyed (the previous copies must be discarded by the
* recipient).
*
+ * Each listener should maintain a single callback object to register here. The callback can
+ * be registered upon the listener's initialization, and re-registered on HDM status changes, if
+ * {@link #isStarted} is true.
+ *
* @param callback InterfaceRttControllerLifecycleCallback object.
* @param handler Handler on which to dispatch callback
*/
@@ -590,11 +612,11 @@ public class HalDeviceManager {
return;
}
- if (mIWifiRttController == null) {
- mIWifiRttController = createRttControllerIfPossible();
+ if (mWifiRttController == null) {
+ mWifiRttController = createRttControllerIfPossible();
}
- if (mIWifiRttController != null) {
- proxy.onNewRttController(mIWifiRttController);
+ if (mWifiRttController != null) {
+ proxy.onNewRttController(mWifiRttController);
}
}
}
@@ -602,25 +624,11 @@ public class HalDeviceManager {
/**
* Return the name of the input interface or null on error.
*/
- public static String getName(IWifiIface iface) {
+ public String getName(WifiHal.WifiInterface iface) {
if (iface == null) {
return "<null>";
}
-
- Mutable<String> nameResp = new Mutable<>();
- try {
- iface.getName((WifiStatus status, String name) -> {
- if (status.code == WifiStatusCode.SUCCESS) {
- nameResp.value = name;
- } else {
- Log.e(TAG, "Error on getName: " + statusString(status));
- }
- });
- } catch (RemoteException e) {
- Log.e(TAG, "Exception on getName: " + e);
- }
-
- return nameResp.value;
+ return iface.getName();
}
/**
@@ -669,12 +677,12 @@ public class HalDeviceManager {
*
* @param controller The RTT controller object.
*/
- void onNewRttController(@NonNull IWifiRttController controller);
+ void onNewRttController(@NonNull WifiRttController controller);
/**
* Called when the previously provided RTT controller is destroyed. Clients must discard
* their copy. A new copy may be provided later by
- * {@link #onNewRttController(IWifiRttController)}.
+ * {@link #onNewRttController(WifiRttController)}.
*/
void onRttControllerDestroyed();
}
@@ -683,7 +691,7 @@ public class HalDeviceManager {
* Returns whether the provided @HdmIfaceTypeForCreation combo can be supported by the device.
* Note: This only returns an answer based on the create type combination exposed by the HAL.
* The actual iface creation/deletion rules depend on the iface priorities set in
- * {@link #allowedToDeleteIfaceTypeForRequestedType(int, WorkSource, int, WifiIfaceInfo[][])}
+ * {@link #allowedToDelete(int, int, int, int)}
*
* @param createTypeCombo SparseArray keyed in by @HdmIfaceTypeForCreation to number of ifaces
* needed.
@@ -732,7 +740,7 @@ public class HalDeviceManager {
*
* @param createIfaceType Type of iface requested.
* @param requiredChipCapabilities The bitmask of Capabilities which are required.
- * See IWifiChip.hal for documentation.
+ * See the HAL for documentation.
* @param requestorWs Requestor worksource. This will be used to determine priority of this
* interface using rules based on the requestor app's context.
* @return true if the device supports the provided combo, false otherwise.
@@ -768,7 +776,7 @@ public class HalDeviceManager {
*
* Return types imply:
* - null: interface cannot be created
- * - empty list: interface can be crated w/o destroying any other interafces
+ * - empty list: interface can be crated w/o destroying any other interfaces
* - otherwise: a list of interfaces to be destroyed
*
* @param createIfaceType Type of iface requested.
@@ -776,7 +784,7 @@ public class HalDeviceManager {
* there's already an interface of the specified type then no need
* for further operation.
* @param requiredChipCapabilities The bitmask of Capabilities which are required.
- * See IWifiChip.hal for documentation.
+ * See the HAL for documentation.
* @param requestorWs Requestor worksource. This will be used to determine priority of this
* interface using rules based on the requestor app's context.
* @return the list of interfaces that would have to be destroyed and their worksource. The
@@ -793,8 +801,8 @@ public class HalDeviceManager {
IfaceCreationData creationData;
synchronized (mLock) {
- if (mWifi == null) {
- Log.e(TAG, "reportImpactToCreateIface: null IWifi -- ifaceType=" + createIfaceType);
+ if (!mWifiHal.isInitializationComplete()) {
+ Log.e(TAG, "reportImpactToCreateIface: Wifi Hal is not available");
return null;
}
WifiChipInfo[] chipInfos = getAllChipInfo();
@@ -883,27 +891,24 @@ public class HalDeviceManager {
* - Order of dispatch of available for request listeners
*/
private static final int[] IFACE_TYPES_BY_PRIORITY =
- {IfaceType.AP, IfaceType.STA, IfaceType.P2P, IfaceType.NAN};
+ {WifiChip.IFACE_TYPE_AP, WifiChip.IFACE_TYPE_STA, WifiChip.IFACE_TYPE_P2P,
+ WifiChip.IFACE_TYPE_NAN};
private static final int[] CREATE_TYPES_BY_PRIORITY =
{HDM_CREATE_IFACE_AP, HDM_CREATE_IFACE_AP_BRIDGE, HDM_CREATE_IFACE_STA,
HDM_CREATE_IFACE_P2P, HDM_CREATE_IFACE_NAN};
private final Object mLock = new Object();
- private IServiceManager mServiceManager;
- private IWifi mWifi;
- private IWifiRttController mIWifiRttController;
- private final WifiEventCallback mWifiEventCallback = new WifiEventCallback();
- private final WifiEventCallbackV15 mWifiEventCallbackV15 = new WifiEventCallbackV15();
+ private WifiRttController mWifiRttController;
+ private HashMap<String, WifiP2pIface> mWifiP2pIfaces = new HashMap<>();
+ private final WifiHal.Callback mWifiEventCallback = new WifiEventCallback();
private final Set<ManagerStatusListenerProxy> mManagerStatusListeners = new HashSet<>();
private final Set<InterfaceRttControllerLifecycleCallbackProxy>
mRttControllerLifecycleCallbacks = new HashSet<>();
- private final SparseArray<IWifiChipEventCallback.Stub> mDebugCallbacks = new SparseArray<>();
- private boolean mIsReady;
private final Set<SubsystemRestartListenerProxy> mSubsystemRestartListener = new HashSet<>();
/*
- * This is the only place where we cache HIDL information in this manager. Necessary since
+ * This is the only place where we cache HAL information in this manager. Necessary since
* we need to keep a list of registered destroyed listeners. Will be validated regularly
* in getAllChipInfoAndValidateCache().
*/
@@ -911,7 +916,7 @@ public class HalDeviceManager {
new HashMap<>();
private class InterfaceCacheEntry {
- public IWifiChip chip;
+ public WifiChip chip;
public int chipId;
public String name;
public int type;
@@ -932,7 +937,7 @@ public class HalDeviceManager {
private class WifiIfaceInfo {
public String name;
- public IWifiIface iface;
+ public WifiHal.WifiInterface iface;
public @HdmIfaceTypeForCreation int createType;
public WorkSourceHelper requestorWsHelper;
@@ -944,16 +949,16 @@ public class HalDeviceManager {
}
private class WifiChipInfo {
- public IWifiChip chip;
+ public WifiChip chip;
public int chipId = -1;
- public ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> availableModes;
+ public ArrayList<WifiChip.ChipMode> availableModes;
public boolean currentModeIdValid = false;
public int currentModeId = -1;
// Arrays of WifiIfaceInfo indexed by @HdmIfaceTypeForCreation, in order of creation as
- // returned by IWifiChip.getXxxIfaceNames.
+ // returned by WifiChip.getXxxIfaceNames.
public WifiIfaceInfo[][] ifaces = new WifiIfaceInfo[CREATE_TYPES_BY_PRIORITY.length][];
public long chipCapabilities;
- public WifiRadioCombinationMatrix radioCombinationMatrix = null;
+ public WifiChip.WifiRadioCombinationMatrix radioCombinationMatrix = null;
public SparseBooleanArray radioCombinationLookupTable = new SparseBooleanArray();
@Override
@@ -971,56 +976,6 @@ public class HalDeviceManager {
}
}
- /**
- * Wrapper function to access the HIDL services. Created to be mockable in unit-tests.
- */
- protected IWifi getWifiServiceMockable() {
- try {
- return IWifi.getService(true /* retry */);
- } catch (RemoteException e) {
- Log.e(TAG, "Exception getting IWifi service: " + e);
- return null;
- }
- }
-
- protected android.hardware.wifi.V1_5.IWifi getWifiServiceForV1_5Mockable(IWifi iWifi) {
- if (null == iWifi) return null;
- return android.hardware.wifi.V1_5.IWifi.castFrom(iWifi);
- }
-
- protected IServiceManager getServiceManagerMockable() {
- try {
- return IServiceManager.getService();
- } catch (RemoteException e) {
- Log.e(TAG, "Exception getting IServiceManager: " + e);
- return null;
- }
- }
-
- protected android.hardware.wifi.V1_5.IWifiChip getWifiChipForV1_5Mockable(IWifiChip chip) {
- if (null == chip) return null;
- return android.hardware.wifi.V1_5.IWifiChip.castFrom(chip);
- }
-
- protected android.hardware.wifi.V1_6.IWifiChip getWifiChipForV1_6Mockable(IWifiChip chip) {
- if (null == chip) return null;
- return android.hardware.wifi.V1_6.IWifiChip.castFrom(chip);
- }
-
- protected android.hardware.wifi.V1_5.IWifiApIface getIWifiApIfaceForV1_5Mockable(
- IWifiApIface iface) {
- if (null == iface) return null;
- return android.hardware.wifi.V1_5.IWifiApIface.castFrom(iface);
- }
-
- protected boolean isBridgedSoftApSupportedMockable() {
- return mIsBridgedSoftApSupported;
- }
-
- protected boolean isStaWithBridgedSoftApConcurrencySupportedMockable() {
- return mIsStaWithBridgedSoftApConcurrencySupported;
- }
-
protected boolean isWaitForDestroyedListenersMockable() {
return mWaitForDestroyedListeners;
}
@@ -1028,122 +983,25 @@ public class HalDeviceManager {
// internal implementation
private void initializeInternal() {
- initIServiceManagerIfNecessary();
- if (mIsVendorHalSupported) {
- initIWifiIfNecessary();
- }
+ mWifiHal.initialize(mIWifiDeathRecipient);
}
private void teardownInternal() {
managerStatusListenerDispatch();
dispatchAllDestroyedListeners();
- mIWifiRttController = null;
+ mWifiRttController = null;
dispatchRttControllerLifecycleOnDestroyed();
mRttControllerLifecycleCallbacks.clear();
+ mWifiP2pIfaces.clear();
}
- private class ServiceManagerDeathRecipient implements DeathRecipient {
- @Override
- public void serviceDied(long cookie) {
- mEventHandler.post(() -> {
- Log.wtf(TAG, "IServiceManager died: cookie=" + cookie);
- synchronized (mLock) {
- mServiceManager = null;
- // theoretically can call initServiceManager again here - but
- // there's no point since most likely system is going to reboot
- }
- });
- }
- }
-
- private final IServiceNotification mServiceNotificationCallback =
- new IServiceNotification.Stub() {
- @Override
- public void onRegistration(String fqName, String name,
- boolean preexisting) {
- Log.d(TAG, "IWifi registration notification: fqName=" + fqName
- + ", name=" + name + ", preexisting=" + preexisting);
- synchronized (mLock) {
- initIWifiIfNecessary();
- }
- }
- };
-
- /**
- * Failures of IServiceManager are most likely system breaking in any case. Behavior here
- * will be to WTF and continue.
- */
- private void initIServiceManagerIfNecessary() {
- if (mDbg) Log.d(TAG, "initIServiceManagerIfNecessary");
-
- synchronized (mLock) {
- if (mServiceManager != null) {
- return;
- }
-
- mServiceManager = getServiceManagerMockable();
- if (mServiceManager == null) {
- Log.wtf(TAG, "Failed to get IServiceManager instance");
- } else {
- try {
- if (!mServiceManager.linkToDeath(
- mServiceManagerDeathRecipient, /* don't care */ 0)) {
- Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
- mServiceManager = null;
- return;
- }
-
- if (!mServiceManager.registerForNotifications(IWifi.kInterfaceName, "",
- mServiceNotificationCallback)) {
- Log.wtf(TAG, "Failed to register a listener for IWifi service");
- mServiceManager = null;
- }
- } catch (RemoteException e) {
- Log.wtf(TAG, "Exception while operating on IServiceManager: " + e);
- mServiceManager = null;
- }
-
- // Cache the result for the supporting vendor hal or not
- mIsVendorHalSupported = isSupportedInternal();
- }
- }
- }
-
- /**
- * Uses the IServiceManager to query if the vendor HAL is present in the VINTF for the device
- * or not.
- * @return true if supported, false otherwise.
- */
- private boolean isSupportedInternal() {
- if (VDBG) Log.d(TAG, "isSupportedInternal");
-
- synchronized (mLock) {
- if (mServiceManager == null) {
- Log.e(TAG, "isSupported: called but mServiceManager is null!?");
- return false;
- }
- try {
- List<String> wifiServices =
- mServiceManager.listManifestByInterface(IWifi.kInterfaceName);
- return !wifiServices.isEmpty();
- } catch (RemoteException e) {
- Log.wtf(TAG, "Exception while operating on IServiceManager: " + e);
- return false;
- }
- }
- }
-
- private class WifiDeathRecipient implements DeathRecipient {
+ private class WifiDeathRecipient implements WifiHal.DeathRecipient {
@Override
- public void serviceDied(long cookie) {
+ public void onDeath() {
mEventHandler.post(() -> {
- Log.e(TAG, "IWifi HAL service died! Have a listener for it ... cookie=" + cookie);
synchronized (mLock) { // prevents race condition with surrounding method
- mWifi = null;
- mIsReady = false;
teardownInternal();
- // don't restart: wait for registration notification
}
});
}
@@ -1154,192 +1012,7 @@ public class HalDeviceManager {
* @return true if success.
*/
private boolean registerWifiHalEventCallback() {
- try {
- if (mWifi == null) {
- Log.e(TAG, "registerWifiHalEventCallback called but mWifi is null!?");
- return false;
- }
- WifiStatus status;
- android.hardware.wifi.V1_5.IWifi iWifiV15 = getWifiServiceForV1_5Mockable(mWifi);
- if (iWifiV15 != null) {
- status = iWifiV15.registerEventCallback_1_5(mWifiEventCallbackV15);
- } else {
- status = mWifi.registerEventCallback(mWifiEventCallback);
- }
-
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "IWifi.registerEventCallback failed: " + statusString(status));
- mWifi = null;
- }
- return status.code == WifiStatusCode.SUCCESS;
- } catch (RemoteException e) {
- Log.e(TAG, "Exception while operating on IWifi: " + e);
- }
- return false;
- }
-
- /**
- * Initialize IWifi and register death listener and event callback.
- *
- * - It is possible that IWifi is not ready - we have a listener on IServiceManager for it.
- * - It is not expected that any of the registrations will fail. Possible indication that
- * service died after we obtained a handle to it.
- *
- * Here and elsewhere we assume that death listener will do the right thing!
- */
- private void initIWifiIfNecessary() {
- if (mDbg) Log.d(TAG, "initIWifiIfNecessary");
-
- synchronized (mLock) {
- if (mWifi != null) {
- return;
- }
-
- try {
- mWifi = getWifiServiceMockable();
- if (mWifi == null) {
- Log.e(TAG, "IWifi not (yet) available - but have a listener for it ...");
- return;
- }
-
- if (!mWifi.linkToDeath(mIWifiDeathRecipient, /* don't care */ 0)) {
- Log.e(TAG, "Error on linkToDeath on IWifi - will retry later");
- return;
- }
-
- // Stopping wifi just in case. This would also trigger the status callback.
- // Stopping wifi invalidated the registered the event callback, register after the
- // wifi stop.
- stopWifi();
- if (!registerWifiHalEventCallback()) {
- return;
- }
- mIsReady = true;
- } catch (RemoteException e) {
- Log.e(TAG, "Exception while operating on IWifi: " + e);
- }
- }
- }
-
- /**
- * Registers event listeners on all IWifiChips after a successful start: DEBUG only!
- *
- * We don't need the listeners since any callbacks are just confirmation of status codes we
- * obtain directly from mode changes or interface creation/deletion.
- *
- * Relies (to the degree we care) on the service removing all listeners when Wi-Fi is stopped.
- */
- private void initIWifiChipDebugListeners() {
- if (VDBG) Log.d(TAG, "initIWifiChipDebugListeners");
-
- if (!VDBG) {
- return;
- }
-
- synchronized (mLock) {
- try {
- Mutable<Boolean> statusOk = new Mutable<>(false);
- Mutable<ArrayList<Integer>> chipIdsResp = new Mutable<>();
-
- // get all chip IDs
- mWifi.getChipIds((WifiStatus status, ArrayList<Integer> chipIds) -> {
- statusOk.value = false;
- if (status.code == WifiStatusCode.SUCCESS) {
- if (chipIds == null) {
- Log.wtf(TAG, "getChipIds failed, chipIds is null");
- return;
- }
- statusOk.value = true;
- }
- if (statusOk.value) {
- chipIdsResp.value = chipIds;
- } else {
- Log.e(TAG, "getChipIds failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
- return;
- }
-
- Log.d(TAG, "getChipIds=" + chipIdsResp.value);
- if (chipIdsResp.value.size() == 0) {
- Log.e(TAG, "Should have at least 1 chip!");
- return;
- }
-
- // register a callback for each chip
- Mutable<IWifiChip> chipResp = new Mutable<>();
- for (Integer chipId: chipIdsResp.value) {
- mWifi.getChip(chipId, (WifiStatus status, IWifiChip chip) -> {
- statusOk.value = false;
- if (status.code == WifiStatusCode.SUCCESS) {
- if (chip == null) {
- Log.wtf(TAG, "getChip failed, chip " + chipId + " is null");
- }
- statusOk.value = true;
- }
- if (statusOk.value) {
- chipResp.value = chip;
- } else {
- Log.e(TAG, "getChip failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
- continue; // still try next one?
- }
-
- IWifiChipEventCallback.Stub callback =
- new IWifiChipEventCallback.Stub() {
- @Override
- public void onChipReconfigured(int modeId) throws RemoteException {
- Log.d(TAG, "onChipReconfigured: modeId=" + modeId);
- }
-
- @Override
- public void onChipReconfigureFailure(WifiStatus status)
- throws RemoteException {
- Log.e(TAG, "onChipReconfigureFailure: status=" + statusString(
- status));
- }
-
- @Override
- public void onIfaceAdded(int type, String name)
- throws RemoteException {
- Log.d(TAG, "onIfaceAdded: type=" + type + ", name=" + name);
- }
-
- @Override
- public void onIfaceRemoved(int type, String name)
- throws RemoteException {
- Log.d(TAG, "onIfaceRemoved: type=" + type + ", name=" + name);
- }
-
- @Override
- public void onDebugRingBufferDataAvailable(
- WifiDebugRingBufferStatus status,
- ArrayList<Byte> data) throws RemoteException {
- Log.d(TAG, "onDebugRingBufferDataAvailable");
- }
-
- @Override
- public void onDebugErrorAlert(int errorCode,
- ArrayList<Byte> debugData)
- throws RemoteException {
- Log.d(TAG, "onDebugErrorAlert");
- }
- };
- mDebugCallbacks.put(chipId, callback); // store to prevent GC: needed by HIDL
- WifiStatus status = chipResp.value.registerEventCallback(callback);
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "registerEventCallback failed: " + statusString(status));
- continue; // still try next one?
- }
- }
- } catch (RemoteException e) {
- Log.e(TAG, "initIWifiChipDebugListeners: exception: " + e);
- return;
- }
- }
+ return mWifiHal.registerEventCallback(mWifiEventCallback);
}
@Nullable
@@ -1374,373 +1047,171 @@ public class HalDeviceManager {
return null;
}
- try {
- Mutable<Boolean> statusOk = new Mutable<>(false);
- Mutable<ArrayList<Integer>> chipIdsResp = new Mutable<>();
+ // get all chip IDs
+ List<Integer> chipIds = mWifiHal.getChipIds();
+ if (chipIds == null) {
+ return null;
+ }
- // get all chip IDs
- mWifi.getChipIds((WifiStatus status, ArrayList<Integer> chipIds) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- chipIdsResp.value = chipIds;
- } else {
- Log.e(TAG, "getChipIds failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
- return null;
- }
+ if (VDBG) Log.d(TAG, "getChipIds=" + Arrays.toString(chipIds.toArray()));
+ if (chipIds.size() == 0) {
+ Log.e(TAG, "Should have at least 1 chip!");
+ return null;
+ }
- if (VDBG) Log.d(TAG, "getChipIds=" + chipIdsResp.value);
- if (chipIdsResp.value.size() == 0) {
- Log.e(TAG, "Should have at least 1 chip!");
- return null;
- }
+ SparseArray<StaticChipInfo> staticChipInfoPerId = new SparseArray<>();
+ for (StaticChipInfo staticChipInfo : getStaticChipInfos()) {
+ staticChipInfoPerId.put(staticChipInfo.getChipId(), staticChipInfo);
+ }
+
+ int chipInfoIndex = 0;
+ WifiChipInfo[] chipsInfo = new WifiChipInfo[chipIds.size()];
- SparseArray<StaticChipInfo> staticChipInfoPerId = new SparseArray<>();
- for (StaticChipInfo staticChipInfo : getStaticChipInfos()) {
- staticChipInfoPerId.put(staticChipInfo.getChipId(), staticChipInfo);
+ for (Integer chipId : chipIds) {
+ WifiChip chip = mWifiHal.getChip(chipId);
+ if (chip == null) {
+ return null;
}
- int chipInfoIndex = 0;
- WifiChipInfo[] chipsInfo = new WifiChipInfo[chipIdsResp.value.size()];
-
- Mutable<IWifiChip> chipResp = new Mutable<>();
- for (Integer chipId: chipIdsResp.value) {
- mWifi.getChip(chipId, (WifiStatus status, IWifiChip chip) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- chipResp.value = chip;
- } else {
- Log.e(TAG, "getChip failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
+ StaticChipInfo staticChipInfo = staticChipInfoPerId.get(chipId);
+ List<WifiChip.ChipMode> chipModes = null;
+ if (staticChipInfo == null) {
+ chipModes = chip.getAvailableModes();
+ if (chipModes == null) {
return null;
}
+ }
- StaticChipInfo staticChipInfo = staticChipInfoPerId.get(chipId);
- Mutable<ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode>>
- availableModesResp = new Mutable<>();
- if (staticChipInfo == null) {
- android.hardware.wifi.V1_6.IWifiChip chipV16 =
- getWifiChipForV1_6Mockable(chipResp.value);
- if (chipV16 != null) {
- chipV16.getAvailableModes_1_6((WifiStatus status,
- ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> modes)
- -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- availableModesResp.value = modes;
- } else {
- Log.e(TAG, "getAvailableModes_1_6 failed: "
- + statusString(status));
- }
- });
- } else {
- chipResp.value.getAvailableModes((WifiStatus status,
- ArrayList<IWifiChip.ChipMode> modes) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- availableModesResp.value = upgradeV1_0ChipModesToV1_6(modes);
- } else {
- Log.e(TAG, "getAvailableModes failed: "
- + statusString(status));
- }
- });
- }
- if (!statusOk.value) {
- return null;
- }
- }
-
- Mutable<Boolean> currentModeValidResp = new Mutable<>(false);
- Mutable<Integer> currentModeResp = new Mutable<>(0);
- chipResp.value.getMode((WifiStatus status, int modeId) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- currentModeValidResp.value = true;
- currentModeResp.value = modeId;
- } else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) {
- statusOk.value = true; // valid response
- } else {
- Log.e(TAG, "getMode failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
- return null;
- }
+ WifiChip.Response<Integer> currentMode = chip.getMode();
+ if (currentMode.getStatusCode() != WifiHal.WIFI_STATUS_SUCCESS
+ && currentMode.getStatusCode() != WifiHal.WIFI_STATUS_ERROR_NOT_AVAILABLE) {
+ return null;
+ }
- Mutable<Long> chipCapabilities = new Mutable<>(0L);
- chipCapabilities.value = getChipCapabilities(chipResp.value);
+ long chipCapabilities = getChipCapabilities(chip);
- Mutable<ArrayList<String>> ifaceNamesResp = new Mutable<>();
- Mutable<Integer> ifaceIndex = new Mutable<>(0);
+ List<String> ifaceNames = chip.getStaIfaceNames();
+ if (ifaceNames == null) {
+ return null;
+ }
- chipResp.value.getStaIfaceNames(
- (WifiStatus status, ArrayList<String> ifnames) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- ifaceNamesResp.value = ifnames;
- } else {
- Log.e(TAG, "getStaIfaceNames failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
+ int ifaceIndex = 0;
+ WifiIfaceInfo[] staIfaces = new WifiIfaceInfo[ifaceNames.size()];
+ for (String ifaceName: ifaceNames) {
+ WifiHal.WifiInterface iface = chip.getStaIface(ifaceName);
+ if (iface == null) {
return null;
}
+ WifiIfaceInfo ifaceInfo = new WifiIfaceInfo();
+ ifaceInfo.name = ifaceName;
+ ifaceInfo.iface = iface;
+ ifaceInfo.createType = HDM_CREATE_IFACE_STA;
+ staIfaces[ifaceIndex++] = ifaceInfo;
+ }
- WifiIfaceInfo[] staIfaces = new WifiIfaceInfo[ifaceNamesResp.value.size()];
- for (String ifaceName: ifaceNamesResp.value) {
- chipResp.value.getStaIface(ifaceName,
- (WifiStatus status, IWifiStaIface iface) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- WifiIfaceInfo ifaceInfo = new WifiIfaceInfo();
- ifaceInfo.name = ifaceName;
- ifaceInfo.iface = iface;
- ifaceInfo.createType = HDM_CREATE_IFACE_STA;
- staIfaces[ifaceIndex.value++] = ifaceInfo;
- } else {
- Log.e(TAG, "getStaIface failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
- return null;
- }
- }
+ ifaceIndex = 0;
+ ifaceNames = chip.getApIfaceNames();
+ if (ifaceNames == null) {
+ return null;
+ }
- ifaceIndex.value = 0;
- chipResp.value.getApIfaceNames(
- (WifiStatus status, ArrayList<String> ifnames) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- ifaceNamesResp.value = ifnames;
- } else {
- Log.e(TAG, "getApIfaceNames failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
+ WifiIfaceInfo[] apIfaces = new WifiIfaceInfo[ifaceNames.size()];
+ for (String ifaceName : ifaceNames) {
+ WifiHal.WifiInterface iface = chip.getApIface(ifaceName);
+ if (iface == null) {
return null;
}
+ WifiIfaceInfo ifaceInfo = new WifiIfaceInfo();
+ ifaceInfo.name = ifaceName;
+ ifaceInfo.iface = iface;
+ ifaceInfo.createType = HDM_CREATE_IFACE_AP;
+ apIfaces[ifaceIndex++] = ifaceInfo;
+ }
- WifiIfaceInfo[] apIfaces = new WifiIfaceInfo[ifaceNamesResp.value.size()];
- for (String ifaceName: ifaceNamesResp.value) {
- chipResp.value.getApIface(ifaceName,
- (WifiStatus status, IWifiApIface iface) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- WifiIfaceInfo ifaceInfo = new WifiIfaceInfo();
- ifaceInfo.name = ifaceName;
- ifaceInfo.iface = iface;
- ifaceInfo.createType = HDM_CREATE_IFACE_AP;
- apIfaces[ifaceIndex.value++] = ifaceInfo;
- } else {
- Log.e(TAG, "getApIface failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
- return null;
- }
- }
- Mutable<Integer> numBridgedAps = new Mutable<>(0);
- for (WifiIfaceInfo apIfaceInfo : apIfaces) {
- android.hardware.wifi.V1_5.IWifiApIface wifiApIfaceV15 =
- getIWifiApIfaceForV1_5Mockable((IWifiApIface) apIfaceInfo.iface);
- if (wifiApIfaceV15 == null) {
- continue;
- }
- try {
- wifiApIfaceV15.getBridgedInstances((status, instances) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- // Only count bridged APs with more than 1 instance as a bridged
- // AP; 1 instance bridged APs will be counted as single AP.
- if (instances != null && instances.size() > 1) {
- apIfaceInfo.createType = HDM_CREATE_IFACE_AP_BRIDGE;
- numBridgedAps.value++;
- }
- } else {
- Log.e(TAG, "getBridgedInstances failed: "
- + statusString(status));
- }
- });
- } catch (RemoteException e) {
- Log.e(TAG, "IWifiApIface.getBridgedInstances exception: " + e);
- }
- }
- WifiIfaceInfo[] singleApIfaces =
- new WifiIfaceInfo[apIfaces.length - numBridgedAps.value];
- WifiIfaceInfo[] bridgedApIfaces = new WifiIfaceInfo[numBridgedAps.value];
- int singleApIndex = 0;
- int bridgedApIndex = 0;
- for (WifiIfaceInfo apIfaceInfo : apIfaces) {
- if (apIfaceInfo.createType == HDM_CREATE_IFACE_AP_BRIDGE) {
- bridgedApIfaces[bridgedApIndex++] = apIfaceInfo;
- } else {
- singleApIfaces[singleApIndex++] = apIfaceInfo;
- }
+ int numBridgedAps = 0;
+ for (WifiIfaceInfo apIfaceInfo : apIfaces) {
+ List<String> bridgedInstances = ((WifiApIface) apIfaceInfo.iface)
+ .getBridgedInstances();
+ // Only count bridged APs with more than 1 instance as a bridged
+ // AP; 1 instance bridged APs will be counted as single AP.
+ if (bridgedInstances != null && bridgedInstances.size() > 1) {
+ apIfaceInfo.createType = HDM_CREATE_IFACE_AP_BRIDGE;
+ numBridgedAps++;
}
+ }
- ifaceIndex.value = 0;
- chipResp.value.getP2pIfaceNames(
- (WifiStatus status, ArrayList<String> ifnames) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- ifaceNamesResp.value = ifnames;
- } else {
- Log.e(TAG, "getP2pIfaceNames failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
- return null;
+ WifiIfaceInfo[] singleApIfaces = new WifiIfaceInfo[apIfaces.length - numBridgedAps];
+ WifiIfaceInfo[] bridgedApIfaces = new WifiIfaceInfo[numBridgedAps];
+ int singleApIndex = 0;
+ int bridgedApIndex = 0;
+ for (WifiIfaceInfo apIfaceInfo : apIfaces) {
+ if (apIfaceInfo.createType == HDM_CREATE_IFACE_AP_BRIDGE) {
+ bridgedApIfaces[bridgedApIndex++] = apIfaceInfo;
+ } else {
+ singleApIfaces[singleApIndex++] = apIfaceInfo;
}
+ }
- WifiIfaceInfo[] p2pIfaces = new WifiIfaceInfo[ifaceNamesResp.value.size()];
- for (String ifaceName: ifaceNamesResp.value) {
- chipResp.value.getP2pIface(ifaceName,
- (WifiStatus status, IWifiP2pIface iface) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- WifiIfaceInfo ifaceInfo = new WifiIfaceInfo();
- ifaceInfo.name = ifaceName;
- ifaceInfo.iface = iface;
- ifaceInfo.createType = HDM_CREATE_IFACE_P2P;
- p2pIfaces[ifaceIndex.value++] = ifaceInfo;
- } else {
- Log.e(TAG, "getP2pIface failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
- return null;
- }
- }
+ ifaceIndex = 0;
+ ifaceNames = chip.getP2pIfaceNames();
+ if (ifaceNames == null) {
+ return null;
+ }
- ifaceIndex.value = 0;
- chipResp.value.getNanIfaceNames(
- (WifiStatus status, ArrayList<String> ifnames) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- ifaceNamesResp.value = ifnames;
- } else {
- Log.e(TAG, "getNanIfaceNames failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
+ WifiIfaceInfo[] p2pIfaces = new WifiIfaceInfo[ifaceNames.size()];
+ for (String ifaceName : ifaceNames) {
+ WifiHal.WifiInterface iface = chip.getP2pIface(ifaceName);
+ if (iface == null) {
return null;
}
+ WifiIfaceInfo ifaceInfo = new WifiIfaceInfo();
+ ifaceInfo.name = ifaceName;
+ ifaceInfo.iface = iface;
+ ifaceInfo.createType = HDM_CREATE_IFACE_P2P;
+ p2pIfaces[ifaceIndex++] = ifaceInfo;
+ }
- WifiIfaceInfo[] nanIfaces = new WifiIfaceInfo[ifaceNamesResp.value.size()];
- for (String ifaceName: ifaceNamesResp.value) {
- chipResp.value.getNanIface(ifaceName,
- (WifiStatus status, IWifiNanIface iface) -> {
- statusOk.value = status.code == WifiStatusCode.SUCCESS;
- if (statusOk.value) {
- WifiIfaceInfo ifaceInfo = new WifiIfaceInfo();
- ifaceInfo.name = ifaceName;
- ifaceInfo.iface = iface;
- ifaceInfo.createType = HDM_CREATE_IFACE_NAN;
- nanIfaces[ifaceIndex.value++] = ifaceInfo;
- } else {
- Log.e(TAG, "getNanIface failed: " + statusString(status));
- }
- });
- if (!statusOk.value) {
- return null;
- }
- }
-
- WifiChipInfo chipInfo = new WifiChipInfo();
- chipsInfo[chipInfoIndex++] = chipInfo;
+ ifaceIndex = 0;
+ ifaceNames = chip.getNanIfaceNames();
+ if (ifaceNames == null) {
+ return null;
+ }
- chipInfo.chip = chipResp.value;
- chipInfo.chipId = chipId;
- if (staticChipInfo != null) {
- chipInfo.availableModes = staticChipInfo.getAvailableModes();
- } else {
- chipInfo.availableModes = availableModesResp.value;
+ WifiIfaceInfo[] nanIfaces = new WifiIfaceInfo[ifaceNames.size()];
+ for (String ifaceName : ifaceNames) {
+ WifiHal.WifiInterface iface = chip.getNanIface(ifaceName);
+ if (iface == null) {
+ return null;
}
- chipInfo.currentModeIdValid = currentModeValidResp.value;
- chipInfo.currentModeId = currentModeResp.value;
- chipInfo.chipCapabilities = chipCapabilities.value;
- chipInfo.ifaces[HDM_CREATE_IFACE_STA] = staIfaces;
- chipInfo.ifaces[HDM_CREATE_IFACE_AP] = singleApIfaces;
- chipInfo.ifaces[HDM_CREATE_IFACE_AP_BRIDGE] = bridgedApIfaces;
- chipInfo.ifaces[HDM_CREATE_IFACE_P2P] = p2pIfaces;
- chipInfo.ifaces[HDM_CREATE_IFACE_NAN] = nanIfaces;
+ WifiIfaceInfo ifaceInfo = new WifiIfaceInfo();
+ ifaceInfo.name = ifaceName;
+ ifaceInfo.iface = iface;
+ ifaceInfo.createType = HDM_CREATE_IFACE_NAN;
+ nanIfaces[ifaceIndex++] = ifaceInfo;
}
- return chipsInfo;
- } catch (RemoteException e) {
- Log.e(TAG, "getAllChipInfoAndValidateCache exception: " + e);
- }
- }
- return null;
- }
+ WifiChipInfo chipInfo = new WifiChipInfo();
+ chipsInfo[chipInfoIndex++] = chipInfo;
- private ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode>
- upgradeV1_0ChipModesToV1_6(ArrayList<IWifiChip.ChipMode> oldChipModes) {
- ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> newChipModes = new ArrayList<>();
- for (IWifiChip.ChipMode oldChipMode : oldChipModes) {
- android.hardware.wifi.V1_6.IWifiChip.ChipMode newChipMode =
- new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
- newChipMode.id = oldChipMode.id;
- newChipMode.availableCombinations = new ArrayList<>();
- for (IWifiChip.ChipIfaceCombination oldCombo : oldChipMode.availableCombinations) {
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination
- newCombo = new ChipConcurrencyCombination();
- newCombo.limits = new ArrayList<>();
- // Define a duplicate combination list with AP converted to AP_BRIDGED
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination
- newComboWithBridgedAp = new ChipConcurrencyCombination();
- newComboWithBridgedAp.limits = new ArrayList<>();
- ChipConcurrencyCombinationLimit bridgedApLimit =
- new ChipConcurrencyCombinationLimit();
- bridgedApLimit.maxIfaces = 1;
- bridgedApLimit.types = new ArrayList<>();
- bridgedApLimit.types.add(IfaceConcurrencyType.AP_BRIDGED);
- newComboWithBridgedAp.limits.add(bridgedApLimit);
-
- boolean apInCombo = false;
- // Populate both the combo with AP_BRIDGED and the combo without AP_BRIDGED
- for (IWifiChip.ChipIfaceCombinationLimit oldLimit : oldCombo.limits) {
- ChipConcurrencyCombinationLimit newLimit =
- new ChipConcurrencyCombinationLimit();
- newLimit.types = new ArrayList<>();
- newLimit.maxIfaces = oldLimit.maxIfaces;
- for (int oldType : oldLimit.types) {
- newLimit.types.add(IFACE_TYPE_TO_CONCURRENCY_TYPE_MAP.get(oldType));
- }
- newCombo.limits.add(newLimit);
-
- ChipConcurrencyCombinationLimit newLimitForBridgedApCombo =
- new ChipConcurrencyCombinationLimit();
- newLimitForBridgedApCombo.types = new ArrayList<>(newLimit.types);
- newLimitForBridgedApCombo.maxIfaces = newLimit.maxIfaces;
- if (newLimitForBridgedApCombo.types.contains(IfaceConcurrencyType.AP)) {
- // Skip the limit if it contains AP, since this corresponds to the
- // AP_BRIDGED in the duplicate AP_BRIDGED combo.
- apInCombo = true;
- } else if (!isStaWithBridgedSoftApConcurrencySupportedMockable()
- && newLimitForBridgedApCombo.types.contains(IfaceConcurrencyType.STA)) {
- // Don't include STA in the AP_BRIDGED combo if STA + AP_BRIDGED is not
- // supported.
- newLimitForBridgedApCombo.types.remove((Integer) IfaceConcurrencyType.STA);
- if (!newLimitForBridgedApCombo.types.isEmpty()) {
- newComboWithBridgedAp.limits.add(newLimitForBridgedApCombo);
- }
- } else {
- newComboWithBridgedAp.limits.add(newLimitForBridgedApCombo);
- }
- }
- newChipMode.availableCombinations.add(newCombo);
- if (isBridgedSoftApSupportedMockable() && apInCombo) {
- newChipMode.availableCombinations.add(newComboWithBridgedAp);
+ chipInfo.chip = chip;
+ chipInfo.chipId = chipId;
+ if (staticChipInfo != null) {
+ chipInfo.availableModes = staticChipInfo.getAvailableModes();
+ } else {
+ chipInfo.availableModes = new ArrayList<>(chipModes);
}
+ chipInfo.currentModeIdValid =
+ currentMode.getStatusCode() == WifiHal.WIFI_STATUS_SUCCESS;
+ chipInfo.currentModeId = currentMode.getValue();
+ chipInfo.chipCapabilities = chipCapabilities;
+ chipInfo.ifaces[HDM_CREATE_IFACE_STA] = staIfaces;
+ chipInfo.ifaces[HDM_CREATE_IFACE_AP] = singleApIfaces;
+ chipInfo.ifaces[HDM_CREATE_IFACE_AP_BRIDGE] = bridgedApIfaces;
+ chipInfo.ifaces[HDM_CREATE_IFACE_P2P] = p2pIfaces;
+ chipInfo.ifaces[HDM_CREATE_IFACE_NAN] = nanIfaces;
}
- newChipModes.add(newChipMode);
+ return chipsInfo;
}
- return newChipModes;
}
@Nullable
@@ -1858,95 +1329,69 @@ public class HalDeviceManager {
private boolean isWifiStarted() {
if (VDBG) Log.d(TAG, "isWifiStart");
-
synchronized (mLock) {
- try {
- if (mWifi == null) {
- return false;
- } else {
- return mWifi.isStarted();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "isWifiStarted exception: " + e);
- return false;
- }
+ return mWifiHal.isStarted();
}
}
private boolean startWifi() {
if (VDBG) Log.d(TAG, "startWifi");
- initIWifiIfNecessary();
+ initializeInternal();
synchronized (mLock) {
- try {
- if (mWifi == null) {
- Log.w(TAG, "startWifi called but mWifi is null!?");
- return false;
- } else {
- int triedCount = 0;
- while (triedCount <= START_HAL_RETRY_TIMES) {
- WifiStatus status = mWifi.start();
- if (status.code == WifiStatusCode.SUCCESS) {
- initIWifiChipDebugListeners();
- managerStatusListenerDispatch();
- if (triedCount != 0) {
- Log.d(TAG, "start IWifi succeeded after trying "
- + triedCount + " times");
- }
- WifiChipInfo[] wifiChipInfos = getAllChipInfo();
- if (wifiChipInfos == null) {
- Log.e(TAG, "Started wifi but could not get current chip info.");
- }
- return true;
- } else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) {
- // Should retry. Hal might still be stopping. the registered event
- // callback will not be cleared.
- Log.e(TAG, "Cannot start IWifi: " + statusString(status)
- + ", Retrying...");
- try {
- Thread.sleep(START_HAL_RETRY_INTERVAL_MS);
- } catch (InterruptedException ignore) {
- // no-op
- }
- triedCount++;
- } else {
- // Should not retry on other failures.
- // Will be handled in the onFailure event.
- Log.e(TAG, "Cannot start IWifi: " + statusString(status));
- return false;
- }
+ int triedCount = 0;
+ while (triedCount <= START_HAL_RETRY_TIMES) {
+ int status = mWifiHal.start();
+ if (status == WifiHal.WIFI_STATUS_SUCCESS) {
+ managerStatusListenerDispatch();
+ if (triedCount != 0) {
+ Log.d(TAG, "start IWifi succeeded after trying "
+ + triedCount + " times");
}
- Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times");
+ WifiChipInfo[] wifiChipInfos = getAllChipInfo();
+ if (wifiChipInfos == null) {
+ Log.e(TAG, "Started wifi but could not get current chip info.");
+ }
+ return true;
+ } else if (status == WifiHal.WIFI_STATUS_ERROR_NOT_AVAILABLE) {
+ // Should retry. Hal might still be stopping. the registered event
+ // callback will not be cleared.
+ Log.e(TAG, "Cannot start wifi because unavailable. Retrying...");
+ try {
+ Thread.sleep(START_HAL_RETRY_INTERVAL_MS);
+ } catch (InterruptedException ignore) {
+ // no-op
+ }
+ triedCount++;
+ } else {
+ // Should not retry on other failures.
+ // Will be handled in the onFailure event.
+ Log.e(TAG, "Cannot start IWifi. Status: " + status);
return false;
}
- } catch (RemoteException e) {
- Log.e(TAG, "startWifi exception: " + e);
- return false;
}
+ Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times");
+ return false;
}
}
private void stopWifi() {
if (VDBG) Log.d(TAG, "stopWifi");
-
- try {
- if (mWifi == null) {
- Log.w(TAG, "stopWifi called but mWifi is null!?");
- } else {
- WifiStatus status = mWifi.stop();
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "Cannot stop IWifi: " + statusString(status));
- }
- // even on failure since WTF??
- teardownInternal();
+ synchronized (mLock) {
+ if (!mWifiHal.isInitializationComplete()) {
+ Log.w(TAG, "stopWifi was called, but Wifi Hal is not initialized");
+ return;
+ }
+ if (!mWifiHal.stop()) {
+ Log.e(TAG, "Cannot stop IWifi");
}
- } catch (RemoteException e) {
- Log.e(TAG, "stopWifi exception: " + e);
+ // even on failure since WTF??
+ teardownInternal();
}
}
- private class WifiEventCallback extends IWifiEventCallback.Stub {
+ private class WifiEventCallback implements WifiHal.Callback {
@Override
- public void onStart() throws RemoteException {
+ public void onStart() {
mEventHandler.post(() -> {
if (VDBG) Log.d(TAG, "IWifiEventCallback.onStart");
// NOP: only happens in reaction to my calls - will handle directly
@@ -1954,7 +1399,7 @@ public class HalDeviceManager {
}
@Override
- public void onStop() throws RemoteException {
+ public void onStop() {
mEventHandler.post(() -> {
if (VDBG) Log.d(TAG, "IWifiEventCallback.onStop");
// NOP: only happens in reaction to my calls - will handle directly
@@ -1962,41 +1407,20 @@ public class HalDeviceManager {
}
@Override
- public void onFailure(WifiStatus status) throws RemoteException {
+ public void onFailure(int status) {
mEventHandler.post(() -> {
- Log.e(TAG, "IWifiEventCallback.onFailure: " + statusString(status));
+ Log.e(TAG, "IWifiEventCallback.onFailure. Status: " + status);
synchronized (mLock) {
- mWifi = null;
- mIsReady = false;
teardownInternal();
}
});
}
- }
-
- private class WifiEventCallbackV15 extends
- android.hardware.wifi.V1_5.IWifiEventCallback.Stub {
- private final WifiEventCallback mWifiEventCallback = new WifiEventCallback();
- @Override
- public void onStart() throws RemoteException {
- mWifiEventCallback.onStart();
- }
@Override
- public void onStop() throws RemoteException {
- mWifiEventCallback.onStop();
- }
-
- @Override
- public void onFailure(WifiStatus status) throws RemoteException {
- mWifiEventCallback.onFailure(status);
- }
-
- @Override
- public void onSubsystemRestart(WifiStatus status) throws RemoteException {
+ public void onSubsystemRestart(int status) {
Log.i(TAG, "onSubsystemRestart");
mEventHandler.post(() -> {
- Log.i(TAG, "IWifiEventCallback.onSubsystemRestart: " + statusString(status));
+ Log.i(TAG, "IWifiEventCallback.onSubsystemRestart. Status: " + status);
synchronized (mLock) {
Log.i(TAG, "Attempting to invoke mSubsystemRestartListener");
for (SubsystemRestartListenerProxy cb : mSubsystemRestartListener) {
@@ -2028,7 +1452,7 @@ public class HalDeviceManager {
}
}
- private Set<Integer> getSupportedIfaceTypesInternal(IWifiChip chip) {
+ private Set<Integer> getSupportedIfaceTypesInternal(WifiChip chip) {
Set<Integer> results = new HashSet<>();
WifiChipInfo[] chipInfos = getAllChipInfoCached();
@@ -2037,37 +1461,22 @@ public class HalDeviceManager {
return results;
}
- Mutable<Integer> chipIdIfProvided = new Mutable<>(0); // NOT using 0 as a magic value
+ int chipIdIfProvided = 0; // NOT using 0 as a magic value
if (chip != null) {
- Mutable<Boolean> statusOk = new Mutable<>(false);
- try {
- chip.getId((WifiStatus status, int id) -> {
- if (status.code == WifiStatusCode.SUCCESS) {
- chipIdIfProvided.value = id;
- statusOk.value = true;
- } else {
- Log.e(TAG, "getSupportedIfaceTypesInternal: IWifiChip.getId() error: "
- + statusString(status));
- statusOk.value = false;
- }
- });
- } catch (RemoteException e) {
- Log.e(TAG, "getSupportedIfaceTypesInternal IWifiChip.getId() exception: " + e);
- return results;
- }
- if (!statusOk.value) {
+ chipIdIfProvided = chip.getId();
+ if (chipIdIfProvided == -1) {
return results;
}
}
for (WifiChipInfo wci: chipInfos) {
- if (chip != null && wci.chipId != chipIdIfProvided.value) {
+ if (chip != null && wci.chipId != chipIdIfProvided) {
continue;
}
- // Map the V1_6 IfaceConcurrencyTypes to the corresponding IfaceType.
- for (android.hardware.wifi.V1_6.IWifiChip.ChipMode cm: wci.availableModes) {
- for (ChipConcurrencyCombination cic : cm.availableCombinations) {
- for (ChipConcurrencyCombinationLimit cicl : cic.limits) {
+ // Map the IfaceConcurrencyTypes to the corresponding IfaceType.
+ for (WifiChip.ChipMode cm : wci.availableModes) {
+ for (WifiChip.ChipConcurrencyCombination cic : cm.availableCombinations) {
+ for (WifiChip.ChipConcurrencyCombinationLimit cicl : cic.limits) {
for (int concurrencyType: cicl.types) {
results.add(HAL_IFACE_MAP.get(
CONCURRENCY_TYPE_TO_CREATE_TYPE_MAP.get(concurrencyType)));
@@ -2076,11 +1485,10 @@ public class HalDeviceManager {
}
}
}
-
return results;
}
- private IWifiIface createIface(@HdmIfaceTypeForCreation int createIfaceType,
+ private WifiHal.WifiInterface createIface(@HdmIfaceTypeForCreation int createIfaceType,
long requiredChipCapabilities, InterfaceDestroyedListener destroyedListener,
Handler handler, WorkSource requestorWs) {
if (mDbg) {
@@ -2175,11 +1583,11 @@ public class HalDeviceManager {
* supported by that id.
*/
private SparseArray<List<int[][]>> getExpandedCreateTypeCombosPerChipModeId(
- ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> chipModes) {
+ ArrayList<WifiChip.ChipMode> chipModes) {
SparseArray<List<int[][]>> combosPerChipModeId = new SparseArray<>();
- for (android.hardware.wifi.V1_6.IWifiChip.ChipMode chipMode : chipModes) {
+ for (WifiChip.ChipMode chipMode : chipModes) {
List<int[][]> expandedCreateTypeCombos = new ArrayList<>();
- for (ChipConcurrencyCombination chipConcurrencyCombo
+ for (WifiChip.ChipConcurrencyCombination chipConcurrencyCombo
: chipMode.availableCombinations) {
expandedCreateTypeCombos.add(expandCreateTypeCombo(chipConcurrencyCombo));
}
@@ -2188,7 +1596,7 @@ public class HalDeviceManager {
return combosPerChipModeId;
}
- private IWifiIface createIfaceIfPossible(
+ private WifiHal.WifiInterface createIfaceIfPossible(
WifiChipInfo[] chipInfos, @HdmIfaceTypeForCreation int createIfaceType,
long requiredChipCapabilities, InterfaceDestroyedListener destroyedListener,
Handler handler, WorkSource requestorWs) {
@@ -2205,13 +1613,12 @@ public class HalDeviceManager {
createIfaceType, requiredChipCapabilities, requestorWs);
if (bestIfaceCreationProposal != null) {
- IWifiIface iface = executeChipReconfiguration(bestIfaceCreationProposal,
+ WifiHal.WifiInterface iface = executeChipReconfiguration(bestIfaceCreationProposal,
createIfaceType);
if (iface == null) {
// If the chip reconfiguration failed, we'll need to clean up internal state.
Log.e(TAG, "Teardown Wifi internal state");
- mWifi = null;
- mIsReady = false;
+ mWifiHal.invalidate();
teardownInternal();
} else {
InterfaceCacheEntry cacheEntry = new InterfaceCacheEntry();
@@ -2251,9 +1658,10 @@ public class HalDeviceManager {
* TODO: optimize by using a Set as opposed to a []: will remove duplicates. Will need to
* provide correct hashes.
*/
- private int[][] expandCreateTypeCombo(ChipConcurrencyCombination chipConcurrencyCombo) {
+ private int[][] expandCreateTypeCombo(
+ WifiChip.ChipConcurrencyCombination chipConcurrencyCombo) {
int numOfCombos = 1;
- for (ChipConcurrencyCombinationLimit limit : chipConcurrencyCombo.limits) {
+ for (WifiChip.ChipConcurrencyCombinationLimit limit : chipConcurrencyCombo.limits) {
for (int i = 0; i < limit.maxIfaces; ++i) {
numOfCombos *= limit.types.size();
}
@@ -2263,7 +1671,7 @@ public class HalDeviceManager {
new int[numOfCombos][CREATE_TYPES_BY_PRIORITY.length];
int span = numOfCombos; // span of an individual type (or sub-tree size)
- for (ChipConcurrencyCombinationLimit limit : chipConcurrencyCombo.limits) {
+ for (WifiChip.ChipConcurrencyCombinationLimit limit : chipConcurrencyCombo.limits) {
for (int i = 0; i < limit.maxIfaces; ++i) {
span /= limit.types.size();
for (int k = 0; k < numOfCombos; ++k) {
@@ -2468,52 +1876,6 @@ public class HalDeviceManager {
}
/**
- * Returns true if the requested iface can delete an existing iface only after user approval.
- */
- public boolean needsUserApprovalToDelete(
- int requestedCreateType, @NonNull WorkSourceHelper newRequestorWsHelper,
- int existingCreateType, @NonNull WorkSourceHelper existingRequestorWsHelper) {
- @WorkSourceHelper.RequestorWsPriority int newRequestorWsPriority =
- newRequestorWsHelper.getRequestorWsPriority();
- @WorkSourceHelper.RequestorWsPriority int existingRequestorWsPriority =
- existingRequestorWsHelper.getRequestorWsPriority();
-
- if (!mWifiUserApprovalRequiredForD2dInterfacePriority
- || newRequestorWsPriority <= WorkSourceHelper.PRIORITY_BG
- || existingRequestorWsPriority == WorkSourceHelper.PRIORITY_INTERNAL) {
- return false;
- }
-
- // Allow LOHS to beat Settings STA if there's no STA+AP concurrency (legacy behavior)
- if (allowedToDeleteForNoStaApConcurrencyLohs(
- requestedCreateType, newRequestorWsPriority,
- existingCreateType, existingRequestorWsPriority)) {
- return false;
- }
-
- if (requestedCreateType == HDM_CREATE_IFACE_AP
- || requestedCreateType == HDM_CREATE_IFACE_AP_BRIDGE) {
- if (existingCreateType == HDM_CREATE_IFACE_P2P
- || existingCreateType == HDM_CREATE_IFACE_NAN) {
- return true;
- }
- } else if (requestedCreateType == HDM_CREATE_IFACE_P2P) {
- if (existingCreateType == HDM_CREATE_IFACE_AP
- || existingCreateType == HDM_CREATE_IFACE_AP_BRIDGE
- || existingCreateType == HDM_CREATE_IFACE_NAN) {
- return true;
- }
- } else if (requestedCreateType == HDM_CREATE_IFACE_NAN) {
- if (existingCreateType == HDM_CREATE_IFACE_AP
- || existingCreateType == HDM_CREATE_IFACE_AP_BRIDGE
- || existingCreateType == HDM_CREATE_IFACE_P2P) {
- return true;
- }
- }
- return false;
- }
-
- /**
* Returns whether interface request from |newRequestorWsPriority| is allowed to delete an
* interface request from |existingRequestorWsPriority|.
*
@@ -2536,8 +1898,9 @@ public class HalDeviceManager {
}
// Defer deletion decision to the InterfaceConflictManager dialog.
- if (needsUserApprovalToDelete(requestedCreateType, newRequestorWs,
- existingCreateType, existingRequestorWs)) {
+ if (mWifiInjector.getInterfaceConflictManager().needsUserApprovalToDelete(
+ requestedCreateType, newRequestorWs,
+ existingCreateType, existingRequestorWs)) {
return true;
}
@@ -2591,8 +1954,8 @@ public class HalDeviceManager {
@WorkSourceHelper.RequestorWsPriority int existingRequestorWsPriority) {
return !canDeviceSupportCreateTypeCombo(
new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.AP, 1);
+ put(HDM_CREATE_IFACE_STA, 1);
+ put(HDM_CREATE_IFACE_AP, 1);
}})
&& (requestedCreateType == HDM_CREATE_IFACE_AP
|| requestedCreateType == HDM_CREATE_IFACE_AP_BRIDGE)
@@ -2812,131 +2175,98 @@ public class HalDeviceManager {
*
* Returns the newly created interface or a null on any error.
*/
- private IWifiIface executeChipReconfiguration(IfaceCreationData ifaceCreationData,
+ private WifiHal.WifiInterface executeChipReconfiguration(IfaceCreationData ifaceCreationData,
@HdmIfaceTypeForCreation int createIfaceType) {
if (mDbg) {
Log.d(TAG, "executeChipReconfiguration: ifaceCreationData=" + ifaceCreationData
+ ", createIfaceType=" + createIfaceType);
}
synchronized (mLock) {
- try {
- // is this a mode change?
- boolean isModeConfigNeeded = !ifaceCreationData.chipInfo.currentModeIdValid
- || ifaceCreationData.chipInfo.currentModeId != ifaceCreationData.chipModeId;
- if (mDbg) Log.d(TAG, "isModeConfigNeeded=" + isModeConfigNeeded);
-
- // first delete interfaces/change modes
- if (isModeConfigNeeded) {
- // remove all interfaces pre mode-change
- // TODO: is this necessary? note that even if we don't want to explicitly
- // remove the interfaces we do need to call the onDeleted callbacks - which
- // this does
- for (WifiIfaceInfo[] ifaceInfos : ifaceCreationData.chipInfo.ifaces) {
- for (WifiIfaceInfo ifaceInfo : ifaceInfos) {
- removeIfaceInternal(ifaceInfo.iface,
- /* validateRttController */false); // ignore return value
- }
- }
-
- WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(
- ifaceCreationData.chipModeId);
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "executeChipReconfiguration: configureChip error: "
- + statusString(status));
- return null;
- }
- if (!mIsConcurrencyComboLoadedFromDriver) {
- WifiChipInfo[] wifiChipInfos = getAllChipInfo();
- if (wifiChipInfos != null) {
- mCachedStaticChipInfos =
- convertWifiChipInfoToStaticChipInfos(getAllChipInfo());
- saveStaticChipInfoToStore(mCachedStaticChipInfos);
- mIsConcurrencyComboLoadedFromDriver = true;
- } else {
- Log.e(TAG, "Configured chip but could not get current chip info.");
- }
- }
- } else {
- // remove all interfaces on the delete list
- for (WifiIfaceInfo ifaceInfo : ifaceCreationData.interfacesToBeRemovedFirst) {
+ // is this a mode change?
+ boolean isModeConfigNeeded = !ifaceCreationData.chipInfo.currentModeIdValid
+ || ifaceCreationData.chipInfo.currentModeId != ifaceCreationData.chipModeId;
+ if (mDbg) Log.d(TAG, "isModeConfigNeeded=" + isModeConfigNeeded);
+ Log.i(TAG, "currentModeId=" + ifaceCreationData.chipInfo.currentModeId
+ + ", requestModeId=" + ifaceCreationData.chipModeId
+ + ", currentModeIdValid=" + ifaceCreationData.chipInfo.currentModeIdValid);
+
+ // first delete interfaces/change modes
+ if (isModeConfigNeeded) {
+ // remove all interfaces pre mode-change
+ // TODO: is this necessary? note that even if we don't want to explicitly
+ // remove the interfaces we do need to call the onDeleted callbacks - which
+ // this does
+ for (WifiIfaceInfo[] ifaceInfos : ifaceCreationData.chipInfo.ifaces) {
+ for (WifiIfaceInfo ifaceInfo : ifaceInfos) {
removeIfaceInternal(ifaceInfo.iface,
/* validateRttController */false); // ignore return value
}
- // downgrade all interfaces on the downgrade list
- for (WifiIfaceInfo ifaceInfo : ifaceCreationData.interfacesToBeDowngraded) {
- if (ifaceInfo.createType == HDM_CREATE_IFACE_AP_BRIDGE) {
- if (!downgradeBridgedApIface(ifaceInfo)) {
- Log.e(TAG, "executeChipReconfiguration: failed to downgrade bridged"
- + " AP: " + ifaceInfo);
- return null;
- }
- }
- }
}
- // create new interface
- Mutable<WifiStatus> statusResp = new Mutable<>();
- Mutable<IWifiIface> ifaceResp = new Mutable<>();
- switch (createIfaceType) {
- case HDM_CREATE_IFACE_STA:
- ifaceCreationData.chipInfo.chip.createStaIface(
- (WifiStatus status, IWifiStaIface iface) -> {
- statusResp.value = status;
- ifaceResp.value = iface;
- });
- break;
- case HDM_CREATE_IFACE_AP_BRIDGE:
- android.hardware.wifi.V1_5.IWifiChip chip15 =
- getWifiChipForV1_5Mockable(ifaceCreationData.chipInfo.chip);
- if (chip15 != null) {
- chip15.createBridgedApIface(
- (WifiStatus status,
- android.hardware.wifi.V1_5.IWifiApIface iface) -> {
- statusResp.value = status;
- ifaceResp.value = iface;
- });
- } else {
- Log.e(TAG, "Hal doesn't support to create AP bridge mode");
+ boolean success = ifaceCreationData.chipInfo.chip.configureChip(
+ ifaceCreationData.chipModeId);
+ if (!success) {
+ Log.e(TAG, "executeChipReconfiguration: configureChip error");
+ return null;
+ }
+ if (!mIsConcurrencyComboLoadedFromDriver) {
+ WifiChipInfo[] wifiChipInfos = getAllChipInfo();
+ if (wifiChipInfos != null) {
+ mCachedStaticChipInfos =
+ convertWifiChipInfoToStaticChipInfos(getAllChipInfo());
+ saveStaticChipInfoToStore(mCachedStaticChipInfos);
+ mIsConcurrencyComboLoadedFromDriver = true;
+ } else {
+ Log.e(TAG, "Configured chip but could not get current chip info.");
+ }
+ }
+ } else {
+ // remove all interfaces on the delete list
+ for (WifiIfaceInfo ifaceInfo : ifaceCreationData.interfacesToBeRemovedFirst) {
+ removeIfaceInternal(ifaceInfo.iface,
+ /* validateRttController */false); // ignore return value
+ }
+ // downgrade all interfaces on the downgrade list
+ for (WifiIfaceInfo ifaceInfo : ifaceCreationData.interfacesToBeDowngraded) {
+ if (ifaceInfo.createType == HDM_CREATE_IFACE_AP_BRIDGE) {
+ if (!downgradeBridgedApIface(ifaceInfo)) {
+ Log.e(TAG, "executeChipReconfiguration: failed to downgrade bridged"
+ + " AP: " + ifaceInfo);
return null;
}
- break;
- case HDM_CREATE_IFACE_AP:
- ifaceCreationData.chipInfo.chip.createApIface(
- (WifiStatus status, IWifiApIface iface) -> {
- statusResp.value = status;
- ifaceResp.value = iface;
- });
- break;
- case HDM_CREATE_IFACE_P2P:
- ifaceCreationData.chipInfo.chip.createP2pIface(
- (WifiStatus status, IWifiP2pIface iface) -> {
- statusResp.value = status;
- ifaceResp.value = iface;
- });
- break;
- case HDM_CREATE_IFACE_NAN:
- ifaceCreationData.chipInfo.chip.createNanIface(
- (WifiStatus status, IWifiNanIface iface) -> {
- statusResp.value = status;
- ifaceResp.value = iface;
- });
- break;
+ }
}
+ }
- updateRttControllerWhenInterfaceChanges();
+ // create new interface
+ WifiHal.WifiInterface iface = null;
+ switch (createIfaceType) {
+ case HDM_CREATE_IFACE_STA:
+ iface = ifaceCreationData.chipInfo.chip.createStaIface();
+ break;
+ case HDM_CREATE_IFACE_AP_BRIDGE:
+ iface = ifaceCreationData.chipInfo.chip.createBridgedApIface();
+ break;
+ case HDM_CREATE_IFACE_AP:
+ iface = ifaceCreationData.chipInfo.chip.createApIface();
+ break;
+ case HDM_CREATE_IFACE_P2P:
+ iface = ifaceCreationData.chipInfo.chip.createP2pIface();
+ break;
+ case HDM_CREATE_IFACE_NAN:
+ iface = ifaceCreationData.chipInfo.chip.createNanIface();
+ break;
+ }
- if (statusResp.value.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "executeChipReconfiguration: failed to create interface"
- + " createIfaceType=" + createIfaceType + ": "
- + statusString(statusResp.value));
- return null;
- }
+ updateRttControllerWhenInterfaceChanges();
- return ifaceResp.value;
- } catch (RemoteException e) {
- Log.e(TAG, "executeChipReconfiguration exception: " + e);
+ if (iface == null) {
+ Log.e(TAG, "executeChipReconfiguration: failed to create interface"
+ + " createIfaceType=" + createIfaceType);
return null;
}
+
+ return iface;
}
}
@@ -2948,7 +2278,8 @@ public class HalDeviceManager {
* this must be true.
* @return True if removal succeed, otherwise false.
*/
- private boolean removeIfaceInternal(IWifiIface iface, boolean validateRttController) {
+ private boolean removeIfaceInternal(WifiHal.WifiInterface iface,
+ boolean validateRttController) {
String name = getName(iface);
int type = getType(iface);
if (mDbg) Log.d(TAG, "removeIfaceInternal: iface(name)=" + name + ", type=" + type);
@@ -2959,12 +2290,7 @@ public class HalDeviceManager {
}
synchronized (mLock) {
- if (mWifi == null) {
- Log.e(TAG, "removeIfaceInternal: null IWifi -- iface(name)=" + name);
- return false;
- }
-
- IWifiChip chip = getChip(iface);
+ WifiChip chip = getChip(iface);
if (chip == null) {
Log.e(TAG, "removeIfaceInternal: null IWifiChip -- iface(name)=" + name);
return false;
@@ -2980,27 +2306,23 @@ public class HalDeviceManager {
// status.
dispatchDestroyedListeners(name, type, true);
- WifiStatus status = null;
- try {
- switch (type) {
- case IfaceType.STA:
- status = chip.removeStaIface(name);
- break;
- case IfaceType.AP:
- status = chip.removeApIface(name);
- break;
- case IfaceType.P2P:
- status = chip.removeP2pIface(name);
- break;
- case IfaceType.NAN:
- status = chip.removeNanIface(name);
- break;
- default:
- Log.wtf(TAG, "removeIfaceInternal: invalid type=" + type);
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "IWifiChip.removeXxxIface exception: " + e);
+ boolean success = false;
+ switch (type) {
+ case WifiChip.IFACE_TYPE_STA:
+ success = chip.removeStaIface(name);
+ break;
+ case WifiChip.IFACE_TYPE_AP:
+ success = chip.removeApIface(name);
+ break;
+ case WifiChip.IFACE_TYPE_P2P:
+ success = chip.removeP2pIface(name);
+ break;
+ case WifiChip.IFACE_TYPE_NAN:
+ success = chip.removeNanIface(name);
+ break;
+ default:
+ Log.wtf(TAG, "removeIfaceInternal: invalid type=" + type);
+ return false;
}
// dispatch listeners no matter what status
@@ -3010,10 +2332,10 @@ public class HalDeviceManager {
updateRttControllerWhenInterfaceChanges();
}
- if (status != null && status.code == WifiStatusCode.SUCCESS) {
+ if (success) {
return true;
} else {
- Log.e(TAG, "IWifiChip.removeXxxIface failed: " + statusString(status));
+ Log.e(TAG, "IWifiChip.removeXxxIface failed, name=" + name + ", type=" + type);
return false;
}
}
@@ -3084,24 +2406,13 @@ public class HalDeviceManager {
if (name == null) {
return false;
}
- IWifiChip chip = getChip(bridgedApIfaceInfo.iface);
+ WifiChip chip = getChip(bridgedApIfaceInfo.iface);
if (chip == null) {
return false;
}
- android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipForV1_5Mockable(chip);
- if (chip15 == null) {
- return false;
- }
String instanceForRemoval =
bridgedSoftApManager.getBridgedApDowngradeIfaceInstanceForRemoval();
- try {
- chip15.removeIfaceInstanceFromBridgedApIface(name, instanceForRemoval);
- } catch (RemoteException e) {
- Log.e(TAG,
- "IWifiChip.removeIfaceInstanceFromBridgedApIface exception: " + e);
- return false;
- }
- return true;
+ return chip.removeIfaceInstanceFromBridgedApIface(name, instanceForRemoval);
}
private abstract class ListenerProxy<LISTENER> {
@@ -3147,9 +2458,12 @@ public class HalDeviceManager {
} else {
// Current thread is not the thread the listener should be invoked on.
// Post action to the intended thread.
- mHandler.postAtFrontOfQueue(() -> {
- action();
- });
+ if (mHandler instanceof RunnerHandler) {
+ RunnerHandler rh = (RunnerHandler) mHandler;
+ rh.postToFront(() -> action());
+ } else {
+ mHandler.postAtFrontOfQueue(() -> action());
+ }
}
}
@@ -3214,7 +2528,7 @@ public class HalDeviceManager {
}
@Override
- public void onNewRttController(IWifiRttController controller) {
+ public void onNewRttController(WifiRttController controller) {
mHandler.post(() -> mCallback.onNewRttController(controller));
}
@@ -3230,7 +2544,7 @@ public class HalDeviceManager {
+ mRttControllerLifecycleCallbacks.size());
}
for (InterfaceRttControllerLifecycleCallbackProxy cbp : mRttControllerLifecycleCallbacks) {
- cbp.onNewRttController(mIWifiRttController);
+ cbp.onNewRttController(mWifiRttController);
}
}
@@ -3240,7 +2554,6 @@ public class HalDeviceManager {
}
}
-
/**
* Updates the RttController when the interface changes:
* - Handles callbacks to registered listeners
@@ -3248,55 +2561,37 @@ public class HalDeviceManager {
*/
private void updateRttControllerWhenInterfaceChanges() {
synchronized (mLock) {
- if (validateRttController()) {
+ if (mWifiRttController != null && mWifiRttController.validate()) {
if (mDbg) {
Log.d(TAG, "Current RttController is valid, Don't try to create a new one");
}
return;
}
- boolean controllerDestroyed = mIWifiRttController != null;
- mIWifiRttController = null;
+ boolean controllerDestroyed = mWifiRttController != null;
+ mWifiRttController = null;
if (mRttControllerLifecycleCallbacks.size() == 0) {
Log.d(TAG, "updateRttController: no one is interested in RTT controllers");
return;
}
- IWifiRttController newRttController = createRttControllerIfPossible();
+ WifiRttController newRttController = createRttControllerIfPossible();
if (newRttController == null) {
if (controllerDestroyed) {
dispatchRttControllerLifecycleOnDestroyed();
}
} else {
- mIWifiRttController = newRttController;
+ mWifiRttController = newRttController;
dispatchRttControllerLifecycleOnNew();
}
}
}
- private boolean validateRttController() {
- if (mIWifiRttController == null) {
- return false;
- }
- Mutable<Boolean> isRttControllerValid = new Mutable<>(false);
- try {
- mIWifiRttController.getBoundIface(
- (status, iface) -> {
- if (status.code == WifiStatusCode.SUCCESS) {
- isRttControllerValid.value = true;
- }
- });
- } catch (RemoteException e) {
- Log.e(TAG, "RttController: exception getBoundIface" + e);
- }
- return isRttControllerValid.value;
- }
-
/**
- * Try to create a new RttController.
+ * Try to create and set up a new RttController.
*
* @return The new RttController - or null on failure.
*/
- private IWifiRttController createRttControllerIfPossible() {
+ private WifiRttController createRttControllerIfPossible() {
synchronized (mLock) {
if (!isWifiStarted()) {
Log.d(TAG, "createRttControllerIfPossible: Wifi is not started");
@@ -3319,51 +2614,13 @@ public class HalDeviceManager {
continue;
}
- Mutable<IWifiRttController> rttResp = new Mutable<>();
- try {
- android.hardware.wifi.V1_6.IWifiChip chip16 =
- android.hardware.wifi.V1_6.IWifiChip.castFrom(chipInfo.chip);
- android.hardware.wifi.V1_4.IWifiChip chip14 =
- android.hardware.wifi.V1_4.IWifiChip.castFrom(chipInfo.chip);
-
- if (chip16 != null) {
- chip16.createRttController_1_6(null,
- (WifiStatus status,
- android.hardware.wifi.V1_6.IWifiRttController rtt) -> {
- if (status.code == WifiStatusCode.SUCCESS) {
- rttResp.value = rtt;
- } else {
- Log.e(TAG, "IWifiChip.createRttController_1_6 failed: "
- + statusString(status));
- }
- });
- } else if (chip14 != null) {
- chip14.createRttController_1_4(null,
- (WifiStatus status,
- android.hardware.wifi.V1_4.IWifiRttController rtt) -> {
- if (status.code == WifiStatusCode.SUCCESS) {
- rttResp.value = rtt;
- } else {
- Log.e(TAG, "IWifiChip.createRttController_1_4 failed: "
- + statusString(status));
- }
- });
- } else {
- chipInfo.chip.createRttController(null,
- (WifiStatus status, IWifiRttController rtt) -> {
- if (status.code == WifiStatusCode.SUCCESS) {
- rttResp.value = rtt;
- } else {
- Log.e(TAG, "IWifiChip.createRttController failed: "
- + statusString(status));
- }
- });
+ WifiRttController rttController = chipInfo.chip.createRttController();
+ if (rttController != null) {
+ if (!rttController.setup()) {
+ return null;
}
- } catch (RemoteException e) {
- Log.e(TAG, "IWifiChip.createRttController exception: " + e);
- }
- if (rttResp.value != null) {
- return rttResp.value;
+ rttController.enableVerboseLogging(mDbg);
+ return rttController;
}
}
}
@@ -3374,57 +2631,30 @@ public class HalDeviceManager {
// general utilities
- private static String statusString(WifiStatus status) {
- if (status == null) {
- return "status=null";
- }
- StringBuilder sb = new StringBuilder();
- sb.append(status.code).append(" (").append(status.description).append(")");
- return sb.toString();
- }
-
// Will return -1 for invalid results! Otherwise will return one of the 4 valid values.
- private static int getType(IWifiIface iface) {
- Mutable<Integer> typeResp = new Mutable<>(-1);
- try {
- iface.getType((WifiStatus status, int type) -> {
- if (status.code == WifiStatusCode.SUCCESS) {
- typeResp.value = type;
- } else {
- Log.e(TAG, "Error on getType: " + statusString(status));
- }
- });
- } catch (RemoteException e) {
- Log.e(TAG, "Exception on getType: " + e);
+ @VisibleForTesting
+ protected static int getType(WifiHal.WifiInterface iface) {
+ if (iface instanceof WifiStaIface) {
+ return WifiChip.IFACE_TYPE_STA;
+ } else if (iface instanceof WifiApIface) {
+ return WifiChip.IFACE_TYPE_AP;
+ } else if (iface instanceof WifiP2pIface) {
+ return WifiChip.IFACE_TYPE_P2P;
+ } else if (iface instanceof WifiNanIface) {
+ return WifiChip.IFACE_TYPE_NAN;
}
-
- return typeResp.value;
- }
-
- /**
- * Checks for a successful status result.
- *
- * Failures are logged to mLog.
- *
- * @param status is the WifiStatus generated by a hal call
- * @return true for success, false for failure
- */
- private boolean ok(String method, WifiStatus status) {
- if (status.code == WifiStatusCode.SUCCESS) return true;
-
- Log.e(TAG, "Error on " + method + ": " + statusString(status));
- return false;
+ return -1;
}
private static SparseBooleanArray convertRadioCombinationMatrixToLookupTable(
- WifiRadioCombinationMatrix matrix) {
+ WifiChip.WifiRadioCombinationMatrix matrix) {
SparseBooleanArray lookupTable = new SparseBooleanArray();
- if (null == matrix) return lookupTable;
+ if (matrix == null) return lookupTable;
- for (WifiRadioCombination combination: matrix.radioCombinations) {
+ for (WifiChip.WifiRadioCombination combination : matrix.radioCombinations) {
int bandMask = 0;
- for (WifiRadioConfiguration config: combination.radioConfigurations) {
- bandMask |= 1 << config.bandInfo;
+ for (WifiChip.WifiRadioConfiguration config : combination.radioConfigurations) {
+ bandMask |= config.bandInfo;
}
if ((bandMask & DBS_24G_5G_MASK) == DBS_24G_5G_MASK) {
lookupTable.put(DBS_24G_5G_MASK, true);
@@ -3436,36 +2666,24 @@ public class HalDeviceManager {
}
/**
- * Get the chip capabilities
- *
- * This is called before creating an interface and needs at least v1.5 HAL.
+ * Get the chip capabilities.
*
- * @param wifiChip WifiChip
- * @return bitmask defined by HAL interface
+ * @param wifiChip WifiChip to get the features for.
+ * @return Bitset of WifiManager.WIFI_FEATURE_* values.
*/
- public long getChipCapabilities(@NonNull IWifiChip wifiChip) {
- long featureSet = 0;
- if (wifiChip == null) return featureSet;
-
- try {
- final Mutable<Long> feat = new Mutable<>(CHIP_CAPABILITY_UNINITIALIZED);
- synchronized (mLock) {
- android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 =
- getWifiChipForV1_5Mockable(wifiChip);
- // HAL newer than v1.5 support getting capabilities before creating an interface.
- if (iWifiChipV15 != null) {
- iWifiChipV15.getCapabilities_1_5((status, capabilities) -> {
- if (!ok("getCapabilities_1_5", status)) return;
- feat.value = (long) capabilities;
- });
- }
- }
- featureSet = feat.value;
- } catch (RemoteException e) {
- Log.e(TAG, "Exception on getCapabilities: " + e);
+ public long getChipCapabilities(@NonNull WifiChip wifiChip) {
+ if (wifiChip == null) return 0;
+
+ WifiChip.Response<Long> capsResp = wifiChip.getCapabilitiesBeforeIfacesExist();
+ if (capsResp.getStatusCode() == WifiHal.WIFI_STATUS_SUCCESS) {
+ return capsResp.getValue();
+ } else if (capsResp.getStatusCode() != WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION) {
+ // Non-remote exception here is likely because HIDL HAL < v1.5
+ // does not support getting capabilities before creating an interface.
+ return CHIP_CAPABILITY_UNINITIALIZED;
+ } else { // remote exception
return 0;
}
- return featureSet;
}
/**
@@ -3476,35 +2694,11 @@ public class HalDeviceManager {
* @param wifiChip WifiChip
* @return Wifi radio combinmation matrix
*/
- private WifiRadioCombinationMatrix getChipSupportedRadioCombinationsMatrix(
- @NonNull IWifiChip wifiChip) {
+ private WifiChip.WifiRadioCombinationMatrix getChipSupportedRadioCombinationsMatrix(
+ @NonNull WifiChip wifiChip) {
synchronized (mLock) {
- if (null == wifiChip) return null;
- android.hardware.wifi.V1_6.IWifiChip chipV16 =
- getWifiChipForV1_6Mockable(wifiChip);
- if (null == chipV16) return null;
-
- Mutable<WifiRadioCombinationMatrix> radioCombinationMatrixResp =
- new Mutable<>();
- radioCombinationMatrixResp.value = null;
- try {
- chipV16.getSupportedRadioCombinationsMatrix((WifiStatus status,
- WifiRadioCombinationMatrix matrix) -> {
- if (status.code == WifiStatusCode.SUCCESS) {
- radioCombinationMatrixResp.value = matrix;
- if (mDbg) {
- Log.d(TAG, "radioCombinationMatrix=" + matrix);
- }
- } else {
- Log.e(TAG, "getSupportedRadioCombinationsMatrix failed: "
- + statusString(status));
- }
- });
- } catch (RemoteException e) {
- Log.e(TAG, "Exception on getSupportedRadioCombinationsMatrix: " + e);
- radioCombinationMatrixResp.value = null;
- }
- return radioCombinationMatrixResp.value;
+ if (wifiChip == null) return null;
+ return wifiChip.getSupportedRadioCombinationsMatrix();
}
}
@@ -3513,8 +2707,6 @@ public class HalDeviceManager {
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Dump of HalDeviceManager:");
- pw.println(" mServiceManager: " + mServiceManager);
- pw.println(" mWifi: " + mWifi);
pw.println(" mManagerStatusListeners: " + mManagerStatusListeners);
pw.println(" mInterfaceInfoCache: " + mInterfaceInfoCache);
pw.println(" mDebugChipsInfo: " + Arrays.toString(getAllChipInfo()));
diff --git a/service/java/com/android/server/wifi/HalDeviceManagerUtil.java b/service/java/com/android/server/wifi/HalDeviceManagerUtil.java
index 08a4727924..5897307522 100644
--- a/service/java/com/android/server/wifi/HalDeviceManagerUtil.java
+++ b/service/java/com/android/server/wifi/HalDeviceManagerUtil.java
@@ -17,13 +17,15 @@
package com.android.server.wifi;
import android.annotation.NonNull;
-import android.hardware.wifi.V1_6.IWifiChip;
+
+import com.android.server.wifi.hal.WifiChip;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
+import java.util.List;
/**
* Utility methods for HalDeviceManager.
@@ -32,13 +34,12 @@ public class HalDeviceManagerUtil {
static class StaticChipInfo {
private int mChipId;
private long mChipCapabilities;
- private @NonNull ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> mAvailableModes =
- new ArrayList<>();
+ private @NonNull ArrayList<WifiChip.ChipMode> mAvailableModes = new ArrayList<>();
StaticChipInfo(
int chipId,
long chipCapabilities,
- @NonNull ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> availableModes) {
+ @NonNull ArrayList<WifiChip.ChipMode> availableModes) {
mChipId = chipId;
mChipCapabilities = chipCapabilities;
if (availableModes != null) {
@@ -54,7 +55,7 @@ public class HalDeviceManagerUtil {
return mChipCapabilities;
}
- ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> getAvailableModes() {
+ ArrayList<WifiChip.ChipMode> getAvailableModes() {
return mAvailableModes;
}
}
@@ -69,8 +70,7 @@ public class HalDeviceManagerUtil {
jsonObject.put(KEY_CHIP_ID, staticChipInfo.getChipId());
jsonObject.put(KEY_CHIP_CAPABILITIES, staticChipInfo.getChipCapabilities());
JSONArray availableModesJson = new JSONArray();
- for (android.hardware.wifi.V1_6.IWifiChip.ChipMode mode
- : staticChipInfo.getAvailableModes()) {
+ for (WifiChip.ChipMode mode : staticChipInfo.getAvailableModes()) {
availableModesJson.put(chipModeToJson(mode));
}
jsonObject.put(KEY_AVAILABLE_MODES, availableModesJson);
@@ -78,8 +78,7 @@ public class HalDeviceManagerUtil {
}
static StaticChipInfo jsonToStaticChipInfo(JSONObject jsonObject) throws JSONException {
- ArrayList<IWifiChip.ChipMode> availableModes =
- new ArrayList<>();
+ ArrayList<WifiChip.ChipMode> availableModes = new ArrayList<>();
int chipId = jsonObject.getInt(KEY_CHIP_ID);
long chipCapabilities = jsonObject.getLong(KEY_CHIP_CAPABILITIES);
JSONArray modesJson = jsonObject.getJSONArray(KEY_AVAILABLE_MODES);
@@ -92,80 +91,72 @@ public class HalDeviceManagerUtil {
private static final String KEY_ID = "id";
private static final String KEY_AVAILABLE_COMBINATIONS = "availableCombinations";
- private static JSONObject chipModeToJson(android.hardware.wifi.V1_6.IWifiChip.ChipMode chipMode)
+ private static JSONObject chipModeToJson(WifiChip.ChipMode chipMode)
throws JSONException {
JSONObject jsonObject = new JSONObject();
jsonObject.put(KEY_ID, chipMode.id);
JSONArray availableCombinationsJson = new JSONArray();
- for (IWifiChip.ChipConcurrencyCombination combo
- : chipMode.availableCombinations) {
+ for (WifiChip.ChipConcurrencyCombination combo : chipMode.availableCombinations) {
availableCombinationsJson.put(chipConcurrencyCombinationToJson(combo));
}
jsonObject.put(KEY_AVAILABLE_COMBINATIONS, availableCombinationsJson);
return jsonObject;
}
- private static android.hardware.wifi.V1_6.IWifiChip.ChipMode jsonToChipMode(
- JSONObject jsonObject) throws JSONException {
- android.hardware.wifi.V1_6.IWifiChip.ChipMode chipMode =
- new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
- chipMode.id = jsonObject.getInt(KEY_ID);
+ private static WifiChip.ChipMode jsonToChipMode(JSONObject jsonObject) throws JSONException {
+ List<WifiChip.ChipConcurrencyCombination> availableCombinations = new ArrayList<>();
JSONArray availableCombinationsJson =
jsonObject.getJSONArray(KEY_AVAILABLE_COMBINATIONS);
for (int i = 0; i < availableCombinationsJson.length(); i++) {
- chipMode.availableCombinations.add(jsonToChipConcurrencyCombination(
+ availableCombinations.add(jsonToChipConcurrencyCombination(
availableCombinationsJson.getJSONObject(i)));
}
- return chipMode;
+ return new WifiChip.ChipMode(jsonObject.getInt(KEY_ID), availableCombinations);
}
private static final String KEY_CONCURRENCY_LIMITS = "limits";
private static JSONObject chipConcurrencyCombinationToJson(
- IWifiChip.ChipConcurrencyCombination combo) throws JSONException {
+ WifiChip.ChipConcurrencyCombination combo) throws JSONException {
JSONObject jsonObject = new JSONObject();
JSONArray limitsJson = new JSONArray();
- for (IWifiChip.ChipConcurrencyCombinationLimit limit : combo.limits) {
+ for (WifiChip.ChipConcurrencyCombinationLimit limit : combo.limits) {
limitsJson.put(chipConcurrencyCombinationLimitToJson(limit));
}
jsonObject.put(KEY_CONCURRENCY_LIMITS, limitsJson);
return jsonObject;
}
- private static IWifiChip.ChipConcurrencyCombination jsonToChipConcurrencyCombination(
+ private static WifiChip.ChipConcurrencyCombination jsonToChipConcurrencyCombination(
JSONObject jsonObject) throws JSONException {
- IWifiChip.ChipConcurrencyCombination combo = new IWifiChip.ChipConcurrencyCombination();
- combo.limits = new ArrayList<>();
+ List<WifiChip.ChipConcurrencyCombinationLimit> limits = new ArrayList<>();
JSONArray limitsJson = jsonObject.getJSONArray(KEY_CONCURRENCY_LIMITS);
for (int i = 0; i < limitsJson.length(); i++) {
- combo.limits.add(
+ limits.add(
jsonToChipConcurrencyCombinationLimit(limitsJson.getJSONObject(i)));
}
- return combo;
+ return new WifiChip.ChipConcurrencyCombination(limits);
}
private static final String KEY_MAX_IFACES = "maxIfaces";
private static final String KEY_TYPES = "types";
private static JSONObject chipConcurrencyCombinationLimitToJson(
- IWifiChip.ChipConcurrencyCombinationLimit limit) throws JSONException {
+ WifiChip.ChipConcurrencyCombinationLimit limit) throws JSONException {
JSONObject jsonObject = new JSONObject();
jsonObject.put(KEY_MAX_IFACES, limit.maxIfaces);
jsonObject.put(KEY_TYPES, new JSONArray(limit.types));
return jsonObject;
}
- private static IWifiChip.ChipConcurrencyCombinationLimit jsonToChipConcurrencyCombinationLimit(
+ private static WifiChip.ChipConcurrencyCombinationLimit jsonToChipConcurrencyCombinationLimit(
JSONObject jsonObject) throws JSONException {
- IWifiChip.ChipConcurrencyCombinationLimit
- limit = new IWifiChip.ChipConcurrencyCombinationLimit();
- limit.maxIfaces = jsonObject.getInt(KEY_MAX_IFACES);
- limit.types = new ArrayList<>();
+ List<Integer> types = new ArrayList<>();
JSONArray limitsJson = jsonObject.getJSONArray(KEY_TYPES);
for (int i = 0; i < limitsJson.length(); i++) {
- limit.types.add(limitsJson.getInt(i));
+ types.add(limitsJson.getInt(i));
}
- return limit;
+ return new WifiChip.ChipConcurrencyCombinationLimit(
+ jsonObject.getInt(KEY_MAX_IFACES), types);
}
}
-
diff --git a/service/java/com/android/server/wifi/InterfaceConflictManager.java b/service/java/com/android/server/wifi/InterfaceConflictManager.java
index 8faba11d32..bb2cf2114e 100644
--- a/service/java/com/android/server/wifi/InterfaceConflictManager.java
+++ b/service/java/com/android/server/wifi/InterfaceConflictManager.java
@@ -44,6 +44,7 @@ import androidx.annotation.NonNull;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.wifi.util.WaitingState;
+import com.android.server.wifi.util.WorkSourceHelper;
import com.android.wifi.resources.R;
import java.io.FileDescriptor;
@@ -129,30 +130,67 @@ public class InterfaceConflictManager {
}
/**
- * Returns an indication as to whether user approval is needed for this specific request. User
- * approval is controlled by:
+ * Returns whether user approval is needed to delete an existing interface for a new one.
+ * User approval is controlled by:
* - A global overlay `config_wifiUserApprovalRequiredForD2dInterfacePriority`
* - An exemption list overlay `config_wifiExcludedFromUserApprovalForD2dInterfacePriority`
* which is a list of packages which are *exempted* from user approval
* - A shell command which can be used to override
*
- * @param requestorWs The WorkSource of the requestor - used to determine whether it is exempted
- * from user approval. All requesting packages must be exempted for the
- * dialog to NOT be displayed.
+ * @param requestedCreateType Requested interface type
+ * @param newRequestorWsHelper WorkSourceHelper of the new interface
+ * @param existingCreateType Existing interface type
+ * @param existingRequestorWsHelper WorkSourceHelper of the existing interface
+ * @return true if the new interface needs user approval to delete the existing one.
*/
- private boolean isUserApprovalNeeded(WorkSource requestorWs) {
- if (mUserApprovalNeededOverride) return mUserApprovalNeededOverrideValue;
- if (!mUserApprovalNeeded || mUserApprovalExemptedPackages.isEmpty()) {
- return mUserApprovalNeeded;
+ public boolean needsUserApprovalToDelete(
+ int requestedCreateType, @NonNull WorkSourceHelper newRequestorWsHelper,
+ int existingCreateType, @NonNull WorkSourceHelper existingRequestorWsHelper) {
+ if (!isUserApprovalEnabled()) {
+ return false;
}
- for (int i = 0; i < requestorWs.size(); ++i) {
- if (!mUserApprovalExemptedPackages.contains(requestorWs.getPackageName(i))) {
+ // Check if every package in the WorkSource are exempt from user approval.
+ if (!mUserApprovalExemptedPackages.isEmpty()) {
+ boolean exemptFromUserApproval = true;
+ WorkSource requestorWs = newRequestorWsHelper.getWorkSource();
+ for (int i = 0; i < requestorWs.size(); i++) {
+ if (!mUserApprovalExemptedPackages.contains(requestorWs.getPackageName(i))) {
+ exemptFromUserApproval = false;
+ break;
+ }
+ }
+ if (exemptFromUserApproval) {
+ return false;
+ }
+ }
+ // Check if priority level can get user approval.
+ if (newRequestorWsHelper.getRequestorWsPriority() <= WorkSourceHelper.PRIORITY_BG
+ || existingRequestorWsHelper.getRequestorWsPriority()
+ == WorkSourceHelper.PRIORITY_INTERNAL) {
+ return false;
+ }
+ // Check if the conflicting interface types can get user approval.
+ if (requestedCreateType == HDM_CREATE_IFACE_AP
+ || requestedCreateType == HDM_CREATE_IFACE_AP_BRIDGE) {
+ if (existingCreateType == HDM_CREATE_IFACE_P2P
+ || existingCreateType == HDM_CREATE_IFACE_NAN) {
+ return true;
+ }
+ } else if (requestedCreateType == HDM_CREATE_IFACE_P2P) {
+ if (existingCreateType == HDM_CREATE_IFACE_AP
+ || existingCreateType == HDM_CREATE_IFACE_AP_BRIDGE
+ || existingCreateType == HDM_CREATE_IFACE_NAN) {
+ return true;
+ }
+ } else if (requestedCreateType == HDM_CREATE_IFACE_NAN) {
+ if (existingCreateType == HDM_CREATE_IFACE_AP
+ || existingCreateType == HDM_CREATE_IFACE_AP_BRIDGE
+ || existingCreateType == HDM_CREATE_IFACE_P2P) {
return true;
}
}
-
- return false; // all packages of the requestor are excluded
+ return false;
}
/**
@@ -169,6 +207,13 @@ public class InterfaceConflictManager {
mUserApprovalNeededOverrideValue = overrideValue;
}
+ private boolean isUserApprovalEnabled() {
+ if (mUserApprovalNeededOverride) {
+ return mUserApprovalNeededOverrideValue;
+ }
+ return mUserApprovalNeeded;
+ }
+
/**
* Return values for {@link #manageInterfaceConflictForStateMachine}
*/
@@ -240,6 +285,7 @@ public class InterfaceConflictManager {
@HalDeviceManager.HdmIfaceTypeForCreation int createIfaceType, WorkSource requestorWs,
boolean bypassDialog) {
synchronized (mLock) {
+ // Check if we're waiting for user approval for a different caller.
if (mUserApprovalPending && !TextUtils.equals(tag, mUserApprovalPendingTag)) {
Log.w(TAG, tag + ": rejected since there's a pending user approval for "
+ mUserApprovalPendingTag);
@@ -261,6 +307,7 @@ public class InterfaceConflictManager {
return mUserJustApproved ? ICM_EXECUTE_COMMAND : ICM_ABORT_COMMAND;
}
+ // Check if we're already waiting for user approval for this caller.
if (mUserApprovalPending) {
Log.w(TAG, tag
+ ": trying for another potentially waiting operation - but should be"
@@ -269,8 +316,13 @@ public class InterfaceConflictManager {
return ICM_SKIP_COMMAND_WAIT_FOR_USER; // same effect
}
- if (bypassDialog || !isUserApprovalNeeded(requestorWs)) return ICM_EXECUTE_COMMAND;
+ // Execute the command if the dialogs aren't enabled.
+ if (!isUserApprovalEnabled()) return ICM_EXECUTE_COMMAND;
+
+ // Auto-approve dialog if bypass is specified.
+ if (bypassDialog) return ICM_EXECUTE_COMMAND;
+ // Check if we need to show the dialog.
List<Pair<Integer, WorkSource>> impact = mHdm.reportImpactToCreateIface(createIfaceType,
false, requestorWs);
localLog(tag + ": Asking user about creating the interface, impact=" + impact);
@@ -280,6 +332,7 @@ public class InterfaceConflictManager {
return ICM_EXECUTE_COMMAND;
}
+ // Auto-approve dialog if we only need to delete a disconnected P2P.
if (mUserApprovalNotRequireForDisconnectedP2p && !mIsP2pConnected
&& impact.size() == 1 && impact.get(0).first == HDM_CREATE_IFACE_P2P) {
localLog(tag
@@ -289,7 +342,7 @@ public class InterfaceConflictManager {
boolean shouldShowDialogToDelete = false;
for (Pair<Integer, WorkSource> ifaceToDelete : impact) {
- if (mHdm.needsUserApprovalToDelete(
+ if (needsUserApprovalToDelete(
createIfaceType, mWifiInjector.makeWsHelper(requestorWs),
ifaceToDelete.first, mWifiInjector.makeWsHelper(ifaceToDelete.second))) {
shouldShowDialogToDelete = true;
diff --git a/service/java/com/android/server/wifi/MultiInternetManager.java b/service/java/com/android/server/wifi/MultiInternetManager.java
index ed1212d048..6afdde7ad5 100644
--- a/service/java/com/android/server/wifi/MultiInternetManager.java
+++ b/service/java/com/android/server/wifi/MultiInternetManager.java
@@ -28,6 +28,8 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.WorkSource;
+import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
@@ -38,6 +40,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Map;
/**
* Manages STA + STA for multi internet networks.
@@ -84,6 +87,7 @@ public class MultiInternetManager {
public long connectionStartTimeMillis;
// The WorkSource of the connection requestor.
public WorkSource requestorWorkSource;
+ public String bssid;
NetworkConnectionState(WorkSource workSource) {
this(workSource, -1L);
@@ -95,6 +99,7 @@ public class MultiInternetManager {
mConnected = false;
mValidated = false;
+ bssid = null;
}
public NetworkConnectionState setConnected(boolean connected) {
@@ -173,7 +178,9 @@ public class MultiInternetManager {
}
final ConcreteClientModeManager ccm = (ConcreteClientModeManager) activeModeManager;
// TODO: b/197670907 : Add client role ROLE_CLIENT_SECONDARY_INTERNET
- if (ccm.getRole() != ROLE_CLIENT_SECONDARY_LONG_LIVED || !ccm.isSecondaryInternet()) {
+ // Needs to call getPreviousRole here since the role is set to null after a CMM stops
+ if (ccm.getPreviousRole() != ROLE_CLIENT_SECONDARY_LONG_LIVED
+ || !ccm.isSecondaryInternet()) {
return;
}
if (mVerboseLoggingEnabled) {
@@ -213,7 +220,7 @@ public class MultiInternetManager {
|| !isStaConcurrencyForMultiInternetEnabled()) {
return;
}
- final WifiInfo info = clientModeManager.syncRequestConnectionInfo();
+ final WifiInfo info = clientModeManager.getConnectionInfo();
if (info != null) {
final int band = ScanResult.toBand(info.getFrequency());
if (mNetworkConnectionStates.contains(band)) {
@@ -367,6 +374,7 @@ public class MultiInternetManager {
if (mode == mStaConcurrencyMultiInternetMode) {
return true;
}
+ mStaConcurrencyMultiInternetMode = mode;
// If the STA+STA multi internet feature was disabled, disconnect the secondary cmm.
// TODO: b/197670907 : Add client role ROLE_CLIENT_SECONDARY_INTERNET
if (!enabled) {
@@ -376,10 +384,6 @@ public class MultiInternetManager {
cmm.disconnect();
}
}
- for (int i = 0; i < mNetworkConnectionStates.size(); i++) {
- // Clear the connection state for all bands.
- mNetworkConnectionStates.setValueAt(i, new NetworkConnectionState(null));
- }
handleConnectionStateChange(MULTI_INTERNET_STATE_NONE, null);
} else {
updateNetworkConnectionStates();
@@ -389,7 +393,7 @@ public class MultiInternetManager {
getRequestorWorkSource(band));
}
}
- mStaConcurrencyMultiInternetMode = mode;
+
mSettingsStore.handleWifiMultiInternetMode(mode);
// Check if there is already multi internet request then start scan for connection.
if (hasPendingConnectionRequests()) {
@@ -422,14 +426,14 @@ public class MultiInternetManager {
}
// If primary CMM has associated to a new BSSID, need to check if it is in a different band
// of secondary CMM.
- final WifiInfo info = clientModeManager.syncRequestConnectionInfo();
+ final WifiInfo info = clientModeManager.getConnectionInfo();
final ConcreteClientModeManager secondaryCcmm =
mActiveModeWarden.getClientModeManagerInRole(ROLE_CLIENT_SECONDARY_LONG_LIVED);
// If no secondary client mode manager then it's ok
if (secondaryCcmm == null) return;
// If secondary client mode manager is not connected or not for secondary internet
if (!secondaryCcmm.isConnected() || !secondaryCcmm.isSecondaryInternet()) return;
- final WifiInfo info2 = secondaryCcmm.syncRequestConnectionInfo();
+ final WifiInfo info2 = secondaryCcmm.getConnectionInfo();
// If secondary network is in same band as primary now
if (ScanResult.toBand(info.getFrequency()) == ScanResult.toBand(info2.getFrequency())) {
// Need to disconnect secondary network
@@ -450,20 +454,13 @@ public class MultiInternetManager {
}
/**
- * Check if there is connection request on a specific band.
- * @param band The band for the connection request.
- * @return true if there is connection request on specific band.
- */
- public boolean hasConnectionRequest(int band) {
- return mNetworkConnectionStates.contains(band)
- ? (getRequestorWorkSource(band) != null) : false;
- }
-
- /**
* Check if there is unconnected network connection request.
* @return the band of the connection request that is still not connected.
*/
public int findUnconnectedRequestBand() {
+ if (mStaConcurrencyMultiInternetMode == WifiManager.WIFI_MULTI_INTERNET_MODE_DISABLED) {
+ return ScanResult.UNSPECIFIED;
+ }
for (int i = 0; i < mNetworkConnectionStates.size(); i++) {
if (!mNetworkConnectionStates.valueAt(i).isConnected()) {
return mNetworkConnectionStates.keyAt(i);
@@ -473,6 +470,22 @@ public class MultiInternetManager {
}
/**
+ * Return the mapping from band (one of ScanResult.WIFI_BAND_*) to the specified BSSID for that
+ * band.
+ */
+ public Map<Integer, String> getSpecifiedBssids() {
+ Map<Integer, String> result = new ArrayMap<>();
+ for (int i = 0; i < mNetworkConnectionStates.size(); i++) {
+ int band = mNetworkConnectionStates.keyAt(i);
+ String bssid = mNetworkConnectionStates.valueAt(i).bssid;
+ if (bssid != null) {
+ result.put(band, bssid);
+ }
+ }
+ return result;
+ }
+
+ /**
* Traverse the client mode managers and update the internal connection states.
*/
private void updateNetworkConnectionStates() {
@@ -492,7 +505,7 @@ public class MultiInternetManager {
&& !ccmm.isSecondaryInternet()) {
continue;
}
- WifiInfo info = clientModeManager.syncRequestConnectionInfo();
+ WifiInfo info = clientModeManager.getConnectionInfo();
// Exclude the network that is not connected or restricted.
if (info == null || !clientModeManager.isConnected()
|| info.isRestricted()) continue;
@@ -534,14 +547,15 @@ public class MultiInternetManager {
* @param requestorWs The requestor's WorkSource. Null to clear a network request for a
* a band.
*/
- public void setMultiInternetConnectionWorksource(int band, WorkSource requestorWs) {
+ public void setMultiInternetConnectionWorksource(int band, String targetBssid,
+ WorkSource requestorWs) {
if (!isStaConcurrencyForMultiInternetEnabled()) {
Log.w(TAG, "MultInternet is not enabled.");
return;
}
if (mVerboseLoggingEnabled) {
- Log.v(TAG, "setMultiInternetConnectionWorksource: band=" + band + ", requestorWs="
- + requestorWs);
+ Log.v(TAG, "setMultiInternetConnectionWorksource: band=" + band + ", bssid="
+ + targetBssid + ", requestorWs=" + requestorWs);
}
if (requestorWs == null) {
// Disconnect secondary network if the request is removed.
@@ -559,12 +573,48 @@ public class MultiInternetManager {
}
if (mNetworkConnectionStates.contains(band)) {
Log.w(TAG, "band " + band + " already requested.");
+ if (TextUtils.equals(mNetworkConnectionStates.get(band).bssid, targetBssid)) {
+ // No change in BSSID field, so early return to avoid unnecessary scanning.
+ return;
+ }
+ disconnectSecondaryIfNeeded(band, targetBssid);
}
- mNetworkConnectionStates.put(band, new NetworkConnectionState(requestorWs,
- mClock.getElapsedSinceBootMillis()));
+ NetworkConnectionState connectionState = new NetworkConnectionState(requestorWs,
+ mClock.getElapsedSinceBootMillis());
+ connectionState.bssid = targetBssid;
+ mNetworkConnectionStates.put(band, connectionState);
startConnectivityScan();
}
+ /**
+ * Disconnect the secondary that's connected to the same band but different bssid.
+ */
+ private void disconnectSecondaryIfNeeded(int band, String targetBssid) {
+ if (targetBssid == null) {
+ return;
+ }
+ for (ConcreteClientModeManager cmm : mActiveModeWarden.getClientModeManagersInRoles(
+ ROLE_CLIENT_SECONDARY_LONG_LIVED)) {
+ if (cmm.isSecondaryInternet()) {
+ WifiInfo wifiInfo = cmm.getConnectionInfo();
+ if (band != ScanResult.toBand(wifiInfo.getFrequency())) {
+ continue;
+ }
+ String connectingBssid = cmm.getConnectingBssid();
+ String connectedBssid = cmm.getConnectedBssid();
+ if ((connectingBssid != null && !connectingBssid.equals(targetBssid))
+ || (connectedBssid != null && !connectedBssid.equals(targetBssid))) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Disconnect secondary client mode manager due to specified"
+ + " BSSID in the same band");
+ }
+ cmm.disconnect();
+ break;
+ }
+ }
+ }
+ }
+
/** Returns the band of the secondary network connected. */
private int getSecondaryConnectedNetworkBand() {
final ConcreteClientModeManager secondaryCcmm =
@@ -572,7 +622,7 @@ public class MultiInternetManager {
if (secondaryCcmm == null) {
return ScanResult.UNSPECIFIED;
}
- final WifiInfo info = secondaryCcmm.syncRequestConnectionInfo();
+ final WifiInfo info = secondaryCcmm.getConnectionInfo();
// Make sure secondary network is connected.
if (info == null || !secondaryCcmm.isConnected() || !secondaryCcmm.isSecondaryInternet()) {
return ScanResult.UNSPECIFIED;
@@ -624,7 +674,8 @@ public class MultiInternetManager {
pw.println(TAG + ": mStaConcurrencyMultiInternetMode "
+ mStaConcurrencyMultiInternetMode);
for (int i = 0; i < mNetworkConnectionStates.size(); i++) {
- pw.println("band " + mNetworkConnectionStates.keyAt(i) + " connected "
+ pw.println("band " + mNetworkConnectionStates.keyAt(i) + " bssid "
+ + mNetworkConnectionStates.valueAt(i).bssid + " connected "
+ mNetworkConnectionStates.valueAt(i).isConnected()
+ " validated " + mNetworkConnectionStates.valueAt(i).isValidated());
}
diff --git a/service/java/com/android/server/wifi/MultiInternetWifiNetworkFactory.java b/service/java/com/android/server/wifi/MultiInternetWifiNetworkFactory.java
index 1cdcda74f8..543fae46b5 100644
--- a/service/java/com/android/server/wifi/MultiInternetWifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/MultiInternetWifiNetworkFactory.java
@@ -91,7 +91,8 @@ public class MultiInternetWifiNetworkFactory extends NetworkFactory {
* @param networkRequest the network requested by connectivity service
* @return true if the request if for multi internet Wifi network, false if not.
*/
- public static boolean isWifiMultiInternetRequest(NetworkRequest networkRequest) {
+ public static boolean isWifiMultiInternetRequest(NetworkRequest networkRequest,
+ boolean isFromSettings) {
if (networkRequest.getNetworkSpecifier() == null
|| !(networkRequest.getNetworkSpecifier() instanceof WifiNetworkSpecifier)) {
return false;
@@ -101,7 +102,7 @@ public class MultiInternetWifiNetworkFactory extends NetworkFactory {
// and must not have SSID/BSSID pattern matcher.
if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& wns.getBand() != ScanResult.UNSPECIFIED
- && WifiConfigurationUtil.isMatchAllNetworkSpecifier(wns)) {
+ && (isFromSettings || WifiConfigurationUtil.isMatchAllNetworkSpecifier(wns))) {
return true;
}
return false;
@@ -137,13 +138,13 @@ public class MultiInternetWifiNetworkFactory extends NetworkFactory {
*/
@Override
public boolean acceptRequest(NetworkRequest networkRequest) {
- if (!mMultiInternetManager.isStaConcurrencyForMultiInternetEnabled()
- || !isWifiMultiInternetRequest(networkRequest)) {
- return false;
- }
final int uid = networkRequest.getRequestorUid();
boolean isFromSetting = mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
|| mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid);
+ if (!mMultiInternetManager.isStaConcurrencyForMultiInternetEnabled()
+ || !isWifiMultiInternetRequest(networkRequest, isFromSetting)) {
+ return false;
+ }
boolean isFromNetworkStack = mWifiPermissionsUtil.checkNetworkStackPermission(uid)
|| mWifiPermissionsUtil.checkMainlineNetworkStackPermission(uid);
// Only allow specific wifi network request with band from apps or services with settings
@@ -164,14 +165,14 @@ public class MultiInternetWifiNetworkFactory extends NetworkFactory {
@Override
protected void needNetworkFor(NetworkRequest networkRequest) {
+ boolean isFromSetting = mWifiPermissionsUtil.checkNetworkSettingsPermission(
+ networkRequest.getRequestorUid());
if (!mMultiInternetManager.isStaConcurrencyForMultiInternetEnabled()
- || !isWifiMultiInternetRequest(networkRequest)) {
+ || !isWifiMultiInternetRequest(networkRequest, isFromSetting)) {
return;
}
WifiNetworkSpecifier wns = (WifiNetworkSpecifier) networkRequest.getNetworkSpecifier();
final int band = wns.getBand();
- boolean isFromSetting = mWifiPermissionsUtil.checkNetworkSettingsPermission(
- networkRequest.getRequestorUid());
boolean isFromForegroundApp = mFacade.isRequestFromForegroundApp(mContext,
networkRequest.getRequestorPackageName());
boolean isFromForegroundAppOrService =
@@ -180,7 +181,7 @@ public class MultiInternetWifiNetworkFactory extends NetworkFactory {
NetworkRequestState nrs = new NetworkRequestState(networkRequest,
new WifiNetworkSpecifier(
wns.ssidPatternMatcher, wns.bssidPatternMatcher, wns.getBand(),
- wns.wifiConfiguration),
+ wns.wifiConfiguration, wns.getPreferredChannelFrequenciesMhz()),
isFromSetting,
isFromForegroundApp,
isFromForegroundAppOrService);
@@ -193,13 +194,14 @@ public class MultiInternetWifiNetworkFactory extends NetworkFactory {
if (mConnectionReqCount.contains(band)) {
reqCount = mConnectionReqCount.get(band);
}
- if (reqCount == 0) {
+ if (reqCount == 0 || isFromSetting) {
localLog("Need network : Uid " + networkRequest.getRequestorUid() + " PackageName "
+ networkRequest.getRequestorPackageName() + " for band " + band
+ " is rom Setting " + isFromSetting + " ForegroundApp " + isFromForegroundApp
+ " ForegroundAppOrService " + isFromForegroundApp);
mMultiInternetManager.setMultiInternetConnectionWorksource(
- band, new WorkSource(networkRequest.getRequestorUid(),
+ band, wns.wifiConfiguration.BSSID,
+ new WorkSource(networkRequest.getRequestorUid(),
networkRequest.getRequestorPackageName()));
}
mConnectionReqCount.put(band, reqCount + 1);
@@ -207,7 +209,9 @@ public class MultiInternetWifiNetworkFactory extends NetworkFactory {
@Override
protected void releaseNetworkFor(NetworkRequest networkRequest) {
- if (!isWifiMultiInternetRequest(networkRequest)) {
+ boolean isFromSetting = mWifiPermissionsUtil.checkNetworkSettingsPermission(
+ networkRequest.getRequestorUid());
+ if (!isWifiMultiInternetRequest(networkRequest, isFromSetting)) {
return;
}
localLog("releaseNetworkFor " + networkRequest);
@@ -219,7 +223,7 @@ public class MultiInternetWifiNetworkFactory extends NetworkFactory {
return;
}
if (reqCount == 1) {
- mMultiInternetManager.setMultiInternetConnectionWorksource(band, null);
+ mMultiInternetManager.setMultiInternetConnectionWorksource(band, null, null);
}
mConnectionReqCount.put(band, reqCount - 1);
}
diff --git a/service/java/com/android/server/wifi/NetworkConnectionEventInfo.java b/service/java/com/android/server/wifi/NetworkConnectionEventInfo.java
index c73e7dafe2..55f6bbaf3c 100644
--- a/service/java/com/android/server/wifi/NetworkConnectionEventInfo.java
+++ b/service/java/com/android/server/wifi/NetworkConnectionEventInfo.java
@@ -19,6 +19,8 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.net.wifi.WifiSsid;
+import java.util.BitSet;
+
/** Data class to hold information for a {@link WifiMonitor#NETWORK_CONNECTION_EVENT}. */
public class NetworkConnectionEventInfo {
public final int networkId;
@@ -27,13 +29,15 @@ public class NetworkConnectionEventInfo {
@NonNull
public final String bssid;
public final boolean isFilsConnection;
+ public final BitSet keyMgmtMask;
public NetworkConnectionEventInfo(int networkId, WifiSsid wifiSsid, String bssid,
- boolean isFilsConnection) {
+ boolean isFilsConnection, BitSet keyMgmtMask) {
this.networkId = networkId;
this.wifiSsid = wifiSsid;
this.bssid = bssid;
this.isFilsConnection = isFilsConnection;
+ this.keyMgmtMask = keyMgmtMask;
}
@Override
@@ -43,6 +47,7 @@ public class NetworkConnectionEventInfo {
+ ", wifiSsid=" + wifiSsid
+ ", bssid='" + bssid + '\''
+ ", isFilsConnection=" + isFilsConnection
+ + ", keyMgmtMask=" + keyMgmtMask
+ '}';
}
}
diff --git a/service/java/com/android/server/wifi/RunnerHandler.java b/service/java/com/android/server/wifi/RunnerHandler.java
new file mode 100644
index 0000000000..19e756a8b4
--- /dev/null
+++ b/service/java/com/android/server/wifi/RunnerHandler.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2022 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.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.LocalLog;
+
+import com.android.modules.utils.HandlerExecutor;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * RunnerHandler tracks all the Runnable jobs posted to the handler for the running time and
+ * monitor if the running time exceeds the expected threshold.
+ *
+ */
+public class RunnerHandler extends Handler {
+ private static final String TAG = "WifiThreadRunner";
+
+ private static final String KEY_SIGNATURE = "KEY_RUNNER_HANDLER_SIGNATURE";
+ private static final String KEY_WHEN = "KEY_RUNNER_HANDLER_WHEN";
+
+ private final int mRunningTimeThresholdInMilliseconds;
+
+ private Set<String> mIgnoredClasses = new HashSet<>();
+ private Set<String> mIgnoredMethods = new HashSet<>();
+
+ // TODO: b/246623192 Add Wifi metric for Runner state overruns.
+ private final LocalLog mLocalLog;
+
+ /**
+ * The Runner handler Constructor
+ * @param looper looper for the handler
+ * @param threshold the running time threshold in milliseconds
+ */
+ public RunnerHandler(Looper looper, int threshold, @NonNull LocalLog localLog) {
+ super(looper);
+ mRunningTimeThresholdInMilliseconds = threshold;
+ mLocalLog = localLog;
+ mIgnoredClasses.add(WifiThreadRunner.class.getName());
+ mIgnoredClasses.add(WifiThreadRunner.class.getName() + "$BlockingRunnable");
+ mIgnoredClasses.add(RunnerHandler.class.getName());
+ mIgnoredClasses.add(HandlerExecutor.class.getName());
+ mIgnoredClasses.add(Handler.class.getName());
+ mIgnoredClasses.add(HandlerThread.class.getName());
+ mIgnoredClasses.add(Looper.class.getName());
+ mIgnoredMethods.add("handleMessage");
+ }
+
+ private String getSignature(StackTraceElement[] elements, Runnable callback) {
+ StringBuilder sb = new StringBuilder();
+ for (StackTraceElement e : elements) {
+ // Go through the stack elements to find out the caller who schedule the job.
+ // Ignore the stack frames generated with ignored classes and methods, until the stack
+ // frame where the runnable job is posted to the handler.
+ if (!mIgnoredClasses.contains(e.getClassName()) && !mIgnoredMethods.contains(
+ e.getMethodName())) {
+ String[] nameArr = e.getClassName().split("\\.", 5);
+ final int len = nameArr.length;
+ if (len > 0) {
+ sb.append(nameArr[len - 1]).append("#").append(e.getMethodName());
+ break;
+ }
+ }
+ // The callback is the lambada function posted as Runnable#run function.
+ // If we can't identify the caller from the stack trace, then we will use the symbol
+ // of the lambada function as the signature of the caller.
+ if (HandlerThread.class.getName().equals(e.getClassName())) {
+ sb.append(callback);
+ break;
+ }
+ }
+ return sb.length() == 0 ? "<UNKNOWN>" : sb.toString();
+ }
+
+ @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);
+ return super.sendMessageAtTime(msg, uptimeMillis);
+ }
+
+ @Override
+ public void dispatchMessage(@NonNull Message msg) {
+ final Bundle bundle = msg.getData();
+ final String signature = bundle.getString(KEY_SIGNATURE);
+ if (signature != null) {
+ Trace.traceBegin(Trace.TRACE_TAG_NETWORK, signature);
+ }
+ // The message sent to front of the queue has when=0, get from the bundle in that case.
+ final long when = msg.getWhen() != 0 ? msg.getWhen() : bundle.getLong(KEY_WHEN);
+ final long start = SystemClock.uptimeMillis();
+ final long scheduleLatency = start - when;
+ super.dispatchMessage(msg);
+ if (signature != null) {
+ Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
+ }
+ final long runTime = SystemClock.uptimeMillis() - start;
+ final String signatureToLog = signature != null ? signature : "<EMPTY>";
+ if (runTime > mRunningTimeThresholdInMilliseconds) {
+ mLocalLog.log(signatureToLog + " was running for " + runTime);
+ }
+ if (scheduleLatency > WifiThreadRunner.getScissorsTimeoutThreshold()) {
+ mLocalLog.log(signatureToLog + " schedule latency " + scheduleLatency + " ms");
+ }
+ }
+
+ /**
+ * Use this helper function rather than directly calling Handler#postAtFrontOfQueue, which does
+ * not call sendMessageAtTime and set the signature. This function will set the signature
+ * before enqueueing the message to front of the queue.
+ * @param r runnable to be queued to the front
+ * @return true when success
+ */
+ public final boolean postToFront(@NonNull Runnable r) {
+ Message msg = Message.obtain(this, r);
+ String signature = getSignature(new Throwable("RunnerHandler:").getStackTrace(),
+ msg.getCallback());
+ Bundle bundle = msg.getData();
+ bundle.putString(KEY_SIGNATURE, signature);
+ bundle.putLong(KEY_WHEN, SystemClock.uptimeMillis());
+ return sendMessageAtFrontOfQueue(msg);
+ }
+}
diff --git a/service/java/com/android/server/wifi/RunnerState.java b/service/java/com/android/server/wifi/RunnerState.java
new file mode 100644
index 0000000000..d219ee91f8
--- /dev/null
+++ b/service/java/com/android/server/wifi/RunnerState.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2022 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.os.Message;
+import android.os.Trace;
+import android.util.LocalLog;
+
+import com.android.internal.util.State;
+
+/**
+ * RunnerState class is a wrapper based on State class to monitor and track the State enter/exit
+ * and message handler execution for taking longer time than the expected threshold.
+ * User must extend the RunnerState class instead of State, and provide the implementation of:
+ * { @link RunnerState#enterImpl() } { @link RunnerState#exitImpl() }
+ * { @link RunnerState#processMessageImpl() }
+ * { @link RunnerState#getMessageLogRec() }
+ *
+ */
+public abstract class RunnerState extends State {
+ private static final String TAG = "RunnerState";
+
+ /** Message.what value when entering */
+ public static final int STATE_ENTER_CMD = -3;
+
+ /** Message.what value when exiting */
+ public static final int STATE_EXIT_CMD = -4;
+
+ private final int mRunningTimeThresholdInMilliseconds;
+ // TODO: b/246623192 Add Wifi metric for Runner state overruns.
+ private final LocalLog mLocalLog;
+
+ /**
+ * The Runner state Constructor
+ * @param threshold the running time threshold in milliseconds
+ */
+ RunnerState(int threshold, @NonNull LocalLog localLog) {
+ mRunningTimeThresholdInMilliseconds = threshold;
+ mLocalLog = localLog;
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ Long startTime = System.currentTimeMillis();
+
+ Trace.traceBegin(Trace.TRACE_TAG_NETWORK, getMessageLogRec(message.what));
+ boolean ret = processMessageImpl(message);
+ Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
+ Long runTime = System.currentTimeMillis() - startTime;
+ if (runTime > mRunningTimeThresholdInMilliseconds) {
+ mLocalLog.log(getMessageLogRec(message.what) + " was running for " + runTime + " ms");
+ }
+ return ret;
+ }
+
+ @Override
+ public void enter() {
+ Long startTime = System.currentTimeMillis();
+ Trace.traceBegin(Trace.TRACE_TAG_NETWORK, getMessageLogRec(STATE_ENTER_CMD));
+ enterImpl();
+ Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
+ Long runTime = System.currentTimeMillis() - startTime;
+ if (runTime > mRunningTimeThresholdInMilliseconds) {
+ mLocalLog.log(
+ getMessageLogRec(STATE_ENTER_CMD) + " was running for " + runTime + " ms");
+ }
+ }
+
+ @Override
+ public void exit() {
+ Long startTime = System.currentTimeMillis();
+ Trace.traceBegin(Trace.TRACE_TAG_NETWORK, getMessageLogRec(STATE_EXIT_CMD));
+ exitImpl();
+ Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
+ Long runTime = System.currentTimeMillis() - startTime;
+ if (runTime > mRunningTimeThresholdInMilliseconds) {
+ mLocalLog.log(getMessageLogRec(STATE_EXIT_CMD) + " was running for " + runTime + " ms");
+ }
+ }
+
+ /**
+ * Implement this method for State enter process, instead of enter()
+ */
+ abstract void enterImpl();
+
+ /**
+ * Implement this method for State exit process, instead of exit()
+ */
+ abstract void exitImpl();
+
+ /**
+ * Implement this method for State message processing, instead of processMessage()
+ */
+ abstract boolean processMessageImpl(Message message);
+
+ /**
+ * Implement this to translate a message `what` into a readable String
+ * @param what message 'what' field
+ * @return Readable string
+ */
+ abstract String getMessageLogRec(int what);
+}
diff --git a/service/java/com/android/server/wifi/ScanRequestProxy.java b/service/java/com/android/server/wifi/ScanRequestProxy.java
index f82da29170..abec2ebd52 100644
--- a/service/java/com/android/server/wifi/ScanRequestProxy.java
+++ b/service/java/com/android/server/wifi/ScanRequestProxy.java
@@ -39,9 +39,10 @@ import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.modules.utils.HandlerExecutor;
import com.android.modules.utils.build.SdkLevel;
+import com.android.server.wifi.scanner.WifiScannerInternal;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.wifi.resources.R;
@@ -97,10 +98,12 @@ public class ScanRequestProxy {
private final WifiMetrics mWifiMetrics;
private final Clock mClock;
private final WifiSettingsConfigStore mSettingsConfigStore;
- private WifiScanner mWifiScanner;
+ private WifiScannerInternal mWifiScanner;
// Verbose logging flag.
private boolean mVerboseLoggingEnabled = false;
+ private final Object mThrottleEnabledLock = new Object();
+ @GuardedBy("mThrottleEnabledLock")
private boolean mThrottleEnabled = true;
// Flag to decide if we need to scan or not.
private boolean mScanningEnabled = false;
@@ -119,7 +122,6 @@ public class ScanRequestProxy {
private final Map<String, ScanResult> mLastScanResultsMap = new HashMap<>();
// external ScanResultCallback tracker
private final RemoteCallbackList<IScanResultsCallback> mRegisteredScanResultsCallbacks;
- // Global scan listener for listening to all scan requests.
private class GlobalScanListener implements WifiScanner.ScanListener {
@Override
public void onSuccess() {
@@ -233,22 +235,28 @@ public class ScanRequestProxy {
mVerboseLoggingEnabled = verboseEnabled;
}
+ private void updateThrottleEnabled() {
+ synchronized (mThrottleEnabledLock) {
+ // Start listening for throttle settings change after we retrieve scanner instance.
+ mThrottleEnabled = mSettingsConfigStore.get(WIFI_SCAN_THROTTLE_ENABLED);
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Scan throttle enabled " + mThrottleEnabled);
+ }
+ }
+ }
+
/**
* Helper method to populate WifiScanner handle. This is done lazily because
* WifiScanningService is started after WifiService.
*/
private boolean retrieveWifiScannerIfNecessary() {
if (mWifiScanner == null) {
- mWifiScanner = mWifiInjector.getWifiScanner();
- // Start listening for throttle settings change after we retrieve scanner instance.
- mThrottleEnabled = mSettingsConfigStore.get(WIFI_SCAN_THROTTLE_ENABLED);
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "Scan throttle enabled " + mThrottleEnabled);
- }
+ mWifiScanner = WifiLocalServices.getService(WifiScannerInternal.class);
+ updateThrottleEnabled();
// Register the global scan listener.
if (mWifiScanner != null) {
mWifiScanner.registerScanListener(
- new HandlerExecutor(mHandler), new GlobalScanListener());
+ new WifiScannerInternal.ScanListener(new GlobalScanListener(), mHandler));
}
}
return mWifiScanner != null;
@@ -338,13 +346,15 @@ public class ScanRequestProxy {
private LinkedList<Long> getOrCreateScanRequestTimestampsForForegroundApp(
int callingUid, String packageName) {
Pair<Integer, String> uidAndPackageNamePair = Pair.create(callingUid, packageName);
- LinkedList<Long> scanRequestTimestamps =
- mLastScanTimestampsForFgApps.get(uidAndPackageNamePair);
- if (scanRequestTimestamps == null) {
- scanRequestTimestamps = new LinkedList<>();
- mLastScanTimestampsForFgApps.put(uidAndPackageNamePair, scanRequestTimestamps);
+ synchronized (mThrottleEnabledLock) {
+ LinkedList<Long> scanRequestTimestamps =
+ mLastScanTimestampsForFgApps.get(uidAndPackageNamePair);
+ if (scanRequestTimestamps == null) {
+ scanRequestTimestamps = new LinkedList<>();
+ mLastScanTimestampsForFgApps.put(uidAndPackageNamePair, scanRequestTimestamps);
+ }
+ return scanRequestTimestamps;
}
- return scanRequestTimestamps;
}
/**
@@ -396,15 +406,17 @@ public class ScanRequestProxy {
if (isPackageNameInExceptionList(packageName, false)) {
return false;
}
- long lastScanMs = mLastScanTimestampForBgApps;
- long elapsedRealtime = mClock.getElapsedSinceBootMillis();
- if (lastScanMs != 0
- && (elapsedRealtime - lastScanMs) < SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS) {
- return true;
+ synchronized (mThrottleEnabledLock) {
+ long lastScanMs = mLastScanTimestampForBgApps;
+ long elapsedRealtime = mClock.getElapsedSinceBootMillis();
+ if (lastScanMs != 0
+ && (elapsedRealtime - lastScanMs) < SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS) {
+ return true;
+ }
+ // Proceed with the scan request and record the time.
+ mLastScanTimestampForBgApps = elapsedRealtime;
+ return false;
}
- // Proceed with the scan request and record the time.
- mLastScanTimestampForBgApps = elapsedRealtime;
- return false;
}
/**
@@ -470,8 +482,9 @@ public class ScanRequestProxy {
// a) App has either NETWORK_SETTINGS or NETWORK_SETUP_WIZARD permission.
// b) Throttling has been disabled by user.
int packageImportance = getPackageImportance(callingUid, packageName);
- if (!fromSettingsOrSetupWizard && mThrottleEnabled
- && shouldScanRequestBeThrottledForApp(callingUid, packageName, packageImportance)) {
+ if (!fromSettingsOrSetupWizard && isScanThrottleEnabled()
+ && shouldScanRequestBeThrottledForApp(callingUid, packageName,
+ packageImportance)) {
Log.i(TAG, "Scan request from " + packageName + " throttled");
sendScanResultFailureBroadcastToPackage(packageName);
return false;
@@ -497,15 +510,15 @@ public class ScanRequestProxy {
| WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT;
if (mScanningForHiddenNetworksEnabled) {
settings.hiddenNetworks.clear();
- // retrieve the list of hidden network SSIDs from saved network to scan for, if enabled.
+ // retrieve the list of hidden network SSIDs from saved network to scan if enabled.
settings.hiddenNetworks.addAll(mWifiConfigManager.retrieveHiddenNetworkList(false));
// retrieve the list of hidden network SSIDs from Network suggestion to scan for.
- settings.hiddenNetworks.addAll(
- mWifiInjector.getWifiNetworkSuggestionsManager()
+ settings.hiddenNetworks.addAll(mWifiInjector.getWifiNetworkSuggestionsManager()
.retrieveHiddenNetworkList(false));
}
- mWifiScanner.startScan(settings, new HandlerExecutor(mHandler),
- new ScanRequestProxyScanListener(), workSource);
+ mWifiScanner.startScan(settings,
+ new WifiScannerInternal.ScanListener(new ScanRequestProxyScanListener(), mHandler),
+ workSource);
return true;
}
@@ -537,9 +550,11 @@ public class ScanRequestProxy {
* Clear the stored scan results.
*/
private void clearScanResults() {
- mLastScanResultsMap.clear();
- mLastScanTimestampForBgApps = 0;
- mLastScanTimestampsForFgApps.clear();
+ synchronized (mThrottleEnabledLock) {
+ mLastScanResultsMap.clear();
+ mLastScanTimestampForBgApps = 0;
+ mLastScanTimestampsForFgApps.clear();
+ }
}
/**
@@ -549,11 +564,13 @@ public class ScanRequestProxy {
* @param packageName Name of the package.
*/
public void clearScanRequestTimestampsForApp(@NonNull String packageName, int uid) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "Clearing scan request timestamps for uid=" + uid + ", packageName="
- + packageName);
+ synchronized (mThrottleEnabledLock) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Clearing scan request timestamps for uid=" + uid + ", packageName="
+ + packageName);
+ }
+ mLastScanTimestampsForFgApps.remove(Pair.create(uid, packageName));
}
- mLastScanTimestampsForFgApps.remove(Pair.create(uid, packageName));
}
private void sendScanResultsAvailableToCallbacks() {
@@ -589,13 +606,16 @@ public class ScanRequestProxy {
* Enable/disable wifi scan throttling from 3rd party apps.
*/
public void setScanThrottleEnabled(boolean enable) {
- mThrottleEnabled = enable;
- mSettingsConfigStore.put(WIFI_SCAN_THROTTLE_ENABLED, enable);
-
- // reset internal counters when enabling/disabling throttling
- mLastScanTimestampsForFgApps.clear();
- mLastScanTimestampForBgApps = 0;
- Log.i(TAG, "Scan throttle enabled " + mThrottleEnabled);
+ synchronized (mThrottleEnabledLock) {
+ mThrottleEnabled = enable;
+ mSettingsConfigStore.put(WIFI_SCAN_THROTTLE_ENABLED, enable);
+ if (mVerboseLoggingEnabled) {
+ Log.i(TAG, "Scan throttle enabled " + mThrottleEnabled);
+ }
+ // reset internal counters when enabling/disabling throttling
+ mLastScanTimestampsForFgApps.clear();
+ mLastScanTimestampForBgApps = 0;
+ }
}
/**
@@ -603,55 +623,57 @@ public class ScanRequestProxy {
* {@link #setScanThrottleEnabled(boolean)}.
*/
public boolean isScanThrottleEnabled() {
- return mThrottleEnabled;
+ synchronized (mThrottleEnabledLock) {
+ return mThrottleEnabled;
+ }
}
/** Indicate whether there are WPA2 personal only networks. */
public boolean isWpa2PersonalOnlyNetworkInRange(String ssid) {
return mLastScanResultsMap.values().stream().anyMatch(r ->
TextUtils.equals(ssid, r.getWifiSsid().toString())
- && ScanResultUtil.isScanResultForPskOnlyNetwork(r));
+ && ScanResultUtil.isScanResultForPskOnlyNetwork(r));
}
/** Indicate whether there are WPA3 only networks. */
public boolean isWpa3PersonalOnlyNetworkInRange(String ssid) {
return mLastScanResultsMap.values().stream().anyMatch(r ->
TextUtils.equals(ssid, r.getWifiSsid().toString())
- && ScanResultUtil.isScanResultForSaeOnlyNetwork(r));
+ && ScanResultUtil.isScanResultForSaeOnlyNetwork(r));
}
/** Indicate whether there are WPA2/WPA3 transition mode networks. */
public boolean isWpa2Wpa3PersonalTransitionNetworkInRange(String ssid) {
return mLastScanResultsMap.values().stream().anyMatch(r ->
TextUtils.equals(ssid, ScanResultUtil.createQuotedSsid(r.SSID))
- && ScanResultUtil.isScanResultForPskSaeTransitionNetwork(r));
+ && ScanResultUtil.isScanResultForPskSaeTransitionNetwork(r));
}
/** Indicate whether there are OPEN only networks. */
public boolean isOpenOnlyNetworkInRange(String ssid) {
return mLastScanResultsMap.values().stream().anyMatch(r ->
TextUtils.equals(ssid, r.getWifiSsid().toString())
- && ScanResultUtil.isScanResultForOpenOnlyNetwork(r));
+ && ScanResultUtil.isScanResultForOpenOnlyNetwork(r));
}
/** Indicate whether there are OWE only networks. */
public boolean isOweOnlyNetworkInRange(String ssid) {
return mLastScanResultsMap.values().stream().anyMatch(r ->
TextUtils.equals(ssid, r.getWifiSsid().toString())
- && ScanResultUtil.isScanResultForOweOnlyNetwork(r));
+ && ScanResultUtil.isScanResultForOweOnlyNetwork(r));
}
/** Indicate whether there are WPA2 Enterprise only networks. */
public boolean isWpa2EnterpriseOnlyNetworkInRange(String ssid) {
return mLastScanResultsMap.values().stream().anyMatch(r ->
TextUtils.equals(ssid, r.getWifiSsid().toString())
- && ScanResultUtil.isScanResultForWpa2EnterpriseOnlyNetwork(r));
+ && ScanResultUtil.isScanResultForWpa2EnterpriseOnlyNetwork(r));
}
/** Indicate whether there are WPA3 Enterprise only networks. */
public boolean isWpa3EnterpriseOnlyNetworkInRange(String ssid) {
return mLastScanResultsMap.values().stream().anyMatch(r ->
TextUtils.equals(ssid, r.getWifiSsid().toString())
- && ScanResultUtil.isScanResultForWpa3EnterpriseOnlyNetwork(r));
+ && ScanResultUtil.isScanResultForWpa3EnterpriseOnlyNetwork(r));
}
}
diff --git a/service/java/com/android/server/wifi/ScoringParams.java b/service/java/com/android/server/wifi/ScoringParams.java
index 0f42f16129..edc0971ab8 100644
--- a/service/java/com/android/server/wifi/ScoringParams.java
+++ b/service/java/com/android/server/wifi/ScoringParams.java
@@ -98,7 +98,8 @@ public class ScoringParams {
public int secureNetworkBonus = 40;
public int band6GhzBonus = 0;
public int scoringBucketStepSize = 500;
- public int lastSelectionMinutes = 480;
+ public int lastUnmeteredSelectionMinutes = 480;
+ public int lastMeteredSelectionMinutes = 120;
public int estimateRssiErrorMargin = 5;
public static final int MIN_MINUTES = 1;
public static final int MAX_MINUTES = Integer.MAX_VALUE / (60 * 1000);
@@ -132,7 +133,8 @@ public class ScoringParams {
validateRange(horizon, MIN_HORIZON, MAX_HORIZON);
validateRange(nud, MIN_NUD, MAX_NUD);
validateRange(expid, MIN_EXPID, MAX_EXPID);
- validateRange(lastSelectionMinutes, MIN_MINUTES, MAX_MINUTES);
+ validateRange(lastUnmeteredSelectionMinutes, MIN_MINUTES, MAX_MINUTES);
+ validateRange(lastMeteredSelectionMinutes, MIN_MINUTES, MAX_MINUTES);
}
private void validateRssiArray(int[] rssi) throws IllegalArgumentException {
@@ -295,8 +297,10 @@ public class ScoringParams {
mVal.band6GhzBonus = context.getResources().getInteger(R.integer.config_wifiBand6GhzBonus);
mVal.scoringBucketStepSize = context.getResources().getInteger(
R.integer.config_wifiScoringBucketStepSize);
- mVal.lastSelectionMinutes = context.getResources().getInteger(
+ mVal.lastUnmeteredSelectionMinutes = context.getResources().getInteger(
R.integer.config_wifiFrameworkLastSelectionMinutes);
+ mVal.lastMeteredSelectionMinutes = context.getResources().getInteger(
+ R.integer.config_wifiFrameworkLastMeteredSelectionMinutes);
mVal.estimateRssiErrorMargin = context.getResources().getInteger(
R.integer.config_wifiEstimateRssiErrorMarginDb);
mVal.pps[ACTIVE_TRAFFIC] = context.getResources().getInteger(
@@ -532,11 +536,19 @@ public class ScoringParams {
}
/*
- * Returns the duration in minutes for a recently selected network
+ * Returns the duration in minutes for a recently selected non-metered network
* to be strongly favored.
*/
- public int getLastSelectionMinutes() {
- return mVal.lastSelectionMinutes;
+ public int getLastUnmeteredSelectionMinutes() {
+ return mVal.lastUnmeteredSelectionMinutes;
+ }
+
+ /*
+ * Returns the duration in minutes for a recently selected metered network
+ * to be strongly favored.
+ */
+ public int getLastMeteredSelectionMinutes() {
+ return mVal.lastMeteredSelectionMinutes;
}
/**
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 1dfb3d1f62..dde875f324 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -100,6 +100,7 @@ public class SoftApManager implements ActiveModeManager {
private final SoftApNotifier mSoftApNotifier;
private final BatteryManager mBatteryManager;
private final InterfaceConflictManager mInterfaceConflictManager;
+ private final WifiInjector mWifiInjector;
@VisibleForTesting
static final long SOFT_AP_PENDING_DISCONNECTION_CHECK_DELAY_MS = 1000;
@@ -331,6 +332,7 @@ public class SoftApManager implements ActiveModeManager {
@NonNull Looper looper,
@NonNull FrameworkFacade framework,
@NonNull WifiNative wifiNative,
+ @NonNull WifiInjector wifiInjector,
@NonNull CoexManager coexManager,
@NonNull BatteryManager batteryManager,
@NonNull InterfaceConflictManager interfaceConflictManager,
@@ -352,6 +354,7 @@ public class SoftApManager implements ActiveModeManager {
mFrameworkFacade = framework;
mSoftApNotifier = softApNotifier;
mWifiNative = wifiNative;
+ mWifiInjector = wifiInjector;
mCoexManager = coexManager;
mBatteryManager = batteryManager;
mInterfaceConflictManager = interfaceConflictManager;
@@ -606,7 +609,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.syncRequestConnectionInfo());
+ clientModeManager.getConnectionInfo());
}
@@ -894,9 +897,9 @@ public class SoftApManager implements ActiveModeManager {
public static final int CMD_CHARGING_STATE_CHANGED = 17;
private final State mActiveState = new ActiveState();
- private final State mIdleState = new IdleState();
+ private final State mIdleState;
private final WaitingState mWaitingState = new WaitingState(this);
- private final State mStartedState = new StartedState();
+ private final State mStartedState;
private final InterfaceCallback mWifiNativeInterfaceCallback = new InterfaceCallback() {
@Override
@@ -924,6 +927,10 @@ public class SoftApManager implements ActiveModeManager {
SoftApStateMachine(Looper looper) {
super(TAG, looper);
+ final int threshold = mContext.getResources().getInteger(
+ R.integer.config_wifiConfigurationWifiRunnerThresholdInMs);
+ mIdleState = new IdleState(threshold);
+ mStartedState = new StartedState(threshold);
// CHECKSTYLE:OFF IndentationCheck
addState(mActiveState);
addState(mIdleState, mActiveState);
@@ -935,6 +942,7 @@ public class SoftApManager implements ActiveModeManager {
start();
}
+
private class ActiveState extends State {
@Override
public void exit() {
@@ -942,16 +950,76 @@ public class SoftApManager implements ActiveModeManager {
}
}
- private class IdleState extends State {
+ @Override
+ protected String getWhatToString(int what) {
+ switch (what) {
+ case CMD_START:
+ return "CMD_START";
+ case CMD_STOP:
+ return "CMD_STOP";
+ case CMD_FAILURE:
+ return "CMD_FAILURE";
+ case CMD_INTERFACE_STATUS_CHANGED:
+ return "CMD_INTERFACE_STATUS_CHANGED";
+ case CMD_ASSOCIATED_STATIONS_CHANGED:
+ return "CMD_ASSOCIATED_STATIONS_CHANGED";
+ case CMD_NO_ASSOCIATED_STATIONS_TIMEOUT:
+ return "CMD_NO_ASSOCIATED_STATIONS_TIMEOUT";
+ case CMD_INTERFACE_DESTROYED:
+ return "CMD_INTERFACE_DESTROYED";
+ case CMD_INTERFACE_DOWN:
+ return "CMD_INTERFACE_DOWN";
+ case CMD_AP_INFO_CHANGED:
+ return "CMD_AP_INFO_CHANGED";
+ case CMD_UPDATE_CAPABILITY:
+ return "CMD_UPDATE_CAPABILITY";
+ case CMD_UPDATE_CONFIG:
+ return "CMD_UPDATE_CONFIG";
+ case CMD_FORCE_DISCONNECT_PENDING_CLIENTS:
+ return "CMD_FORCE_DISCONNECT_PENDING_CLIENTS";
+ case CMD_NO_ASSOCIATED_STATIONS_TIMEOUT_ON_ONE_INSTANCE:
+ return "CMD_NO_ASSOCIATED_STATIONS_TIMEOUT_ON_ONE_INSTANCE";
+ case CMD_SAFE_CHANNEL_FREQUENCY_CHANGED:
+ return "CMD_SAFE_CHANNEL_FREQUENCY_CHANGED";
+ case CMD_HANDLE_WIFI_CONNECTED:
+ return "CMD_HANDLE_WIFI_CONNECTED";
+ case CMD_UPDATE_COUNTRY_CODE:
+ return "CMD_UPDATE_COUNTRY_CODE";
+ case CMD_CHARGING_STATE_CHANGED:
+ return "CMD_CHARGING_STATE_CHANGED";
+ case RunnerState.STATE_ENTER_CMD:
+ return "Enter";
+ case RunnerState.STATE_EXIT_CMD:
+ return "Exit";
+ default:
+ return "what:" + what;
+ }
+ }
+
+ private class IdleState extends RunnerState {
+ IdleState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
@Override
- public void enter() {
+ public void enterImpl() {
mApInterfaceName = null;
mIfaceIsUp = false;
mIfaceIsDestroyed = false;
}
@Override
- public boolean processMessage(Message message) {
+ public void exitImpl() {
+ }
+
+ @Override
+ String getMessageLogRec(int what) {
+ return SoftApManager.class.getSimpleName() + "." + IdleState.class.getSimpleName()
+ + "." + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
switch (message.what) {
case CMD_STOP:
quitNow();
@@ -981,8 +1049,7 @@ public class SoftApManager implements ActiveModeManager {
if (ApConfigUtil.isStaWithBridgedModeSupported(mContext)) {
for (ClientModeManager cmm
: mActiveModeWarden.getClientModeManagers()) {
- WifiInfo wifiConnectedInfo =
- cmm.syncRequestConnectionInfo();
+ WifiInfo wifiConnectedInfo = cmm.getConnectionInfo();
int wifiFrequency = wifiConnectedInfo.getFrequency();
if (wifiFrequency > 0
&& !mSafeChannelFrequencyList.contains(
@@ -1132,7 +1199,11 @@ public class SoftApManager implements ActiveModeManager {
}
}
- private class StartedState extends State {
+ private class StartedState extends RunnerState {
+ StartedState(int threshold) {
+ super(threshold, mWifiInjector.getWifiHandlerLocalLog());
+ }
+
BroadcastReceiver mBatteryChargingReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -1480,7 +1551,7 @@ public class SoftApManager implements ActiveModeManager {
}
@Override
- public void enter() {
+ public void enterImpl() {
mIfaceIsUp = false;
mIfaceIsDestroyed = false;
onUpChanged(mWifiNative.isInterfaceUp(mApInterfaceName));
@@ -1504,7 +1575,7 @@ public class SoftApManager implements ActiveModeManager {
}
@Override
- public void exit() {
+ public void exitImpl() {
if (!mIfaceIsDestroyed) {
stopSoftAp();
}
@@ -1575,7 +1646,13 @@ public class SoftApManager implements ActiveModeManager {
}
@Override
- public boolean processMessage(Message message) {
+ String getMessageLogRec(int what) {
+ return SoftApManager.class.getSimpleName() + "." + RunnerState.class.getSimpleName()
+ + "." + getWhatToString(what);
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
switch (message.what) {
case CMD_ASSOCIATED_STATIONS_CHANGED:
if (!(message.obj instanceof WifiClient)) {
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
index 2ee2edaf7b..09a37c9473 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
@@ -70,6 +70,7 @@ import com.android.server.wifi.hotspot2.WnmData;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
import com.android.server.wifi.hotspot2.anqp.ANQPParser;
import com.android.server.wifi.hotspot2.anqp.Constants;
+import com.android.server.wifi.util.HalAidlUtil;
import com.android.server.wifi.util.NativeUtil;
import java.io.IOException;
@@ -77,6 +78,7 @@ import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -156,12 +158,33 @@ class SupplicantStaIfaceCallbackAidlImpl extends ISupplicantStaIfaceCallback.Stu
@Override
public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
byte[] ssid, boolean filsHlpSent) {
+ onStateChangedWithAkm(newState, bssid, id, ssid, filsHlpSent, 0);
+ }
+
+ @Override
+ public void onStateChangedWithAkm(int newState, byte[/* 6 */] bssid, int id,
+ byte[] ssid, boolean filsHlpSent, int supplicantKeyMgmtMask) {
synchronized (mLock) {
- mStaIfaceHal.logCallback("onStateChanged");
SupplicantState newSupplicantState =
supplicantAidlStateToFrameworkState(newState);
WifiSsid wifiSsid = mSsidTranslator.getTranslatedSsid(WifiSsid.fromBytes(ssid));
String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
+ BitSet keyMgmtMask = null;
+ if (supplicantKeyMgmtMask != 0) {
+ try {
+ keyMgmtMask = HalAidlUtil.supplicantToWifiConfigurationKeyMgmtMask(
+ supplicantKeyMgmtMask);
+ } catch (IllegalArgumentException ex) {
+ Log.w(TAG, "Failed convert supplicant key management mask to"
+ + " the framework value: " + ex.toString());
+ keyMgmtMask = null;
+ }
+ }
+ mStaIfaceHal.logCallback("onStateChanged: newState=" + newSupplicantState
+ + ", bssid=" + bssidStr + ", ssid=" + wifiSsid.toString()
+ + ", filsHlpSent=" + filsHlpSent + ", supplicantKeyMgmtMask="
+ + String.format("0x%08X", supplicantKeyMgmtMask)
+ + ", frameworkKeyMgmtMask=" + keyMgmtMask);
if (newState != StaIfaceCallbackState.DISCONNECTED) {
// onStateChanged(DISCONNECTED) may come before onDisconnected(), so add this
// cache to track the state before the disconnect.
@@ -177,7 +200,7 @@ class SupplicantStaIfaceCallbackAidlImpl extends ISupplicantStaIfaceCallback.Stu
if (newState == StaIfaceCallbackState.COMPLETED) {
mWifiMonitor.broadcastNetworkConnectionEvent(
mIfaceName, mStaIfaceHal.getCurrentNetworkId(mIfaceName), filsHlpSent,
- wifiSsid, bssidStr);
+ wifiSsid, bssidStr, keyMgmtMask);
} else if (newState == StaIfaceCallbackState.ASSOCIATING) {
mCurrentSsid = wifiSsid.toString();
}
@@ -1198,4 +1221,38 @@ class SupplicantStaIfaceCallbackAidlImpl extends ISupplicantStaIfaceCallback.Stu
public int getInterfaceVersion() {
return ISupplicantStaIfaceCallback.VERSION;
}
+
+ private String getMloLinksInfoChangedReasonStr(int reason) {
+ switch (reason) {
+ case ISupplicantStaIfaceCallback.MloLinkInfoChangeReason.TID_TO_LINK_MAP:
+ return "TID_TO_LINK_MAP";
+ case ISupplicantStaIfaceCallback.MloLinkInfoChangeReason.MULTI_LINK_RECONFIG_AP_REMOVAL:
+ return "MULTI_LINK_RECONFIG_AP_REMOVAL";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ private WifiMonitor.MloLinkInfoChangeReason convertMloLinkInfoChangedReason(int reason) {
+ switch (reason) {
+ case ISupplicantStaIfaceCallback.MloLinkInfoChangeReason.TID_TO_LINK_MAP:
+ return WifiMonitor.MloLinkInfoChangeReason.TID_TO_LINK_MAP;
+ case ISupplicantStaIfaceCallback.MloLinkInfoChangeReason.MULTI_LINK_RECONFIG_AP_REMOVAL:
+ return WifiMonitor.MloLinkInfoChangeReason.MULTI_LINK_RECONFIG_AP_REMOVAL;
+ default:
+ return WifiMonitor.MloLinkInfoChangeReason.UNKNOWN;
+ }
+ }
+
+ @Override
+ public void onMloLinksInfoChanged(int reason)
+ throws android.os.RemoteException {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback(
+ "onMloLinksInfoChanged: reason " + Integer.toString(reason) + " ("
+ + getMloLinksInfoChangedReasonStr(reason) + ")");
+ mWifiMonitor.broadcastMloLinksInfoChanged(mIfaceName,
+ convertMloLinkInfoChangedReason(reason));
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_2Impl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_2Impl.java
index efff6089f7..c4de2e0e8a 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_2Impl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_2Impl.java
@@ -29,6 +29,7 @@ import android.util.Log;
import com.android.server.wifi.util.NativeUtil;
import java.util.ArrayList;
+import java.util.Arrays;
abstract class SupplicantStaIfaceCallbackHidlV1_2Impl extends
android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback.Stub {
@@ -182,7 +183,7 @@ abstract class SupplicantStaIfaceCallbackHidlV1_2Impl extends
if (password != null) {
newWifiConfiguration.preSharedKey = "\"" + password + "\"";
} else if (psk != null) {
- newWifiConfiguration.preSharedKey = psk.toString();
+ newWifiConfiguration.preSharedKey = Arrays.toString(psk);
}
// Set up key management: SAE or PSK
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
index 07a2c3d48c..02a62cbff9 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
@@ -26,6 +26,8 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_OCE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS;
import static android.net.wifi.WifiManager.WIFI_FEATURE_SAE_PK;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_SET_TLS_MINIMUM_VERSION;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_TLS_V1_3;
import static android.net.wifi.WifiManager.WIFI_FEATURE_TRUST_ON_FIRST_USE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WAPI;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WFD_R2;
@@ -120,6 +122,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
private boolean mVerboseLoggingEnabled = false;
private boolean mVerboseHalLoggingEnabled = false;
private boolean mServiceDeclared = false;
+ private int mServiceVersion;
// Supplicant HAL interface objects
private ISupplicant mISupplicant = null;
@@ -135,6 +138,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
@VisibleForTesting
PmkCacheManager mPmkCacheManager;
private WifiNative.SupplicantDeathEventHandler mDeathEventHandler;
+ private SupplicantDeathRecipient mSupplicantDeathRecipient;
private final Context mContext;
private final WifiMonitor mWifiMonitor;
private final Handler mEventHandler;
@@ -146,25 +150,24 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
private CountDownLatch mWaitForDeathLatch;
private class SupplicantDeathRecipient implements DeathRecipient {
- private final IBinder mWho;
@Override
public void binderDied() {
+ }
+
+ @Override
+ public void binderDied(@NonNull IBinder who) {
synchronized (mLock) {
- Log.w(TAG, "ISupplicant binder died. who=" + mWho + ", service="
+ Log.w(TAG, "ISupplicant binder died. who=" + who + ", service="
+ getServiceBinderMockable());
- if (mWho == getServiceBinderMockable()) {
+ if (who == getServiceBinderMockable()) {
if (mWaitForDeathLatch != null) {
mWaitForDeathLatch.countDown();
}
Log.w(TAG, "Handle supplicant death");
- supplicantServiceDiedHandler(mWho);
+ supplicantServiceDiedHandler(who);
}
}
}
-
- SupplicantDeathRecipient(IBinder who) {
- mWho = who;
- }
}
public SupplicantStaIfaceHalAidlImpl(Context context, WifiMonitor monitor, Handler handler,
@@ -177,6 +180,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
mWifiMetrics = wifiMetrics;
mWifiGlobals = wifiGlobals;
mSsidTranslator = ssidTranslator;
+ mSupplicantDeathRecipient = new SupplicantDeathRecipient();
mPmkCacheManager = new PmkCacheManager(mClock, mEventHandler);
}
@@ -379,6 +383,15 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
return ServiceManager.isDeclared(HAL_INSTANCE_NAME);
}
+ /**
+ * Check that the service is running at least the expected version.
+ * Use to avoid the case where the framework is using a newer
+ * interface version than the service.
+ */
+ private boolean isServiceVersionIsAtLeast(int expectedVersion) {
+ return expectedVersion <= mServiceVersion;
+ }
+
private void clearState() {
synchronized (mLock) {
Log.i(TAG, "Clearing internal state");
@@ -426,14 +439,14 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
Log.i(TAG, "Local Version: " + ISupplicant.VERSION);
try {
- Log.i(TAG, "Remote Version: " + mISupplicant.getInterfaceVersion());
+ mServiceVersion = mISupplicant.getInterfaceVersion();
+ Log.i(TAG, "Remote Version: " + mServiceVersion);
IBinder serviceBinder = getServiceBinderMockable();
if (serviceBinder == null) {
return false;
}
mWaitForDeathLatch = null;
- serviceBinder.linkToDeath(
- new SupplicantDeathRecipient(serviceBinder), /* flags= */ 0);
+ serviceBinder.linkToDeath(mSupplicantDeathRecipient, /* flags= */ 0);
setLogLevel(mVerboseHalLoggingEnabled);
return true;
} catch (RemoteException e) {
@@ -1056,9 +1069,11 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
@NonNull String ifaceName, ISupplicantStaNetwork network) {
synchronized (mLock) {
SupplicantStaNetworkHalAidlImpl networkWrapper =
- new SupplicantStaNetworkHalAidlImpl(network, ifaceName, mContext,
+ new SupplicantStaNetworkHalAidlImpl(mServiceVersion,
+ network, ifaceName, mContext,
mWifiMonitor, mWifiGlobals,
- getAdvancedCapabilities(ifaceName));
+ getAdvancedCapabilities(ifaceName),
+ getWpaDriverCapabilities(ifaceName));
if (networkWrapper != null) {
networkWrapper.enableVerboseLogging(
mVerboseLoggingEnabled, mVerboseHalLoggingEnabled);
@@ -2572,6 +2587,28 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
}
+ private long aidlWpaDrvFeatureSetToFrameworkV2(int drvCapabilitiesMask) {
+ if (!isServiceVersionIsAtLeast(2)) return 0;
+
+ final String methodStr = "getWpaDriverFeatureSetV2";
+ long featureSet = 0;
+
+ if ((drvCapabilitiesMask & WpaDriverCapabilitiesMask.SET_TLS_MINIMUM_VERSION) != 0) {
+ featureSet |= WIFI_FEATURE_SET_TLS_MINIMUM_VERSION;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, methodStr + ": EAP-TLS minimum version supported");
+ }
+ }
+
+ if ((drvCapabilitiesMask & WpaDriverCapabilitiesMask.TLS_V1_3) != 0) {
+ featureSet |= WIFI_FEATURE_TLS_V1_3;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, methodStr + ": EAP-TLS v1.3 supported");
+ }
+ }
+ return featureSet;
+ }
+
/**
* Get the driver supported features through supplicant.
*
@@ -2619,6 +2656,8 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
}
+ featureSet |= aidlWpaDrvFeatureSetToFrameworkV2(drvCapabilitiesMask);
+
return featureSet;
}
}
@@ -2859,10 +2898,10 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
nativeInfo.links = new WifiNative.ConnectionMloLink[halInfo.links.length];
for (int i = 0; i < halInfo.links.length; i++) {
- nativeInfo.links[i] = new WifiNative.ConnectionMloLink();
- nativeInfo.links[i].linkId = halInfo.links[i].linkId;
- nativeInfo.links[i].staMacAddress = MacAddress.fromBytes(
- halInfo.links[i].staLinkMacAddress);
+ nativeInfo.links[i] = new WifiNative.ConnectionMloLink(
+ halInfo.links[i].linkId,
+ MacAddress.fromBytes(halInfo.links[i].staLinkMacAddress),
+ halInfo.links[i].tidsUplinkMap, halInfo.links[i].tidsDownlinkMap);
}
return nativeInfo;
} catch (RemoteException e) {
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
index 47b76b1795..9c2d177663 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
@@ -79,7 +79,6 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
-import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
@@ -95,7 +94,7 @@ import javax.annotation.concurrent.ThreadSafe;
*/
@ThreadSafe
public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
- private static final String TAG = "SupplicantStaIfaceHalHidlImp";
+ private static final String TAG = "SupplicantStaIfaceHalHidlImpl";
@VisibleForTesting
public static final String HAL_INSTANCE_NAME = "default";
@VisibleForTesting
@@ -130,6 +129,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
private SupplicantDeathRecipient mSupplicantDeathRecipient;
// Death recipient cookie registered for current supplicant instance.
private long mDeathRecipientCookie = 0;
+ private CountDownLatch mWaitForDeathLatch;
private final Context mContext;
private final WifiMonitor mWifiMonitor;
private final FrameworkFacade mFrameworkFacade;
@@ -176,6 +176,12 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
private class SupplicantDeathRecipient implements DeathRecipient {
@Override
public void serviceDied(long cookie) {
+ synchronized (mLock) {
+ if (mWaitForDeathLatch != null) {
+ mWaitForDeathLatch.countDown();
+ }
+ }
+
mEventHandler.post(() -> {
synchronized (mLock) {
Log.w(TAG, "ISupplicant died: cookie=" + cookie);
@@ -640,6 +646,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
Log.i(TAG, "Ignoring stale death recipient notification");
return;
}
+ Log.i(TAG, "Handling service death");
clearState();
if (mDeathEventHandler != null) {
mDeathEventHandler.onDeath();
@@ -715,18 +722,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
*/
public void terminate() {
synchronized (mLock) {
- // Register for a new death listener to block until supplicant is dead.
- final long waitForDeathCookie = new Random().nextLong();
- final CountDownLatch waitForDeathLatch = new CountDownLatch(1);
- linkToSupplicantDeath((cookie) -> {
- mEventHandler.post(() -> {
- Log.d(TAG, "ISupplicant died: cookie=" + cookie);
- if (cookie != waitForDeathCookie) return;
- supplicantServiceDiedHandler(mDeathRecipientCookie);
- waitForDeathLatch.countDown();
- });
- }, waitForDeathCookie);
-
+ mWaitForDeathLatch = new CountDownLatch(1);
if (isV1_1()) {
Log.i(TAG, "Terminating supplicant using HIDL");
terminate_V1_1();
@@ -734,15 +730,15 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
Log.i(TAG, "Terminating supplicant using init");
mFrameworkFacade.stopSupplicant();
}
+ }
- // Now wait for death listener callback to confirm that it's dead.
- try {
- if (!waitForDeathLatch.await(WAIT_FOR_DEATH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
- Log.w(TAG, "Timed out waiting for confirmation of supplicant death");
- }
- } catch (InterruptedException e) {
- Log.w(TAG, "Failed to wait for supplicant death");
+ // Now wait for death listener callback to confirm that it's dead.
+ try {
+ if (!mWaitForDeathLatch.await(WAIT_FOR_DEATH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ Log.w(TAG, "Timed out waiting for confirmation of supplicant death");
}
+ } catch (InterruptedException e) {
+ Log.w(TAG, "Failed to wait for supplicant death");
}
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
index 4e0af8dff1..db332769a2 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
@@ -32,6 +32,7 @@ import android.hardware.wifi.supplicant.OcspType;
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.SecurityParams;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
@@ -44,6 +45,7 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.util.ArrayUtils;
+import com.android.server.wifi.util.HalAidlUtil;
import com.android.server.wifi.util.NativeUtil;
import com.android.wifi.resources.R;
@@ -107,6 +109,7 @@ public class SupplicantStaNetworkHalAidlImpl {
private final WifiGlobals mWifiGlobals;
private ISupplicantStaNetwork mISupplicantStaNetwork;
private ISupplicantStaNetworkCallback mISupplicantStaNetworkCallback;
+ private int mServiceVersion;
private boolean mVerboseLoggingEnabled = false;
// Network variables read from wpa_supplicant.
@@ -145,16 +148,29 @@ public class SupplicantStaNetworkHalAidlImpl {
private @WifiEnterpriseConfig.Ocsp int mOcsp;
private String mWapiCertSuite;
private long mAdvanceKeyMgmtFeatures;
+ private long mWpaDriverFeatures;
- SupplicantStaNetworkHalAidlImpl(ISupplicantStaNetwork staNetwork, String ifaceName,
+ SupplicantStaNetworkHalAidlImpl(int serviceVersion,
+ ISupplicantStaNetwork staNetwork, String ifaceName,
Context context, WifiMonitor monitor, WifiGlobals wifiGlobals,
- long advanceKeyMgmtFeature) {
+ long advanceKeyMgmtFeature, long wpaDriverFeatures) {
+ mServiceVersion = serviceVersion;
mISupplicantStaNetwork = staNetwork;
mContext = context;
mIfaceName = ifaceName;
mWifiMonitor = monitor;
mWifiGlobals = wifiGlobals;
mAdvanceKeyMgmtFeatures = advanceKeyMgmtFeature;
+ mWpaDriverFeatures = wpaDriverFeatures;
+ }
+
+ /**
+ * Check that the service is running at least the expected version.
+ * Use to avoid the case where the framework is using a newer
+ * interface version than the service.
+ */
+ private boolean isServiceVersionIsAtLeast(int expectedVersion) {
+ return expectedVersion <= mServiceVersion;
}
/**
@@ -229,7 +245,8 @@ public class SupplicantStaNetworkHalAidlImpl {
/** allowedKeyManagement */
if (getKeyMgmt()) {
- BitSet keyMgmtMask = supplicantToWifiConfigurationKeyMgmtMask(mKeyMgmtMask);
+ BitSet keyMgmtMask = HalAidlUtil.supplicantToWifiConfigurationKeyMgmtMask(
+ mKeyMgmtMask);
keyMgmtMask = removeFastTransitionFlags(keyMgmtMask);
keyMgmtMask = removeSha256KeyMgmtFlags(keyMgmtMask);
keyMgmtMask = removePskSaeUpgradableTypeFlags(keyMgmtMask);
@@ -323,8 +340,8 @@ public class SupplicantStaNetworkHalAidlImpl {
}
Log.d(TAG, "The target security params: " + securityParams);
- boolean isRequirePmf = getOptimalPmfSettingForConfig(config,
- securityParams.isRequirePmf());
+ boolean isRequirePmf = NativeUtil.getOptimalPmfSettingForConfig(config,
+ securityParams.isRequirePmf(), mWifiGlobals);
/** RequirePMF */
if (!setRequirePmf(isRequirePmf)) {
Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePmf);
@@ -373,7 +390,8 @@ public class SupplicantStaNetworkHalAidlImpl {
return false;
}
/** Group Cipher */
- BitSet allowedGroupCiphers = securityParams.getAllowedGroupCiphers();
+ BitSet allowedGroupCiphers = NativeUtil.getOptimalGroupCiphersForConfig(
+ config, securityParams.getAllowedGroupCiphers(), mWifiGlobals);
if (allowedGroupCiphers.cardinality() != 0
&& (!setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
allowedGroupCiphers)))) {
@@ -381,7 +399,8 @@ public class SupplicantStaNetworkHalAidlImpl {
return false;
}
/** Pairwise Cipher*/
- BitSet allowedPairwiseCiphers = securityParams.getAllowedPairwiseCiphers();
+ BitSet allowedPairwiseCiphers = NativeUtil.getOptimalPairwiseCiphersForConfig(
+ config, securityParams.getAllowedPairwiseCiphers(), mWifiGlobals);
if (allowedPairwiseCiphers.cardinality() != 0
&& !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
allowedPairwiseCiphers))) {
@@ -825,10 +844,32 @@ public class SupplicantStaNetworkHalAidlImpl {
return false;
}
}
+ if (isServiceVersionIsAtLeast(2)) {
+ if (!setMinimumTlsVersionEapPhase1Param(getOptimalMinimumTlsVersion(eapConfig))) {
+ Log.e(TAG, "Failed to set the minimum TLS version");
+ return false;
+ }
+ }
return true;
}
}
+ private int getOptimalMinimumTlsVersion(WifiEnterpriseConfig enterpriseConfig) {
+ int maxTlsVersionSupported = WifiEnterpriseConfig.TLS_V1_2;
+ if ((mWpaDriverFeatures & WifiManager.WIFI_FEATURE_TLS_V1_3) != 0) {
+ maxTlsVersionSupported = WifiEnterpriseConfig.TLS_V1_3;
+ }
+
+ int requiredMinimumTlsVersion = enterpriseConfig.getMinimumTlsVersion();
+ if (requiredMinimumTlsVersion > maxTlsVersionSupported) {
+ Log.w(TAG, "The required minimum TLS version " + requiredMinimumTlsVersion
+ + " exceeds the maximum supported TLS version " + maxTlsVersionSupported
+ + ", fallback to the maximum supported TLS version.");
+ return maxTlsVersionSupported;
+ }
+ return requiredMinimumTlsVersion;
+ }
+
/**
* Maps WifiConfiguration Key Management BitSet to Supplicant AIDL bitmask int
*
@@ -1105,70 +1146,6 @@ public class SupplicantStaNetworkHalAidlImpl {
}
}
- private static int supplicantMaskValueToWifiConfigurationBitSet(int supplicantMask,
- int supplicantValue, BitSet bitset, int bitSetPosition) {
- bitset.set(bitSetPosition, (supplicantMask & supplicantValue) == supplicantValue);
- int modifiedSupplicantMask = supplicantMask & ~supplicantValue;
- return modifiedSupplicantMask;
- }
-
- private static BitSet supplicantToWifiConfigurationKeyMgmtMask(int mask) {
- BitSet bitset = new BitSet();
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.NONE, bitset,
- WifiConfiguration.KeyMgmt.NONE);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.WPA_PSK, bitset,
- WifiConfiguration.KeyMgmt.WPA_PSK);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.WPA_EAP, bitset,
- WifiConfiguration.KeyMgmt.WPA_EAP);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.IEEE8021X, bitset,
- WifiConfiguration.KeyMgmt.IEEE8021X);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.OSEN, bitset,
- WifiConfiguration.KeyMgmt.OSEN);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.FT_PSK, bitset,
- WifiConfiguration.KeyMgmt.FT_PSK);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.FT_EAP, bitset,
- WifiConfiguration.KeyMgmt.FT_EAP);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.SAE,
- bitset, WifiConfiguration.KeyMgmt.SAE);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.OWE,
- bitset, WifiConfiguration.KeyMgmt.OWE);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.SUITE_B_192,
- bitset, WifiConfiguration.KeyMgmt.SUITE_B_192);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.WPA_PSK_SHA256,
- bitset, WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.WPA_EAP_SHA256,
- bitset, WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.WAPI_PSK,
- bitset, WifiConfiguration.KeyMgmt.WAPI_PSK);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.WAPI_CERT,
- bitset, WifiConfiguration.KeyMgmt.WAPI_CERT);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.FILS_SHA256,
- bitset, WifiConfiguration.KeyMgmt.FILS_SHA256);
- mask = supplicantMaskValueToWifiConfigurationBitSet(
- mask, KeyMgmtMask.FILS_SHA384,
- bitset, WifiConfiguration.KeyMgmt.FILS_SHA384);
- if (mask != 0) {
- throw new IllegalArgumentException(
- "invalid key mgmt mask from supplicant: " + mask);
- }
- return bitset;
- }
-
private static int wifiConfigurationToSupplicantEapMethod(int value) {
switch (value) {
case WifiEnterpriseConfig.Eap.PEAP:
@@ -1461,6 +1438,9 @@ public class SupplicantStaNetworkHalAidlImpl {
if (!checkStaNetworkAndLogFailure(methodStr)) {
return false;
}
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, String.format("setGroupCipher: 0x%x", groupCipherMask));
+ }
try {
mISupplicantStaNetwork.setGroupCipher(groupCipherMask);
return true;
@@ -1533,6 +1513,9 @@ public class SupplicantStaNetworkHalAidlImpl {
if (!checkStaNetworkAndLogFailure(methodStr)) {
return false;
}
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, String.format("setPairwiseCipher: 0x%x", pairwiseCipherMask));
+ }
try {
mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask);
return true;
@@ -1690,6 +1673,9 @@ public class SupplicantStaNetworkHalAidlImpl {
if (!checkStaNetworkAndLogFailure(methodStr)) {
return false;
}
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "setRequirePmf: " + enable);
+ }
try {
mISupplicantStaNetwork.setRequirePmf(enable);
return true;
@@ -3547,29 +3533,6 @@ public class SupplicantStaNetworkHalAidlImpl {
}
/**
- * Update PMF requirement if auto-upgrade offload is supported.
- *
- * If SAE auto-upgrade offload is supported and this config enables
- * both PSK and SAE, do not set PMF requirement to
- * mandatory to allow the device to roam between PSK and SAE BSSes.
- * wpa_supplicant will set PMF requirement to optional by default.
- */
- private boolean getOptimalPmfSettingForConfig(WifiConfiguration config,
- boolean isPmfRequiredFromSelectedSecurityParams) {
- if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)
- && config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK).isEnabled()
- && config.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)
- && config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE).isEnabled()
- && mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()) {
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "Keep optional PMF for SAE auto-upgrade offload.");
- }
- return false;
- }
- return isPmfRequiredFromSelectedSecurityParams;
- }
-
- /**
* Adds both PSK and SAE AKM if auto-upgrade offload is supported.
*/
private BitSet addPskSaeUpgradableTypeFlagsIfSupported(
@@ -3703,4 +3666,49 @@ public class SupplicantStaNetworkHalAidlImpl {
return false;
}
}
+
+ private int frameworkToAidlTlsVersion(@WifiEnterpriseConfig.TlsVersion int tlsVersion) {
+ switch (tlsVersion) {
+ case WifiEnterpriseConfig.TLS_V1_3:
+ return TlsVersion.TLS_V1_3;
+ case WifiEnterpriseConfig.TLS_V1_2:
+ return TlsVersion.TLS_V1_2;
+ case WifiEnterpriseConfig.TLS_V1_1:
+ return TlsVersion.TLS_V1_1;
+ case WifiEnterpriseConfig.TLS_V1_0:
+ return TlsVersion.TLS_V1_0;
+ default:
+ Log.e(TAG, "Invalid TLS version: " + tlsVersion);
+ return -1;
+ }
+ }
+
+ /**
+ * Enable TLS V1.3 in EAP Phase1
+ *
+ * @param tlsVersion the TLS version
+ * @return true if successful, false otherwise
+ */
+ private boolean setMinimumTlsVersionEapPhase1Param(
+ @WifiEnterpriseConfig.TlsVersion int tlsVersion) {
+ synchronized (mLock) {
+ final String methodStr = "setMinimumTlsVersionEapPhase1Param";
+ if (!checkStaNetworkAndLogFailure(methodStr)) {
+ return false;
+ }
+ int aidlTlsVersion = frameworkToAidlTlsVersion(tlsVersion);
+ if (aidlTlsVersion < 0) {
+ return false;
+ }
+ try {
+ mISupplicantStaNetwork.setMinimumTlsVersionEapPhase1Param(aidlTlsVersion);
+ 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/SupplicantStaNetworkHalHidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHalHidlImpl.java
index 251340ee63..faf9aa501d 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkHalHidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHalHidlImpl.java
@@ -309,8 +309,8 @@ public class SupplicantStaNetworkHalHidlImpl {
}
Log.d(TAG, "The target security params: " + securityParams);
- boolean isRequirePmf = getOptimalPmfSettingForConfig(config,
- securityParams.isRequirePmf());
+ boolean isRequirePmf = NativeUtil.getOptimalPmfSettingForConfig(config,
+ securityParams.isRequirePmf(), mWifiGlobals);
/** RequirePMF */
if (!setRequirePmf(isRequirePmf)) {
Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePmf);
@@ -353,7 +353,8 @@ public class SupplicantStaNetworkHalHidlImpl {
return false;
}
/** Group Cipher */
- BitSet allowedGroupCiphers = securityParams.getAllowedGroupCiphers();
+ BitSet allowedGroupCiphers = NativeUtil.getOptimalGroupCiphersForConfig(
+ config, securityParams.getAllowedGroupCiphers(), mWifiGlobals);
if (allowedGroupCiphers.cardinality() != 0
&& (!setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
allowedGroupCiphers)))) {
@@ -361,7 +362,8 @@ public class SupplicantStaNetworkHalHidlImpl {
return false;
}
/** Pairwise Cipher*/
- BitSet allowedPairwiseCiphers = securityParams.getAllowedPairwiseCiphers();
+ BitSet allowedPairwiseCiphers = NativeUtil.getOptimalPairwiseCiphersForConfig(
+ config, securityParams.getAllowedPairwiseCiphers(), mWifiGlobals);
if (allowedPairwiseCiphers.cardinality() != 0
&& !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
allowedPairwiseCiphers))) {
@@ -1613,6 +1615,9 @@ public class SupplicantStaNetworkHalHidlImpl {
synchronized (mLock) {
final String methodStr = "setGroupCipher";
if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, String.format("setGroupCipher: 0x%x", groupCipherMask));
+ }
try {
SupplicantStatus status;
android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
@@ -1721,6 +1726,9 @@ public class SupplicantStaNetworkHalHidlImpl {
synchronized (mLock) {
final String methodStr = "setPairwiseCipher";
if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, String.format("setPairwiseCipher: 0x%x", pairwiseCipherMask));
+ }
try {
SupplicantStatus status;
android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
@@ -1845,6 +1853,9 @@ public class SupplicantStaNetworkHalHidlImpl {
synchronized (mLock) {
final String methodStr = "setRequirePmf";
if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "setRequirePmf: " + enable);
+ }
try {
SupplicantStatus status = mISupplicantStaNetwork.setRequirePmf(enable);
return checkStatusAndLogFailure(status, methodStr);
@@ -3829,29 +3840,6 @@ public class SupplicantStaNetworkHalHidlImpl {
}
/**
- * Update PMF requirement if auto-upgrade offload is supported.
- *
- * If SAE auto-upgrade offload is supported and this config enables
- * both PSK and SAE, do not set PMF requirement to
- * mandatory to allow the device to roam between PSK and SAE BSSes.
- * wpa_supplicant will set PMF requirement to optional by default.
- */
- private boolean getOptimalPmfSettingForConfig(WifiConfiguration config,
- boolean isPmfRequiredFromSelectedSecurityParams) {
- if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)
- && config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK).isEnabled()
- && config.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)
- && config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE).isEnabled()
- && mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()) {
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "Keep optional PMF for SAE auto-upgrade offload.");
- }
- return false;
- }
- return isPmfRequiredFromSelectedSecurityParams;
- }
-
- /**
* Adds both PSK and SAE AKM if auto-upgrade offload is supported.
*/
private BitSet addPskSaeUpgradableTypeFlagsIfSupported(
diff --git a/service/java/com/android/server/wifi/ThroughputScorer.java b/service/java/com/android/server/wifi/ThroughputScorer.java
index ab2511f8de..30acce38ab 100644
--- a/service/java/com/android/server/wifi/ThroughputScorer.java
+++ b/service/java/com/android/server/wifi/ThroughputScorer.java
@@ -105,6 +105,10 @@ final class ThroughputScorer implements WifiCandidates.CandidateScorer {
? mScoringParams.getBand6GhzBonus() : 0;
int currentNetworkBoost = (candidate.isCurrentNetwork() && !unExpectedNoInternet)
? currentNetworkBonus : 0;
+ int rssiBoost = (candidate.isCurrentNetwork() && unExpectedNoInternet)
+ ? 0 : rssiBaseScore;
+ int throughputBoost = (candidate.isCurrentNetwork() && unExpectedNoInternet)
+ ? 0 : throughputBonusScore;
int securityAward = candidate.isOpenNetwork()
? 0
@@ -157,7 +161,7 @@ final class ThroughputScorer implements WifiCandidates.CandidateScorer {
+ notOemPaidAward + notOemPrivateAward + securityAward;
// Within the same scoring bucket, ties are broken by the following bonus scores. The sum
// of these scores should be capped to the buket step size to prevent overlapping bucket.
- int scoreWithinBucket = rssiBaseScore + throughputBonusScore + currentNetworkBoost
+ int scoreWithinBucket = rssiBoost + throughputBoost + currentNetworkBoost
+ bandSpecificBonus;
int score = scoreToDetermineBucket
+ Math.min(mScoringParams.getScoringBucketStepSize(), scoreWithinBucket);
diff --git a/service/java/com/android/server/wifi/WakeupController.java b/service/java/com/android/server/wifi/WakeupController.java
index d1d0cab94c..7d87b0c9a6 100644
--- a/service/java/com/android/server/wifi/WakeupController.java
+++ b/service/java/com/android/server/wifi/WakeupController.java
@@ -27,6 +27,7 @@ import android.os.Process;
import android.provider.Settings;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.HandlerExecutor;
@@ -67,6 +68,7 @@ public class WakeupController {
private final WifiWakeMetrics mWifiWakeMetrics;
private final Clock mClock;
private final ActiveModeWarden mActiveModeWarden;
+ private final Object mLock = new Object();
private final WifiScanner.ScanListener mScanListener = new WifiScanner.ScanListener() {
@Override
@@ -100,6 +102,7 @@ public class WakeupController {
};
/** Whether this feature is enabled in Settings. */
+ @GuardedBy("mLock")
private boolean mWifiWakeupEnabled;
/** Whether the WakeupController is currently active. */
@@ -186,9 +189,11 @@ public class WakeupController {
}
private void readWifiWakeupEnabledFromSettings() {
- mWifiWakeupEnabled = mFrameworkFacade.getIntegerSetting(
- mContext, Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1;
- Log.d(TAG, "WifiWake " + (mWifiWakeupEnabled ? "enabled" : "disabled"));
+ synchronized (mLock) {
+ mWifiWakeupEnabled = mFrameworkFacade.getIntegerSetting(
+ mContext, Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1;
+ Log.d(TAG, "WifiWake " + (mWifiWakeupEnabled ? "enabled" : "disabled"));
+ }
}
private void setActive(boolean isActive) {
@@ -203,15 +208,19 @@ public class WakeupController {
* Enable/Disable the feature.
*/
public void setEnabled(boolean enable) {
- mFrameworkFacade.setIntegerSetting(
- mContext, Settings.Global.WIFI_WAKEUP_ENABLED, enable ? 1 : 0);
+ synchronized (mLock) {
+ mFrameworkFacade.setIntegerSetting(
+ mContext, Settings.Global.WIFI_WAKEUP_ENABLED, enable ? 1 : 0);
+ }
}
/**
* Whether the feature is currently enabled.
*/
public boolean isEnabled() {
- return mWifiWakeupEnabled;
+ synchronized (mLock) {
+ return mWifiWakeupEnabled;
+ }
}
/**
@@ -461,7 +470,9 @@ public class WakeupController {
*/
@VisibleForTesting
boolean isEnabledAndReady() {
- return mWifiWakeupEnabled && mWakeupConfigStoreData.hasBeenRead();
+ synchronized (mLock) {
+ return mWifiWakeupEnabled && mWakeupConfigStoreData.hasBeenRead();
+ }
}
/** Dumps wakeup controller state. */
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index 490c27a3f6..063737f831 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -188,7 +188,8 @@ public class WifiApConfigStore {
* Returns SoftApConfiguration in which some parameters might be upgrade to supported default
* configuration.
*/
- public SoftApConfiguration upgradeSoftApConfiguration(@NonNull SoftApConfiguration config) {
+ public synchronized SoftApConfiguration upgradeSoftApConfiguration(
+ @NonNull SoftApConfiguration config) {
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(config);
if (SdkLevel.isAtLeastS() && ApConfigUtil.isBridgedModeSupported(mContext)
&& config.getBands().length == 1 && mContext.getResources().getBoolean(
@@ -221,7 +222,7 @@ public class WifiApConfigStore {
* - If previous bands configuration is bridged mode. Reset to 2.4G when device doesn't support
* it.
*/
- public SoftApConfiguration resetToDefaultForUnsupportedConfig(
+ public synchronized SoftApConfiguration resetToDefaultForUnsupportedConfig(
@NonNull SoftApConfiguration config) {
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(config);
if ((!ApConfigUtil.isClientForceDisconnectSupported(mContext)
@@ -443,15 +444,17 @@ public class WifiApConfigStore {
configBuilder.setPassphrase(generatePassword(),
SECURITY_TYPE_WPA2_PSK);
}
- // Update default MAC randomization setting to NONE when feature doesn't support it or
- // It was disabled in tethered mode.
- if (!ApConfigUtil.isApMacRandomizationSupported(context)
- || (mPersistentWifiApConfig != null
- && mPersistentWifiApConfig.getMacRandomizationSettingInternal()
- == SoftApConfiguration.RANDOMIZATION_NONE)) {
- if (SdkLevel.isAtLeastS()) {
- configBuilder.setMacRandomizationSetting(
- SoftApConfiguration.RANDOMIZATION_NONE);
+ synchronized (this) {
+ // Update default MAC randomization setting to NONE when feature doesn't support
+ // it, or it was disabled in tethered mode.
+ if (!ApConfigUtil.isApMacRandomizationSupported(context)
+ || (mPersistentWifiApConfig != null
+ && mPersistentWifiApConfig.getMacRandomizationSettingInternal()
+ == SoftApConfiguration.RANDOMIZATION_NONE)) {
+ if (SdkLevel.isAtLeastS()) {
+ configBuilder.setMacRandomizationSetting(
+ SoftApConfiguration.RANDOMIZATION_NONE);
+ }
}
}
}
@@ -516,6 +519,7 @@ public class WifiApConfigStore {
* Verify provided preSharedKey in ap config for WPA2_PSK/WPA3_SAE (Transition) network
* meets requirements.
*/
+ @SuppressWarnings("ReturnValueIgnored")
private static boolean validateApConfigAsciiPreSharedKey(
@SoftApConfiguration.SecurityType int securityType, String preSharedKey) {
final int sharedKeyLen = preSharedKey.length();
@@ -680,7 +684,8 @@ public class WifiApConfigStore {
* @param forcedApBand The forced band.
* @param forcedApChannel The forced IEEE channel number or 0 when forced AP band only.
*/
- public void enableForceSoftApBandOrChannel(@BandType int forcedApBand, int forcedApChannel) {
+ public synchronized void enableForceSoftApBandOrChannel(@BandType int forcedApBand,
+ int forcedApChannel) {
mForceApChannel = true;
mForcedApChannel = forcedApChannel;
mForcedApBand = forcedApBand;
@@ -689,7 +694,7 @@ public class WifiApConfigStore {
/**
* Disable force-soft-AP-channel mode which take effect when soft AP starts next time
*/
- public void disableForceSoftApBandOrChannel() {
+ public synchronized void disableForceSoftApBandOrChannel() {
mForceApChannel = false;
}
diff --git a/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java b/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
index b99d987273..2d9f91e43d 100644
--- a/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
+++ b/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
@@ -96,65 +96,77 @@ class WifiBackupDataV1Parser implements WifiBackupDataParser {
private static final int HIGHEST_SUPPORTED_MINOR_VERSION = 3;
// List of tags supported for <WifiConfiguration> section in minor version 0
- private static final Set<String> WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS =
- new HashSet<String>(Arrays.asList(new String[] {
- WifiConfigurationXmlUtil.XML_TAG_CONFIG_KEY,
- WifiConfigurationXmlUtil.XML_TAG_SSID,
- WifiConfigurationXmlUtil.XML_TAG_PRE_SHARED_KEY,
- WifiConfigurationXmlUtil.XML_TAG_WEP_KEYS,
- WifiConfigurationXmlUtil.XML_TAG_WEP_TX_KEY_INDEX,
- WifiConfigurationXmlUtil.XML_TAG_HIDDEN_SSID,
- WifiConfigurationXmlUtil.XML_TAG_REQUIRE_PMF,
- WifiConfigurationXmlUtil.XML_TAG_ALLOWED_KEY_MGMT,
- WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PROTOCOLS,
- WifiConfigurationXmlUtil.XML_TAG_ALLOWED_AUTH_ALGOS,
- WifiConfigurationXmlUtil.XML_TAG_ALLOWED_GROUP_CIPHERS,
- WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PAIRWISE_CIPHERS,
- WifiConfigurationXmlUtil.XML_TAG_SHARED,
- }));
+ private static final Set<String> WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS = Set.of(
+ WifiConfigurationXmlUtil.XML_TAG_CONFIG_KEY,
+ WifiConfigurationXmlUtil.XML_TAG_SSID,
+ WifiConfigurationXmlUtil.XML_TAG_PRE_SHARED_KEY,
+ WifiConfigurationXmlUtil.XML_TAG_WEP_KEYS,
+ WifiConfigurationXmlUtil.XML_TAG_WEP_TX_KEY_INDEX,
+ WifiConfigurationXmlUtil.XML_TAG_HIDDEN_SSID,
+ WifiConfigurationXmlUtil.XML_TAG_REQUIRE_PMF,
+ WifiConfigurationXmlUtil.XML_TAG_ALLOWED_KEY_MGMT,
+ WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PROTOCOLS,
+ WifiConfigurationXmlUtil.XML_TAG_ALLOWED_AUTH_ALGOS,
+ WifiConfigurationXmlUtil.XML_TAG_ALLOWED_GROUP_CIPHERS,
+ WifiConfigurationXmlUtil.XML_TAG_ALLOWED_PAIRWISE_CIPHERS,
+ WifiConfigurationXmlUtil.XML_TAG_SHARED);
// List of tags supported for <WifiConfiguration> section in minor version 1
private static final Set<String> WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS =
- new HashSet<String>() {{
- addAll(WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS);
- add(WifiConfigurationXmlUtil.XML_TAG_METERED_OVERRIDE);
- }};
+ new HashSet<String>();
+ static {
+ WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS.addAll(
+ WIFI_CONFIGURATION_MINOR_V0_SUPPORTED_TAGS);
+ WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_METERED_OVERRIDE);
+ }
// List of tags supported for <WifiConfiguration> section in minor version 2
private static final Set<String> WIFI_CONFIGURATION_MINOR_V2_SUPPORTED_TAGS =
- new HashSet<String>() {{
- addAll(WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS);
- add(WifiConfigurationXmlUtil.XML_TAG_IS_AUTO_JOIN);
- }};
+ new HashSet<String>();
+ static {
+ WIFI_CONFIGURATION_MINOR_V2_SUPPORTED_TAGS.addAll(
+ WIFI_CONFIGURATION_MINOR_V1_SUPPORTED_TAGS);
+ WIFI_CONFIGURATION_MINOR_V2_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_IS_AUTO_JOIN);
+ }
// List of tags supported for <WifiConfiguration> section in minor version 3
private static final Set<String> WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS =
- new HashSet<String>() {{
- addAll(WIFI_CONFIGURATION_MINOR_V2_SUPPORTED_TAGS);
- add(WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS_LIST);
- add(WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS);
- add(WifiConfigurationXmlUtil.XML_TAG_SECURITY_TYPE);
- add(WifiConfigurationXmlUtil.XML_TAG_SAE_IS_H2E_ONLY_MODE);
- add(WifiConfigurationXmlUtil.XML_TAG_SAE_IS_PK_ONLY_MODE);
- add(WifiConfigurationXmlUtil.XML_TAG_IS_ADDED_BY_AUTO_UPGRADE);
- add(WifiConfigurationXmlUtil.XML_TAG_DELETION_PRIORITY);
- add(WifiConfigurationXmlUtil.XML_TAG_NUM_REBOOTS_SINCE_LAST_USE);
- }};
+ new HashSet<String>();
+ static {
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS.addAll(
+ WIFI_CONFIGURATION_MINOR_V2_SUPPORTED_TAGS);
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS_LIST);
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_SECURITY_PARAMS);
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_SECURITY_TYPE);
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_SAE_IS_H2E_ONLY_MODE);
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_SAE_IS_PK_ONLY_MODE);
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_IS_ADDED_BY_AUTO_UPGRADE);
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS.add(
+ WifiConfigurationXmlUtil.XML_TAG_DELETION_PRIORITY);
+ WIFI_CONFIGURATION_MINOR_V3_SUPPORTED_TAGS.add(
+ 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 =
- new HashSet<String>(Arrays.asList(new String[] {
- IpConfigurationXmlUtil.XML_TAG_IP_ASSIGNMENT,
- IpConfigurationXmlUtil.XML_TAG_LINK_ADDRESS,
- IpConfigurationXmlUtil.XML_TAG_LINK_PREFIX_LENGTH,
- IpConfigurationXmlUtil.XML_TAG_GATEWAY_ADDRESS,
- IpConfigurationXmlUtil.XML_TAG_DNS_SERVER_ADDRESSES,
- IpConfigurationXmlUtil.XML_TAG_PROXY_SETTINGS,
- IpConfigurationXmlUtil.XML_TAG_PROXY_HOST,
- IpConfigurationXmlUtil.XML_TAG_PROXY_PORT,
- IpConfigurationXmlUtil.XML_TAG_PROXY_EXCLUSION_LIST,
- IpConfigurationXmlUtil.XML_TAG_PROXY_PAC_FILE,
- }));
+ private static final Set<String> IP_CONFIGURATION_MINOR_V0_V1_V2_V3_SUPPORTED_TAGS = Set.of(
+ IpConfigurationXmlUtil.XML_TAG_IP_ASSIGNMENT,
+ IpConfigurationXmlUtil.XML_TAG_LINK_ADDRESS,
+ IpConfigurationXmlUtil.XML_TAG_LINK_PREFIX_LENGTH,
+ IpConfigurationXmlUtil.XML_TAG_GATEWAY_ADDRESS,
+ IpConfigurationXmlUtil.XML_TAG_DNS_SERVER_ADDRESSES,
+ IpConfigurationXmlUtil.XML_TAG_PROXY_SETTINGS,
+ IpConfigurationXmlUtil.XML_TAG_PROXY_HOST,
+ IpConfigurationXmlUtil.XML_TAG_PROXY_PORT,
+ IpConfigurationXmlUtil.XML_TAG_PROXY_EXCLUSION_LIST,
+ IpConfigurationXmlUtil.XML_TAG_PROXY_PAC_FILE);
@Override
public List<WifiConfiguration> parseNetworkConfigurationsFromXml(XmlPullParser in,
diff --git a/service/java/com/android/server/wifi/WifiBackupRestore.java b/service/java/com/android/server/wifi/WifiBackupRestore.java
index 564a9021f0..1c2883635a 100644
--- a/service/java/com/android/server/wifi/WifiBackupRestore.java
+++ b/service/java/com/android/server/wifi/WifiBackupRestore.java
@@ -46,6 +46,7 @@ import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -459,7 +460,7 @@ public class WifiBackupRestore {
}
if (mDebugLastIpConfigBackupDataRestored != null) {
pw.println("Last old ipconfig backup data restored: "
- + mDebugLastIpConfigBackupDataRestored);
+ + Arrays.toString(mDebugLastIpConfigBackupDataRestored));
}
}
@@ -640,9 +641,8 @@ public class WifiBackupRestore {
}
if (mParsedKeyMgmtLine == null) {
// no key_mgmt line specified; this is defined as equivalent to
- // "WPA-PSK WPA-EAP".
+ // "WPA-PSK".
configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
} else {
// Need to parse the mParsedKeyMgmtLine line
final String bareKeyMgmt =
diff --git a/service/java/com/android/server/wifi/WifiBlocklistMonitor.java b/service/java/com/android/server/wifi/WifiBlocklistMonitor.java
index 14cd162f59..0c362a636f 100644
--- a/service/java/com/android/server/wifi/WifiBlocklistMonitor.java
+++ b/service/java/com/android/server/wifi/WifiBlocklistMonitor.java
@@ -131,6 +131,7 @@ public class WifiBlocklistMonitor {
private final ScoringParams mScoringParams;
private final WifiMetrics mWifiMetrics;
private final WifiPermissionsUtil mWifiPermissionsUtil;
+ private ScanRequestProxy mScanRequestProxy;
private final Map<Integer, BssidDisableReason> mBssidDisableReasons =
buildBssidDisableReasons();
private final SparseArray<DisableReasonInfo> mDisableReasonInfo;
@@ -201,6 +202,49 @@ public class WifiBlocklistMonitor {
}
}
+ /** Map of BSSID to affiliated BSSIDs. */
+ private Map<String, List<String>> mAffiliatedBssidMap = new ArrayMap<>();
+
+ /**
+ * Set the mapping of BSSID to affiliated BSSIDs.
+ *
+ * @param bssid A unique identifier of the AP.
+ * @param bssids List of affiliated BSSIDs.
+ */
+ public void setAffiliatedBssids(@NonNull String bssid, @NonNull List<String> bssids) {
+ mAffiliatedBssidMap.put(bssid, bssids);
+ }
+
+ /**
+ * Get affiliated BSSIDs mapped to a BSSID.
+ *
+ * @param bssid A unique identifier of the AP.
+ * @return List of affiliated BSSIDs or an empty list.
+ */
+ public List<String> getAffiliatedBssids(@NonNull String bssid) {
+ List<String> affiliatedBssids = mAffiliatedBssidMap.get(bssid);
+ return affiliatedBssids == null ? Collections.EMPTY_LIST : affiliatedBssids;
+ }
+
+ /**
+ * Remove affiliated BSSIDs mapped to a BSSID.
+ *
+ * @param bssid A unique identifier of the AP.
+ */
+ public void removeAffiliatedBssids(@NonNull String bssid) {
+ mAffiliatedBssidMap.remove(bssid);
+ }
+
+ /** Clear affiliated BSSID mapping table. */
+ public void clearAffiliatedBssids() {
+ mAffiliatedBssidMap.clear();
+ }
+
+ /** Sets the ScanRequestProxy **/
+ public void setScanRequestProxy(ScanRequestProxy scanRequestProxy) {
+ mScanRequestProxy = scanRequestProxy;
+ }
+
/**
* Create a new instance of WifiBlocklistMonitor
*/
@@ -252,6 +296,8 @@ public class WifiBlocklistMonitor {
pw.println("WifiBlocklistMonitor - Bssid blocklist begin ----");
mBssidStatusMap.values().stream().forEach(entry -> pw.println(entry));
pw.println("WifiBlocklistMonitor - Bssid blocklist end ----");
+ pw.println("Dump of BSSID to Affiliated BSSID mapping");
+ mAffiliatedBssidMap.forEach((bssid, aList) -> pw.println(bssid + " -> " + aList));
mBssidBlocklistMonitorLogger.dump(pw);
}
@@ -365,6 +411,14 @@ public class WifiBlocklistMonitor {
return;
}
addToBlocklist(status, durationMs, blockReason, rssi);
+ /**
+ * Add affiliated BSSIDs also into the block list with the same parameters as connected
+ * BSSID.
+ */
+ for (String affiliatedBssid : getAffiliatedBssids(bssid)) {
+ status = getOrCreateBssidStatus(affiliatedBssid, config.SSID);
+ addToBlocklist(status, durationMs, blockReason, rssi);
+ }
}
private String getFailureReasonString(@FailureReason int reasonCode) {
@@ -431,11 +485,37 @@ public class WifiBlocklistMonitor {
localLog("Ignoring failure to wait for watchdog to trigger first.");
return false;
}
+ // rssi may be unavailable for the first ever connection to a newly added network
+ // because it hasn't been cached inside the ScanDetailsCache yet. In this case, try to
+ // read the RSSI from the latest scan results.
+ if (rssi == WifiConfiguration.INVALID_RSSI && bssid != null) {
+ if (mScanRequestProxy != null) {
+ ScanResult scanResult = mScanRequestProxy.getScanResult(bssid);
+ if (scanResult != null) {
+ rssi = scanResult.level;
+ }
+ } else {
+ localLog("mScanRequestProxy is null");
+ Log.w(TAG, "mScanRequestProxy is null");
+ }
+ }
int baseBlockDurationMs = getBaseBlockDurationForReason(reasonCode);
- addToBlocklist(entry,
- getBlocklistDurationWithExponentialBackoff(currentStreak, baseBlockDurationMs),
- reasonCode, rssi);
+ long expBackoff = getBlocklistDurationWithExponentialBackoff(currentStreak,
+ baseBlockDurationMs);
+ addToBlocklist(entry, expBackoff, reasonCode, rssi);
mWifiScoreCard.incrementBssidBlocklistStreak(ssid, bssid, reasonCode);
+
+ /**
+ * Block list affiliated BSSID with same parameters, e.g. reason code, rssi ..etc.
+ * as connected BSSID.
+ */
+ for (String affiliatedBssid : getAffiliatedBssids(bssid)) {
+ BssidStatus affEntry = getOrCreateBssidStatus(affiliatedBssid, ssid);
+ affEntry.failureCount[reasonCode] = entry.failureCount[reasonCode];
+ addToBlocklist(affEntry, expBackoff, reasonCode, rssi);
+ mWifiScoreCard.incrementBssidBlocklistStreak(ssid, affiliatedBssid, reasonCode);
+ }
+
return true;
}
return false;
@@ -446,9 +526,12 @@ public class WifiBlocklistMonitor {
case REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE:
return mContext.getResources().getInteger(R.integer
.config_wifiBssidBlocklistMonitorConnectedScoreBaseBlockDurationMs);
+ case REASON_NETWORK_VALIDATION_FAILURE:
+ return mContext.getResources().getInteger(
+ R.integer.config_wifiBssidBlocklistMonitorValidationFailureBaseBlockDurationMs);
default:
return mContext.getResources().getInteger(
- R.integer.config_wifiBssidBlocklistMonitorBaseBlockDurationMs);
+ R.integer.config_wifiBssidBlocklistMonitorBaseBlockDurationMs);
}
}
@@ -499,6 +582,20 @@ public class WifiBlocklistMonitor {
*/
public void handleBssidConnectionSuccess(@NonNull String bssid, @NonNull String ssid) {
mDisabledSsids.remove(ssid);
+ resetFailuresAfterConnection(bssid, ssid);
+ for (String affiliatedBssid : getAffiliatedBssids(bssid)) {
+ resetFailuresAfterConnection(affiliatedBssid, ssid);
+ }
+ }
+
+ /**
+ * Reset all failure counters related to a connection.
+ *
+ * @param bssid A unique identifier of the AP.
+ * @param ssid Network name.
+ */
+ private void resetFailuresAfterConnection(@NonNull String bssid, @NonNull String ssid) {
+
/**
* First reset the blocklist streak.
* This needs to be done even if a BssidStatus is not found, since the BssidStatus may
@@ -546,27 +643,67 @@ public class WifiBlocklistMonitor {
* And then remove the BSSID from blocklist.
*/
public void handleNetworkValidationSuccess(@NonNull String bssid, @NonNull String ssid) {
+ resetNetworkValidationFailures(bssid, ssid);
+ /**
+ * Network validation may take more than 1 tries to succeed.
+ * remove the BSSID from blocklist to make sure we are not accidentally blocking good
+ * BSSIDs.
+ **/
+ removeFromBlocklist(bssid, "Network validation success");
+
+ for (String affiliatedBssid : getAffiliatedBssids(bssid)) {
+ resetNetworkValidationFailures(affiliatedBssid, ssid);
+ removeFromBlocklist(affiliatedBssid, "Network validation success");
+ }
+ }
+
+ /**
+ * Clear failure counters related to network validation.
+ *
+ * @param bssid A unique identifier of the AP.
+ * @param ssid Network name.
+ */
+ private void resetNetworkValidationFailures(@NonNull String bssid, @NonNull String ssid) {
mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_NETWORK_VALIDATION_FAILURE);
BssidStatus status = mBssidStatusMap.get(bssid);
if (status == null) {
return;
}
status.failureCount[REASON_NETWORK_VALIDATION_FAILURE] = 0;
- /**
- * Network validation may take more than 1 tries to succeed.
- * remove the BSSID from blocklist to make sure we are not accidentally blocking good
- * BSSIDs.
- **/
+ }
+
+ /**
+ * Remove BSSID from block list.
+ *
+ * @param bssid A unique identifier of the AP.
+ * @param reasonString A string to be logged while removing the entry from the block list.
+ */
+ private void removeFromBlocklist(@NonNull String bssid, final String reasonString) {
+ BssidStatus status = mBssidStatusMap.get(bssid);
+ if (status == null) {
+ return;
+ }
+
if (status.isInBlocklist) {
- mBssidBlocklistMonitorLogger.logBssidUnblocked(status, "Network validation success");
+ mBssidBlocklistMonitorLogger.logBssidUnblocked(status, reasonString);
mBssidStatusMap.remove(bssid);
}
}
/**
- * Note a successful DHCP provisioning and clear appropriate faliure counters.
+ * Note a successful DHCP provisioning and clear appropriate failure counters.
*/
public void handleDhcpProvisioningSuccess(@NonNull String bssid, @NonNull String ssid) {
+ resetDhcpFailures(bssid, ssid);
+ for (String affiliatedBssid : getAffiliatedBssids(bssid)) {
+ resetDhcpFailures(affiliatedBssid, ssid);
+ }
+ }
+
+ /**
+ * Reset failure counters related to DHCP.
+ */
+ private void resetDhcpFailures(@NonNull String bssid, @NonNull String ssid) {
mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_DHCP_FAILURE);
BssidStatus status = mBssidStatusMap.get(bssid);
if (status == null) {
@@ -712,9 +849,10 @@ public class WifiBlocklistMonitor {
status.lastRssi < sufficientRssi && scanResult.level >= sufficientRssi;
boolean goodRssiBreached = status.lastRssi < goodRssi && scanResult.level >= goodRssi;
if (rssiMinDiffAchieved && (sufficientRssiBreached || goodRssiBreached)) {
- mBssidBlocklistMonitorLogger.logBssidUnblocked(
- status, "rssi significantly improved");
- mBssidStatusMap.remove(status.bssid);
+ removeFromBlocklist(status.bssid, "rssi significantly improved");
+ for (String affiliatedBssid : getAffiliatedBssids(status.bssid)) {
+ removeFromBlocklist(affiliatedBssid, "rssi significantly improved");
+ }
results.add(scanDetail);
}
}
@@ -961,28 +1099,80 @@ public class WifiBlocklistMonitor {
"NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ",
mContext.getResources().getInteger(R.integer
.config_wifiDisableReasonAssociationRejectionThreshold),
- 5 * 60 * 1000));
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonAssociationRejectionDurationMs)));
mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE,
new DisableReasonInfo(
"NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE",
mContext.getResources().getInteger(R.integer
.config_wifiDisableReasonAuthenticationFailureThreshold),
- 5 * 60 * 1000));
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonAuthenticationFailureDurationMs)));
mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_DHCP_FAILURE,
new DisableReasonInfo(
"NETWORK_SELECTION_DISABLED_DHCP_FAILURE",
mContext.getResources().getInteger(R.integer
.config_wifiDisableReasonDhcpFailureThreshold),
- 5 * 60 * 1000));
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonDhcpFailureDurationMs)));
mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_NETWORK_NOT_FOUND,
new DisableReasonInfo(
"NETWORK_SELECTION_DISABLED_NETWORK_NOT_FOUND",
mContext.getResources().getInteger(R.integer
.config_wifiDisableReasonNetworkNotFoundThreshold),
- 5 * 60 * 1000));
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonNetworkNotFoundDurationMs)));
+
+ mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY,
+ new DisableReasonInfo(
+ "NETWORK_SELECTION_DISABLED_NO_INTERNET_TEMPORARY",
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonNoInternetTemporaryThreshold),
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonNoInternetTemporaryDurationMs)));
+
+ mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_CREDENTIALS,
+ new DisableReasonInfo(
+ "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonAuthenticationNoCredentialsThreshold),
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonAuthenticationNoCredentialsDurationMs)));
+
+ mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT,
+ new DisableReasonInfo(
+ "NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT",
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonNoInternetPermanentThreshold),
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonNoInternetPermanentDurationMs)));
+
+ mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD,
+ new DisableReasonInfo(
+ "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD",
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonByWrongPasswordThreshold),
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonByWrongPasswordDurationMs)));
+
+ mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_SUBSCRIPTION,
+ new DisableReasonInfo(
+ "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_SUBSCRIPTION",
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonAuthenticationNoSubscriptionThreshold),
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonAuthenticationNoSubscriptionDurationMs)));
+
+ mDisableReasonInfo.put(NetworkSelectionStatus.DISABLED_CONSECUTIVE_FAILURES,
+ new DisableReasonInfo(
+ "NETWORK_SELECTION_DISABLED_CONSECUTIVE_FAILURES",
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonConsecutiveFailuresThreshold),
+ mContext.getResources().getInteger(R.integer
+ .config_wifiDisableReasonConsecutiveFailuresDurationMs)));
}
/**
diff --git a/service/java/com/android/server/wifi/WifiCandidates.java b/service/java/com/android/server/wifi/WifiCandidates.java
index f32d3a2704..0eb6032492 100644
--- a/service/java/com/android/server/wifi/WifiCandidates.java
+++ b/service/java/com/android/server/wifi/WifiCandidates.java
@@ -99,10 +99,7 @@ public class WifiCandidates {
* Returns true for a oem private network.
*/
boolean isOemPrivate();
- /**
- * Returns true for a secondary network with internet.
- */
- boolean isSecondaryInternet();
+
/**
* Returns true if suggestion came from a carrier or privileged app.
*/
@@ -200,7 +197,6 @@ public class WifiCandidates {
private final boolean mRestricted;
private final boolean mOemPaid;
private final boolean mOemPrivate;
- private final boolean mSecondaryInternet;
private final boolean mCarrierOrPrivileged;
private final int mPredictedThroughputMbps;
private final int mEstimatedPercentInternetAvailability;
@@ -235,7 +231,6 @@ public class WifiCandidates {
this.mTrusted = config.trusted;
this.mOemPaid = config.oemPaid;
this.mOemPrivate = config.oemPrivate;
- this.mSecondaryInternet = config.dbsSecondaryInternet;
this.mCarrierOrPrivileged = isCarrierOrPrivileged;
this.mPredictedThroughputMbps = predictedThroughputMbps;
this.mEstimatedPercentInternetAvailability = perBssid == null ? 50 :
@@ -289,11 +284,6 @@ public class WifiCandidates {
}
@Override
- public boolean isSecondaryInternet() {
- return mSecondaryInternet;
- }
-
- @Override
public boolean isCarrierOrPrivileged() {
return mCarrierOrPrivileged;
}
@@ -396,7 +386,6 @@ public class WifiCandidates {
+ (isRestricted() ? "restricted, " : "")
+ (isOemPaid() ? "oemPaid, " : "")
+ (isOemPrivate() ? "oemPrivate, " : "")
- + (isSecondaryInternet() ? "secondaryInternet, " : "")
+ (isCarrierOrPrivileged() ? "priv, " : "")
+ (isMetered() ? "metered, " : "")
+ (hasNoInternetAccess() ? "noInternet, " : "")
diff --git a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
index 59d9ae602f..cebd07119a 100644
--- a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
+++ b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
@@ -58,6 +58,7 @@ import android.util.SparseBooleanArray;
import androidx.annotation.RequiresApi;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.modules.utils.HandlerExecutor;
@@ -190,8 +191,11 @@ public class WifiCarrierInfoManager {
private boolean mVerboseLogEnabled = false;
private SparseBooleanArray mImsiEncryptionInfoAvailable = new SparseBooleanArray();
private final Map<Integer, Boolean> mImsiPrivacyProtectionExemptionMap = new HashMap<>();
- private final Map<Integer, Boolean> mMergedCarrierNetworkOffloadMap = new HashMap<>();
- private final Map<Integer, Boolean> mUnmergedCarrierNetworkOffloadMap = new HashMap<>();
+ private final Object mCarrierNetworkOffloadMapLock = new Object();
+ @GuardedBy("mCarrierNetworkOffloadMapLock")
+ private SparseBooleanArray mMergedCarrierNetworkOffloadMap = new SparseBooleanArray();
+ @GuardedBy("mCarrierNetworkOffloadMapLock")
+ private SparseBooleanArray mUnmergedCarrierNetworkOffloadMap = new SparseBooleanArray();
private final List<OnUserApproveCarrierListener> mOnUserApproveCarrierListeners =
new ArrayList<>();
private final SparseBooleanArray mUserDataEnabled = new SparseBooleanArray();
@@ -317,13 +321,11 @@ public class WifiCarrierInfoManager {
WifiCarrierInfoStoreManagerData.DataSource {
@Override
- public Map<Integer, Boolean> toSerializeMergedCarrierNetworkOffloadMap() {
- return mMergedCarrierNetworkOffloadMap;
- }
-
- @Override
- public Map<Integer, Boolean> toSerializeUnmergedCarrierNetworkOffloadMap() {
- return mUnmergedCarrierNetworkOffloadMap;
+ public SparseBooleanArray getCarrierNetworkOffloadMap(boolean isMerged) {
+ synchronized (mCarrierNetworkOffloadMapLock) {
+ return isMerged ? mMergedCarrierNetworkOffloadMap
+ : mUnmergedCarrierNetworkOffloadMap;
+ }
}
@Override
@@ -331,25 +333,24 @@ public class WifiCarrierInfoManager {
mHasNewSharedDataToSerialize = false;
}
-
@Override
- public void fromMergedCarrierNetworkOffloadMapDeserialized(
- Map<Integer, Boolean> carrierOffloadMap) {
- mMergedCarrierNetworkOffloadMap.clear();
- mMergedCarrierNetworkOffloadMap.putAll(carrierOffloadMap);
- }
-
- @Override
- public void fromUnmergedCarrierNetworkOffloadMapDeserialized(
- Map<Integer, Boolean> subscriptionOffloadMap) {
- mUnmergedCarrierNetworkOffloadMap.clear();
- mUnmergedCarrierNetworkOffloadMap.putAll(subscriptionOffloadMap);
+ public void setCarrierNetworkOffloadMap(SparseBooleanArray carrierOffloadMap,
+ boolean isMerged) {
+ synchronized (mCarrierNetworkOffloadMapLock) {
+ if (isMerged) {
+ mMergedCarrierNetworkOffloadMap = carrierOffloadMap;
+ } else {
+ mUnmergedCarrierNetworkOffloadMap = carrierOffloadMap;
+ }
+ }
}
@Override
public void reset() {
- mMergedCarrierNetworkOffloadMap.clear();
- mUnmergedCarrierNetworkOffloadMap.clear();
+ synchronized (mCarrierNetworkOffloadMapLock) {
+ mMergedCarrierNetworkOffloadMap.clear();
+ mUnmergedCarrierNetworkOffloadMap.clear();
+ }
}
@Override
@@ -1915,17 +1916,22 @@ public class WifiCarrierInfoManager {
*/
public void setCarrierNetworkOffloadEnabled(int subscriptionId, boolean merged,
boolean enabled) {
- if (merged) {
- mMergedCarrierNetworkOffloadMap.put(subscriptionId, enabled);
- } else {
- mUnmergedCarrierNetworkOffloadMap.put(subscriptionId, enabled);
- }
- if (!enabled) {
- for (OnCarrierOffloadDisabledListener listener : mOnCarrierOffloadDisabledListeners) {
- listener.onCarrierOffloadDisabled(subscriptionId, merged);
+ synchronized (mCarrierNetworkOffloadMapLock) {
+ if (merged) {
+ mMergedCarrierNetworkOffloadMap.put(subscriptionId, enabled);
+ } else {
+ mUnmergedCarrierNetworkOffloadMap.put(subscriptionId, enabled);
}
}
- saveToStore();
+ mHandler.post(() -> {
+ if (!enabled) {
+ for (OnCarrierOffloadDisabledListener listener :
+ mOnCarrierOffloadDisabledListeners) {
+ listener.onCarrierOffloadDisabled(subscriptionId, merged);
+ }
+ }
+ saveToStore();
+ });
}
/**
@@ -1935,11 +1941,13 @@ public class WifiCarrierInfoManager {
* @return True to indicate carrier offload is enabled, false otherwise.
*/
public boolean isCarrierNetworkOffloadEnabled(int subId, boolean merged) {
- if (merged) {
- return mMergedCarrierNetworkOffloadMap.getOrDefault(subId, true)
- && isMobileDataEnabled(subId);
- } else {
- return mUnmergedCarrierNetworkOffloadMap.getOrDefault(subId, true);
+ synchronized (mCarrierNetworkOffloadMapLock) {
+ if (merged) {
+ return mMergedCarrierNetworkOffloadMap.get(subId, true)
+ && isMobileDataEnabled(subId);
+ } else {
+ return mUnmergedCarrierNetworkOffloadMap.get(subId, true);
+ }
}
}
@@ -1976,9 +1984,11 @@ public class WifiCarrierInfoManager {
* Helper method for user factory reset network setting.
*/
public void clear() {
+ synchronized (mCarrierNetworkOffloadMapLock) {
+ mMergedCarrierNetworkOffloadMap.clear();
+ mUnmergedCarrierNetworkOffloadMap.clear();
+ }
mImsiPrivacyProtectionExemptionMap.clear();
- mMergedCarrierNetworkOffloadMap.clear();
- mUnmergedCarrierNetworkOffloadMap.clear();
mUserDataEnabled.clear();
mCarrierPrivilegedPackagesBySimSlot.clear();
if (SdkLevel.isAtLeastS()) {
diff --git a/service/java/com/android/server/wifi/WifiCarrierInfoStoreManagerData.java b/service/java/com/android/server/wifi/WifiCarrierInfoStoreManagerData.java
index 29e7a6ac6f..bf2b4ce33e 100644
--- a/service/java/com/android/server/wifi/WifiCarrierInfoStoreManagerData.java
+++ b/service/java/com/android/server/wifi/WifiCarrierInfoStoreManagerData.java
@@ -18,6 +18,7 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.util.Log;
+import android.util.SparseBooleanArray;
import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
@@ -51,14 +52,10 @@ public class WifiCarrierInfoStoreManagerData implements WifiConfigStore.StoreDat
/**
* Retrieve the merged carrier network offload map from the data source to serialize to
* disk.
+ *
+ * @param isMerged true for merged map, false for unmerged map.
*/
- Map<Integer, Boolean> toSerializeMergedCarrierNetworkOffloadMap();
-
- /**
- * Retrieve the unmerged carrier network offload map from the data source to serialize to
- * disk.
- */
- Map<Integer, Boolean> toSerializeUnmergedCarrierNetworkOffloadMap();
+ SparseBooleanArray getCarrierNetworkOffloadMap(boolean isMerged);
/**
* Should be called when serialize is completed.
@@ -69,16 +66,9 @@ public class WifiCarrierInfoStoreManagerData implements WifiConfigStore.StoreDat
/**
* Set the merged carrier network offload map in the data source after deserialize them
* from disk.
+ * @param isMerged true for merged map, false for unmerged map.
*/
- void fromMergedCarrierNetworkOffloadMapDeserialized(
- Map<Integer, Boolean> carrierOffloadMap);
-
- /**
- * Set the unmerged carrier network offload map in the data source after serializing them
- * from disk.
- */
- void fromUnmergedCarrierNetworkOffloadMapDeserialized(
- Map<Integer, Boolean> subscriptionOffloadMap);
+ void setCarrierNetworkOffloadMap(SparseBooleanArray carrierOffloadMap, boolean isMerged);
/**
* Clear internal data structure in preparation for user switch or initial store read.
@@ -104,9 +94,9 @@ public class WifiCarrierInfoStoreManagerData implements WifiConfigStore.StoreDat
public void serializeData(XmlSerializer out, WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
XmlUtil.writeNextValue(out, XML_TAG_MERGED_CARRIER_NETWORK_OFFLOAD_MAP,
- integerMapToStringMap(mDataSource.toSerializeMergedCarrierNetworkOffloadMap()));
+ sparseArrayToStringMap(mDataSource.getCarrierNetworkOffloadMap(true)));
XmlUtil.writeNextValue(out, XML_TAG_UNMERGED_CARRIER_NETWORK_OFFLOAD_MAP,
- integerMapToStringMap(mDataSource.toSerializeUnmergedCarrierNetworkOffloadMap()));
+ sparseArrayToStringMap(mDataSource.getCarrierNetworkOffloadMap(false)));
mDataSource.serializeComplete();
}
@@ -132,14 +122,14 @@ public class WifiCarrierInfoStoreManagerData implements WifiConfigStore.StoreDat
switch (valueName[0]) {
case XML_TAG_MERGED_CARRIER_NETWORK_OFFLOAD_MAP:
if (value instanceof Map) {
- mDataSource.fromMergedCarrierNetworkOffloadMapDeserialized(
- stringMapToIntegerMap((Map<String, Boolean>) value));
+ mDataSource.setCarrierNetworkOffloadMap(
+ stringMapToSparseArray((Map<String, Boolean>) value), true);
}
break;
case XML_TAG_UNMERGED_CARRIER_NETWORK_OFFLOAD_MAP:
if (value instanceof Map) {
- mDataSource.fromUnmergedCarrierNetworkOffloadMapDeserialized(
- stringMapToIntegerMap((Map<String, Boolean>) value));
+ mDataSource.setCarrierNetworkOffloadMap(
+ stringMapToSparseArray((Map<String, Boolean>) value), false);
}
break;
default:
@@ -151,19 +141,19 @@ public class WifiCarrierInfoStoreManagerData implements WifiConfigStore.StoreDat
}
}
- private Map<String, Boolean> integerMapToStringMap(Map<Integer, Boolean> input) {
+ private Map<String, Boolean> sparseArrayToStringMap(SparseBooleanArray input) {
Map<String, Boolean> output = new HashMap<>();
if (input == null) {
return output;
}
- for (Map.Entry<Integer, Boolean> entry : input.entrySet()) {
- output.put(Integer.toString(entry.getKey()), entry.getValue());
+ for (int i = 0; i < input.size(); i++) {
+ output.put(Integer.toString(input.keyAt(i)), input.valueAt(i));
}
return output;
}
- private Map<Integer, Boolean> stringMapToIntegerMap(Map<String, Boolean> input) {
- Map<Integer, Boolean> output = new HashMap<>();
+ private SparseBooleanArray stringMapToSparseArray(Map<String, Boolean> input) {
+ SparseBooleanArray output = new SparseBooleanArray();
if (input == null) {
return output;
}
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index f0512e98f5..cd1b0881dd 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -1020,7 +1020,8 @@ public class WifiConfigManager {
// modify the network.
return isCreator
|| mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
- || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid);
+ || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)
+ || mWifiPermissionsUtil.checkConfigOverridePermission(uid);
}
final ContentResolver resolver = mContext.getContentResolver();
@@ -1029,7 +1030,8 @@ public class WifiConfigManager {
return !isLockdownFeatureEnabled
// If not locked down, settings app (i.e user) has permission to modify the network.
&& (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
- || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid));
+ || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)
+ || mWifiPermissionsUtil.checkConfigOverridePermission(uid));
}
private void mergeSecurityParamsListWithInternalWifiConfiguration(
@@ -1183,7 +1185,6 @@ public class WifiConfigManager {
internalConfig.trusted = externalConfig.trusted;
internalConfig.oemPaid = externalConfig.oemPaid;
internalConfig.oemPrivate = externalConfig.oemPrivate;
- internalConfig.dbsSecondaryInternet = externalConfig.dbsSecondaryInternet;
internalConfig.carrierMerged = externalConfig.carrierMerged;
internalConfig.restricted = externalConfig.restricted;
@@ -1408,7 +1409,8 @@ public class WifiConfigManager {
// Only allow changes in Repeater Enabled flag if the user has permission to
if (WifiConfigurationUtil.hasRepeaterEnabledChanged(
existingInternalConfig, newInternalConfig)
- && !mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
+ && !mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
+ && !mWifiPermissionsUtil.checkConfigOverridePermission(uid)) {
Log.e(TAG, "UID " + uid
+ " does not have permission to modify Repeater Enabled Settings "
+ " , or add a network with Repeater Enabled set to true "
@@ -1421,6 +1423,7 @@ public class WifiConfigManager {
if (WifiConfigurationUtil.hasMacRandomizationSettingsChanged(existingInternalConfig,
newInternalConfig) && !mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
&& !mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)
+ && !mWifiPermissionsUtil.checkConfigOverridePermission(uid)
&& !(newInternalConfig.isPasspoint() && uid == newInternalConfig.creatorUid)
&& !config.fromWifiNetworkSuggestion
&& !mWifiPermissionsUtil.isDeviceInDemoMode(mContext)
@@ -3575,7 +3578,7 @@ public class WifiConfigManager {
* @param forceWrite Whether the write needs to be forced or not.
* @return Whether the write was successful or not, this is applicable only for force writes.
*/
- public boolean saveToStore(boolean forceWrite) {
+ public synchronized boolean saveToStore(boolean forceWrite) {
if (mPendingStoreRead) {
Log.e(TAG, "Cannot save to store before store is read!");
return false;
@@ -3692,7 +3695,8 @@ public class WifiConfigManager {
mWifiPermissionsUtil.checkNetworkManagedProvisioningPermission(uid);
// If |uid| corresponds to the admin, allow all modifications.
if (isAdmin || hasNetworkSettingsPermission
- || hasNetworkSetupWizardPermission || hasNetworkManagedProvisioningPermission) {
+ || hasNetworkSetupWizardPermission || hasNetworkManagedProvisioningPermission
+ || mWifiPermissionsUtil.checkConfigOverridePermission(uid)) {
return true;
}
if (mVerboseLoggingEnabled) {
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index 74952014a4..958cb1e538 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -1026,9 +1026,8 @@ public class WifiConfigStore {
* sections (for migration purposes), then override this method.
* @return a set of section headers
*/
- default HashSet<String> getSectionsToParse() {
- //
- return new HashSet<String>() {{ add(getName()); }};
+ default Set<String> getSectionsToParse() {
+ return Set.of(getName());
}
/**
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index 95db4d75aa..aafe7f79b4 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -616,9 +616,8 @@ public class WifiConfigurationUtil {
Log.e(TAG, "validateKeyMgmt failed: not WPA_EAP");
return false;
}
- if (!keyMgmnt.get(WifiConfiguration.KeyMgmt.IEEE8021X)
- && !keyMgmnt.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
- Log.e(TAG, "validateKeyMgmt failed: not PSK or 8021X");
+ if (!keyMgmnt.get(WifiConfiguration.KeyMgmt.IEEE8021X)) {
+ Log.e(TAG, "validateKeyMgmt failed: not 8021X");
return false;
}
// SUITE-B keymgmt must be WPA_EAP + IEEE8021X + SUITE_B_192.
@@ -630,6 +629,11 @@ public class WifiConfigurationUtil {
return false;
}
}
+ // There should be at least one keymgmt.
+ if (keyMgmnt.cardinality() == 0) {
+ Log.e(TAG, "validateKeyMgmt failed: cardinality = 0");
+ return false;
+ }
return true;
}
@@ -814,9 +818,11 @@ public class WifiConfigurationUtil {
* 12. {@link WifiConfiguration#getIpConfiguration()}
*
* @param specifier Instance of {@link WifiNetworkSpecifier}.
+ * @param maxChannelsAllowed The max number allowed to set in a WifiNetworkSpecifier
* @return true if the parameters are valid, false otherwise.
*/
- public static boolean validateNetworkSpecifier(WifiNetworkSpecifier specifier) {
+ public static boolean validateNetworkSpecifier(WifiNetworkSpecifier specifier,
+ int maxChannelsAllowed) {
if (!isValidNetworkSpecifier(specifier)) {
Log.e(TAG, "validateNetworkSpecifier failed : invalid network specifier");
return false;
@@ -832,6 +838,9 @@ public class WifiConfigurationUtil {
if (!WifiNetworkSpecifier.validateBand(getBand(specifier))) {
return false;
}
+ if (specifier.getPreferredChannelFrequenciesMhz().length > maxChannelsAllowed) {
+ return false;
+ }
WifiConfiguration config = specifier.wifiConfiguration;
if (specifier.ssidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) {
// For literal SSID matches, the value should satisfy SSID requirements.
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 1d2a188b9c..b147be6592 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -32,6 +32,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.net.IpConfiguration;
import android.net.MacAddress;
import android.net.wifi.IPnoScanResultsCallback;
import android.net.wifi.ScanResult;
@@ -48,11 +49,11 @@ import android.net.wifi.WifiScanner.ScanSettings;
import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.util.ScanResultUtil;
-import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.Process;
import android.os.WorkSource;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -60,9 +61,10 @@ import android.util.LocalLog;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.modules.utils.HandlerExecutor;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.hotspot2.PasspointManager;
+import com.android.server.wifi.scanner.WifiScannerInternal;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.wifi.resources.R;
import java.io.FileDescriptor;
@@ -148,6 +150,7 @@ public class WifiConnectivityManager {
private final WifiContext mContext;
private final WifiConfigManager mConfigManager;
+ private final WifiCarrierInfoManager mWifiCarrierInfoManager;
private final WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
private final WifiConnectivityHelper mConnectivityHelper;
private final WifiNetworkSelector mNetworkSelector;
@@ -155,7 +158,7 @@ public class WifiConnectivityManager {
private final OpenNetworkNotifier mOpenNetworkNotifier;
private final WifiMetrics mWifiMetrics;
private final AlarmManager mAlarmManager;
- private final Handler mEventHandler;
+ private final RunnerHandler mEventHandler;
private final ExternalPnoScanRequestManager mExternalPnoScanRequestManager;
private final @NonNull SsidTranslator mSsidTranslator;
private final Clock mClock;
@@ -175,8 +178,9 @@ public class WifiConnectivityManager {
private final DeviceConfigFacade mDeviceConfigFacade;
private final ActiveModeWarden mActiveModeWarden;
private final FrameworkFacade mFrameworkFacade;
+ private final WifiPermissionsUtil mWifiPermissionsUtil;
- private WifiScanner mScanner;
+ private WifiScannerInternal mScanner;
private final MultiInternetManager mMultiInternetManager;
private boolean mDbg = false;
private boolean mVerboseLoggingEnabled = false;
@@ -320,8 +324,9 @@ public class WifiConnectivityManager {
settings.channels[index++] = new WifiScanner.ChannelSpec(freq);
}
SingleScanListener singleScanListener = new SingleScanListener(false);
- mScanner.startScan(settings, new HandlerExecutor(mEventHandler),
- singleScanListener, WIFI_WORK_SOURCE);
+ mScanner.startScan(settings,
+ new WifiScannerInternal.ScanListener(singleScanListener,
+ mEventHandler));
mWifiMetrics.incrementConnectivityOneshotScanCount();
}
};
@@ -375,7 +380,7 @@ public class WifiConnectivityManager {
// a different band with the primary.
return false;
}
- final WifiInfo primaryInfo = primaryCcm.syncRequestConnectionInfo();
+ final WifiInfo primaryInfo = primaryCcm.getConnectionInfo();
final int primaryBand = ScanResult.toBand(primaryInfo.getFrequency());
List<WifiCandidates.Candidate> secondaryCmmCandidates;
@@ -394,11 +399,20 @@ public class WifiConnectivityManager {
&& c.getKey().securityType == primaryInfo.getCurrentSecurityType();
}).collect(Collectors.toList());
}
+ // Filter by specified BSSIDs
+ Map<Integer, String> specifiedBssids = mMultiInternetManager.getSpecifiedBssids();
+ List<WifiCandidates.Candidate> preferredSecondaryCandidates =
+ secondaryCmmCandidates.stream().filter(c -> {
+ final int band = ScanResult.toBand(c.getFrequency());
+ return specifiedBssids.containsKey(band) && specifiedBssids.get(band).equals(
+ c.getKey().bssid.toString());
+ }).collect(Collectors.toList());
// Perform network selection among secondary candidates. Create a new copy. Do not allow
// user choice override.
final WifiConfiguration secondaryCmmCandidate =
- mNetworkSelector.selectNetwork(secondaryCmmCandidates,
- false /* overrideEnabled */);
+ mNetworkSelector.selectNetwork(preferredSecondaryCandidates.isEmpty()
+ ? secondaryCmmCandidates : preferredSecondaryCandidates,
+ false /* overrideEnabled */);
// No secondary cmm for internet selected, fallback to legacy flow.
if (secondaryCmmCandidate == null
@@ -411,6 +425,16 @@ public class WifiConnectivityManager {
localLog(listenerName + ":secondaryCmmCandidate "
+ secondaryCmmCandidate.getNetworkSelectionStatus().getCandidate().SSID + " / "
+ secondaryCmmCandidate.getNetworkSelectionStatus().getCandidate().BSSID);
+ // Check if secondary candidate is the same SSID and network id with primary.
+ final boolean isDbsAp = TextUtils.equals(primaryInfo.getSSID(),
+ secondaryCmmCandidate.SSID) && (primaryInfo.getNetworkId()
+ == secondaryCmmCandidate.networkId);
+ final boolean isUsingStaticIp =
+ (secondaryCmmCandidate.getIpAssignment() == IpConfiguration.IpAssignment.STATIC);
+ if (isDbsAp && isUsingStaticIp) {
+ localLog(listenerName + ": Can't connect to DBS AP with Static IP.");
+ return false;
+ }
// At this point secondaryCmmCandidate must be multi internet.
final WorkSource secondaryRequestorWs = mMultiInternetConnectionRequestorWs;
@@ -459,10 +483,6 @@ public class WifiConnectivityManager {
// Set the concrete client mode manager to secondary internet usage.
ConcreteClientModeManager ccm = (ConcreteClientModeManager) cm;
ccm.setSecondaryInternet(true);
- // Check if secondary candidate is the same SSID and network Id with primary.
- final boolean isDbsAp = TextUtils.equals(primaryInfo.getSSID(),
- secondaryCmmCandidate.SSID) && (primaryInfo.getNetworkId()
- == secondaryCmmCandidate.networkId);
ccm.setSecondaryInternetDbsAp(isDbsAp);
localLog(listenerName + ": WNS candidate(secondary)-"
+ secondaryCmmCandidate.SSID + " / "
@@ -471,7 +491,6 @@ public class WifiConnectivityManager {
// Secondary candidate cannot be null (otherwise we would have switched to
// legacy flow above). Use the explicit bssid for network connection.
WifiConfiguration targetNetwork = new WifiConfiguration(secondaryCmmCandidate);
- targetNetwork.dbsSecondaryInternet = isDbsAp;
targetNetwork.ephemeral = true;
targetNetwork.BSSID = targetBssid2; // specify the BSSID to disable roaming.
connectToNetworkUsingCmmWithoutMbb(cm, targetNetwork);
@@ -503,7 +522,7 @@ public class WifiConnectivityManager {
mWifiChannelUtilization.refreshChannelStatsAndChannelUtilization(
clientModeManager.getWifiLinkLayerStats(),
WifiChannelUtilization.UNKNOWN_FREQ);
- WifiInfo wifiInfo = clientModeManager.syncRequestConnectionInfo();
+ WifiInfo wifiInfo = clientModeManager.getConnectionInfo();
if (clientModeManager.isConnected()) {
connectedSsids.add(wifiInfo.getSSID());
}
@@ -722,6 +741,16 @@ public class WifiConnectivityManager {
WifiConfiguration candidate = mNetworkSelector.selectNetwork(candidates);
if (candidate != null) {
localLog(listenerName + ": WNS candidate-" + candidate.SSID);
+ if (hasMultiInternetConnection()) {
+ // Disconnect secondary cmm first before connecting the primary.
+ final ConcreteClientModeManager secondaryCcm = mActiveModeWarden
+ .getClientModeManagerInRole(ROLE_CLIENT_SECONDARY_LONG_LIVED);
+ if (secondaryCcm != null && isClientModeManagerConnectedOrConnectingToCandidate(
+ secondaryCcm, candidate)) {
+ localLog("Disconnect secondary first.");
+ secondaryCcm.disconnect();
+ }
+ }
connectToNetworkForPrimaryCmmUsingMbbIfAvailable(candidate);
handleScanResultsWithCandidate(handleScanResultsListener);
} else {
@@ -843,7 +872,7 @@ public class WifiConnectivityManager {
@Override
public void onFailure(int reason, String description) {
localLog("registerScanListener onFailure:"
- + " reason: " + reason + " description: " + description);
+ + " reason: " + reason + " description: " + description);
}
@Override
@@ -958,7 +987,8 @@ public class WifiConnectivityManager {
}
}
- private final AllSingleScanListener mAllSingleScanListener = new AllSingleScanListener();
+ private final AllSingleScanListener mAllSingleScanListener;
+ private final WifiScannerInternal.ScanListener mInternalAllSingleScanListener;
// Single scan results listener. A single scan is initiated when
// DisconnectedPNO scan found a valid network and woke up
@@ -1112,7 +1142,8 @@ public class WifiConnectivityManager {
}
}
- private final PnoScanListener mPnoScanListener = new PnoScanListener();
+ private final PnoScanListener mPnoScanListener;
+ private final WifiScannerInternal.ScanListener mInternalPnoScanListener;
private class OnNetworkUpdateListener implements
WifiConfigManager.OnNetworkUpdateListener {
@@ -1219,7 +1250,7 @@ public class WifiConnectivityManager {
WifiLastResortWatchdog wifiLastResortWatchdog,
OpenNetworkNotifier openNetworkNotifier,
WifiMetrics wifiMetrics,
- Handler handler,
+ RunnerHandler handler,
Clock clock,
LocalLog localLog,
WifiScoreCard scoreCard,
@@ -1232,7 +1263,9 @@ public class WifiConnectivityManager {
FrameworkFacade frameworkFacade,
WifiGlobals wifiGlobals,
ExternalPnoScanRequestManager externalPnoScanRequestManager,
- @NonNull SsidTranslator ssidTranslator) {
+ @NonNull SsidTranslator ssidTranslator,
+ WifiPermissionsUtil wifiPermissionsUtil,
+ WifiCarrierInfoManager wifiCarrierInfoManager) {
mContext = context;
mScoringParams = scoringParams;
mConfigManager = configManager;
@@ -1259,6 +1292,8 @@ public class WifiConnectivityManager {
mPowerManager = mContext.getSystemService(PowerManager.class);
mExternalPnoScanRequestManager = externalPnoScanRequestManager;
mSsidTranslator = ssidTranslator;
+ mWifiPermissionsUtil = wifiPermissionsUtil;
+ mWifiCarrierInfoManager = wifiCarrierInfoManager;
// Listen for screen state change events.
// TODO: We should probably add a shared broadcast receiver in the wifi stack which
@@ -1282,7 +1317,7 @@ public class WifiConnectivityManager {
handleScreenStateChanged(mPowerManager.isInteractive());
// Listen to WifiConfigManager network update events
- mEventHandler.postAtFrontOfQueue(() ->
+ mEventHandler.postToFront(() ->
mConfigManager.addOnNetworkUpdateListener(new OnNetworkUpdateListener()));
// Listen to WifiNetworkSuggestionsManager suggestion update events
mWifiNetworkSuggestionsManager.addOnSuggestionUpdateListener(
@@ -1290,11 +1325,17 @@ public class WifiConnectivityManager {
mActiveModeWarden.registerModeChangeCallback(new ModeChangeCallback());
mMultiInternetManager.setConnectionStatusListener(
new InternalMultiInternetConnectionStatusListener());
+ mAllSingleScanListener = new AllSingleScanListener();
+ mInternalAllSingleScanListener = new WifiScannerInternal.ScanListener(
+ mAllSingleScanListener, mEventHandler);
+ mPnoScanListener = new PnoScanListener();
+ mInternalPnoScanListener = new WifiScannerInternal.ScanListener(mPnoScanListener,
+ mEventHandler);
}
@NonNull
private WifiInfo getPrimaryWifiInfo() {
- return getPrimaryClientModeManager().syncRequestConnectionInfo();
+ return getPrimaryClientModeManager().getConnectionInfo();
}
private ClientModeManager getPrimaryClientModeManager() {
@@ -2046,8 +2087,8 @@ public class WifiConnectivityManager {
SingleScanListener singleScanListener =
new SingleScanListener(isFullBandScan);
- mScanner.startScan(
- settings, new HandlerExecutor(mEventHandler), singleScanListener, workSource);
+ mScanner.startScan(settings,
+ new WifiScannerInternal.ScanListener(singleScanListener, mEventHandler));
mWifiMetrics.incrementConnectivityOneshotScanCount();
}
@@ -2101,6 +2142,10 @@ public class WifiConnectivityManager {
mNetworkSelector.setSufficiencyCheckEnabled(
nsConfig.isSufficiencyCheckEnabledWhenScreenOff(),
nsConfig.isSufficiencyCheckEnabledWhenScreenOn());
+ mNetworkSelector.setUserConnectChoiceOverrideEnabled(
+ nsConfig.isUserConnectChoiceOverrideEnabled());
+ mNetworkSelector.setLastSelectionWeightEnabled(
+ nsConfig.isLastSelectionWeightEnabled());
}
/**
@@ -2187,8 +2232,8 @@ public class WifiConnectivityManager {
scanSettings.numBssidsPerScan = 0;
scanSettings.periodInMs = deviceMobilityStateToPnoScanIntervalMs(mDeviceMobilityState);
- mScanner.startDisconnectedPnoScan(
- scanSettings, pnoSettings, new HandlerExecutor(mEventHandler), mPnoScanListener);
+ pnoSettings.isConnected = false;
+ mScanner.startPnoScan(scanSettings, pnoSettings, mInternalPnoScanListener);
mPnoScanStarted = true;
mWifiMetrics.logPnoScanStart();
}
@@ -2202,7 +2247,12 @@ public class WifiConnectivityManager {
|| (!config.ephemeral && !config.getNetworkSelectionStatus().hasEverConnected())
|| !config.getNetworkSelectionStatus().isNetworkEnabled()
|| mConfigManager.isNetworkTemporarilyDisabledByUser(
- config.isPasspoint() ? config.FQDN : config.SSID));
+ config.isPasspoint() ? config.FQDN : config.SSID)
+ || (config.enterpriseConfig != null
+ && config.enterpriseConfig.isAuthenticationSimBased()
+ && config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID)
+ && !mWifiCarrierInfoManager.isSimReady(
+ mWifiCarrierInfoManager.getBestMatchSubscriptionId(config)));
return networks;
}
@@ -2309,7 +2359,7 @@ public class WifiConnectivityManager {
private void stopPnoScan() {
if (!mPnoScanStarted) return;
- mScanner.stopPnoScan(mPnoScanListener);
+ mScanner.stopPnoScan(mInternalPnoScanListener);
mPnoScanStarted = false;
mWifiMetrics.logPnoScanStop();
}
@@ -2775,7 +2825,8 @@ public class WifiConnectivityManager {
mOpenNetworkNotifier.handleConnectionFailure();
// Only attempt to reconnect when connection on the primary CMM fails, since MBB
// CMM will be destroyed after the connection failure.
- if (clientModeManager.getRole() == ROLE_CLIENT_PRIMARY) {
+ if (clientModeManager.getRole() == ROLE_CLIENT_PRIMARY
+ && !mWifiPermissionsUtil.isAdminRestrictedNetwork(config)) {
retryConnectionOnLatestCandidates(clientModeManager, bssid, config,
failureCode == FAILURE_AUTHENTICATION_FAILURE
&& failureReason == AUTH_FAILURE_EAP_FAILURE);
@@ -2987,10 +3038,10 @@ public class WifiConnectivityManager {
*/
private void retrieveWifiScanner() {
if (mScanner != null) return;
- mScanner = Objects.requireNonNull(mContext.getSystemService(WifiScanner.class),
+ mScanner = Objects.requireNonNull(WifiLocalServices.getService(WifiScannerInternal.class),
"Got a null instance of WifiScanner!");
// Register for all single scan results
- mScanner.registerScanListener(new HandlerExecutor(mEventHandler), mAllSingleScanListener);
+ mScanner.registerScanListener(mInternalAllSingleScanListener);
}
/**
diff --git a/service/java/com/android/server/wifi/WifiCountryCode.java b/service/java/com/android/server/wifi/WifiCountryCode.java
index d9aed9bc67..b64066d7b6 100644
--- a/service/java/com/android/server/wifi/WifiCountryCode.java
+++ b/service/java/com/android/server/wifi/WifiCountryCode.java
@@ -461,7 +461,7 @@ public class WifiCountryCode {
if (!cmm.isConnected()) {
continue;
}
- WifiInfo wifiInfo = cmm.syncRequestConnectionInfo();
+ WifiInfo wifiInfo = cmm.getConnectionInfo();
if (wifiInfo.getSuccessfulTxPacketsPerSecond() < PKT_COUNT_HIGH_PKT_PER_SEC
&& wifiInfo.getSuccessfulRxPacketsPerSecond() < PKT_COUNT_HIGH_PKT_PER_SEC) {
return true;
diff --git a/service/java/com/android/server/wifi/WifiDialogManager.java b/service/java/com/android/server/wifi/WifiDialogManager.java
index 1048570aba..73e5c5c39e 100644
--- a/service/java/com/android/server/wifi/WifiDialogManager.java
+++ b/service/java/com/android/server/wifi/WifiDialogManager.java
@@ -16,6 +16,7 @@
package com.android.server.wifi;
+import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
@@ -331,7 +332,8 @@ public class WifiDialogManager {
mActiveDialogIds.add(mDialogId);
mActiveDialogHandles.put(mDialogId, this);
if (mVerboseLoggingEnabled) {
- Log.v(TAG, "Registered dialog with id=" + mDialogId);
+ Log.v(TAG, "Registered dialog with id=" + mDialogId
+ + ". Active dialogs ids: " + mActiveDialogIds);
}
}
@@ -347,15 +349,28 @@ public class WifiDialogManager {
mActiveDialogIds.remove(mDialogId);
mActiveDialogHandles.remove(mDialogId);
if (mVerboseLoggingEnabled) {
- Log.v(TAG, "Unregistered dialog with id=" + mDialogId);
+ Log.v(TAG, "Unregistered dialog with id=" + mDialogId
+ + ". Active dialogs ids: " + mActiveDialogIds);
}
mDialogId = WifiManager.INVALID_DIALOG_ID;
+ if (mActiveDialogIds.isEmpty()) {
+ String wifiDialogApkPkgName = mContext.getWifiDialogApkPkgName();
+ if (wifiDialogApkPkgName == null) {
+ Log.wtf(TAG, "Could not get WifiDialog APK package name to force stop!");
+ return;
+ }
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Force stopping WifiDialog app");
+ }
+ mContext.getSystemService(ActivityManager.class)
+ .forceStopPackage(wifiDialogApkPkgName);
+ }
}
}
private class SimpleDialogHandle extends DialogHandleInternal {
- private @NonNull SimpleDialogCallback mCallback;
- private @NonNull WifiThreadRunner mCallbackThreadRunner;
+ @Nullable private final SimpleDialogCallback mCallback;
+ @Nullable private final WifiThreadRunner mCallbackThreadRunner;
SimpleDialogHandle(
final String title,
@@ -366,8 +381,8 @@ public class WifiDialogManager {
final String positiveButtonText,
final String negativeButtonText,
final String neutralButtonText,
- @NonNull SimpleDialogCallback callback,
- @NonNull WifiThreadRunner callbackThreadRunner) throws IllegalArgumentException {
+ @Nullable final SimpleDialogCallback callback,
+ @Nullable final WifiThreadRunner callbackThreadRunner) {
Intent intent = getBaseLaunchIntent(WifiManager.DIALOG_TYPE_SIMPLE);
if (intent != null) {
intent.putExtra(WifiManager.EXTRA_DIALOG_TITLE, title)
@@ -381,45 +396,35 @@ public class WifiDialogManager {
setIntent(intent);
}
setDisplayId(Display.DEFAULT_DISPLAY);
- if (messageUrl != null) {
- if (message == null) {
- throw new IllegalArgumentException("Cannot set span for null message!");
- }
- if (messageUrlStart < 0) {
- throw new IllegalArgumentException("Span start cannot be less than 0!");
- }
- if (messageUrlEnd > message.length()) {
- throw new IllegalArgumentException("Span end index " + messageUrlEnd
- + " cannot be greater than message length " + message.length() + "!");
- }
- }
- if (callback == null) {
- throw new IllegalArgumentException("Callback cannot be null!");
- }
- if (callbackThreadRunner == null) {
- throw new IllegalArgumentException("Callback thread runner cannot be null!");
- }
mCallback = callback;
mCallbackThreadRunner = callbackThreadRunner;
}
void notifyOnPositiveButtonClicked() {
- mCallbackThreadRunner.post(() -> mCallback.onPositiveButtonClicked());
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(mCallback::onPositiveButtonClicked);
+ }
unregisterDialog();
}
void notifyOnNegativeButtonClicked() {
- mCallbackThreadRunner.post(() -> mCallback.onNegativeButtonClicked());
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(mCallback::onNegativeButtonClicked);
+ }
unregisterDialog();
}
void notifyOnNeutralButtonClicked() {
- mCallbackThreadRunner.post(() -> mCallback.onNeutralButtonClicked());
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(mCallback::onNeutralButtonClicked);
+ }
unregisterDialog();
}
void notifyOnCancelled() {
- mCallbackThreadRunner.post(() -> mCallback.onCancelled());
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(mCallback::onCancelled);
+ }
unregisterDialog();
}
}
@@ -433,8 +438,8 @@ public class WifiDialogManager {
final String mPositiveButtonText;
final String mNegativeButtonText;
final String mNeutralButtonText;
- @NonNull SimpleDialogCallback mCallback;
- @NonNull WifiThreadRunner mCallbackThreadRunner;
+ @Nullable final SimpleDialogCallback mCallback;
+ @Nullable final WifiThreadRunner mCallbackThreadRunner;
private Runnable mTimeoutRunnable;
private AlertDialog mAlertDialog;
int mWindowType = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
@@ -449,42 +454,32 @@ public class WifiDialogManager {
final String positiveButtonText,
final String negativeButtonText,
final String neutralButtonText,
- @NonNull SimpleDialogCallback callback,
- @NonNull WifiThreadRunner callbackThreadRunner) throws IllegalArgumentException {
- if (messageUrl != null) {
- if (message == null) {
- throw new IllegalArgumentException("Cannot set span for null message!");
- }
- if (messageUrlStart < 0) {
- throw new IllegalArgumentException("Span start cannot be less than 0!");
- }
- if (messageUrlEnd > message.length()) {
- throw new IllegalArgumentException("Span end index " + messageUrlEnd
- + " cannot be greater than message length " + message.length() + "!");
- }
- }
- if (callback == null) {
- throw new IllegalArgumentException("Callback cannot be null!");
- }
- if (callbackThreadRunner == null) {
- throw new IllegalArgumentException("Callback thread runner cannot be null!");
- }
+ @Nullable final SimpleDialogCallback callback,
+ @Nullable final WifiThreadRunner callbackThreadRunner) {
mTitle = title;
if (message != null) {
mMessage = new SpannableString(message);
- if (messageUrlStart >= 0 && messageUrlEnd <= message.length()
- && messageUrlStart < messageUrlEnd) {
- mMessage.setSpan(new URLSpan(messageUrl) {
- @Override
- public void onClick(@NonNull View widget) {
- Context c = widget.getContext();
- Intent openLinkIntent = new Intent(Intent.ACTION_VIEW)
- .setData(Uri.parse(messageUrl))
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .putExtra(Browser.EXTRA_APPLICATION_ID, c.getPackageName());
- c.startActivity(openLinkIntent);
- LegacySimpleDialogHandle.this.dismissDialog();
- }}, messageUrlStart, messageUrlEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ if (messageUrl != null) {
+ if (messageUrlStart < 0) {
+ Log.w(TAG, "Span start cannot be less than 0!");
+ } else if (messageUrlEnd > message.length()) {
+ Log.w(TAG, "Span end index " + messageUrlEnd + " cannot be greater than "
+ + "message length " + message.length() + "!");
+ } else if (messageUrlStart > messageUrlEnd) {
+ Log.w(TAG, "Span start index cannot be greater than end index!");
+ } else {
+ mMessage.setSpan(new URLSpan(messageUrl) {
+ @Override
+ public void onClick(@NonNull View widget) {
+ Context c = widget.getContext();
+ Intent openLinkIntent = new Intent(Intent.ACTION_VIEW)
+ .setData(Uri.parse(messageUrl))
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .putExtra(Browser.EXTRA_APPLICATION_ID, c.getPackageName());
+ c.startActivity(openLinkIntent);
+ LegacySimpleDialogHandle.this.dismissDialog();
+ }}, messageUrlStart, messageUrlEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
}
} else {
mMessage = null;
@@ -516,25 +511,33 @@ public class WifiDialogManager {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Positive button pressed for legacy simple dialog");
}
- mCallbackThreadRunner.post(mCallback::onPositiveButtonClicked);
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(mCallback::onPositiveButtonClicked);
+ }
})
.setNegativeButton(mNegativeButtonText, (dialogNegative, which) -> {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Negative button pressed for legacy simple dialog");
}
- mCallbackThreadRunner.post(mCallback::onNegativeButtonClicked);
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(mCallback::onNegativeButtonClicked);
+ }
})
.setNeutralButton(mNeutralButtonText, (dialogNeutral, which) -> {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Neutral button pressed for legacy simple dialog");
}
- mCallbackThreadRunner.post(mCallback::onNeutralButtonClicked);
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(mCallback::onNeutralButtonClicked);
+ }
})
.setOnCancelListener((dialogCancel) -> {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Legacy simple dialog cancelled.");
}
- mCallbackThreadRunner.post(mCallback::onCancelled);
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(mCallback::onCancelled);
+ }
})
.setOnDismissListener((dialogDismiss) -> {
mWifiThreadRunner.post(() -> {
@@ -634,7 +637,7 @@ public class WifiDialogManager {
* be created.
*/
@AnyThread
- @Nullable
+ @NonNull
public DialogHandle createSimpleDialog(
@Nullable String title,
@Nullable String message,
@@ -644,16 +647,16 @@ public class WifiDialogManager {
@NonNull SimpleDialogCallback callback,
@NonNull WifiThreadRunner callbackThreadRunner) {
return createSimpleDialogWithUrl(
- title,
- message,
- null /* messageUrl */,
- 0 /* messageUrlStart */,
- 0 /* messageUrlEnd */,
- positiveButtonText,
- negativeButtonText,
- neutralButtonText,
- callback,
- callbackThreadRunner);
+ title,
+ message,
+ null /* messageUrl */,
+ 0 /* messageUrlStart */,
+ 0 /* messageUrlEnd */,
+ positiveButtonText,
+ negativeButtonText,
+ neutralButtonText,
+ callback,
+ callbackThreadRunner);
}
/**
@@ -676,7 +679,7 @@ public class WifiDialogManager {
* be created.
*/
@AnyThread
- @Nullable
+ @NonNull
public DialogHandle createSimpleDialogWithUrl(
@Nullable String title,
@Nullable String message,
@@ -688,41 +691,36 @@ public class WifiDialogManager {
@Nullable String neutralButtonText,
@NonNull SimpleDialogCallback callback,
@NonNull WifiThreadRunner callbackThreadRunner) {
- try {
- if (SdkLevel.isAtLeastT()) {
- return new DialogHandle(
- new SimpleDialogHandle(
- title,
- message,
- messageUrl,
- messageUrlStart,
- messageUrlEnd,
- positiveButtonText,
- negativeButtonText,
- neutralButtonText,
- callback,
- callbackThreadRunner)
- );
- } else {
- // TODO(b/238353074): Remove this fallback to the legacy implementation once the
- // AlertDialog style on pre-T platform is fixed.
- return new DialogHandle(
- new LegacySimpleDialogHandle(
- title,
- message,
- messageUrl,
- messageUrlStart,
- messageUrlEnd,
- positiveButtonText,
- negativeButtonText,
- neutralButtonText,
- callback,
- callbackThreadRunner)
- );
- }
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Could not create DialogHandle for simple dialog: " + e);
- return null;
+ if (SdkLevel.isAtLeastT()) {
+ return new DialogHandle(
+ new SimpleDialogHandle(
+ title,
+ message,
+ messageUrl,
+ messageUrlStart,
+ messageUrlEnd,
+ positiveButtonText,
+ negativeButtonText,
+ neutralButtonText,
+ callback,
+ callbackThreadRunner)
+ );
+ } else {
+ // TODO(b/238353074): Remove this fallback to the legacy implementation once the
+ // AlertDialog style on pre-T platform is fixed.
+ return new DialogHandle(
+ new LegacySimpleDialogHandle(
+ title,
+ message,
+ messageUrl,
+ messageUrlStart,
+ messageUrlEnd,
+ positiveButtonText,
+ negativeButtonText,
+ neutralButtonText,
+ callback,
+ callbackThreadRunner)
+ );
}
}
@@ -741,7 +739,7 @@ public class WifiDialogManager {
* be created.
*/
@AnyThread
- @Nullable
+ @NonNull
public DialogHandle createLegacySimpleDialog(
@Nullable String title,
@Nullable String message,
@@ -783,7 +781,7 @@ public class WifiDialogManager {
* be created.
*/
@AnyThread
- @Nullable
+ @NonNull
public DialogHandle createLegacySimpleDialogWithUrl(
@Nullable String title,
@Nullable String message,
@@ -793,26 +791,21 @@ public class WifiDialogManager {
@Nullable String positiveButtonText,
@Nullable String negativeButtonText,
@Nullable String neutralButtonText,
- @NonNull SimpleDialogCallback callback,
- @NonNull WifiThreadRunner callbackThreadRunner) {
- try {
- return new DialogHandle(
- new LegacySimpleDialogHandle(
- title,
- message,
- messageUrl,
- messageUrlStart,
- messageUrlEnd,
- positiveButtonText,
- negativeButtonText,
- neutralButtonText,
- callback,
- callbackThreadRunner)
- );
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Could not create DialogHandle for simple dialog: " + e);
- return null;
- }
+ @Nullable SimpleDialogCallback callback,
+ @Nullable WifiThreadRunner callbackThreadRunner) {
+ return new DialogHandle(
+ new LegacySimpleDialogHandle(
+ title,
+ message,
+ messageUrl,
+ messageUrlStart,
+ messageUrlEnd,
+ positiveButtonText,
+ negativeButtonText,
+ neutralButtonText,
+ callback,
+ callbackThreadRunner)
+ );
}
/**
@@ -858,16 +851,16 @@ public class WifiDialogManager {
}
private class P2pInvitationReceivedDialogHandle extends DialogHandleInternal {
- private @NonNull P2pInvitationReceivedDialogCallback mCallback;
- private @NonNull WifiThreadRunner mCallbackThreadRunner;
+ @Nullable private final P2pInvitationReceivedDialogCallback mCallback;
+ @Nullable private final WifiThreadRunner mCallbackThreadRunner;
P2pInvitationReceivedDialogHandle(
- final @NonNull String deviceName,
+ final @Nullable String deviceName,
final boolean isPinRequested,
@Nullable String displayPin,
int displayId,
- @NonNull P2pInvitationReceivedDialogCallback callback,
- @NonNull WifiThreadRunner callbackThreadRunner) throws IllegalArgumentException {
+ @Nullable P2pInvitationReceivedDialogCallback callback,
+ @Nullable WifiThreadRunner callbackThreadRunner) {
Intent intent = getBaseLaunchIntent(WifiManager.DIALOG_TYPE_P2P_INVITATION_RECEIVED);
if (intent != null) {
intent.putExtra(WifiManager.EXTRA_P2P_DEVICE_NAME, deviceName)
@@ -876,26 +869,21 @@ public class WifiDialogManager {
setIntent(intent);
}
setDisplayId(displayId);
- if (deviceName == null) {
- throw new IllegalArgumentException("Device name cannot be null!");
- }
- if (callback == null) {
- throw new IllegalArgumentException("Callback cannot be null!");
- }
- if (callbackThreadRunner == null) {
- throw new IllegalArgumentException("Callback thread runner cannot be null!");
- }
mCallback = callback;
mCallbackThreadRunner = callbackThreadRunner;
}
void notifyOnAccepted(@Nullable String optionalPin) {
- mCallbackThreadRunner.post(() -> mCallback.onAccepted(optionalPin));
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(() -> mCallback.onAccepted(optionalPin));
+ }
unregisterDialog();
}
void notifyOnDeclined() {
- mCallbackThreadRunner.post(() -> mCallback.onDeclined());
+ if (mCallbackThreadRunner != null && mCallback != null) {
+ mCallbackThreadRunner.post(mCallback::onDeclined);
+ }
unregisterDialog();
}
}
@@ -932,27 +920,23 @@ public class WifiDialogManager {
* be created.
*/
@AnyThread
+ @NonNull
public DialogHandle createP2pInvitationReceivedDialog(
- @NonNull String deviceName,
+ @Nullable String deviceName,
boolean isPinRequested,
@Nullable String displayPin,
int displayId,
- @NonNull P2pInvitationReceivedDialogCallback callback,
- @NonNull WifiThreadRunner callbackThreadRunner) {
- try {
- return new DialogHandle(
- new P2pInvitationReceivedDialogHandle(
- deviceName,
- isPinRequested,
- displayPin,
- displayId,
- callback,
- callbackThreadRunner)
- );
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Could not create DialogHandle for P2P Invitation Received dialog: " + e);
- return null;
- }
+ @Nullable P2pInvitationReceivedDialogCallback callback,
+ @Nullable WifiThreadRunner callbackThreadRunner) {
+ return new DialogHandle(
+ new P2pInvitationReceivedDialogHandle(
+ deviceName,
+ isPinRequested,
+ displayPin,
+ displayId,
+ callback,
+ callbackThreadRunner)
+ );
}
/**
@@ -997,9 +981,9 @@ public class WifiDialogManager {
private class P2pInvitationSentDialogHandle extends DialogHandleInternal {
P2pInvitationSentDialogHandle(
- final @NonNull String deviceName,
- final @Nullable String displayPin,
- int displayId) throws IllegalArgumentException {
+ @Nullable final String deviceName,
+ @Nullable final String displayPin,
+ int displayId) {
Intent intent = getBaseLaunchIntent(WifiManager.DIALOG_TYPE_P2P_INVITATION_SENT);
if (intent != null) {
intent.putExtra(WifiManager.EXTRA_P2P_DEVICE_NAME, deviceName)
@@ -1007,9 +991,6 @@ public class WifiDialogManager {
setIntent(intent);
}
setDisplayId(displayId);
- if (deviceName == null) {
- throw new IllegalArgumentException("Device name cannot be null!");
- }
}
}
@@ -1023,16 +1004,12 @@ public class WifiDialogManager {
* be created.
*/
@AnyThread
+ @NonNull
public DialogHandle createP2pInvitationSentDialog(
- @NonNull String deviceName,
+ @Nullable String deviceName,
@Nullable String displayPin,
int displayId) {
- try {
- return new DialogHandle(new P2pInvitationSentDialogHandle(deviceName, displayPin,
- displayId));
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Could not create DialogHandle for P2P Invitation Sent dialog: " + e);
- return null;
- }
+ return new DialogHandle(new P2pInvitationSentDialogHandle(deviceName, displayPin,
+ displayId));
}
}
diff --git a/service/java/com/android/server/wifi/WifiHealthMonitor.java b/service/java/com/android/server/wifi/WifiHealthMonitor.java
index 8c56b12915..7c26902f00 100644
--- a/service/java/com/android/server/wifi/WifiHealthMonitor.java
+++ b/service/java/com/android/server/wifi/WifiHealthMonitor.java
@@ -33,7 +33,6 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.DeviceMobilityState;
import android.net.wifi.WifiScanner;
import android.os.Build;
-import android.os.Handler;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -45,6 +44,7 @@ import com.android.server.wifi.proto.WifiScoreCardProto.SystemInfoStats;
import com.android.server.wifi.proto.WifiStatsLog;
import com.android.server.wifi.proto.nano.WifiMetricsProto.HealthMonitorFailureStats;
import com.android.server.wifi.proto.nano.WifiMetricsProto.HealthMonitorMetrics;
+import com.android.server.wifi.scanner.WifiScannerInternal;
import com.google.protobuf.InvalidProtocolBufferException;
@@ -106,12 +106,12 @@ public class WifiHealthMonitor {
private final WifiScoreCard mWifiScoreCard;
private final Clock mClock;
private final AlarmManager mAlarmManager;
- private final Handler mHandler;
+ private final RunnerHandler mHandler;
private final WifiNative mWifiNative;
private final WifiInjector mWifiInjector;
private final DeviceConfigFacade mDeviceConfigFacade;
private final ActiveModeWarden mActiveModeWarden;
- private WifiScanner mScanner;
+ private WifiScannerInternal mScanner;
private MemoryStore mMemoryStore;
private boolean mWifiEnabled;
private WifiSystemInfoStats mWifiSystemInfoStats;
@@ -149,7 +149,7 @@ public class WifiHealthMonitor {
}
WifiHealthMonitor(Context context, WifiInjector wifiInjector, Clock clock,
- WifiConfigManager wifiConfigManager, WifiScoreCard wifiScoreCard, Handler handler,
+ WifiConfigManager wifiConfigManager, WifiScoreCard wifiScoreCard, RunnerHandler handler,
WifiNative wifiNative, String l2KeySeed, DeviceConfigFacade deviceConfigFacade,
ActiveModeWarden activeModeWarden) {
mContext = context;
@@ -164,7 +164,7 @@ public class WifiHealthMonitor {
mActiveModeWarden = activeModeWarden;
mWifiSystemInfoStats = new WifiSystemInfoStats(l2KeySeed);
mActiveModeWarden.registerModeChangeCallback(new ModeChangeCallback());
- mHandler.postAtFrontOfQueue(() -> mWifiConfigManager
+ mHandler.postToFront(() -> mWifiConfigManager
.addOnNetworkUpdateListener(new OnNetworkUpdateListener()));
}
@@ -267,10 +267,11 @@ public class WifiHealthMonitor {
*/
private void retrieveWifiScanner() {
if (mScanner != null) return;
- mScanner = mWifiInjector.getWifiScanner();
+ mScanner = WifiLocalServices.getService(WifiScannerInternal.class);
if (mScanner == null) return;
// Register for all single scan results
- mScanner.registerScanListener(new ScanListener());
+ mScanner.registerScanListener(
+ new WifiScannerInternal.ScanListener(new ScanListener(), mHandler));
}
/**
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index bf8f2ef061..c2afbd9cdd 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -183,6 +183,7 @@ public class WifiInjector {
private final WifiConnectivityHelper mWifiConnectivityHelper;
private final LocalLog mConnectivityLocalLog;
private final LocalLog mWifiAwareLocalLog;
+ private final LocalLog mWifiHandlerLocalLog;
private final ThroughputScorer mThroughputScorer;
private final WifiNetworkSelector mWifiNetworkSelector;
private final SavedNetworkNominator mSavedNetworkNominator;
@@ -266,7 +267,10 @@ public class WifiInjector {
mWifiHandlerThread = new HandlerThread("WifiHandlerThread");
mWifiHandlerThread.start();
Looper wifiLooper = mWifiHandlerThread.getLooper();
- Handler wifiHandler = new Handler(wifiLooper);
+ mWifiHandlerLocalLog = new LocalLog(128);
+ RunnerHandler wifiHandler = new RunnerHandler(wifiLooper, context.getResources().getInteger(
+ R.integer.config_wifiConfigurationWifiRunnerThresholdInMs),
+ mWifiHandlerLocalLog);
mWifiDiagnosticsHandlerThread = new HandlerThread("WifiDiagnostics");
mWifiDiagnosticsHandlerThread.start();
@@ -403,6 +407,7 @@ public class WifiInjector {
mContext.getSystemService(ActivityManager.class),
this, mWifiConfigManager,
mWifiPermissionsUtil, mWifiMetrics, mClock, wifiHandler, mSettingsConfigStore);
+ mWifiBlocklistMonitor.setScanRequestProxy(mScanRequestProxy);
mSarManager = new SarManager(mContext, makeTelephonyManager(), wifiLooper,
mWifiNative);
mWifiNetworkSelector = new WifiNetworkSelector(mContext, mWifiScoreCard, mScoringParams,
@@ -482,7 +487,8 @@ public class WifiInjector {
mClock, mConnectivityLocalLog, mWifiScoreCard, mWifiBlocklistMonitor,
mWifiChannelUtilizationScan, mPasspointManager, mMultiInternetManager,
mDeviceConfigFacade, mActiveModeWarden, mFrameworkFacade, mWifiGlobals,
- mExternalPnoScanRequestManager, mSsidTranslator);
+ mExternalPnoScanRequestManager, mSsidTranslator, mWifiPermissionsUtil,
+ mWifiCarrierInfoManager);
mMboOceController = new MboOceController(makeTelephonyManager(), mActiveModeWarden);
mCountryCode = new WifiCountryCode(mContext, mActiveModeWarden,
mCmiMonitor, mWifiNative, mSettingsConfigStore);
@@ -760,7 +766,8 @@ public class WifiInjector {
@NonNull ActiveModeManager.SoftApRole role,
boolean verboseLoggingEnabled) {
return new SoftApManager(mContext, mWifiHandlerThread.getLooper(), mFrameworkFacade,
- mWifiNative, mCoexManager, makeBatteryManager(), mInterfaceConflictManager,
+ mWifiNative, this,
+ mCoexManager, makeBatteryManager(), mInterfaceConflictManager,
listener, callback, mWifiApConfigStore,
config, mWifiMetrics, mSarManager, mWifiDiagnostics,
new SoftApNotifier(mContext, mFrameworkFacade, mWifiNotificationManager),
@@ -1169,6 +1176,11 @@ public class WifiInjector {
}
@NonNull
+ public LocalLog getWifiHandlerLocalLog() {
+ return mWifiHandlerLocalLog;
+ }
+
+ @NonNull
public WifiKeyStore getWifiKeyStore() {
return mWifiKeyStore;
}
diff --git a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
index 5a27899170..86228edded 100644
--- a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
+++ b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
@@ -184,7 +184,7 @@ public class WifiLastResortWatchdog {
if (activeModeWarden == null) return new WifiInfo();
// Cannot be null.
ClientModeManager primaryCmm = activeModeWarden.getPrimaryClientModeManager();
- return primaryCmm.syncRequestConnectionInfo();
+ return primaryCmm.getConnectionInfo();
}
/**
diff --git a/service/java/com/android/server/wifi/WifiLocalServices.java b/service/java/com/android/server/wifi/WifiLocalServices.java
new file mode 100644
index 0000000000..6702269904
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiLocalServices.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 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.ArrayMap;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * This class is used in a similar way as ServiceManager, except the services registered here
+ * are not Binder objects and are only available in the same process.
+ *
+ * Once all services are converted to the SystemService interface, this class can be absorbed
+ * into SystemServiceManager.
+ *
+ */
+public final class WifiLocalServices {
+ private WifiLocalServices() {}
+
+ private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
+ new ArrayMap<Class<?>, Object>();
+
+ /**
+ * Returns a local service instance that implements the specified interface.
+ *
+ * @param type The type of service.
+ * @return The service object.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T getService(Class<T> type) {
+ synchronized (sLocalServiceObjects) {
+ return (T) sLocalServiceObjects.get(type);
+ }
+ }
+
+ /**
+ * Adds a service instance of the specified interface to the global registry of local services.
+ */
+ public static <T> void addService(Class<T> type, T service) {
+ synchronized (sLocalServiceObjects) {
+ if (sLocalServiceObjects.containsKey(type)) {
+ throw new IllegalStateException("Overriding service registration");
+ }
+ sLocalServiceObjects.put(type, service);
+ }
+ }
+
+ /**
+ * Remove a service instance, must be only used in tests.
+ */
+ @VisibleForTesting
+ public static <T> void removeServiceForTest(Class<T> type) {
+ synchronized (sLocalServiceObjects) {
+ sLocalServiceObjects.remove(type);
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index 0fdb69b899..63b1eeb27a 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -41,6 +41,7 @@ import com.android.server.wifi.hotspot2.WnmData;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.security.cert.X509Certificate;
+import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -119,6 +120,9 @@ public class WifiMonitor {
public static final int QOS_POLICY_RESET_EVENT = BASE + 75;
public static final int QOS_POLICY_REQUEST_EVENT = BASE + 76;
+ /* MLO links change event */
+ public static final int MLO_LINKS_INFO_CHANGED = BASE + 77;
+
/* WPS config errrors */
private static final int CONFIG_MULTIPLE_PBC_DETECTED = 12;
private static final int CONFIG_AUTH_FAILURE = 18;
@@ -142,6 +146,13 @@ public class WifiMonitor {
@Retention(RetentionPolicy.SOURCE)
@interface TransitionDisableIndication{}
+ /* MLO links change event reason codes */
+ public enum MloLinkInfoChangeReason {
+ UNKNOWN,
+ TID_TO_LINK_MAP,
+ MULTI_LINK_RECONFIG_AP_REMOVAL,
+ }
+
/**
* Use this key to get the interface name of the message sent by WifiMonitor,
* or null if not available.
@@ -558,8 +569,22 @@ public class WifiMonitor {
*/
public void broadcastNetworkConnectionEvent(String iface, int networkId, boolean filsHlpSent,
WifiSsid ssid, String bssid) {
+ broadcastNetworkConnectionEvent(iface, networkId, filsHlpSent, ssid, bssid, null);
+ }
+
+ /**
+ * Broadcast the network connection event to all the handlers registered for this event.
+ *
+ * @param iface Name of iface on which this occurred.
+ * @param networkId ID of the network in wpa_supplicant.
+ * @param filsHlpSent Whether the connection used FILS.
+ * @param bssid BSSID of the access point.
+ * @param keyMgmtMask Current used key management mask.
+ */
+ public void broadcastNetworkConnectionEvent(String iface, int networkId, boolean filsHlpSent,
+ WifiSsid ssid, String bssid, BitSet keyMgmtMask) {
sendMessage(iface, NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(networkId, ssid, bssid, filsHlpSent));
+ new NetworkConnectionEventInfo(networkId, ssid, bssid, filsHlpSent, keyMgmtMask));
}
/**
@@ -663,4 +688,15 @@ public class WifiMonitor {
List<QosPolicyRequest> qosPolicyData) {
sendMessage(iface, QOS_POLICY_REQUEST_EVENT, qosPolicyRequestId, 0, qosPolicyData);
}
+
+ /**
+ * Broadcast the MLO link changes with reason code to all handlers registered for this event.
+ *
+ * @param iface Name of the iface on which this occurred.
+ * @param reason Reason code for the MLO link info change.
+ */
+ public void broadcastMloLinksInfoChanged(String iface,
+ WifiMonitor.MloLinkInfoChangeReason reason) {
+ sendMessage(iface, MLO_LINKS_INFO_CHANGED, reason);
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 1063f04f5e..cbaa2f2337 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -47,6 +47,7 @@ import android.net.wifi.nl80211.RadioChainInfo;
import android.net.wifi.nl80211.WifiNl80211Manager;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.SystemClock;
import android.os.WorkSource;
import android.text.TextUtils;
@@ -56,10 +57,12 @@ import android.util.Log;
import android.util.SparseArray;
import com.android.internal.annotations.Immutable;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.HexDump;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.SupplicantStaIfaceHal.QosPolicyStatus;
import com.android.server.wifi.hotspot2.NetworkDetail;
+import com.android.server.wifi.mockwifi.MockWifiServiceUtil;
import com.android.server.wifi.util.FrameParser;
import com.android.server.wifi.util.InformationElementUtil;
import com.android.server.wifi.util.NativeUtil;
@@ -76,6 +79,7 @@ import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -119,6 +123,7 @@ public class WifiNative {
private long mCachedFeatureSet;
private boolean mQosPolicyFeatureEnabled = false;
private final Map<String, String> mWifiCondIfacesForBridgedAp = new ArrayMap<>();
+ private MockWifiServiceUtil mMockWifiModem = null;
public WifiNative(WifiVendorHal vendorHal,
SupplicantStaIfaceHal staIfaceHal, HostapdHal hostapdHal,
@@ -278,6 +283,7 @@ public class WifiNative {
public NetworkObserverInternal networkObserver;
/** Interface feature set / capabilities */
public long featureSet;
+ public int bandsSupported;
public DeviceWiphyCapabilities phyCapabilities;
Iface(int id, @Iface.IfaceType int type) {
@@ -1158,27 +1164,6 @@ public class WifiNative {
void onDown(String ifaceName);
}
- private void initializeNwParamsForClientInterface(@NonNull String ifaceName) {
- try {
- // A runtime crash or shutting down AP mode can leave
- // IP addresses configured, and this affects
- // connectivity when supplicant starts up.
- // Ensure we have no IP addresses before a supplicant start.
- mNetdWrapper.clearInterfaceAddresses(ifaceName);
-
- // Set privacy extensions
- mNetdWrapper.setInterfaceIpv6PrivacyExtensions(ifaceName, true);
-
- // IPv6 is enabled only as long as access point is connected since:
- // - IPv6 addresses and routes stick around after disconnection
- // - kernel is unaware when connected and fails to start IPv6 negotiation
- // - kernel can start autoconfiguration when 802.1x is not complete
- mNetdWrapper.disableIpv6(ifaceName);
- } catch (IllegalStateException e) {
- Log.e(TAG, "Unable to change interface settings", e);
- }
- }
-
private void takeBugReportInterfaceFailureIfNeeded(String bugTitle, String bugDetail) {
if (mWifiInjector.getDeviceConfigFacade().isInterfaceFailureBugreportEnabled()) {
mWifiInjector.getWifiDiagnostics().takeBugReport(bugTitle, bugDetail);
@@ -1186,85 +1171,6 @@ public class WifiNative {
}
/**
- * Setup an interface for client mode (for connectivity) operations.
- *
- * This method configures an interface in STA mode in all the native daemons
- * (wificond, wpa_supplicant & vendor HAL).
- *
- * @param interfaceCallback Associated callback for notifying status changes for the iface.
- * @param requestorWs Requestor worksource.
- * @return Returns the name of the allocated interface, will be null on failure.
- */
- public String setupInterfaceForClientInConnectivityMode(
- @NonNull InterfaceCallback interfaceCallback, @NonNull WorkSource requestorWs) {
- synchronized (mLock) {
- if (!startHal()) {
- Log.e(TAG, "Failed to start Hal");
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
- return null;
- }
- if (!startSupplicant()) {
- Log.e(TAG, "Failed to start supplicant");
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
- return null;
- }
- Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY);
- if (iface == null) {
- Log.e(TAG, "Failed to allocate new STA iface");
- return null;
- }
- iface.externalListener = interfaceCallback;
- iface.name = createStaIface(iface, requestorWs);
- if (TextUtils.isEmpty(iface.name)) {
- Log.e(TAG, "Failed to create STA iface in vendor HAL");
- mIfaceMgr.removeIface(iface.id);
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
- return null;
- }
- if (!mWifiCondManager.setupInterfaceForClientMode(iface.name, Runnable::run,
- new NormalScanEventCallback(iface.name),
- new PnoScanEventCallback(iface.name))) {
- Log.e(TAG, "Failed to setup iface in wificond on " + iface);
- teardownInterface(iface.name);
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
- return null;
- }
- if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
- Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
- teardownInterface(iface.name);
- mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
- return null;
- }
- if (mContext.getResources().getBoolean(
- R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled)) {
- mQosPolicyFeatureEnabled = mSupplicantStaIfaceHal
- .setNetworkCentricQosPolicyFeatureEnabled(iface.name, true);
- if (!mQosPolicyFeatureEnabled) {
- Log.e(TAG, "Failed to enable QoS policy feature for iface " + iface.name);
- }
- }
- iface.networkObserver = new NetworkObserverInternal(iface.id);
- if (!registerNetworkObserver(iface.networkObserver)) {
- Log.e(TAG, "Failed to register network observer on " + iface);
- teardownInterface(iface.name);
- return null;
- }
- mWifiMonitor.startMonitoring(iface.name);
- // Just to avoid any race conditions with interface state change callbacks,
- // update the interface state before we exit.
- onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
- mWifiVendorHal.enableLinkLayerStats(iface.name);
- initializeNwParamsForClientInterface(iface.name);
- Log.i(TAG, "Successfully setup " + iface);
-
- iface.featureSet = getSupportedFeatureSetInternal(iface.name);
- saveCompleteFeatureSetInConfigStoreIfNecessary(iface.featureSet);
- mIsEnhancedOpenSupported = (iface.featureSet & WIFI_FEATURE_OWE) != 0;
- return iface.name;
- }
- }
-
- /**
* Setup an interface for client mode (for scan) operations.
*
* This method configures an interface in STA mode in the native daemons
@@ -1317,6 +1223,7 @@ public class WifiNative {
Log.i(TAG, "Successfully setup " + iface);
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
+ updateSupportedBandForStaInternal(iface);
return iface.name;
}
}
@@ -1404,6 +1311,7 @@ public class WifiNative {
Log.i(TAG, "Successfully setup " + iface);
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
+ updateSupportedBandForStaInternal(iface);
return iface.name;
}
}
@@ -1444,6 +1352,7 @@ public class WifiNative {
iface.type = Iface.IFACE_TYPE_STA_FOR_SCAN;
stopSupplicantIfNecessary();
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
+ updateSupportedBandForStaInternal(iface);
iface.phyCapabilities = null;
Log.i(TAG, "Successfully switched to scan mode on iface=" + iface);
return true;
@@ -1502,6 +1411,7 @@ public class WifiNative {
iface.type = Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY;
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
saveCompleteFeatureSetInConfigStoreIfNecessary(iface.featureSet);
+ updateSupportedBandForStaInternal(iface);
mIsEnhancedOpenSupported = (iface.featureSet & WIFI_FEATURE_OWE) != 0;
Log.i(TAG, "Successfully switched to connectivity mode on iface=" + iface);
return true;
@@ -2124,15 +2034,6 @@ public class WifiNative {
*
* @param interfaceName Name of the interface
*/
- public boolean isStaSetMacAddressSupported(@NonNull String interfaceName) {
- return mWifiVendorHal.isStaSetMacAddressSupported(interfaceName);
- }
-
- /**
- * Returns true if Hal version supports setMacAddress, otherwise false.
- *
- * @param interfaceName Name of the interface
- */
public boolean isApSetMacAddressSupported(@NonNull String interfaceName) {
return mWifiVendorHal.isApSetMacAddressSupported(interfaceName);
}
@@ -3203,7 +3104,7 @@ public class WifiNative {
@Override
public int hashCode() {
- return Objects.hash(ssid, flags, auth_bit_field, frequencies);
+ return Objects.hash(ssid, flags, auth_bit_field, Arrays.hashCode(frequencies));
}
android.net.wifi.nl80211.PnoNetwork toNativePnoNetwork() {
@@ -3524,6 +3425,22 @@ public class WifiNative {
}
/**
+ * Get the supported bands for STA mode.
+ * @return supported bands
+ */
+ public @WifiScanner.WifiBand int getSupportedBandsForSta(String ifaceName) {
+ synchronized (mLock) {
+ if (ifaceName != null) {
+ Iface iface = mIfaceMgr.getIface(ifaceName);
+ if (iface != null) {
+ return iface.bandsSupported;
+ }
+ }
+ return WifiScanner.WIFI_BAND_UNSPECIFIED;
+ }
+ }
+
+ /**
* Get the supported features
*
* @param ifaceName Name of the interface.
@@ -3544,6 +3461,47 @@ public class WifiNative {
return featureSet;
}
+ private void updateSupportedBandForStaInternal(Iface iface) {
+ List<WifiAvailableChannel> usableChannelList =
+ mWifiVendorHal.getUsableChannels(WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ,
+ WifiAvailableChannel.OP_MODE_STA,
+ WifiAvailableChannel.FILTER_REGULATORY);
+ int bands = 0;
+ if (usableChannelList == null) {
+ // If HAL doesn't support getUsableChannels then check wificond
+ if (getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ).length > 0) {
+ bands |= WifiScanner.WIFI_BAND_24_GHZ;
+ }
+ if (getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ).length > 0) {
+ bands |= WifiScanner.WIFI_BAND_5_GHZ;
+ }
+ if (getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ).length > 0) {
+ bands |= WifiScanner.WIFI_BAND_6_GHZ;
+ }
+ if (getChannelsForBand(WifiScanner.WIFI_BAND_60_GHZ).length > 0) {
+ bands |= WifiScanner.WIFI_BAND_60_GHZ;
+ }
+ } else {
+ for (int i = 0; i < usableChannelList.size(); i++) {
+ int frequency = usableChannelList.get(i).getFrequencyMhz();
+ if (ScanResult.is24GHz(frequency)) {
+ bands |= WifiScanner.WIFI_BAND_24_GHZ;
+ } else if (ScanResult.is5GHz(frequency)) {
+ bands |= WifiScanner.WIFI_BAND_5_GHZ;
+ } else if (ScanResult.is6GHz(frequency)) {
+ bands |= WifiScanner.WIFI_BAND_6_GHZ;
+ } else if (ScanResult.is60GHz(frequency)) {
+ bands |= WifiScanner.WIFI_BAND_60_GHZ;
+ }
+ }
+ }
+ if (mVerboseLoggingEnabled) {
+ Log.i(TAG, "updateSupportedBandForStaInternal " + iface.name + " : 0x"
+ + Integer.toHexString(bands));
+ }
+ iface.bandsSupported = bands;
+ }
+
/**
* Class to retrieve connection capability parameters after association
*/
@@ -3576,12 +3534,73 @@ public class WifiNative {
* Class to represent a connection MLO Link
*/
public static class ConnectionMloLink {
- public int linkId;
- public MacAddress staMacAddress;
-
- ConnectionMloLink() {
- // Nothing for now
+ private int mLinkId;
+ private MacAddress mStaMacAddress;
+ private BitSet mTidsUplinkMap;
+ private BitSet mTidsDownlinkMap;
+
+ ConnectionMloLink(int id, MacAddress mac, byte tidsUplink, byte tidsDownlink) {
+ mLinkId = id;
+ mStaMacAddress = mac;
+ mTidsDownlinkMap = BitSet.valueOf(new byte[] { tidsDownlink });
+ mTidsUplinkMap = BitSet.valueOf(new byte[] { tidsUplink });
};
+
+ /**
+ * Check if there is any TID mapped to this link in uplink of downlink direction.
+ *
+ * @return true if there is any TID mapped to this link, otherwise false.
+ */
+ public boolean isAnyTidMapped() {
+ if (mTidsDownlinkMap.isEmpty() && mTidsUplinkMap.isEmpty()) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Check if a TID is mapped to this link in uplink direction.
+ *
+ * @param tid TID value.
+ * @return true if the TID is mapped in uplink direction. Otherwise, false.
+ */
+ public boolean isTidMappedToUplink(byte tid) {
+ if (tid < mTidsUplinkMap.length()) {
+ return mTidsUplinkMap.get(tid);
+ }
+ return false;
+ }
+
+ /**
+ * Check if a TID is mapped to this link in downlink direction. Otherwise, false.
+ *
+ * @param tid TID value
+ * @return true if the TID is mapped in downlink direction. Otherwise, false.
+ */
+ public boolean isTidMappedtoDownlink(byte tid) {
+ if (tid < mTidsDownlinkMap.length()) {
+ return mTidsDownlinkMap.get(tid);
+ }
+ return false;
+ }
+
+ /**
+ * Get link id for the link.
+ *
+ * @return link id.
+ */
+ public int getLinkId() {
+ return mLinkId;
+ }
+
+ /**
+ * Get link address.
+ *
+ * @return link mac address.
+ */
+ public MacAddress getMacAddress() {
+ return mStaMacAddress;
+ }
}
/**
@@ -3737,11 +3756,11 @@ public class WifiNative {
}
public static class RingBufferStatus{
- String name;
- int flag;
- int ringBufferId;
- int ringBufferByteSize;
- int verboseLevel;
+ public String name;
+ public int flag;
+ public int ringBufferId;
+ public int ringBufferByteSize;
+ public int verboseLevel;
int writtenBytes;
int readBytes;
int writtenRecords;
@@ -3817,18 +3836,18 @@ public class WifiNative {
/* Packet fate API */
@Immutable
- abstract static class FateReport {
+ public abstract static class FateReport {
final static int USEC_PER_MSEC = 1000;
// The driver timestamp is a 32-bit counter, in microseconds. This field holds the
// maximal value of a driver timestamp in milliseconds.
final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
- final byte mFate;
- final long mDriverTimestampUSec;
- final byte mFrameType;
- final byte[] mFrameBytes;
- final long mEstimatedWallclockMSec;
+ public final byte mFate;
+ public final long mDriverTimestampUSec;
+ public final byte mFrameType;
+ public final byte[] mFrameBytes;
+ public final long mEstimatedWallclockMSec;
FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
mFate = fate;
@@ -3931,7 +3950,8 @@ public class WifiNative {
*/
@Immutable
public static final class TxFateReport extends FateReport {
- TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
+ public TxFateReport(byte fate, long driverTimestampUSec, byte frameType,
+ byte[] frameBytes) {
super(fate, driverTimestampUSec, frameType, frameBytes);
}
@@ -3974,7 +3994,8 @@ public class WifiNative {
*/
@Immutable
public static final class RxFateReport extends FateReport {
- RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
+ public RxFateReport(byte fate, long driverTimestampUSec, byte frameType,
+ byte[] frameBytes) {
super(fate, driverTimestampUSec, frameType, frameBytes);
}
@@ -4479,4 +4500,80 @@ public class WifiNative {
public boolean isSoftApInstanceDiedHandlerSupported() {
return mHostapdHal.isSoftApInstanceDiedHandlerSupported();
}
+
+ @VisibleForTesting
+ /** Checks if there are any STA (for connectivity) iface active. */
+ boolean hasAnyStaIfaceForConnectivity() {
+ return mIfaceMgr.hasAnyStaIfaceForConnectivity();
+ }
+
+ @VisibleForTesting
+ /** Checks if there are any STA (for scan) iface active. */
+ boolean hasAnyStaIfaceForScan() {
+ return mIfaceMgr.hasAnyStaIfaceForScan();
+ }
+
+ @VisibleForTesting
+ /** Checks if there are any AP iface active. */
+ boolean hasAnyApIface() {
+ return mIfaceMgr.hasAnyApIface();
+ }
+
+ @VisibleForTesting
+ /** Checks if there are any iface active. */
+ boolean hasAnyIface() {
+ return mIfaceMgr.hasAnyIface();
+ }
+
+ /**
+ * Sets or clean mock wifi service
+ *
+ * @param serviceName the service name of mock wifi service. When service name is empty, the
+ * framework will clean mock wifi service.
+ */
+ public void setMockWifiService(String serviceName) {
+ Log.d(TAG, "set MockWifiModemService to " + serviceName);
+ if (TextUtils.isEmpty(serviceName)) {
+ mMockWifiModem = null;
+ return;
+ }
+ mMockWifiModem = new MockWifiServiceUtil(mContext, serviceName);
+ if (mMockWifiModem == null) {
+ Log.e(TAG, "MockWifiServiceUtil creation failed.");
+ return;
+ }
+
+ // mock wifi modem service is set, try to bind all supported mock HAL services
+ mMockWifiModem.bindAllMockModemService();
+ for (int service = MockWifiServiceUtil.MIN_SERVICE_IDX;
+ service < MockWifiServiceUtil.NUM_SERVICES; service++) {
+ int retryCount = 0;
+ IBinder binder;
+ do {
+ binder = mMockWifiModem.getServiceBinder(service);
+ retryCount++;
+ if (binder == null) {
+ Log.d(TAG, "Retry(" + retryCount + ") for "
+ + mMockWifiModem.getModuleName(service));
+ try {
+ Thread.sleep(MockWifiServiceUtil.BINDER_RETRY_MILLIS);
+ } catch (InterruptedException e) {
+ }
+ }
+ } while ((binder == null) && (retryCount < MockWifiServiceUtil.BINDER_MAX_RETRY));
+
+ if (binder == null) {
+ Log.e(TAG, "Mock " + mMockWifiModem.getModuleName(service) + " bind fail");
+ }
+ }
+ }
+
+ /**
+ * Returns mock wifi service name.
+ */
+ public String getMockWifiServiceName() {
+ String serviceName = mMockWifiModem != null ? mMockWifiModem.getServiceName() : null;
+ Log.d(TAG, "getMockWifiServiceName - service name is " + serviceName);
+ return serviceName;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 02ab14bd60..3d650e6f0f 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -16,6 +16,9 @@
package com.android.server.wifi;
+import static android.net.wifi.WifiScanner.WIFI_BAND_ALL;
+import static android.net.wifi.WifiScanner.WIFI_BAND_UNSPECIFIED;
+
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_LOCAL_ONLY;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
@@ -165,6 +168,7 @@ public class WifiNetworkFactory extends NetworkFactory {
@Nullable private NetworkRequest mConnectedSpecificNetworkRequest;
@Nullable private WifiNetworkSpecifier mConnectedSpecificNetworkRequestSpecifier;
@Nullable private WifiConfiguration mUserSelectedNetwork;
+ private boolean mShouldHaveInternetCapabilities = false;
private Set<Integer> mConnectedUids = new ArraySet<>();
private int mUserSelectedNetworkConnectRetryCount;
// Map of bssid to latest scan results for all scan results matching a request. Will be
@@ -377,6 +381,10 @@ public class WifiNetworkFactory extends NetworkFactory {
mActiveModeWarden.removeClientModeManager(modeManager);
return;
}
+ if (modeManager != mClientModeManager) {
+ // If clientModeManager changes, teardown the current connection
+ removeClientModeManagerIfNecessary();
+ }
mClientModeManager = modeManager;
mClientModeManagerRole = modeManager.getRole();
if (mVerboseLoggingEnabled) {
@@ -711,7 +719,8 @@ public class WifiNetworkFactory extends NetworkFactory {
Log.e(TAG, "Requesting specific frequency bands is not yet supported. Rejecting");
return false;
}
- if (!WifiConfigurationUtil.validateNetworkSpecifier(wns)) {
+ if (!WifiConfigurationUtil.validateNetworkSpecifier(wns, mContext.getResources()
+ .getInteger(R.integer.config_wifiNetworkSpecifierMaxPreferredChannels))) {
Log.e(TAG, "Invalid wifi network specifier: " + wns + ". Rejecting ");
return false;
}
@@ -726,6 +735,8 @@ public class WifiNetworkFactory extends NetworkFactory {
@Override
public boolean acceptRequest(NetworkRequest networkRequest) {
NetworkSpecifier ns = networkRequest.getNetworkSpecifier();
+ boolean isFromSetting = mWifiPermissionsUtil.checkNetworkSettingsPermission(
+ networkRequest.getRequestorUid());
if (ns == null) {
// Generic wifi request. Always accept.
} else {
@@ -736,7 +747,8 @@ public class WifiNetworkFactory extends NetworkFactory {
}
// MultiInternet Request to be handled by MultiInternetWifiNetworkFactory.
if (mMultiInternetManager.isStaConcurrencyForMultiInternetEnabled()
- && MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(networkRequest)) {
+ && MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(networkRequest,
+ isFromSetting)) {
return false;
}
// Invalid request with wifi network specifier.
@@ -800,6 +812,8 @@ public class WifiNetworkFactory extends NetworkFactory {
@Override
protected void needNetworkFor(NetworkRequest networkRequest) {
NetworkSpecifier ns = networkRequest.getNetworkSpecifier();
+ boolean isFromSetting = mWifiPermissionsUtil.checkNetworkSettingsPermission(
+ networkRequest.getRequestorUid());
if (ns == null) {
// Generic wifi request. Turn on auto-join if necessary.
if (++mGenericConnectionReqCount == 1) {
@@ -813,7 +827,8 @@ public class WifiNetworkFactory extends NetworkFactory {
}
// MultiInternet Request to be handled by MultiInternetWifiNetworkFactory.
if (mMultiInternetManager.isStaConcurrencyForMultiInternetEnabled()
- && MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(networkRequest)) {
+ && MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(networkRequest,
+ isFromSetting)) {
return;
}
// Invalid request with wifi network specifier.
@@ -843,7 +858,7 @@ public class WifiNetworkFactory extends NetworkFactory {
WifiNetworkSpecifier wns = (WifiNetworkSpecifier) ns;
mActiveSpecificNetworkRequestSpecifier = new WifiNetworkSpecifier(
wns.ssidPatternMatcher, wns.bssidPatternMatcher, wns.getBand(),
- wns.wifiConfiguration);
+ wns.wifiConfiguration, wns.getPreferredChannelFrequenciesMhz());
mSkipUserDialogue = false;
mWifiMetrics.incrementNetworkRequestApiNumRequest();
@@ -994,6 +1009,14 @@ public class WifiNetworkFactory extends NetworkFactory {
return Collections.emptySet();
}
+ /**
+ * Return whether if current network request should have the internet capabilities due to a
+ * same saved/suggestion network is present.
+ */
+ public boolean shouldHaveInternetCapabilities() {
+ return mShouldHaveInternetCapabilities;
+ }
+
// Helper method to add the provided network configuration to WifiConfigManager, if it does not
// already exist & return the allocated network ID. This ID will be used in the CONNECT_NETWORK
// request to ClientModeImpl.
@@ -1114,12 +1137,30 @@ public class WifiNetworkFactory extends NetworkFactory {
Log.v(TAG,
"Requesting new ClientModeManager instance - didUserSeeUi = " + didUserSeeUi);
}
+ mShouldHaveInternetCapabilities = false;
+ ClientModeManagerRequestListener listener = new ClientModeManagerRequestListener();
+ if (mWifiPermissionsUtil.checkEnterCarModePrioritized(mActiveSpecificNetworkRequest
+ .getRequestorUid())) {
+ mShouldHaveInternetCapabilities = hasNetworkForInternet(mUserSelectedNetwork);
+ if (mShouldHaveInternetCapabilities) {
+ listener.onAnswer(mActiveModeWarden.getPrimaryClientModeManager());
+ return;
+ }
+ }
WorkSource ws = new WorkSource(mActiveSpecificNetworkRequest.getRequestorUid(),
mActiveSpecificNetworkRequest.getRequestorPackageName());
mActiveModeWarden.requestLocalOnlyClientModeManager(new ClientModeManagerRequestListener(),
ws, networkToConnect.SSID, networkToConnect.BSSID, didUserSeeUi);
}
+ private boolean hasNetworkForInternet(WifiConfiguration network) {
+ List<WifiConfiguration> networks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
+ return networks.stream().anyMatch(a -> Objects.equals(a.SSID, network.SSID)
+ && !WifiConfigurationUtil.hasCredentialChanged(a, network)
+ && !a.fromWifiNetworkSpecifier
+ && !a.noInternetAccessExpected);
+ }
+
private void handleConnectToNetworkUserSelection(WifiConfiguration network,
boolean didUserSeeUi) {
Log.d(TAG, "User initiated connect to network: " + network.SSID);
@@ -1278,7 +1319,6 @@ public class WifiNetworkFactory extends NetworkFactory {
mActiveSpecificNetworkRequest = null;
mActiveSpecificNetworkRequestSpecifier = null;
mSkipUserDialogue = false;
- mUserSelectedNetwork = null;
mUserSelectedNetworkConnectRetryCount = 0;
mIsPeriodicScanEnabled = false;
mIsPeriodicScanPaused = false;
@@ -1493,8 +1533,20 @@ public class WifiNetworkFactory extends NetworkFactory {
mScanSettings.hiddenNetworks.add(new WifiScanner.ScanSettings.HiddenNetwork(
addEnclosingQuotes(wns.ssidPatternMatcher.getPath())));
}
+ int[] channelFreqs = wns.getPreferredChannelFrequenciesMhz();
+ if (channelFreqs.length > 0) {
+ int index = 0;
+ mScanSettings.channels = new WifiScanner.ChannelSpec[channelFreqs.length];
+ for (int freq : channelFreqs) {
+ mScanSettings.channels[index++] = new WifiScanner.ChannelSpec(freq);
+ }
+ mScanSettings.band = WIFI_BAND_UNSPECIFIED;
+ }
mIsPeriodicScanEnabled = true;
startScan();
+ // Clear the channel settings to perform a full band scan.
+ mScanSettings.channels = new WifiScanner.ChannelSpec[0];
+ mScanSettings.band = WIFI_BAND_ALL;
}
private void cancelPeriodicScans() {
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 06acf5f4a0..36cae2eac3 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -128,6 +128,8 @@ public class WifiNetworkSelector {
private boolean mIsEnhancedOpenSupported;
private boolean mSufficiencyCheckEnabledWhenScreenOff = true;
private boolean mSufficiencyCheckEnabledWhenScreenOn = true;
+ private boolean mUserConnectChoiceOverrideEnabled = true;
+ private boolean mLastSelectionWeightEnabled = true;
private @AssociatedNetworkSelectionOverride int mAssociatedNetworkSelectionOverride =
ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE;
private boolean mScreenOn = false;
@@ -319,7 +321,7 @@ public class WifiNetworkSelector {
}
// Metered networks costs the user data, so this is insufficient.
- if (network.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED) {
+ if (WifiConfiguration.isMetered(network, wifiInfo)) {
localLog("Current network is metered");
return false;
}
@@ -880,7 +882,7 @@ public class WifiNetworkSelector {
ifaceName = clientModeManager.getInterfaceName();
connected = clientModeManager.isConnected();
disconnected = clientModeManager.isDisconnected();
- wifiInfo = clientModeManager.syncRequestConnectionInfo();
+ wifiInfo = clientModeManager.getConnectionInfo();
}
ClientModeManagerState() {
@@ -968,6 +970,20 @@ public class WifiNetworkSelector {
}
/**
+ * Enable or disable candidate override with user connect choice.
+ */
+ public void setUserConnectChoiceOverrideEnabled(boolean enabled) {
+ mUserConnectChoiceOverrideEnabled = enabled;
+ }
+
+ /**
+ * Enable or disable last selection weight.
+ */
+ public void setLastSelectionWeightEnabled(boolean enabled) {
+ mLastSelectionWeightEnabled = enabled;
+ }
+
+ /**
* Returns the list of Candidates from networks in range.
*
* @param scanDetails List of ScanDetail for all the APs in range
@@ -1044,7 +1060,8 @@ public class WifiNetworkSelector {
cmmState.wifiInfo.getRssi(),
cmmState.wifiInfo.getFrequency(),
ScanResult.CHANNEL_WIDTH_20MHZ, // channel width not available in WifiInfo
- calculateLastSelectionWeight(currentNetwork.networkId),
+ calculateLastSelectionWeight(currentNetwork.networkId,
+ WifiConfiguration.isMetered(currentNetwork, cmmState.wifiInfo)),
WifiConfiguration.isMetered(currentNetwork, cmmState.wifiInfo),
isFromCarrierOrPrivilegedApp(currentNetwork),
predictedTputMbps);
@@ -1076,7 +1093,7 @@ public class WifiNetworkSelector {
scanDetail.getScanResult().level,
scanDetail.getScanResult().frequency,
scanDetail.getScanResult().channelWidth,
- calculateLastSelectionWeight(config.networkId),
+ calculateLastSelectionWeight(config.networkId, metered),
metered,
isFromCarrierOrPrivilegedApp(config),
predictThroughput(scanDetail));
@@ -1360,7 +1377,8 @@ public class WifiNetworkSelector {
// Get a fresh copy of WifiConfiguration reflecting any scan result updates
WifiConfiguration selectedNetwork =
mWifiConfigManager.getConfiguredNetwork(selectedNetworkId);
- if (selectedNetwork != null && legacyOverrideWanted && overrideEnabled) {
+ if (selectedNetwork != null && legacyOverrideWanted && overrideEnabled
+ && mUserConnectChoiceOverrideEnabled) {
selectedNetwork = overrideCandidateWithUserConnectChoice(selectedNetwork);
}
if (selectedNetwork != null) {
@@ -1423,11 +1441,16 @@ public class WifiNetworkSelector {
}
}
- private double calculateLastSelectionWeight(int networkId) {
- if (networkId != mWifiConfigManager.getLastSelectedNetwork()) return 0.0;
+ private double calculateLastSelectionWeight(int networkId, boolean isMetered) {
+ if (!mLastSelectionWeightEnabled
+ || networkId != mWifiConfigManager.getLastSelectedNetwork()) {
+ return 0.0;
+ }
double timeDifference = mClock.getElapsedSinceBootMillis()
- mWifiConfigManager.getLastSelectedTimeStamp();
- long millis = TimeUnit.MINUTES.toMillis(mScoringParams.getLastSelectionMinutes());
+ long millis = TimeUnit.MINUTES.toMillis(isMetered
+ ? mScoringParams.getLastMeteredSelectionMinutes()
+ : mScoringParams.getLastUnmeteredSelectionMinutes());
if (timeDifference >= millis) return 0.0;
double unclipped = 1.0 - (timeDifference / millis);
return Math.min(Math.max(unclipped, 0.0), 1.0);
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index 773393cf57..79087532fe 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -48,7 +48,6 @@ import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.os.Handler;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -161,7 +160,7 @@ public class WifiNetworkSuggestionsManager {
private final WifiContext mContext;
private final Resources mResources;
- private final Handler mHandler;
+ private final RunnerHandler mHandler;
private final AppOpsManager mAppOps;
private final ActivityManager mActivityManager;
private final WifiNotificationManager mNotificationManager;
@@ -659,7 +658,7 @@ public class WifiNetworkSuggestionsManager {
}
}
- public WifiNetworkSuggestionsManager(WifiContext context, Handler handler,
+ public WifiNetworkSuggestionsManager(WifiContext context, RunnerHandler handler,
WifiInjector wifiInjector, WifiPermissionsUtil wifiPermissionsUtil,
WifiConfigManager wifiConfigManager, WifiConfigStore wifiConfigStore,
WifiMetrics wifiMetrics, WifiCarrierInfoManager wifiCarrierInfoManager,
@@ -695,7 +694,7 @@ public class WifiNetworkSuggestionsManager {
mContext.registerReceiver(mBroadcastReceiver, mIntentFilter, null, handler);
mLruConnectionTracker = lruConnectionTracker;
- mHandler.postAtFrontOfQueue(() -> mWifiConfigManager.addOnNetworkUpdateListener(
+ mHandler.postToFront(() -> mWifiConfigManager.addOnNetworkUpdateListener(
new WifiNetworkSuggestionsManager.OnNetworkUpdateListener()));
}
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 7fcca1d8bd..57204b4938 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -210,6 +210,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
/**
* WifiService handles remote WiFi operation requests by implementing
@@ -852,6 +853,8 @@ public class WifiServiceImpl extends BaseWifiService {
try {
mWifiPermissionsUtil.enforceCanAccessScanResults(packageName, featureId, callingUid,
null);
+ mLastCallerInfoManager.put(WifiManager.API_START_SCAN, Process.myTid(),
+ callingUid, Binder.getCallingPid(), packageName, true);
Boolean scanSuccess = mWifiThreadRunner.call(() ->
mScanRequestProxy.startScan(callingUid, packageName), null);
if (scanSuccess == null) {
@@ -1144,6 +1147,14 @@ public class WifiServiceImpl extends BaseWifiService {
uid);
}
+ private boolean isPlatformOrTargetSdkLessThanU(String packageName, int uid) {
+ if (!SdkLevel.isAtLeastU()) {
+ return true;
+ }
+ return mWifiPermissionsUtil.isTargetSdkLessThan(packageName,
+ Build.VERSION_CODES.UPSIDE_DOWN_CAKE, uid);
+ }
+
/**
* Get the current primary ClientModeManager in a thread safe manner, but blocks on the main
* Wifi thread.
@@ -1247,8 +1258,7 @@ public class WifiServiceImpl extends BaseWifiService {
() -> mWifiConnectivityManager.setAutoJoinEnabledExternal(true, false));
mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_ON);
} else {
- WifiInfo wifiInfo =
- getPrimaryClientModeManagerBlockingThreadSafe().syncRequestConnectionInfo();
+ WifiInfo wifiInfo = mActiveModeWarden.getConnectionInfo();
mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_TOGGLE_WIFI_OFF,
wifiInfo == null ? -1 : wifiInfo.getNetworkId());
}
@@ -1361,8 +1371,7 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("restartWifiSubsystem uid=%").c(Binder.getCallingUid()).flush();
}
mWifiThreadRunner.post(() -> {
- WifiInfo wifiInfo =
- mActiveModeWarden.getPrimaryClientModeManager().syncRequestConnectionInfo();
+ WifiInfo wifiInfo = mActiveModeWarden.getConnectionInfo();
mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_RESTART_WIFI_SUB_SYSTEM,
wifiInfo == null ? -1 : wifiInfo.getNetworkId());
mWifiInjector.getSelfRecovery().trigger(REASON_API_CALL);
@@ -1487,6 +1496,24 @@ public class WifiServiceImpl extends BaseWifiService {
}
/**
+ * Check if input configuration is valid.
+ *
+ * Call this before calling {@link startTetheredHotspot(SoftApConfiguration)} or
+ * {@link #setSoftApConfiguration(softApConfiguration)} to avoid unexpected error duo to
+ * configuration is invalid.
+ *
+ * @param config a configuration would like to be checked.
+ * @return true if config is valid, otherwise false.
+ */
+ @Override
+ public boolean validateSoftApConfiguration(SoftApConfiguration config) {
+ int uid = Binder.getCallingUid();
+ boolean privileged = isSettingsOrSuw(Binder.getCallingPid(), uid);
+ return WifiApConfigStore.validateApWifiConfiguration(
+ config, privileged, mContext);
+ }
+
+ /**
* See {@link WifiManager#unregisterCoexCallback(WifiManager.CoexCallback)}
*/
@RequiresApi(Build.VERSION_CODES.S)
@@ -2496,6 +2523,8 @@ public class WifiServiceImpl extends BaseWifiService {
return LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
}
+ mLastCallerInfoManager.put(WifiManager.API_START_LOCAL_ONLY_HOTSPOT, Process.myTid(),
+ uid, Binder.getCallingPid(), packageName, true);
// the app should be in the foreground
long ident = Binder.clearCallingIdentity();
@@ -2661,10 +2690,9 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("getWifiApConfiguration uid=%").c(uid).flush();
}
- // hand off work to the ClientModeImpl handler thread to sync work between calls
- // and SoftApManager starting up softap
- return (mWifiThreadRunner.call(mWifiApConfigStore::getApConfiguration,
- new SoftApConfiguration.Builder().build())).toWifiConfiguration();
+ final SoftApConfiguration config = mWifiApConfigStore.getApConfiguration();
+ return config == null ? new SoftApConfiguration.Builder().build().toWifiConfiguration()
+ : config.toWifiConfiguration();
}
/**
@@ -2687,10 +2715,8 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("getSoftApConfiguration uid=%").c(uid).flush();
}
- // hand off work to the ClientModeImpl handler thread to sync work between calls
- // and SoftApManager starting up softap
- return mWifiThreadRunner.call(mWifiApConfigStore::getApConfiguration,
- new SoftApConfiguration.Builder().build());
+ final SoftApConfiguration config = mWifiApConfigStore.getApConfiguration();
+ return config == null ? new SoftApConfiguration.Builder().build() : config;
}
/**
@@ -2717,14 +2743,13 @@ public class WifiServiceImpl extends BaseWifiService {
return false;
SoftApConfiguration softApConfig = ApConfigUtil.fromWifiConfiguration(wifiConfig);
if (softApConfig == null) return false;
- if (WifiApConfigStore.validateApWifiConfiguration(
+ if (!WifiApConfigStore.validateApWifiConfiguration(
softApConfig, false, mContext)) {
- mWifiThreadRunner.post(() -> mWifiApConfigStore.setApConfiguration(softApConfig));
- return true;
- } else {
Log.e(TAG, "Invalid WifiConfiguration");
return false;
}
+ mWifiApConfigStore.setApConfiguration(softApConfig);
+ return true;
}
/**
@@ -2748,8 +2773,9 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("setSoftApConfiguration uid=%").c(uid).flush();
if (softApConfig == null) return false;
if (WifiApConfigStore.validateApWifiConfiguration(softApConfig, privileged, mContext)) {
+ mWifiApConfigStore.setApConfiguration(softApConfig);
+ // Send the message for AP config update after the save is done.
mActiveModeWarden.updateSoftApConfiguration(softApConfig);
- mWifiThreadRunner.post(() -> mWifiApConfigStore.setApConfiguration(softApConfig));
return true;
} else {
Log.e(TAG, "Invalid SoftAp Configuration");
@@ -3101,9 +3127,7 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("getPrivilegedConnectedNetwork uid=%").c(callingUid).flush();
}
- WifiInfo wifiInfo = mWifiThreadRunner.call(
- () -> mActiveModeWarden.getPrimaryClientModeManager().syncRequestConnectionInfo(),
- new WifiInfo());
+ WifiInfo wifiInfo = mActiveModeWarden.getConnectionInfo();
int networkId = wifiInfo.getNetworkId();
if (networkId < 0) {
if (mVerboseLoggingEnabled) {
@@ -3623,7 +3647,10 @@ public class WifiServiceImpl extends BaseWifiService {
Log.w(TAG, "Insecure Enterprise network " + config.SSID
+ " configured by Settings/SUW");
}
-
+ mLastCallerInfoManager.put(config.networkId < 0
+ ? WifiManager.API_ADD_NETWORK : WifiManager.API_UPDATE_NETWORK,
+ Process.myTid(), Binder.getCallingUid(),
+ Binder.getCallingPid(), packageName, true);
Log.i("addOrUpdateNetworkInternal", " uid = " + Binder.getCallingUid()
+ " SSID " + config.SSID
+ " nid=" + config.networkId);
@@ -3760,6 +3787,8 @@ public class WifiServiceImpl extends BaseWifiService {
return false;
}
+ mLastCallerInfoManager.put(WifiManager.API_ENABLE_NETWORK, Process.myTid(),
+ callingUid, Binder.getCallingPid(), packageName, disableOthers);
// TODO b/33807876 Log netId
mLog.info("enableNetwork uid=% disableOthers=%")
.c(callingUid)
@@ -3793,6 +3822,8 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("disableNetwork not allowed for uid=%").c(callingUid).flush();
return false;
}
+ mLastCallerInfoManager.put(WifiManager.API_DISABLE_NETWORK, Process.myTid(),
+ callingUid, Binder.getCallingPid(), packageName, true);
mLog.info("disableNetwork uid=%").c(callingUid).flush();
return mWifiThreadRunner.call(
() -> mWifiConfigManager.disableNetwork(netId, callingUid, packageName), false);
@@ -3936,6 +3967,8 @@ public class WifiServiceImpl extends BaseWifiService {
int callingUid = Binder.getCallingUid();
mLog.info("allowAutojoin=% uid=%").c(choice).c(callingUid).flush();
+ mLastCallerInfoManager.put(WifiManager.API_ALLOW_AUTOJOIN, Process.myTid(),
+ callingUid, Binder.getCallingPid(), "<unknown>", choice);
mWifiThreadRunner.post(() -> {
WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(netId);
if (config == null) {
@@ -4093,7 +4126,7 @@ public class WifiServiceImpl extends BaseWifiService {
WifiInfo wifiInfo = mWifiThreadRunner.call(
() -> getClientModeManagerIfSecondaryCmmRequestedByCallerPresent(
uid, callingPackage)
- .syncRequestConnectionInfo(), new WifiInfo());
+ .getConnectionInfo(), new WifiInfo());
long redactions = wifiInfo.getApplicableRedactions();
if (mWifiPermissionsUtil.checkLocalMacAddressPermission(uid)) {
if (mVerboseLoggingEnabled) {
@@ -4505,9 +4538,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (mContext.getResources().getBoolean(R.bool.config_wifi24ghzSupport)) {
return true;
}
- return mWifiThreadRunner.call(
- () -> mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ).length > 0,
- false);
+ return mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ);
}
@@ -4524,9 +4555,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (mContext.getResources().getBoolean(R.bool.config_wifi5ghzSupport)) {
return true;
}
- return mWifiThreadRunner.call(
- () -> mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ).length > 0,
- false);
+ return mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ);
}
@Override
@@ -4542,9 +4571,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (mContext.getResources().getBoolean(R.bool.config_wifi6ghzSupport)) {
return true;
}
- return mWifiThreadRunner.call(
- () -> mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ).length > 0,
- false);
+ return mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ);
}
@Override
@@ -4564,9 +4591,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (mContext.getResources().getBoolean(R.bool.config_wifi60ghzSupport)) {
return true;
}
- return mWifiThreadRunner.call(
- () -> mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_60_GHZ).length > 0,
- false);
+ return mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_60_GHZ);
}
@Override
@@ -5209,7 +5234,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("getCurrentNetwork uid=%").c(Binder.getCallingUid()).flush();
}
- return getPrimaryClientModeManagerBlockingThreadSafe().syncGetCurrentNetwork();
+ return mActiveModeWarden.getCurrentNetwork();
}
public static String toHexString(String s) {
@@ -5971,6 +5996,9 @@ public class WifiServiceImpl extends BaseWifiService {
throw new IllegalArgumentException("packageName must not be null");
}
mLog.info("connect uid=%").c(uid).flush();
+ mLastCallerInfoManager.put(config != null
+ ? WifiManager.API_CONNECT_CONFIG : WifiManager.API_CONNECT_NETWORK_ID,
+ Process.myTid(), uid, Binder.getCallingPid(), packageName, true);
mWifiThreadRunner.post(() -> {
ActionListenerWrapper wrapper = new ActionListenerWrapper(callback);
final NetworkUpdateResult result;
@@ -6070,6 +6098,8 @@ public class WifiServiceImpl extends BaseWifiService {
throw new IllegalArgumentException("packageName must not be null");
}
mLog.info("save uid=%").c(uid).flush();
+ mLastCallerInfoManager.put(WifiManager.API_SAVE, Process.myTid(),
+ uid, Binder.getCallingPid(), packageName, true);
mWifiThreadRunner.post(() -> {
ActionListenerWrapper wrapper = new ActionListenerWrapper(callback);
NetworkUpdateResult result =
@@ -6104,6 +6134,8 @@ public class WifiServiceImpl extends BaseWifiService {
// the netId becomes invalid after the forget operation.
mWifiMetrics.logUserActionEvent(UserActionEvent.EVENT_FORGET_WIFI, netId);
}
+ mLastCallerInfoManager.put(WifiManager.API_FORGET, Process.myTid(),
+ uid, Binder.getCallingPid(), "<unknown>", true);
mWifiThreadRunner.post(() -> {
WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(netId);
boolean success = mWifiConfigManager.removeNetwork(netId, uid, null);
@@ -6229,8 +6261,7 @@ public class WifiServiceImpl extends BaseWifiService {
int uid = Binder.getCallingUid();
mWifiPermissionsUtil.checkPackage(uid, packageName);
if (!mWifiPermissionsUtil.checkRequestCompanionProfileAutomotiveProjectionPermission(uid)
- || !mWifiPermissionsUtil.checkCallersLocationPermission(packageName, featureId,
- uid, false, null)) {
+ || !mWifiPermissionsUtil.checkCallersLocationPermissionInManifest(uid, false)) {
throw new SecurityException(TAG + " Caller uid " + uid + " has no permission");
}
if (mVerboseLoggingEnabled) {
@@ -6353,10 +6384,10 @@ public class WifiServiceImpl extends BaseWifiService {
@Override
public void setScanThrottleEnabled(boolean enable) {
enforceNetworkSettingsPermission();
- mLog.info("setScanThrottleEnabled uid=% verbose=%")
+ mLog.info("setScanThrottleEnabled uid=% enable=%")
.c(Binder.getCallingUid())
.c(enable).flush();
- mWifiThreadRunner.post(()-> mScanRequestProxy.setScanThrottleEnabled(enable));
+ mScanRequestProxy.setScanThrottleEnabled(enable);
}
/**
@@ -6365,10 +6396,12 @@ public class WifiServiceImpl extends BaseWifiService {
@Override
public boolean isScanThrottleEnabled() {
enforceAccessPermission();
+ final boolean enable = mScanRequestProxy.isScanThrottleEnabled();
if (mVerboseLoggingEnabled) {
- mLog.info("isScanThrottleEnabled uid=%").c(Binder.getCallingUid()).flush();
+ mLog.info("isScanThrottleEnabled uid=% enable=%")
+ .c(Binder.getCallingUid()).c(enable).flush();
}
- return mWifiThreadRunner.call(()-> mScanRequestProxy.isScanThrottleEnabled(), true);
+ return enable;
}
/**
@@ -6380,7 +6413,12 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("setWalkeupEnabled uid=% verbose=%")
.c(Binder.getCallingUid())
.c(enable).flush();
- mWifiThreadRunner.post(()-> mWifiInjector.getWakeupController().setEnabled(enable));
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mWifiInjector.getWakeupController().setEnabled(enable);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
/**
@@ -6392,7 +6430,12 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("isAutoWakeupEnabled uid=%").c(Binder.getCallingUid()).flush();
}
- return mWifiThreadRunner.call(()-> mWifiInjector.getWakeupController().isEnabled(), false);
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return mWifiInjector.getWakeupController().isEnabled();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
/**
@@ -6407,8 +6450,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("setCarrierNetworkOffloadEnabled uid=%").c(Binder.getCallingUid()).flush();
}
- mWifiThreadRunner.post(() ->
- mWifiCarrierInfoManager.setCarrierNetworkOffloadEnabled(subscriptionId, merged, enabled));
+ mWifiCarrierInfoManager.setCarrierNetworkOffloadEnabled(subscriptionId, merged, enabled);
}
/**
@@ -6421,8 +6463,7 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("isCarrierNetworkOffload uid=%").c(Binder.getCallingUid()).flush();
}
- return mWifiThreadRunner.call(()->
- mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(subId, merged), true);
+ return mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(subId, merged);
}
/**
@@ -6546,26 +6587,72 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public List<WifiAvailableChannel> getUsableChannels(@WifiScanner.WifiBand int band,
- @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter) {
- // Location mode must be enabled
- long ident = Binder.clearCallingIdentity();
- try {
- if (!mWifiPermissionsUtil.isLocationModeEnabled()) {
- throw new SecurityException("Location mode is disabled for the device");
+ @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter,
+ String packageName, Bundle extras) {
+ final int uid = Binder.getCallingUid();
+ if (isPlatformOrTargetSdkLessThanU(packageName, uid)) {
+ // Location mode must be enabled
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (!mWifiPermissionsUtil.isLocationModeEnabled()) {
+ throw new SecurityException("Location mode is disabled for the device");
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
- } finally {
- Binder.restoreCallingIdentity(ident);
+ if (!mWifiPermissionsUtil.checkCallersHardwareLocationPermission(uid)) {
+ throw new SecurityException(
+ "UID " + uid + " does not have location h/w permission");
+ }
+ } else {
+ mWifiPermissionsUtil.enforceNearbyDevicesPermission(
+ extras.getParcelable(WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE),
+ true, TAG + " getUsableChannels");
}
- final int uid = Binder.getCallingUid();
if (mVerboseLoggingEnabled) {
mLog.info("getUsableChannels uid=%").c(Binder.getCallingUid()).flush();
}
- if (!mWifiPermissionsUtil.checkCallersHardwareLocationPermission(uid)) {
- throw new SecurityException("UID " + uid + " does not have location h/w permission");
- }
if (!isValidBandForGetUsableChannels(band)) {
throw new IllegalArgumentException("Unsupported band: " + band);
}
+ // If querying the usable channels for SoftAp mode and regulatory filtered, return from
+ // cached softAp capabilities directly.
+ if (mode == WifiAvailableChannel.OP_MODE_SAP
+ && filter == WifiAvailableChannel.FILTER_REGULATORY) {
+ int[] chans;
+ switch (band) {
+ case WifiScanner.WIFI_BAND_24_GHZ:
+ chans =
+ mTetheredSoftApTracker.getSoftApCapability().getSupportedChannelList(
+ SoftApConfiguration.BAND_2GHZ);
+ break;
+ case WifiScanner.WIFI_BAND_5_GHZ:
+ chans =
+ mTetheredSoftApTracker.getSoftApCapability().getSupportedChannelList(
+ SoftApConfiguration.BAND_5GHZ);
+ break;
+ case WifiScanner.WIFI_BAND_6_GHZ:
+ chans =
+ mTetheredSoftApTracker.getSoftApCapability().getSupportedChannelList(
+ SoftApConfiguration.BAND_6GHZ);
+ break;
+ case WifiScanner.WIFI_BAND_60_GHZ:
+ chans =
+ mTetheredSoftApTracker.getSoftApCapability().getSupportedChannelList(
+ SoftApConfiguration.BAND_60GHZ);
+ break;
+ default:
+ chans = null;
+ break;
+ }
+ if (chans != null) {
+ return Arrays.stream(chans).mapToObj(
+ v -> new WifiAvailableChannel(
+ ScanResult.convertChannelToFrequencyMhzIfSupported(v, band),
+ WifiAvailableChannel.OP_MODE_SAP)).collect(
+ Collectors.toList());
+ }
+ }
List<WifiAvailableChannel> channels = mWifiThreadRunner.call(
() -> mWifiNative.getUsableChannels(band, mode, filter), null);
if (channels == null) {
@@ -6712,7 +6799,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
mWifiThreadRunner.post(() -> {
for (ClientModeManager cmm : mActiveModeWarden.getClientModeManagers()) {
- WifiInfo wifiInfo = cmm.syncRequestConnectionInfo();
+ WifiInfo wifiInfo = cmm.getConnectionInfo();
if (wifiInfo == null) continue;
//check minimum security level restriction
@@ -6750,7 +6837,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
mWifiThreadRunner.post(() -> {
for (ClientModeManager cmm : mActiveModeWarden.getClientModeManagers()) {
- WifiInfo wifiInfo = cmm.syncRequestConnectionInfo();
+ WifiInfo wifiInfo = cmm.getConnectionInfo();
if (wifiInfo == null) continue;
//skip SSID restriction check for Osu and Passpoint networks
@@ -6913,4 +7000,9 @@ public class WifiServiceImpl extends BaseWifiService {
}
});
}
+ @Override
+ public int getMaxNumberOfChannelsPerRequest() {
+ return mContext.getResources()
+ .getInteger(R.integer.config_wifiNetworkSpecifierMaxPreferredChannels);
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
index 4837e98302..e67fe9e95b 100644
--- a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
@@ -109,6 +109,13 @@ public class WifiSettingsConfigStore {
new Key<>("wifi_sta_factory_mac_address", null);
/**
+ * Store the Secondary STA factory MAC address retrieved from the driver on the first bootup.
+ */
+ public static final Key<String> SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS =
+ new Key<>("secondary_wifi_sta_factory_mac_address", null);
+
+
+ /**
* Store the default country code updated via {@link WifiManager#setDefaultCountryCode(String)}
*/
public static final Key<String> WIFI_DEFAULT_COUNTRY_CODE =
@@ -121,6 +128,12 @@ public class WifiSettingsConfigStore {
new Key<>("wifi_native_supported_features", 0L);
/**
+ * Store the supported features retrieved from WiFi HAL and Supplicant HAL
+ */
+ public static final Key<Integer> WIFI_NATIVE_SUPPORTED_STA_BANDS =
+ new Key<>("wifi_native_supported_sta_bands", 0);
+
+ /**
* Store the static chip info retrieved from WiFi HAL
*/
public static final Key<String> WIFI_STATIC_CHIP_INFO = new Key<>("wifi_static_chip_info", "");
diff --git a/service/java/com/android/server/wifi/WifiSettingsStore.java b/service/java/com/android/server/wifi/WifiSettingsStore.java
index 573b347ecc..1a9d561d34 100644
--- a/service/java/com/android/server/wifi/WifiSettingsStore.java
+++ b/service/java/com/android/server/wifi/WifiSettingsStore.java
@@ -28,6 +28,7 @@ import android.net.wifi.WifiContext;
import android.provider.Settings;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.wifi.resources.R;
import java.io.FileDescriptor;
@@ -131,10 +132,6 @@ public class WifiSettingsStore {
/* Tracks when airplane mode has been enabled in milliseconds since boot */
private long mApmEnabledTimeSinceBootMillis = 0;
- // TODO(b/240650689): Replace NOTE_WIFI_APM_NOTIFICATION with
- // SystemMessage.NOTE_WIFI_APM_NOTIFICATION
- private static final int WIFI_APM_NOTIFICATION_ID = 73;
-
private final String mApmEnhancementHelpLink;
private final WifiContext mContext;
private final WifiSettingsConfigStore mSettingsConfigStore;
@@ -232,7 +229,7 @@ public class WifiSettingsStore {
.setStyle(new Notification.BigTextStyle().bigText(message))
.setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
R.drawable.ic_wifi_settings));
- mNotificationManager.notify(WIFI_APM_NOTIFICATION_ID, builder.build());
+ mNotificationManager.notify(SystemMessage.NOTE_WIFI_APM_NOTIFICATION, builder.build());
}
public synchronized boolean handleWifiToggled(boolean wifiEnabled) {
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index 17dbcd5c84..4dbd48b024 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -1250,6 +1250,11 @@ public class WifiShellCommand extends BasicShellCommandHandler {
mActiveModeWarden.emergencyCallStateChanged(enabled);
return 0;
}
+ case "set-emergency-scan-request": {
+ boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled");
+ mWifiService.setEmergencyScanRequestInProgress(enabled);
+ return 0;
+ }
case "trigger-recovery": {
mSelfRecovery.trigger(REASON_API_CALL);
return 0;
@@ -1769,6 +1774,27 @@ public class WifiShellCommand extends BasicShellCommandHandler {
}
return 0;
}
+ case "set-mock-wifimodem-service":
+ String opt = null;
+ String serviceName = null;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "-s": {
+ serviceName = getNextArgRequired();
+ break;
+ }
+ default:
+ pw.println("set-mock-wifimodem-service requires '-s' option");
+ return -1;
+ }
+ }
+ mWifiNative.setMockWifiService(serviceName);
+ // The result will be checked, must print result "true"
+ pw.print("true");
+ return 0;
+ case "get-mock-wifimodem-service":
+ pw.print(mWifiNative.getMockWifiServiceName());
+ return 0;
default:
return handleDefaultCommands(cmd);
}
@@ -2335,12 +2361,12 @@ public class WifiShellCommand extends BasicShellCommandHandler {
// privileged, dump out all the client mode manager manager statuses
for (ClientModeManager cm : mActiveModeWarden.getClientModeManagers()) {
pw.println("==== ClientModeManager instance: " + cm + " ====");
- WifiInfo info = cm.syncRequestConnectionInfo();
+ WifiInfo info = cm.getConnectionInfo();
printWifiInfo(pw, info);
if (info.getSupplicantState() != SupplicantState.COMPLETED) {
continue;
}
- Network network = cm.syncGetCurrentNetwork();
+ Network network = cm.getCurrentNetwork();
NetworkCapabilities capabilities =
mConnectivityManager.getNetworkCapabilities(network);
pw.println("NetworkCapabilities: " + capabilities);
@@ -2673,6 +2699,8 @@ public class WifiShellCommand extends BasicShellCommandHandler {
pw.println(" Sets whether we are in the middle of an emergency call.");
pw.println("Equivalent to receiving the "
+ "TelephonyManager.ACTION_EMERGENCY_CALL_STATE_CHANGED broadcast.");
+ pw.println(" set-emergency-scan-request enabled|disabled");
+ pw.println(" Sets whether there is a emergency scan request in progress.");
pw.println(" network-suggestions-set-as-carrier-provider <packageName> yes|no");
pw.println(" Set the <packageName> work as carrier provider or not.");
pw.println(" is-network-suggestions-set-as-carrier-provider <packageName>");
diff --git a/service/java/com/android/server/wifi/WifiThreadRunner.java b/service/java/com/android/server/wifi/WifiThreadRunner.java
index a3c0c2295e..491e30cf65 100644
--- a/service/java/com/android/server/wifi/WifiThreadRunner.java
+++ b/service/java/com/android/server/wifi/WifiThreadRunner.java
@@ -216,6 +216,14 @@ public class WifiThreadRunner {
return mHandler.hasCallbacks(r);
}
+ /**
+ * Package private
+ * @return Scissors timeout threshold
+ */
+ static long getScissorsTimeoutThreshold() {
+ return RUN_WITH_SCISSORS_TIMEOUT_MILLIS;
+ }
+
// Note: @hide methods copied from android.os.Handler
/**
* Runs the specified task synchronously.
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index 9d73cd333f..ba0d4b219d 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -15,8 +15,6 @@
*/
package com.android.server.wifi;
-import static android.net.wifi.CoexUnsafeChannel.POWER_CAP_NONE;
-
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;
@@ -25,40 +23,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.hardware.wifi.V1_0.IWifiApIface;
-import android.hardware.wifi.V1_0.IWifiChip;
-import android.hardware.wifi.V1_0.IWifiChipEventCallback;
-import android.hardware.wifi.V1_0.IWifiIface;
-import android.hardware.wifi.V1_0.IWifiStaIface;
-import android.hardware.wifi.V1_0.IWifiStaIfaceEventCallback;
-import android.hardware.wifi.V1_0.IfaceType;
-import android.hardware.wifi.V1_0.StaBackgroundScanBucketEventReportSchemeMask;
-import android.hardware.wifi.V1_0.StaBackgroundScanBucketParameters;
-import android.hardware.wifi.V1_0.StaBackgroundScanParameters;
-import android.hardware.wifi.V1_0.StaLinkLayerIfaceStats;
-import android.hardware.wifi.V1_0.StaLinkLayerRadioStats;
-import android.hardware.wifi.V1_0.StaLinkLayerStats;
-import android.hardware.wifi.V1_0.StaRoamingConfig;
-import android.hardware.wifi.V1_0.StaRoamingState;
-import android.hardware.wifi.V1_0.StaScanData;
-import android.hardware.wifi.V1_0.StaScanDataFlagMask;
-import android.hardware.wifi.V1_0.StaScanResult;
-import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
-import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType;
-import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
-import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
-import android.hardware.wifi.V1_0.WifiDebugRxPacketFate;
-import android.hardware.wifi.V1_0.WifiDebugRxPacketFateReport;
-import android.hardware.wifi.V1_0.WifiDebugTxPacketFate;
-import android.hardware.wifi.V1_0.WifiDebugTxPacketFateReport;
-import android.hardware.wifi.V1_0.WifiInformationElement;
-import android.hardware.wifi.V1_0.WifiStatus;
-import android.hardware.wifi.V1_0.WifiStatusCode;
-import android.hardware.wifi.V1_2.IWifiChipEventCallback.IfaceInfo;
-import android.hardware.wifi.V1_5.IWifiChip.MultiStaUseCase;
-import android.hardware.wifi.V1_5.WifiBand;
-import android.hardware.wifi.V1_5.WifiIfaceMode;
-import android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter;
import android.net.MacAddress;
import android.net.apf.ApfCapabilities;
import android.net.wifi.ScanResult;
@@ -68,7 +32,6 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.os.Handler;
-import android.os.RemoteException;
import android.os.WorkSource;
import android.text.TextUtils;
import android.util.Log;
@@ -76,19 +39,13 @@ import android.util.Pair;
import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.HexDump;
-import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
-import com.android.server.wifi.WifiLinkLayerStats.ChannelStats;
-import com.android.server.wifi.WifiLinkLayerStats.PeerInfo;
-import com.android.server.wifi.WifiLinkLayerStats.RadioStat;
-import com.android.server.wifi.WifiLinkLayerStats.RateStat;
import com.android.server.wifi.WifiNative.RxFateReport;
import com.android.server.wifi.WifiNative.TxFateReport;
-import com.android.server.wifi.util.BitMask;
-import com.android.server.wifi.util.GeneralUtil.Mutable;
-import com.android.server.wifi.util.NativeUtil;
-import com.android.wifi.resources.R;
+import com.android.server.wifi.hal.WifiApIface;
+import com.android.server.wifi.hal.WifiChip;
+import com.android.server.wifi.hal.WifiHal;
+import com.android.server.wifi.hal.WifiStaIface;
import com.google.errorprone.annotations.CompileTimeConstant;
@@ -100,7 +57,8 @@ import java.util.Set;
import java.util.stream.Collectors;
/**
- * Vendor HAL via HIDL
+ * Wi-Fi Vendor HAL.
+ * Interface management is handled by the HalDeviceManager.
*/
public class WifiVendorHal {
@@ -135,103 +93,6 @@ public class WifiVendorHal {
}
/**
- * Checks for a successful status result.
- *
- * Failures are logged to mLog.
- *
- * @param status is the WifiStatus generated by a hal call
- * @return true for success, false for failure
- */
- private boolean ok(WifiStatus status) {
- if (status.code == WifiStatusCode.SUCCESS) return true;
-
- Thread cur = Thread.currentThread();
- StackTraceElement[] trace = cur.getStackTrace();
-
- mLog.err("% failed %")
- .c(niceMethodName(trace, 3))
- .c(status.toString())
- .flush();
-
- return false;
- }
-
- /**
- * Logs the argument along with the method name.
- *
- * Always returns its argument.
- */
- private boolean boolResult(boolean result) {
- if (mVerboseLog == sNoLog) return result;
- // Currently only seen if verbose logging is on
-
- Thread cur = Thread.currentThread();
- StackTraceElement[] trace = cur.getStackTrace();
-
- mVerboseLog.err("% returns %")
- .c(niceMethodName(trace, 3))
- .c(result)
- .flush();
-
- return result;
- }
-
- private <T> T objResult(T obj) {
- if (mVerboseLog == sNoLog) return obj;
- // Currently only seen if verbose logging is on
-
- Thread cur = Thread.currentThread();
- StackTraceElement[] trace = cur.getStackTrace();
-
- mVerboseLog.err("% returns %")
- .c(niceMethodName(trace, 3))
- .c(String.valueOf(obj))
- .flush();
-
- return obj;
- }
-
- /**
- * Logs the argument along with the method name.
- *
- * Always returns its argument.
- */
- private <T> T nullResult() {
- if (mVerboseLog == sNoLog) return null;
- // Currently only seen if verbose logging is on
-
- Thread cur = Thread.currentThread();
- StackTraceElement[] trace = cur.getStackTrace();
-
- mVerboseLog.err("% returns %")
- .c(niceMethodName(trace, 3))
- .c(null)
- .flush();
-
- return null;
- }
-
- /**
- * Logs the argument along with the method name.
- *
- * Always returns its argument.
- */
- private byte[] byteArrayResult(byte[] result) {
- if (mVerboseLog == sNoLog) return result;
- // Currently only seen if verbose logging is on
-
- Thread cur = Thread.currentThread();
- StackTraceElement[] trace = cur.getStackTrace();
-
- mVerboseLog.err("% returns %")
- .c(niceMethodName(trace, 3))
- .c(result == null ? "(null)" : HexDump.dumpHexString(result))
- .flush();
-
- return result;
- }
-
- /**
* Logs at method entry
*
* @param format string with % placeholders
@@ -242,47 +103,17 @@ public class WifiVendorHal {
return mVerboseLog.trace(format, 1);
}
- /**
- * Gets the method name and line number from a stack trace.
- *
- * Attempts to skip frames created by lambdas to get a human-sensible name.
- *
- * @param trace, fo example obtained by Thread.currentThread().getStackTrace()
- * @param start frame number to log, typically 3
- * @return string containing the method name and line number
- */
- private static String niceMethodName(StackTraceElement[] trace, int start) {
- if (start >= trace.length) return "";
- StackTraceElement s = trace[start];
- String name = s.getMethodName();
- if (name.contains("lambda$")) {
- // Try to find a friendlier method name
- String myFile = s.getFileName();
- if (myFile != null) {
- for (int i = start + 1; i < trace.length; i++) {
- if (myFile.equals(trace[i].getFileName())) {
- name = trace[i].getMethodName();
- break;
- }
- }
- }
- }
- return (name + "(l." + s.getLineNumber() + ")");
- }
-
- // Vendor HAL HIDL interface objects.
- private IWifiChip mIWifiChip;
- private HashMap<String, IWifiStaIface> mIWifiStaIfaces = new HashMap<>();
- private HashMap<String, IWifiApIface> mIWifiApIfaces = new HashMap<>();
+ // Vendor HAL interface objects.
+ private WifiChip mWifiChip;
+ private HashMap<String, WifiStaIface> mWifiStaIfaces = new HashMap<>();
+ private HashMap<String, WifiApIface> mWifiApIfaces = new HashMap<>();
private static Context sContext;
private final HalDeviceManager mHalDeviceManager;
private final WifiGlobals mWifiGlobals;
private final SsidTranslator mSsidTranslator;
private final HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
- private final IWifiStaIfaceEventCallback mIWifiStaIfaceEventCallback;
- private final ChipEventCallback mIWifiChipEventCallback;
- private final ChipEventCallbackV12 mIWifiChipEventCallbackV12;
- private final ChipEventCallbackV14 mIWifiChipEventCallbackV14;
+ private final WifiStaIface.Callback mWifiStaIfaceEventCallback;
+ private final ChipEventCallback mWifiChipEventCallback;
// Plumbing for event handling.
//
@@ -300,20 +131,12 @@ public class WifiVendorHal {
mWifiGlobals = wifiGlobals;
mSsidTranslator = ssidTranslator;
mHalDeviceManagerStatusCallbacks = new HalDeviceManagerStatusListener();
- mIWifiStaIfaceEventCallback = new StaIfaceEventCallback();
- mIWifiChipEventCallback = new ChipEventCallback();
- mIWifiChipEventCallbackV12 = new ChipEventCallbackV12();
- mIWifiChipEventCallbackV14 = new ChipEventCallbackV14();
+ mWifiStaIfaceEventCallback = new StaIfaceEventCallback();
+ mWifiChipEventCallback = new ChipEventCallback();
}
public static final Object sLock = new Object();
- private void handleRemoteException(RemoteException e) {
- String methodName = niceMethodName(Thread.currentThread().getStackTrace(), 3);
- mVerboseLog.err("% RemoteException in HIDL call %").c(methodName).c(e.toString()).flush();
- // Recovery on HAL crash will be triggered by death listener.
- }
-
private WifiNative.VendorHalDeathEventHandler mDeathEventHandler;
/**
@@ -375,7 +198,7 @@ public class WifiVendorHal {
}
/**
- * Bring up the HIDL Vendor HAL and configure for STA (Station) mode
+ * Bring up the Vendor HAL and configure for STA (Station) mode
*
* @return true for success
*/
@@ -393,7 +216,7 @@ public class WifiVendorHal {
}
/**
- * Bring up the HIDL Vendor HAL.
+ * Bring up the Vendor HAL.
* @return true on success, false otherwise.
*/
public boolean startVendorHal() {
@@ -409,9 +232,9 @@ public class WifiVendorHal {
/** Helper method to lookup the corresponding STA iface object using iface name. */
- private IWifiStaIface getStaIface(@NonNull String ifaceName) {
+ private WifiStaIface getStaIface(@NonNull String ifaceName) {
synchronized (sLock) {
- return mIWifiStaIfaces.get(ifaceName);
+ return mWifiStaIfaces.get(ifaceName);
}
}
@@ -425,7 +248,7 @@ public class WifiVendorHal {
@Override
public void onDestroyed(@NonNull String ifaceName) {
synchronized (sLock) {
- mIWifiStaIfaces.remove(ifaceName);
+ mWifiStaIfaces.remove(ifaceName);
}
if (mExternalListener != null) {
mExternalListener.onDestroyed(ifaceName);
@@ -443,27 +266,27 @@ public class WifiVendorHal {
public String createStaIface(@Nullable InterfaceDestroyedListener destroyedListener,
@NonNull WorkSource requestorWs) {
synchronized (sLock) {
- IWifiStaIface iface = mHalDeviceManager.createStaIface(
+ WifiStaIface iface = mHalDeviceManager.createStaIface(
new StaInterfaceDestroyedListenerInternal(destroyedListener), mHalEventHandler,
requestorWs);
if (iface == null) {
mLog.err("Failed to create STA iface").flush();
- return nullResult();
+ return null;
}
- String ifaceName = mHalDeviceManager.getName((IWifiIface) iface);
+ String ifaceName = iface.getName();
if (TextUtils.isEmpty(ifaceName)) {
mLog.err("Failed to get iface name").flush();
- return nullResult();
+ return null;
}
if (!registerStaIfaceCallback(iface)) {
mLog.err("Failed to register STA iface callback").flush();
- return nullResult();
+ return null;
}
- if (!retrieveWifiChip((IWifiIface) iface)) {
+ if (!retrieveWifiChip(iface)) {
mLog.err("Failed to get wifi chip").flush();
- return nullResult();
+ return null;
}
- mIWifiStaIfaces.put(ifaceName, iface);
+ mWifiStaIfaces.put(ifaceName, iface);
return ifaceName;
}
}
@@ -478,12 +301,12 @@ public class WifiVendorHal {
public boolean replaceStaIfaceRequestorWs(@NonNull String ifaceName,
@NonNull WorkSource requestorWs) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return boolResult(false);
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
if (!mHalDeviceManager.replaceRequestorWs(iface, requestorWs)) {
mLog.err("Failed to replace requestor worksource for STA iface").flush();
- return boolResult(false);
+ return false;
}
return true;
}
@@ -497,21 +320,21 @@ public class WifiVendorHal {
*/
public boolean removeStaIface(@NonNull String ifaceName) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return boolResult(false);
- if (!mHalDeviceManager.removeIface((IWifiIface) iface)) {
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
+ if (!mHalDeviceManager.removeIface(iface)) {
mLog.err("Failed to remove STA iface").flush();
- return boolResult(false);
+ return false;
}
- mIWifiStaIfaces.remove(ifaceName);
+ mWifiStaIfaces.remove(ifaceName);
return true;
}
}
/** Helper method to lookup the corresponding AP iface object using iface name. */
- private IWifiApIface getApIface(@NonNull String ifaceName) {
+ private WifiApIface getApIface(@NonNull String ifaceName) {
synchronized (sLock) {
- return mIWifiApIfaces.get(ifaceName);
+ return mWifiApIfaces.get(ifaceName);
}
}
@@ -525,7 +348,7 @@ public class WifiVendorHal {
@Override
public void onDestroyed(@NonNull String ifaceName) {
synchronized (sLock) {
- mIWifiApIfaces.remove(ifaceName);
+ mWifiApIfaces.remove(ifaceName);
}
if (mExternalListener != null) {
mExternalListener.onDestroyed(ifaceName);
@@ -536,13 +359,13 @@ public class WifiVendorHal {
private long getNecessaryCapabilitiesForSoftApMode(@SoftApConfiguration.BandType int band) {
long caps = HalDeviceManager.CHIP_CAPABILITY_ANY;
if ((band & SoftApConfiguration.BAND_60GHZ) != 0) {
- caps |= android.hardware.wifi.V1_5.IWifiChip.ChipCapabilityMask.WIGIG;
+ caps |= WifiManager.WIFI_FEATURE_INFRA_60G;
}
return caps;
}
/**
- * Create a AP iface using {@link HalDeviceManager}.
+ * Create an AP iface using {@link HalDeviceManager}.
*
* @param destroyedListener Listener to be invoked when the interface is destroyed.
* @param requestorWs Requestor worksource.
@@ -557,30 +380,30 @@ public class WifiVendorHal {
boolean isBridged,
@NonNull SoftApManager softApManager) {
synchronized (sLock) {
- IWifiApIface iface = mHalDeviceManager.createApIface(
+ WifiApIface iface = mHalDeviceManager.createApIface(
getNecessaryCapabilitiesForSoftApMode(band),
new ApInterfaceDestroyedListenerInternal(destroyedListener), mHalEventHandler,
requestorWs, isBridged, softApManager);
if (iface == null) {
mLog.err("Failed to create AP iface").flush();
- return nullResult();
+ return null;
}
- String ifaceName = mHalDeviceManager.getName((IWifiIface) iface);
+ String ifaceName = iface.getName();
if (TextUtils.isEmpty(ifaceName)) {
mLog.err("Failed to get iface name").flush();
- return nullResult();
+ return null;
}
- if (!retrieveWifiChip((IWifiIface) iface)) {
+ if (!retrieveWifiChip(iface)) {
mLog.err("Failed to get wifi chip").flush();
- return nullResult();
+ return null;
}
- mIWifiApIfaces.put(ifaceName, iface);
+ mWifiApIfaces.put(ifaceName, iface);
return ifaceName;
}
}
/**
- * Replace the requestor worksource info for a AP iface using {@link HalDeviceManager}.
+ * Replace the requestor worksource info for an AP iface using {@link HalDeviceManager}.
*
* @param ifaceName Name of the interface being removed.
* @param requestorWs Requestor worksource.
@@ -589,12 +412,12 @@ public class WifiVendorHal {
public boolean replaceApIfaceRequestorWs(@NonNull String ifaceName,
@NonNull WorkSource requestorWs) {
synchronized (sLock) {
- IWifiApIface iface = getApIface(ifaceName);
- if (iface == null) return boolResult(false);
+ WifiApIface iface = getApIface(ifaceName);
+ if (iface == null) return false;
- if (!mHalDeviceManager.replaceRequestorWs((IWifiIface) iface, requestorWs)) {
+ if (!mHalDeviceManager.replaceRequestorWs(iface, requestorWs)) {
mLog.err("Failed to replace requestor worksource for AP iface").flush();
- return boolResult(false);
+ return false;
}
return true;
}
@@ -608,14 +431,14 @@ public class WifiVendorHal {
*/
public boolean removeApIface(@NonNull String ifaceName) {
synchronized (sLock) {
- IWifiApIface iface = getApIface(ifaceName);
- if (iface == null) return boolResult(false);
+ WifiApIface iface = getApIface(ifaceName);
+ if (iface == null) return false;
- if (!mHalDeviceManager.removeIface((IWifiIface) iface)) {
+ if (!mHalDeviceManager.removeIface(iface)) {
mLog.err("Failed to remove AP iface").flush();
- return boolResult(false);
+ return false;
}
- mIWifiApIfaces.remove(ifaceName);
+ mWifiApIfaces.remove(ifaceName);
return true;
}
}
@@ -629,76 +452,8 @@ public class WifiVendorHal {
*/
public boolean removeIfaceInstanceFromBridgedApIface(@NonNull String ifaceName,
@NonNull String apIfaceInstance) {
- try {
- android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 = getWifiChipForV1_5Mockable();
- if (iWifiChipV15 == null) return boolResult(false);
- return ok(iWifiChipV15.removeIfaceInstanceFromBridgedApIface(
- ifaceName, apIfaceInstance));
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
-
- @NonNull
- private ArrayList<android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel>
- frameworkCoexUnsafeChannelsToHidl(
- @NonNull List<android.net.wifi.CoexUnsafeChannel> frameworkUnsafeChannels) {
- final ArrayList<android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel> hidlList =
- new ArrayList<>();
- if (!SdkLevel.isAtLeastS()) {
- return hidlList;
- }
- for (android.net.wifi.CoexUnsafeChannel frameworkUnsafeChannel : frameworkUnsafeChannels) {
- final android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel hidlUnsafeChannel =
- new android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel();
- switch (frameworkUnsafeChannel.getBand()) {
- case (WifiScanner.WIFI_BAND_24_GHZ):
- hidlUnsafeChannel.band = WifiBand.BAND_24GHZ;
- break;
- case (WifiScanner.WIFI_BAND_5_GHZ):
- hidlUnsafeChannel.band = WifiBand.BAND_5GHZ;
- break;
- case (WifiScanner.WIFI_BAND_6_GHZ):
- hidlUnsafeChannel.band = WifiBand.BAND_6GHZ;
- break;
- case (WifiScanner.WIFI_BAND_60_GHZ):
- hidlUnsafeChannel.band = WifiBand.BAND_60GHZ;
- break;
- default:
- mLog.err("Tried to set unsafe channel with unknown band: %")
- .c(frameworkUnsafeChannel.getBand())
- .flush();
- continue;
- }
- hidlUnsafeChannel.channel = frameworkUnsafeChannel.getChannel();
- final int powerCapDbm = frameworkUnsafeChannel.getPowerCapDbm();
- if (powerCapDbm != POWER_CAP_NONE) {
- hidlUnsafeChannel.powerCapDbm = powerCapDbm;
- } else {
- hidlUnsafeChannel.powerCapDbm =
- android.hardware.wifi.V1_5.IWifiChip.PowerCapConstant.NO_POWER_CAP;
- }
- hidlList.add(hidlUnsafeChannel);
- }
- return hidlList;
- }
-
- private int frameworkCoexRestrictionsToHidl(@WifiManager.CoexRestriction int restrictions) {
- int hidlRestrictions = 0;
- if (!SdkLevel.isAtLeastS()) {
- return hidlRestrictions;
- }
- if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_DIRECT) != 0) {
- hidlRestrictions |= android.hardware.wifi.V1_5.IWifiChip.CoexRestriction.WIFI_DIRECT;
- }
- if ((restrictions & WifiManager.COEX_RESTRICTION_SOFTAP) != 0) {
- hidlRestrictions |= android.hardware.wifi.V1_5.IWifiChip.CoexRestriction.SOFTAP;
- }
- if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_AWARE) != 0) {
- hidlRestrictions |= android.hardware.wifi.V1_5.IWifiChip.CoexRestriction.WIFI_AWARE;
- }
- return hidlRestrictions;
+ if (mWifiChip == null) return false;
+ return mWifiChip.removeIfaceInstanceFromBridgedApIface(ifaceName, apIfaceInstance);
}
/**
@@ -710,23 +465,15 @@ public class WifiVendorHal {
*/
public boolean setCoexUnsafeChannels(
@NonNull List<android.net.wifi.CoexUnsafeChannel> unsafeChannels, int restrictions) {
- try {
- android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 = getWifiChipForV1_5Mockable();
- if (iWifiChipV15 == null) return boolResult(false);
- return ok(iWifiChipV15.setCoexUnsafeChannels(
- frameworkCoexUnsafeChannelsToHidl(unsafeChannels),
- frameworkCoexRestrictionsToHidl(restrictions)));
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ if (mWifiChip == null) return false;
+ return mWifiChip.setCoexUnsafeChannels(unsafeChannels, restrictions);
}
- private boolean retrieveWifiChip(IWifiIface iface) {
+ private boolean retrieveWifiChip(WifiHal.WifiInterface iface) {
synchronized (sLock) {
- boolean registrationNeeded = mIWifiChip == null;
- mIWifiChip = mHalDeviceManager.getChip(iface);
- if (mIWifiChip == null) {
+ boolean registrationNeeded = mWifiChip == null;
+ mWifiChip = mHalDeviceManager.getChip(iface);
+ if (mWifiChip == null) {
mLog.err("Failed to get the chip created for the Iface").flush();
return false;
}
@@ -735,7 +482,7 @@ public class WifiVendorHal {
}
if (!registerChipCallback()) {
mLog.err("Failed to register chip callback").flush();
- mIWifiChip = null;
+ mWifiChip = null;
return false;
}
return true;
@@ -745,18 +492,11 @@ public class WifiVendorHal {
/**
* Registers the sta iface callback.
*/
- private boolean registerStaIfaceCallback(IWifiStaIface iface) {
+ private boolean registerStaIfaceCallback(WifiStaIface iface) {
synchronized (sLock) {
- if (iface == null) return boolResult(false);
- if (mIWifiStaIfaceEventCallback == null) return boolResult(false);
- try {
- WifiStatus status =
- iface.registerEventCallback(mIWifiStaIfaceEventCallback);
- return ok(status);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ if (iface == null) return false;
+ if (mWifiStaIfaceEventCallback == null) return false;
+ return iface.registerFrameworkCallback(mWifiStaIfaceEventCallback);
}
}
@@ -765,24 +505,8 @@ public class WifiVendorHal {
*/
private boolean registerChipCallback() {
synchronized (sLock) {
- if (mIWifiChip == null) return boolResult(false);
- try {
- WifiStatus status;
- android.hardware.wifi.V1_4.IWifiChip iWifiChipV14 = getWifiChipForV1_4Mockable();
- android.hardware.wifi.V1_2.IWifiChip iWifiChipV12 = getWifiChipForV1_2Mockable();
-
- if (iWifiChipV14 != null) {
- status = iWifiChipV14.registerEventCallback_1_4(mIWifiChipEventCallbackV14);
- } else if (iWifiChipV12 != null) {
- status = iWifiChipV12.registerEventCallback_1_2(mIWifiChipEventCallbackV12);
- } else {
- status = mIWifiChip.registerEventCallback(mIWifiChipEventCallback);
- }
- return ok(status);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ if (mWifiChip == null) return false;
+ return mWifiChip.registerCallback(mWifiChipEventCallback);
}
}
@@ -803,20 +527,20 @@ public class WifiVendorHal {
* Caller should hold the lock.
*/
private void clearState() {
- mIWifiChip = null;
- mIWifiStaIfaces.clear();
- mIWifiApIfaces.clear();
+ mWifiChip = null;
+ mWifiStaIfaces.clear();
+ mWifiApIfaces.clear();
mDriverDescription = null;
mFirmwareDescription = null;
}
/**
- * Tests whether the HAL is started and atleast one iface is up.
+ * Tests whether the HAL is started and at least one iface is up.
*/
public boolean isHalStarted() {
// For external use only. Methods in this class should test for null directly.
synchronized (sLock) {
- return (!mIWifiStaIfaces.isEmpty() || !mIWifiApIfaces.isEmpty());
+ return (!mWifiStaIfaces.isEmpty() || !mWifiApIfaces.isEmpty());
}
}
@@ -830,27 +554,18 @@ public class WifiVendorHal {
public boolean getBgScanCapabilities(
@NonNull String ifaceName, WifiNative.ScanCapabilities capabilities) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return boolResult(false);
- try {
- Mutable<Boolean> ans = new Mutable<>(false);
- WifiNative.ScanCapabilities out = capabilities;
- iface.getBackgroundScanCapabilities((status, cap) -> {
- if (!ok(status)) return;
- mVerboseLog.info("scan capabilities %").c(cap.toString()).flush();
- out.max_scan_cache_size = cap.maxCacheSize;
- out.max_ap_cache_per_scan = cap.maxApCachePerScan;
- out.max_scan_buckets = cap.maxBuckets;
- out.max_rssi_sample_size = 0;
- out.max_scan_reporting_threshold = cap.maxReportingThreshold;
- ans.value = true;
- }
- );
- return ans.value;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
+
+ WifiNative.ScanCapabilities result = iface.getBackgroundScanCapabilities();
+ if (result != null) {
+ capabilities.max_scan_cache_size = result.max_scan_cache_size;
+ capabilities.max_ap_cache_per_scan = result.max_ap_cache_per_scan;
+ capabilities.max_scan_buckets = result.max_scan_buckets;
+ capabilities.max_rssi_sample_size = result.max_rssi_sample_size;
+ capabilities.max_scan_reporting_threshold = result.max_scan_reporting_threshold;
}
+ return result != null;
}
}
@@ -860,122 +575,23 @@ public class WifiVendorHal {
@VisibleForTesting
class CurrentBackgroundScan {
public int cmdId;
- public StaBackgroundScanParameters param;
+ public WifiStaIface.StaBackgroundScanParameters param;
public WifiNative.ScanEventHandler eventHandler = null;
public boolean paused = false;
public WifiScanner.ScanData[] latestScanResults = null;
CurrentBackgroundScan(int id, WifiNative.ScanSettings settings) {
cmdId = id;
- param = new StaBackgroundScanParameters();
- param.basePeriodInMs = settings.base_period_ms;
- param.maxApPerScan = settings.max_ap_per_scan;
- param.reportThresholdPercent = settings.report_threshold_percent;
- param.reportThresholdNumScans = settings.report_threshold_num_scans;
+ List<WifiNative.BucketSettings> buckets = new ArrayList<>();
if (settings.buckets != null) {
- for (WifiNative.BucketSettings bs : settings.buckets) {
- param.buckets.add(makeStaBackgroundScanBucketParametersFromBucketSettings(bs));
- }
+ buckets = Arrays.asList(settings.buckets);
}
+ param = new WifiStaIface.StaBackgroundScanParameters(settings.base_period_ms,
+ settings.max_ap_per_scan, settings.report_threshold_percent,
+ settings.report_threshold_num_scans, buckets);
}
}
- /**
- * Makes the Hal flavor of WifiNative.BucketSettings
- *
- * @param bs WifiNative.BucketSettings
- * @return Hal flavor of bs
- * @throws IllegalArgumentException if band value is not recognized
- */
- private StaBackgroundScanBucketParameters
- makeStaBackgroundScanBucketParametersFromBucketSettings(WifiNative.BucketSettings bs) {
- StaBackgroundScanBucketParameters pa = new StaBackgroundScanBucketParameters();
- pa.bucketIdx = bs.bucket;
- pa.band = makeWifiBandFromFrameworkBand(bs.band);
- if (bs.channels != null) {
- for (WifiNative.ChannelSettings cs : bs.channels) {
- pa.frequencies.add(cs.frequency);
- }
- }
- pa.periodInMs = bs.period_ms;
- pa.eventReportScheme = makeReportSchemeFromBucketSettingsReportEvents(bs.report_events);
- pa.exponentialMaxPeriodInMs = bs.max_period_ms;
- // Although HAL API allows configurable base value for the truncated
- // exponential back off scan. Native API and above support only
- // truncated binary exponential back off scan.
- // Hard code value of base to 2 here.
- pa.exponentialBase = 2;
- pa.exponentialStepCount = bs.step_count;
- return pa;
- }
-
- /**
- * Makes the Hal flavor of WifiScanner's band indication
- *
- * Note: This method is only used by background scan which does not
- * support 6GHz, hence band combinations including 6GHz are considered invalid
- *
- * @param frameworkBand one of WifiScanner.WIFI_BAND_*
- * @return A WifiBand value
- * @throws IllegalArgumentException if frameworkBand is not recognized
- */
- private int makeWifiBandFromFrameworkBand(int frameworkBand) {
- switch (frameworkBand) {
- case WifiScanner.WIFI_BAND_UNSPECIFIED:
- return WifiBand.BAND_UNSPECIFIED;
- case WifiScanner.WIFI_BAND_24_GHZ:
- return WifiBand.BAND_24GHZ;
- case WifiScanner.WIFI_BAND_5_GHZ:
- return WifiBand.BAND_5GHZ;
- case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY:
- return WifiBand.BAND_5GHZ_DFS;
- case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS:
- return WifiBand.BAND_5GHZ_WITH_DFS;
- case WifiScanner.WIFI_BAND_BOTH:
- return WifiBand.BAND_24GHZ_5GHZ;
- case WifiScanner.WIFI_BAND_BOTH_WITH_DFS:
- return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS;
- case WifiScanner.WIFI_BAND_6_GHZ:
- return WifiBand.BAND_6GHZ;
- case WifiScanner.WIFI_BAND_24_5_6_GHZ:
- return WifiBand.BAND_24GHZ_5GHZ_6GHZ;
- case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ:
- return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ;
- case WifiScanner.WIFI_BAND_60_GHZ:
- return WifiBand.BAND_60GHZ;
- case WifiScanner.WIFI_BAND_24_5_6_60_GHZ:
- return WifiBand.BAND_24GHZ_5GHZ_6GHZ_60GHZ;
- case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ:
- return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ;
- case WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS:
- default:
- throw new IllegalArgumentException("bad band " + frameworkBand);
- }
- }
-
- /**
- * Makes the Hal flavor of WifiScanner's report event mask
- *
- * @param reportUnderscoreEvents is logical OR of WifiScanner.REPORT_EVENT_* values
- * @return Corresponding StaBackgroundScanBucketEventReportSchemeMask value
- * @throws IllegalArgumentException if a mask bit is not recognized
- */
- private int makeReportSchemeFromBucketSettingsReportEvents(int reportUnderscoreEvents) {
- int ans = 0;
- BitMask in = new BitMask(reportUnderscoreEvents);
- if (in.testAndClear(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN)) {
- ans |= StaBackgroundScanBucketEventReportSchemeMask.EACH_SCAN;
- }
- if (in.testAndClear(WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)) {
- ans |= StaBackgroundScanBucketEventReportSchemeMask.FULL_RESULTS;
- }
- if (in.testAndClear(WifiScanner.REPORT_EVENT_NO_BATCH)) {
- ans |= StaBackgroundScanBucketEventReportSchemeMask.NO_BATCH;
- }
- if (in.value != 0) throw new IllegalArgumentException("bad " + reportUnderscoreEvents);
- return ans;
- }
-
private int mLastScanCmdId; // For assigning cmdIds to scans
@VisibleForTesting
@@ -994,70 +610,55 @@ public class WifiVendorHal {
public boolean startBgScan(@NonNull String ifaceName,
WifiNative.ScanSettings settings,
WifiNative.ScanEventHandler eventHandler) {
- WifiStatus status;
- if (eventHandler == null) return boolResult(false);
+ if (eventHandler == null) return false;
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return boolResult(false);
- try {
- if (mScan != null && !mScan.paused) {
- ok(iface.stopBackgroundScan(mScan.cmdId));
- mScan = null;
- }
- mLastScanCmdId = (mLastScanCmdId % 9) + 1; // cycle through non-zero single digits
- CurrentBackgroundScan scan = new CurrentBackgroundScan(mLastScanCmdId, settings);
- status = iface.startBackgroundScan(scan.cmdId, scan.param);
- if (!ok(status)) return false;
- scan.eventHandler = eventHandler;
- mScan = scan;
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
+ if (mScan != null && !mScan.paused) {
+ iface.stopBackgroundScan(mScan.cmdId);
+ mScan = null;
}
+
+ mLastScanCmdId = (mLastScanCmdId % 9) + 1; // cycle through non-zero single digits
+ CurrentBackgroundScan scan = new CurrentBackgroundScan(mLastScanCmdId, settings);
+ boolean success = iface.startBackgroundScan(scan.cmdId, scan.param);
+ if (!success) return false;
+
+ scan.eventHandler = eventHandler;
+ mScan = scan;
+ return true;
}
}
/**
- * Stops any ongoing backgound scan
+ * Stops any ongoing background scan
*
* @param ifaceName Name of the interface.
*/
public void stopBgScan(@NonNull String ifaceName) {
- WifiStatus status;
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
+ WifiStaIface iface = getStaIface(ifaceName);
if (iface == null) return;
- try {
- if (mScan != null) {
- ok(iface.stopBackgroundScan(mScan.cmdId));
- mScan = null;
- }
- } catch (RemoteException e) {
- handleRemoteException(e);
+ if (mScan != null) {
+ iface.stopBackgroundScan(mScan.cmdId);
+ mScan = null;
}
}
}
/**
- * Pauses an ongoing backgound scan
+ * Pauses an ongoing background scan
*
* @param ifaceName Name of the interface.
*/
public void pauseBgScan(@NonNull String ifaceName) {
- WifiStatus status;
synchronized (sLock) {
- try {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return;
- if (mScan != null && !mScan.paused) {
- status = iface.stopBackgroundScan(mScan.cmdId);
- if (!ok(status)) return;
- mScan.paused = true;
- }
- } catch (RemoteException e) {
- handleRemoteException(e);
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return;
+ if (mScan != null && !mScan.paused) {
+ if (!iface.stopBackgroundScan(mScan.cmdId)) return;
+ mScan.paused = true;
}
}
}
@@ -1068,32 +669,24 @@ public class WifiVendorHal {
* @param ifaceName Name of the interface.
*/
public void restartBgScan(@NonNull String ifaceName) {
- WifiStatus status;
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
+ WifiStaIface iface = getStaIface(ifaceName);
if (iface == null) return;
- try {
- if (mScan != null && mScan.paused) {
- status = iface.startBackgroundScan(mScan.cmdId, mScan.param);
- if (!ok(status)) return;
- mScan.paused = false;
- }
- } catch (RemoteException e) {
- handleRemoteException(e);
+ if (mScan != null && mScan.paused) {
+ if (!iface.startBackgroundScan(mScan.cmdId, mScan.param)) return;
+ mScan.paused = false;
}
}
}
/**
- * Gets the latest scan results received from the HIDL interface callback.
- * TODO(b/35754840): This hop to fetch scan results after callback is unnecessary. Refactor
- * WifiScanner to use the scan results from the callback.
+ * Gets the latest scan results received from the HAL interface callback.
*
* @param ifaceName Name of the interface.
*/
public WifiScanner.ScanData[] getBgScanResults(@NonNull String ifaceName) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
+ WifiStaIface iface = getStaIface(ifaceName);
if (iface == null) return null;
if (mScan == null) return null;
return mScan.latestScanResults;
@@ -1109,506 +702,13 @@ public class WifiVendorHal {
* @return the statistics, or null if unable to do so
*/
public WifiLinkLayerStats getWifiLinkLayerStats(@NonNull String ifaceName) {
- if (getWifiStaIfaceForV1_6Mockable(ifaceName) != null) {
- return getWifiLinkLayerStats_1_6_Internal(ifaceName);
- } else if (getWifiStaIfaceForV1_5Mockable(ifaceName) != null) {
- return getWifiLinkLayerStats_1_5_Internal(ifaceName);
- } else if (getWifiStaIfaceForV1_3Mockable(ifaceName) != null) {
- return getWifiLinkLayerStats_1_3_Internal(ifaceName);
- } else {
- return getWifiLinkLayerStats_internal(ifaceName);
- }
- }
-
- private WifiLinkLayerStats getWifiLinkLayerStats_internal(@NonNull String ifaceName) {
- class AnswerBox {
- public StaLinkLayerStats value = null;
- }
- AnswerBox answer = new AnswerBox();
- synchronized (sLock) {
- try {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return null;
- iface.getLinkLayerStats((status, stats) -> {
- if (!ok(status)) return;
- answer.value = stats;
- });
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
- }
- WifiLinkLayerStats stats = frameworkFromHalLinkLayerStats(answer.value);
- return stats;
- }
-
- private WifiLinkLayerStats getWifiLinkLayerStats_1_3_Internal(@NonNull String ifaceName) {
- class AnswerBox {
- public android.hardware.wifi.V1_3.StaLinkLayerStats value = null;
- }
- AnswerBox answer = new AnswerBox();
- synchronized (sLock) {
- try {
- android.hardware.wifi.V1_3.IWifiStaIface iface =
- getWifiStaIfaceForV1_3Mockable(ifaceName);
- if (iface == null) return null;
- iface.getLinkLayerStats_1_3((status, stats) -> {
- if (!ok(status)) return;
- answer.value = stats;
- });
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
- }
- WifiLinkLayerStats stats = frameworkFromHalLinkLayerStats_1_3(answer.value);
- return stats;
- }
-
- private WifiLinkLayerStats getWifiLinkLayerStats_1_5_Internal(@NonNull String ifaceName) {
- class AnswerBox {
- public android.hardware.wifi.V1_5.StaLinkLayerStats value = null;
- }
- AnswerBox answer = new AnswerBox();
synchronized (sLock) {
- try {
- android.hardware.wifi.V1_5.IWifiStaIface iface =
- getWifiStaIfaceForV1_5Mockable(ifaceName);
- if (iface == null) return null;
- iface.getLinkLayerStats_1_5((status, stats) -> {
- if (!ok(status)) return;
- answer.value = stats;
- });
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
- }
- WifiLinkLayerStats stats = frameworkFromHalLinkLayerStats_1_5(answer.value);
- return stats;
- }
-
- private WifiLinkLayerStats getWifiLinkLayerStats_1_6_Internal(@NonNull String ifaceName) {
- class AnswerBox {
- public android.hardware.wifi.V1_6.StaLinkLayerStats value = null;
- }
- AnswerBox answer = new AnswerBox();
- synchronized (sLock) {
- try {
- android.hardware.wifi.V1_6.IWifiStaIface iface =
- getWifiStaIfaceForV1_6Mockable(ifaceName);
- if (iface == null) return null;
- iface.getLinkLayerStats_1_6((status, stats) -> {
- if (!ok(status)) return;
- answer.value = stats;
- });
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
- }
- WifiLinkLayerStats stats = frameworkFromHalLinkLayerStats_1_6(answer.value);
- return stats;
- }
-
- /**
- * Makes the framework version of link layer stats from the hal version.
- */
- @VisibleForTesting
- static WifiLinkLayerStats frameworkFromHalLinkLayerStats(StaLinkLayerStats stats) {
- if (stats == null) return null;
- WifiLinkLayerStats out = new WifiLinkLayerStats();
- setIfaceStats(out, stats.iface);
- setRadioStats(out, stats.radios);
- setTimeStamp(out, stats.timeStampInMs);
- out.version = WifiLinkLayerStats.V1_0;
- return out;
- }
-
- /**
- * Makes the framework version of link layer stats from the hal version.
- */
- @VisibleForTesting
- static WifiLinkLayerStats frameworkFromHalLinkLayerStats_1_3(
- android.hardware.wifi.V1_3.StaLinkLayerStats stats) {
- if (stats == null) return null;
- WifiLinkLayerStats out = new WifiLinkLayerStats();
- setIfaceStats(out, stats.iface);
- setRadioStats_1_3(out, stats.radios);
- setTimeStamp(out, stats.timeStampInMs);
- out.version = WifiLinkLayerStats.V1_3;
- return out;
- }
-
- /**
- * Makes the framework version of link layer stats from the hal version.
- */
- @VisibleForTesting
- static WifiLinkLayerStats frameworkFromHalLinkLayerStats_1_5(
- android.hardware.wifi.V1_5.StaLinkLayerStats stats) {
- if (stats == null) return null;
- WifiLinkLayerStats out = new WifiLinkLayerStats();
- setIfaceStats_1_5(out, stats.iface);
- setRadioStats_1_5(out, stats.radios);
- setTimeStamp(out, stats.timeStampInMs);
- out.version = WifiLinkLayerStats.V1_5;
- return out;
- }
-
- /**
- * Makes the framework version of link layer stats from the hal version.
- */
- @VisibleForTesting
- static WifiLinkLayerStats frameworkFromHalLinkLayerStats_1_6(
- android.hardware.wifi.V1_6.StaLinkLayerStats stats) {
- if (stats == null) return null;
- WifiLinkLayerStats out = new WifiLinkLayerStats();
- setIfaceStats_1_6(out, stats.iface);
- setRadioStats_1_6(out, stats.radios);
- setTimeStamp(out, stats.timeStampInMs);
- out.version = WifiLinkLayerStats.V1_5; //TODO: Does the change justify moving to 1.6 ??
- return out;
- }
-
- private static void setIfaceStats(WifiLinkLayerStats stats, StaLinkLayerIfaceStats iface) {
- if (iface == null) return;
- stats.beacon_rx = iface.beaconRx;
- stats.rssi_mgmt = iface.avgRssiMgmt;
- // Statistics are broken out by Wireless Multimedia Extensions categories
- // WME Best Effort Access Category
- stats.rxmpdu_be = iface.wmeBePktStats.rxMpdu;
- stats.txmpdu_be = iface.wmeBePktStats.txMpdu;
- stats.lostmpdu_be = iface.wmeBePktStats.lostMpdu;
- stats.retries_be = iface.wmeBePktStats.retries;
- // WME Background Access Category
- stats.rxmpdu_bk = iface.wmeBkPktStats.rxMpdu;
- stats.txmpdu_bk = iface.wmeBkPktStats.txMpdu;
- stats.lostmpdu_bk = iface.wmeBkPktStats.lostMpdu;
- stats.retries_bk = iface.wmeBkPktStats.retries;
- // WME Video Access Category
- stats.rxmpdu_vi = iface.wmeViPktStats.rxMpdu;
- stats.txmpdu_vi = iface.wmeViPktStats.txMpdu;
- stats.lostmpdu_vi = iface.wmeViPktStats.lostMpdu;
- stats.retries_vi = iface.wmeViPktStats.retries;
- // WME Voice Access Category
- stats.rxmpdu_vo = iface.wmeVoPktStats.rxMpdu;
- stats.txmpdu_vo = iface.wmeVoPktStats.txMpdu;
- stats.lostmpdu_vo = iface.wmeVoPktStats.lostMpdu;
- stats.retries_vo = iface.wmeVoPktStats.retries;
- }
-
- private static void setIfaceStats_1_5(WifiLinkLayerStats stats,
- android.hardware.wifi.V1_5.StaLinkLayerIfaceStats iface) {
- if (iface == null) return;
- setIfaceStats(stats, iface.V1_0);
- stats.timeSliceDutyCycleInPercent = iface.timeSliceDutyCycleInPercent;
- // WME Best Effort Access Category
- stats.contentionTimeMinBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMinInUsec;
- stats.contentionTimeMaxBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec;
- stats.contentionTimeAvgBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec;
- stats.contentionNumSamplesBe = iface.wmeBeContentionTimeStats.contentionNumSamples;
- // WME Background Access Category
- stats.contentionTimeMinBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMinInUsec;
- stats.contentionTimeMaxBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec;
- stats.contentionTimeAvgBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec;
- stats.contentionNumSamplesBk = iface.wmeBkContentionTimeStats.contentionNumSamples;
- // WME Video Access Category
- stats.contentionTimeMinViInUsec = iface.wmeViContentionTimeStats.contentionTimeMinInUsec;
- stats.contentionTimeMaxViInUsec = iface.wmeViContentionTimeStats.contentionTimeMaxInUsec;
- stats.contentionTimeAvgViInUsec = iface.wmeViContentionTimeStats.contentionTimeAvgInUsec;
- stats.contentionNumSamplesVi = iface.wmeViContentionTimeStats.contentionNumSamples;
- // WME Voice Access Category
- stats.contentionTimeMinVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMinInUsec;
- stats.contentionTimeMaxVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec;
- stats.contentionTimeAvgVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec;
- stats.contentionNumSamplesVo = iface.wmeVoContentionTimeStats.contentionNumSamples;
- // Peer information statistics
- stats.peerInfo = new PeerInfo[iface.peers.size()];
- for (int i = 0; i < stats.peerInfo.length; i++) {
- PeerInfo peer = new PeerInfo();
- android.hardware.wifi.V1_5.StaPeerInfo staPeerInfo = iface.peers.get(i);
- peer.staCount = staPeerInfo.staCount;
- peer.chanUtil = staPeerInfo.chanUtil;
- RateStat[] rateStats = new RateStat[staPeerInfo.rateStats.size()];
- for (int j = 0; j < staPeerInfo.rateStats.size(); j++) {
- rateStats[j] = new RateStat();
- android.hardware.wifi.V1_5.StaRateStat staRateStat = staPeerInfo.rateStats.get(j);
- rateStats[j].preamble = staRateStat.rateInfo.preamble;
- rateStats[j].nss = staRateStat.rateInfo.nss;
- rateStats[j].bw = staRateStat.rateInfo.bw;
- rateStats[j].rateMcsIdx = staRateStat.rateInfo.rateMcsIdx;
- rateStats[j].bitRateInKbps = staRateStat.rateInfo.bitRateInKbps;
- rateStats[j].txMpdu = staRateStat.txMpdu;
- rateStats[j].rxMpdu = staRateStat.rxMpdu;
- rateStats[j].mpduLost = staRateStat.mpduLost;
- rateStats[j].retries = staRateStat.retries;
- }
- peer.rateStats = rateStats;
- stats.peerInfo[i] = peer;
- }
- }
-
- private static void setIfaceStats_1_6(WifiLinkLayerStats stats,
- android.hardware.wifi.V1_6.StaLinkLayerIfaceStats iface) {
- if (iface == null) return;
- setIfaceStats(stats, iface.V1_0);
- stats.timeSliceDutyCycleInPercent = iface.timeSliceDutyCycleInPercent;
- // WME Best Effort Access Category
- stats.contentionTimeMinBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMinInUsec;
- stats.contentionTimeMaxBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec;
- stats.contentionTimeAvgBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec;
- stats.contentionNumSamplesBe = iface.wmeBeContentionTimeStats.contentionNumSamples;
- // WME Background Access Category
- stats.contentionTimeMinBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMinInUsec;
- stats.contentionTimeMaxBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec;
- stats.contentionTimeAvgBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec;
- stats.contentionNumSamplesBk = iface.wmeBkContentionTimeStats.contentionNumSamples;
- // WME Video Access Category
- stats.contentionTimeMinViInUsec = iface.wmeViContentionTimeStats.contentionTimeMinInUsec;
- stats.contentionTimeMaxViInUsec = iface.wmeViContentionTimeStats.contentionTimeMaxInUsec;
- stats.contentionTimeAvgViInUsec = iface.wmeViContentionTimeStats.contentionTimeAvgInUsec;
- stats.contentionNumSamplesVi = iface.wmeViContentionTimeStats.contentionNumSamples;
- // WME Voice Access Category
- stats.contentionTimeMinVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMinInUsec;
- stats.contentionTimeMaxVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec;
- stats.contentionTimeAvgVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec;
- stats.contentionNumSamplesVo = iface.wmeVoContentionTimeStats.contentionNumSamples;
- // Peer information statistics
- stats.peerInfo = new PeerInfo[iface.peers.size()];
- for (int i = 0; i < stats.peerInfo.length; i++) {
- PeerInfo peer = new PeerInfo();
- android.hardware.wifi.V1_6.StaPeerInfo staPeerInfo = iface.peers.get(i);
- peer.staCount = staPeerInfo.staCount;
- peer.chanUtil = staPeerInfo.chanUtil;
- RateStat[] rateStats = new RateStat[staPeerInfo.rateStats.size()];
- for (int j = 0; j < staPeerInfo.rateStats.size(); j++) {
- rateStats[j] = new RateStat();
- android.hardware.wifi.V1_6.StaRateStat staRateStat = staPeerInfo.rateStats.get(j);
- rateStats[j].preamble = staRateStat.rateInfo.preamble;
- rateStats[j].nss = staRateStat.rateInfo.nss;
- rateStats[j].bw = staRateStat.rateInfo.bw;
- rateStats[j].rateMcsIdx = staRateStat.rateInfo.rateMcsIdx;
- rateStats[j].bitRateInKbps = staRateStat.rateInfo.bitRateInKbps;
- rateStats[j].txMpdu = staRateStat.txMpdu;
- rateStats[j].rxMpdu = staRateStat.rxMpdu;
- rateStats[j].mpduLost = staRateStat.mpduLost;
- rateStats[j].retries = staRateStat.retries;
- }
- peer.rateStats = rateStats;
- stats.peerInfo[i] = peer;
- }
- }
-
- private static void setRadioStats(WifiLinkLayerStats stats,
- List<StaLinkLayerRadioStats> radios) {
- if (radios == null) return;
- // Do not coalesce this info for multi radio devices with older HALs.
- if (radios.size() > 0) {
- StaLinkLayerRadioStats radioStats = radios.get(0);
- stats.on_time = radioStats.onTimeInMs;
- stats.tx_time = radioStats.txTimeInMs;
- stats.tx_time_per_level = new int[radioStats.txTimeInMsPerLevel.size()];
- for (int i = 0; i < stats.tx_time_per_level.length; i++) {
- stats.tx_time_per_level[i] = radioStats.txTimeInMsPerLevel.get(i);
- }
- stats.rx_time = radioStats.rxTimeInMs;
- stats.on_time_scan = radioStats.onTimeInMsForScan;
- stats.numRadios = 1;
- }
- }
-
- /**
- * Set individual radio stats from the hal radio stats for V1_3
- */
- private static void setFrameworkPerRadioStatsFromHidl_1_3(int radioId, RadioStat radio,
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats hidlRadioStats) {
- radio.radio_id = radioId;
- radio.on_time = hidlRadioStats.V1_0.onTimeInMs;
- radio.tx_time = hidlRadioStats.V1_0.txTimeInMs;
- radio.rx_time = hidlRadioStats.V1_0.rxTimeInMs;
- radio.on_time_scan = hidlRadioStats.V1_0.onTimeInMsForScan;
- radio.on_time_nan_scan = hidlRadioStats.onTimeInMsForNanScan;
- radio.on_time_background_scan = hidlRadioStats.onTimeInMsForBgScan;
- radio.on_time_roam_scan = hidlRadioStats.onTimeInMsForRoamScan;
- radio.on_time_pno_scan = hidlRadioStats.onTimeInMsForPnoScan;
- radio.on_time_hs20_scan = hidlRadioStats.onTimeInMsForHs20Scan;
- /* Copy list of channel stats */
- for (android.hardware.wifi.V1_3.WifiChannelStats channelStats
- : hidlRadioStats.channelStats) {
- ChannelStats channelStatsEntry = new ChannelStats();
- channelStatsEntry.frequency = channelStats.channel.centerFreq;
- channelStatsEntry.radioOnTimeMs = channelStats.onTimeInMs;
- channelStatsEntry.ccaBusyTimeMs = channelStats.ccaBusyTimeInMs;
- radio.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
- }
- }
-
- /**
- * Set individual radio stats from the hal radio stats for V1_6
- */
- private static void setFrameworkPerRadioStatsFromHidl_1_6(RadioStat radio,
- android.hardware.wifi.V1_6.StaLinkLayerRadioStats hidlRadioStats) {
- radio.radio_id = hidlRadioStats.radioId;
- radio.on_time = hidlRadioStats.V1_0.onTimeInMs;
- radio.tx_time = hidlRadioStats.V1_0.txTimeInMs;
- radio.rx_time = hidlRadioStats.V1_0.rxTimeInMs;
- radio.on_time_scan = hidlRadioStats.V1_0.onTimeInMsForScan;
- radio.on_time_nan_scan = hidlRadioStats.onTimeInMsForNanScan;
- radio.on_time_background_scan = hidlRadioStats.onTimeInMsForBgScan;
- radio.on_time_roam_scan = hidlRadioStats.onTimeInMsForRoamScan;
- radio.on_time_pno_scan = hidlRadioStats.onTimeInMsForPnoScan;
- radio.on_time_hs20_scan = hidlRadioStats.onTimeInMsForHs20Scan;
- /* Copy list of channel stats */
- for (android.hardware.wifi.V1_6.WifiChannelStats channelStats
- : hidlRadioStats.channelStats) {
- ChannelStats channelStatsEntry = new ChannelStats();
- channelStatsEntry.frequency = channelStats.channel.centerFreq;
- channelStatsEntry.radioOnTimeMs = channelStats.onTimeInMs;
- channelStatsEntry.ccaBusyTimeMs = channelStats.ccaBusyTimeInMs;
- radio.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
- }
- }
-
- /**
- * If config_wifiLinkLayerAllRadiosStatsAggregationEnabled is set to true, aggregate
- * the radio stats from all the radios else process the stats from Radio 0 only.
- * This method is for V1_3
- */
- private static void aggregateFrameworkRadioStatsFromHidl_1_3(int radioIndex,
- WifiLinkLayerStats stats,
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats hidlRadioStats) {
- if (!sContext.getResources()
- .getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled)
- && radioIndex > 0) {
- return;
- }
- // Aggregate the radio stats from all the radios
- stats.on_time += hidlRadioStats.V1_0.onTimeInMs;
- stats.tx_time += hidlRadioStats.V1_0.txTimeInMs;
- // Aggregate tx_time_per_level based on the assumption that the length of
- // txTimeInMsPerLevel is the same across all radios. So txTimeInMsPerLevel on other
- // radios at array indices greater than the length of first radio will be dropped.
- if (stats.tx_time_per_level == null) {
- stats.tx_time_per_level = new int[hidlRadioStats.V1_0.txTimeInMsPerLevel.size()];
- }
- for (int i = 0; i < hidlRadioStats.V1_0.txTimeInMsPerLevel.size()
- && i < stats.tx_time_per_level.length; i++) {
- stats.tx_time_per_level[i] += hidlRadioStats.V1_0.txTimeInMsPerLevel.get(i);
- }
- stats.rx_time += hidlRadioStats.V1_0.rxTimeInMs;
- stats.on_time_scan += hidlRadioStats.V1_0.onTimeInMsForScan;
- stats.on_time_nan_scan += hidlRadioStats.onTimeInMsForNanScan;
- stats.on_time_background_scan += hidlRadioStats.onTimeInMsForBgScan;
- stats.on_time_roam_scan += hidlRadioStats.onTimeInMsForRoamScan;
- stats.on_time_pno_scan += hidlRadioStats.onTimeInMsForPnoScan;
- stats.on_time_hs20_scan += hidlRadioStats.onTimeInMsForHs20Scan;
- /* Copy list of channel stats */
- for (android.hardware.wifi.V1_3.WifiChannelStats channelStats
- : hidlRadioStats.channelStats) {
- ChannelStats channelStatsEntry =
- stats.channelStatsMap.get(channelStats.channel.centerFreq);
- if (channelStatsEntry == null) {
- channelStatsEntry = new ChannelStats();
- channelStatsEntry.frequency = channelStats.channel.centerFreq;
- stats.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
- }
- channelStatsEntry.radioOnTimeMs += channelStats.onTimeInMs;
- channelStatsEntry.ccaBusyTimeMs += channelStats.ccaBusyTimeInMs;
- }
- stats.numRadios++;
- }
-
- /**
- * If config_wifiLinkLayerAllRadiosStatsAggregationEnabled is set to true, aggregate
- * the radio stats from all the radios else process the stats from Radio 0 only.
- * This method is for V1_6
- */
- private static void aggregateFrameworkRadioStatsFromHidl_1_6(int radioIndex,
- WifiLinkLayerStats stats,
- android.hardware.wifi.V1_6.StaLinkLayerRadioStats hidlRadioStats) {
- if (!sContext.getResources()
- .getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled)
- && radioIndex > 0) {
- return;
- }
- // Aggregate the radio stats from all the radios
- stats.on_time += hidlRadioStats.V1_0.onTimeInMs;
- stats.tx_time += hidlRadioStats.V1_0.txTimeInMs;
- // Aggregate tx_time_per_level based on the assumption that the length of
- // txTimeInMsPerLevel is the same across all radios. So txTimeInMsPerLevel on other
- // radios at array indices greater than the length of first radio will be dropped.
- if (stats.tx_time_per_level == null) {
- stats.tx_time_per_level = new int[hidlRadioStats.V1_0.txTimeInMsPerLevel.size()];
- }
- for (int i = 0; i < hidlRadioStats.V1_0.txTimeInMsPerLevel.size()
- && i < stats.tx_time_per_level.length; i++) {
- stats.tx_time_per_level[i] += hidlRadioStats.V1_0.txTimeInMsPerLevel.get(i);
- }
- stats.rx_time += hidlRadioStats.V1_0.rxTimeInMs;
- stats.on_time_scan += hidlRadioStats.V1_0.onTimeInMsForScan;
- stats.on_time_nan_scan += hidlRadioStats.onTimeInMsForNanScan;
- stats.on_time_background_scan += hidlRadioStats.onTimeInMsForBgScan;
- stats.on_time_roam_scan += hidlRadioStats.onTimeInMsForRoamScan;
- stats.on_time_pno_scan += hidlRadioStats.onTimeInMsForPnoScan;
- stats.on_time_hs20_scan += hidlRadioStats.onTimeInMsForHs20Scan;
- /* Copy list of channel stats */
- for (android.hardware.wifi.V1_6.WifiChannelStats channelStats
- : hidlRadioStats.channelStats) {
- ChannelStats channelStatsEntry =
- stats.channelStatsMap.get(channelStats.channel.centerFreq);
- if (channelStatsEntry == null) {
- channelStatsEntry = new ChannelStats();
- channelStatsEntry.frequency = channelStats.channel.centerFreq;
- stats.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
- }
- channelStatsEntry.radioOnTimeMs += channelStats.onTimeInMs;
- channelStatsEntry.ccaBusyTimeMs += channelStats.ccaBusyTimeInMs;
- }
- stats.numRadios++;
- }
-
- private static void setRadioStats_1_3(WifiLinkLayerStats stats,
- List<android.hardware.wifi.V1_3.StaLinkLayerRadioStats> radios) {
- if (radios == null) return;
- int radioIndex = 0;
- for (android.hardware.wifi.V1_3.StaLinkLayerRadioStats radioStats : radios) {
- aggregateFrameworkRadioStatsFromHidl_1_3(radioIndex, stats, radioStats);
- radioIndex++;
- }
- }
-
- private static void setRadioStats_1_5(WifiLinkLayerStats stats,
- List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios) {
- if (radios == null) return;
- int radioIndex = 0;
- stats.radioStats = new RadioStat[radios.size()];
- for (android.hardware.wifi.V1_5.StaLinkLayerRadioStats radioStats : radios) {
- RadioStat radio = new RadioStat();
- setFrameworkPerRadioStatsFromHidl_1_3(radioStats.radioId, radio, radioStats.V1_3);
- stats.radioStats[radioIndex] = radio;
- aggregateFrameworkRadioStatsFromHidl_1_3(radioIndex, stats, radioStats.V1_3);
- radioIndex++;
- }
- }
-
- private static void setRadioStats_1_6(WifiLinkLayerStats stats,
- List<android.hardware.wifi.V1_6.StaLinkLayerRadioStats> radios) {
- if (radios == null) return;
- int radioIndex = 0;
- stats.radioStats = new RadioStat[radios.size()];
- for (android.hardware.wifi.V1_6.StaLinkLayerRadioStats radioStats : radios) {
- RadioStat radio = new RadioStat();
- setFrameworkPerRadioStatsFromHidl_1_6(radio, radioStats);
- stats.radioStats[radioIndex] = radio;
- aggregateFrameworkRadioStatsFromHidl_1_6(radioIndex, stats, radioStats);
- radioIndex++;
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return null;
+ return iface.getLinkLayerStats();
}
}
- private static void setTimeStamp(WifiLinkLayerStats stats, long timeStampInMs) {
- stats.timeStampInMs = timeStampInMs;
- }
-
@VisibleForTesting
boolean mLinkLayerStatsDebug = false; // Passed to Hal
@@ -1617,181 +717,20 @@ public class WifiVendorHal {
*
* This is called unconditionally whenever we create a STA interface.
*
- * @param iface Iface object.
+ * @param ifaceName Name of the interface.
*/
public void enableLinkLayerStats(@NonNull String ifaceName) {
synchronized (sLock) {
- try {
- WifiStatus status;
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) {
- mLog.err("STA iface object is NULL - Failed to enable link layer stats")
- .flush();
- return;
- }
- status = iface.enableLinkLayerStatsCollection(mLinkLayerStatsDebug);
- if (!ok(status)) {
- mLog.err("unable to enable link layer stats collection").flush();
- }
- } catch (RemoteException e) {
- handleRemoteException(e);
- }
- }
- }
-
- /**
- * Translation table used by getSupportedFeatureSet for translating IWifiChip caps for V1.1
- */
- private static final long[][] sChipFeatureCapabilityTranslation = {
- {WifiManager.WIFI_FEATURE_TX_POWER_LIMIT,
- android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT
- },
- {WifiManager.WIFI_FEATURE_D2D_RTT,
- android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
- },
- {WifiManager.WIFI_FEATURE_D2AP_RTT,
- android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2AP_RTT
- }
- };
-
- /**
- * Translation table used by getSupportedFeatureSet for translating IWifiChip caps for
- * additional capabilities introduced in V1.5
- */
- private static final long[][] sChipFeatureCapabilityTranslation15 = {
- {WifiManager.WIFI_FEATURE_INFRA_60G,
- android.hardware.wifi.V1_5.IWifiChip.ChipCapabilityMask.WIGIG
- }
- };
-
- /**
- * Translation table used by getSupportedFeatureSet for translating IWifiChip caps for
- * additional capabilities introduced in V1.3
- */
- private static final long[][] sChipFeatureCapabilityTranslation13 = {
- {WifiManager.WIFI_FEATURE_LOW_LATENCY,
- android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.SET_LATENCY_MODE
- },
- {WifiManager.WIFI_FEATURE_P2P_RAND_MAC,
- android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.P2P_RAND_MAC
- }
-
- };
-
- /**
- * Feature bit mask translation for Chip V1.1
- *
- * @param capabilities bitmask defined IWifiChip.ChipCapabilityMask
- * @return bitmask defined by WifiManager.WIFI_FEATURE_*
- */
- @VisibleForTesting
- int wifiFeatureMaskFromChipCapabilities(int capabilities) {
- int features = 0;
- for (int i = 0; i < sChipFeatureCapabilityTranslation.length; i++) {
- if ((capabilities & sChipFeatureCapabilityTranslation[i][1]) != 0) {
- features |= sChipFeatureCapabilityTranslation[i][0];
- }
- }
- return features;
- }
-
- /**
- * Feature bit mask translation for Chip V1.5
- *
- * @param capabilities bitmask defined IWifiChip.ChipCapabilityMask
- * @return bitmask defined by WifiManager.WIFI_FEATURE_*
- */
- @VisibleForTesting
- long wifiFeatureMaskFromChipCapabilities_1_5(int capabilities) {
- // First collect features from previous versions
- long features = wifiFeatureMaskFromChipCapabilities_1_3(capabilities);
-
- // Next collect features for V1_5 version
- for (int i = 0; i < sChipFeatureCapabilityTranslation15.length; i++) {
- if ((capabilities & sChipFeatureCapabilityTranslation15[i][1]) != 0) {
- features |= sChipFeatureCapabilityTranslation15[i][0];
- }
- }
- return features;
- }
-
- /**
- * Feature bit mask translation for Chip V1.3
- *
- * @param capabilities bitmask defined IWifiChip.ChipCapabilityMask
- * @return bitmask defined by WifiManager.WIFI_FEATURE_*
- */
- @VisibleForTesting
- long wifiFeatureMaskFromChipCapabilities_1_3(int capabilities) {
- // First collect features from previous versions
- long features = wifiFeatureMaskFromChipCapabilities(capabilities);
-
- // Next collect features for V1_3 version
- for (int i = 0; i < sChipFeatureCapabilityTranslation13.length; i++) {
- if ((capabilities & sChipFeatureCapabilityTranslation13[i][1]) != 0) {
- features |= sChipFeatureCapabilityTranslation13[i][0];
- }
- }
- return features;
- }
-
- /**
- * Translation table used by getSupportedFeatureSet for translating IWifiStaIface caps
- */
- private static final long[][] sStaFeatureCapabilityTranslation = {
- {WifiManager.WIFI_FEATURE_PASSPOINT,
- IWifiStaIface.StaIfaceCapabilityMask.HOTSPOT
- },
- {WifiManager.WIFI_FEATURE_SCANNER,
- IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN,
- },
- {WifiManager.WIFI_FEATURE_PNO,
- IWifiStaIface.StaIfaceCapabilityMask.PNO
- },
- {WifiManager.WIFI_FEATURE_TDLS,
- IWifiStaIface.StaIfaceCapabilityMask.TDLS
- },
- {WifiManager.WIFI_FEATURE_TDLS_OFFCHANNEL,
- IWifiStaIface.StaIfaceCapabilityMask.TDLS_OFFCHANNEL
- },
- {WifiManager.WIFI_FEATURE_LINK_LAYER_STATS,
- IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
- },
- {WifiManager.WIFI_FEATURE_RSSI_MONITOR,
- IWifiStaIface.StaIfaceCapabilityMask.RSSI_MONITOR
- },
- {WifiManager.WIFI_FEATURE_MKEEP_ALIVE,
- IWifiStaIface.StaIfaceCapabilityMask.KEEP_ALIVE
- },
- {WifiManager.WIFI_FEATURE_CONFIG_NDO,
- IWifiStaIface.StaIfaceCapabilityMask.ND_OFFLOAD
- },
- {WifiManager.WIFI_FEATURE_CONTROL_ROAMING,
- IWifiStaIface.StaIfaceCapabilityMask.CONTROL_ROAMING
- },
- {WifiManager.WIFI_FEATURE_IE_WHITELIST,
- IWifiStaIface.StaIfaceCapabilityMask.PROBE_IE_WHITELIST
- },
- {WifiManager.WIFI_FEATURE_SCAN_RAND,
- IWifiStaIface.StaIfaceCapabilityMask.SCAN_RAND
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) {
+ mLog.err("STA iface object is NULL - Failed to enable link layer stats")
+ .flush();
+ return;
}
- };
-
- /**
- * Feature bit mask translation for STAs
- *
- * @param capabilities bitmask defined IWifiStaIface.StaIfaceCapabilityMask
- * @return bitmask defined by WifiManager.WIFI_FEATURE_*
- */
- @VisibleForTesting
- long wifiFeatureMaskFromStaCapabilities(int capabilities) {
- long features = 0;
- for (int i = 0; i < sStaFeatureCapabilityTranslation.length; i++) {
- if ((capabilities & sStaFeatureCapabilityTranslation[i][1]) != 0) {
- features |= sStaFeatureCapabilityTranslation[i][0];
+ if (!iface.enableLinkLayerStatsCollection(mLinkLayerStatsDebug)) {
+ mLog.err("unable to enable link layer stats collection").flush();
}
}
- return features;
}
/**
@@ -1831,44 +770,29 @@ public class WifiVendorHal {
* @return bitmask defined by WifiManager.WIFI_FEATURE_*
*/
public long getSupportedFeatureSet(@NonNull String ifaceName) {
- long featureSet = 0;
+ long featureSet = 0L;
if (!mHalDeviceManager.isStarted() || !mHalDeviceManager.isSupported()) {
return getSupportedFeatureSetFromPackageManager();
}
- try {
- final Mutable<Long> feat = new Mutable<>(0L);
- synchronized (sLock) {
- android.hardware.wifi.V1_3.IWifiChip iWifiChipV13 = getWifiChipForV1_3Mockable();
- android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 = getWifiChipForV1_5Mockable();
- if (iWifiChipV15 != null) {
- iWifiChipV15.getCapabilities_1_5((status, capabilities) -> {
- if (!ok(status)) return;
- feat.value = wifiFeatureMaskFromChipCapabilities_1_5(capabilities);
- });
- } else if (iWifiChipV13 != null) {
- iWifiChipV13.getCapabilities_1_3((status, capabilities) -> {
- if (!ok(status)) return;
- feat.value = wifiFeatureMaskFromChipCapabilities_1_3(capabilities);
- });
- } else if (mIWifiChip != null) {
- mIWifiChip.getCapabilities((status, capabilities) -> {
- if (!ok(status)) return;
- feat.value = (long) wifiFeatureMaskFromChipCapabilities(capabilities);
- });
+
+ synchronized (sLock) {
+ if (mWifiChip != null) {
+ WifiChip.Response<Long> capsResp = mWifiChip.getCapabilitiesAfterIfacesExist();
+ if (capsResp.getStatusCode() == WifiHal.WIFI_STATUS_SUCCESS) {
+ featureSet = capsResp.getValue();
+ } else if (capsResp.getStatusCode() == WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION) {
+ return 0;
}
+ }
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface != null) {
- iface.getCapabilities((status, capabilities) -> {
- if (!ok(status)) return;
- feat.value |= wifiFeatureMaskFromStaCapabilities(capabilities);
- });
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface != null) {
+ featureSet |= iface.getCapabilities();
+ if (mHalDeviceManager.is24g5gDbsSupported(iface)
+ || mHalDeviceManager.is5g6gDbsSupported(iface)) {
+ featureSet |= WifiManager.WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS;
}
}
- featureSet = feat.value;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return 0;
}
if (mWifiGlobals.isWpa3SaeH2eSupported()) {
@@ -1876,16 +800,16 @@ public class WifiVendorHal {
}
Set<Integer> supportedIfaceTypes = mHalDeviceManager.getSupportedIfaceTypes();
- if (supportedIfaceTypes.contains(IfaceType.STA)) {
+ if (supportedIfaceTypes.contains(WifiChip.IFACE_TYPE_STA)) {
featureSet |= WifiManager.WIFI_FEATURE_INFRA;
}
- if (supportedIfaceTypes.contains(IfaceType.AP)) {
+ if (supportedIfaceTypes.contains(WifiChip.IFACE_TYPE_AP)) {
featureSet |= WifiManager.WIFI_FEATURE_MOBILE_HOTSPOT;
}
- if (supportedIfaceTypes.contains(IfaceType.P2P)) {
+ if (supportedIfaceTypes.contains(WifiChip.IFACE_TYPE_P2P)) {
featureSet |= WifiManager.WIFI_FEATURE_P2P;
}
- if (supportedIfaceTypes.contains(IfaceType.NAN)) {
+ if (supportedIfaceTypes.contains(WifiChip.IFACE_TYPE_NAN)) {
featureSet |= WifiManager.WIFI_FEATURE_AWARE;
}
@@ -1900,17 +824,10 @@ public class WifiVendorHal {
* @return true for success
*/
public boolean setStaMacAddress(@NonNull String ifaceName, @NonNull MacAddress mac) {
- byte[] macByteArray = mac.toByteArray();
synchronized (sLock) {
- try {
- android.hardware.wifi.V1_2.IWifiStaIface sta12 =
- getWifiStaIfaceForV1_2Mockable(ifaceName);
- if (sta12 == null) return boolResult(false);
- return ok(sta12.setMacAddress(macByteArray));
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
+ return iface.setMacAddress(mac);
}
}
@@ -1922,18 +839,9 @@ public class WifiVendorHal {
*/
public boolean resetApMacToFactoryMacAddress(@NonNull String ifaceName) {
synchronized (sLock) {
- try {
- android.hardware.wifi.V1_5.IWifiApIface ap15 =
- getWifiApIfaceForV1_5Mockable(ifaceName);
- if (ap15 == null) {
- MacAddress mac = getApFactoryMacAddress(ifaceName);
- return mac != null && setApMacAddress(ifaceName, mac);
- }
- return ok(ap15.resetToFactoryMacAddress());
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ WifiApIface iface = getApIface(ifaceName);
+ if (iface == null) return false;
+ return iface.resetToFactoryMacAddress();
}
}
@@ -1945,30 +853,10 @@ public class WifiVendorHal {
* @return true for success
*/
public boolean setApMacAddress(@NonNull String ifaceName, @NonNull MacAddress mac) {
- byte[] macByteArray = mac.toByteArray();
- synchronized (sLock) {
- try {
- android.hardware.wifi.V1_4.IWifiApIface ap14 =
- getWifiApIfaceForV1_4Mockable(ifaceName);
- if (ap14 == null) return boolResult(false);
- return ok(ap14.setMacAddress(macByteArray));
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- }
-
- /**
- * Returns true if Hal version supports setMacAddress, otherwise false.
- *
- * @param ifaceName Name of the interface
- */
- public boolean isStaSetMacAddressSupported(@NonNull String ifaceName) {
synchronized (sLock) {
- android.hardware.wifi.V1_2.IWifiStaIface sta12 =
- getWifiStaIfaceForV1_2Mockable(ifaceName);
- return sta12 != null;
+ WifiApIface iface = getApIface(ifaceName);
+ if (iface == null) return false;
+ return iface.setMacAddress(mac);
}
}
@@ -1979,9 +867,9 @@ public class WifiVendorHal {
*/
public boolean isApSetMacAddressSupported(@NonNull String ifaceName) {
synchronized (sLock) {
- android.hardware.wifi.V1_4.IWifiApIface ap14 =
- getWifiApIfaceForV1_4Mockable(ifaceName);
- return ap14 != null;
+ WifiApIface iface = getApIface(ifaceName);
+ if (iface == null) return false;
+ return iface.isSetMacAddressSupported();
}
}
@@ -1992,25 +880,10 @@ public class WifiVendorHal {
* @return factory MAC address of the interface or null.
*/
public MacAddress getStaFactoryMacAddress(@NonNull String ifaceName) {
- class AnswerBox {
- public MacAddress mac = null;
- }
synchronized (sLock) {
- try {
- AnswerBox box = new AnswerBox();
-
- android.hardware.wifi.V1_3.IWifiStaIface sta13 =
- getWifiStaIfaceForV1_3Mockable(ifaceName);
- if (sta13 == null) return null;
- sta13.getFactoryMacAddress((status, macBytes) -> {
- if (!ok(status)) return;
- box.mac = MacAddress.fromBytes(macBytes);
- });
- return box.mac;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return null;
+ return iface.getFactoryMacAddress();
}
}
@@ -2021,24 +894,10 @@ public class WifiVendorHal {
* @return factory MAC address of the interface or null.
*/
public MacAddress getApFactoryMacAddress(@NonNull String ifaceName) {
- class AnswerBox {
- public MacAddress mac = null;
- }
synchronized (sLock) {
- try {
- AnswerBox box = new AnswerBox();
- android.hardware.wifi.V1_4.IWifiApIface ap14 =
- getWifiApIfaceForV1_4Mockable(ifaceName);
- if (ap14 == null) return null;
- ap14.getFactoryMacAddress((status, macBytes) -> {
- if (!ok(status)) return;
- box.mac = MacAddress.fromBytes(macBytes);
- });
- return box.mac;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
+ WifiApIface iface = getApIface(ifaceName);
+ if (iface == null) return null;
+ return iface.getFactoryMacAddress();
}
}
@@ -2049,26 +908,10 @@ public class WifiVendorHal {
* @return APF capabilities object.
*/
public ApfCapabilities getApfCapabilities(@NonNull String ifaceName) {
- class AnswerBox {
- public ApfCapabilities value = sNoApfCapabilities;
- }
synchronized (sLock) {
- try {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return sNoApfCapabilities;
- AnswerBox box = new AnswerBox();
- iface.getApfPacketFilterCapabilities((status, capabilities) -> {
- if (!ok(status)) return;
- box.value = new ApfCapabilities(
- /* apfVersionSupported */ capabilities.version,
- /* maximumApfProgramSize */ capabilities.maxLength,
- /* apfPacketFormat */ android.system.OsConstants.ARPHRD_ETHER);
- });
- return box.value;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return sNoApfCapabilities;
- }
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return sNoApfCapabilities;
+ return iface.getApfPacketFilterCapabilities();
}
}
@@ -2082,22 +925,12 @@ public class WifiVendorHal {
* @return true for success
*/
public boolean installPacketFilter(@NonNull String ifaceName, byte[] filter) {
- int cmdId = 0; // We only aspire to support one program at a time
- if (filter == null) return boolResult(false);
- // Copy the program before taking the lock.
- ArrayList<Byte> program = NativeUtil.byteArrayToArrayList(filter);
+ if (filter == null) return false;
enter("filter length %").c(filter.length).flush();
synchronized (sLock) {
- try {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return boolResult(false);
- WifiStatus status = iface.installApfPacketFilter(cmdId, program);
- if (!ok(status)) return false;
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
+ return iface.installApfPacketFilter(filter);
}
}
@@ -2108,26 +941,12 @@ public class WifiVendorHal {
* @return the buffer returned by the driver, or null in case of an error
*/
public byte[] readPacketFilter(@NonNull String ifaceName) {
- class AnswerBox {
- public byte[] data = null;
- }
- AnswerBox answer = new AnswerBox();
enter("").flush();
// TODO: Must also take the wakelock here to prevent going to sleep with APF disabled.
synchronized (sLock) {
- try {
- android.hardware.wifi.V1_2.IWifiStaIface ifaceV12 =
- getWifiStaIfaceForV1_2Mockable(ifaceName);
- if (ifaceV12 == null) return byteArrayResult(null);
- ifaceV12.readApfPacketFilterData((status, dataByteArray) -> {
- if (!ok(status)) return;
- answer.data = NativeUtil.byteArrayFromArrayList(dataByteArray);
- });
- return byteArrayResult(answer.data);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return byteArrayResult(null);
- }
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return null;
+ return iface.readApfPacketFilterData();
}
}
@@ -2138,25 +957,9 @@ public class WifiVendorHal {
* @return true for success
*/
public boolean setChipCountryCode(String countryCode) {
- if (countryCode == null) return boolResult(false);
- if (countryCode.length() != 2) return boolResult(false);
- byte[] code;
- try {
- code = NativeUtil.stringToByteArray(countryCode);
- } catch (IllegalArgumentException e) {
- return boolResult(false);
- }
synchronized (sLock) {
- try {
- android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 = getWifiChipForV1_5Mockable();
- if (iWifiChipV15 == null) return boolResult(false);
- WifiStatus status = iWifiChipV15.setCountryCode(code);
- if (!ok(status)) return false;
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ if (mWifiChip == null) return false;
+ return mWifiChip.setCountryCode(countryCode);
}
}
@@ -2169,20 +972,9 @@ public class WifiVendorHal {
@Nullable
public List<String> getBridgedApInstances(@NonNull String ifaceName) {
synchronized (sLock) {
- try {
- Mutable<List<String>> instancesResp = new Mutable<>();
- android.hardware.wifi.V1_5.IWifiApIface ap15 =
- getWifiApIfaceForV1_5Mockable(ifaceName);
- if (ap15 == null) return null;
- ap15.getBridgedInstances((status, instances) -> {
- if (!ok(status)) return;
- instancesResp.value = new ArrayList<>(instances);
- });
- return instancesResp.value;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
+ WifiApIface iface = getApIface(ifaceName);
+ if (iface == null) return null;
+ return iface.getBridgedInstances();
}
}
@@ -2194,25 +986,10 @@ public class WifiVendorHal {
* @return true for success
*/
public boolean setApCountryCode(@NonNull String ifaceName, String countryCode) {
- if (countryCode == null) return boolResult(false);
- if (countryCode.length() != 2) return boolResult(false);
- byte[] code;
- try {
- code = NativeUtil.stringToByteArray(countryCode);
- } catch (IllegalArgumentException e) {
- return boolResult(false);
- }
synchronized (sLock) {
- try {
- IWifiApIface iface = getApIface(ifaceName);
- if (iface == null) return boolResult(false);
- WifiStatus status = iface.setCountryCode(code);
- if (!ok(status)) return false;
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ WifiApIface iface = getApIface(ifaceName);
+ if (iface == null) return false;
+ return iface.setCountryCode(countryCode);
}
}
@@ -2223,19 +1000,15 @@ public class WifiVendorHal {
* Ring buffer data collection is only triggered when |startLoggingRingBuffer| is invoked.
*/
public boolean setLoggingEventHandler(WifiNative.WifiLoggerEventHandler handler) {
- if (handler == null) return boolResult(false);
+ if (handler == null) return false;
synchronized (sLock) {
- if (mIWifiChip == null) return boolResult(false);
- if (mLogEventHandler != null) return boolResult(false);
- try {
- WifiStatus status = mIWifiChip.enableDebugErrorAlerts(true);
- if (!ok(status)) return false;
- mLogEventHandler = handler;
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
+ if (mWifiChip == null) return false;
+ if (mLogEventHandler != null) return false;
+ if (!mWifiChip.enableDebugErrorAlerts(true)) {
return false;
}
+ mLogEventHandler = handler;
+ return true;
}
}
@@ -2247,17 +1020,11 @@ public class WifiVendorHal {
public boolean resetLogHandler() {
synchronized (sLock) {
mLogEventHandler = null;
- if (mIWifiChip == null) return boolResult(false);
- try {
- WifiStatus status = mIWifiChip.enableDebugErrorAlerts(false);
- if (!ok(status)) return false;
- status = mIWifiChip.stopLoggingToDebugRingBuffer();
- if (!ok(status)) return false;
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
+ if (mWifiChip == null) return false;
+ if (!mWifiChip.enableDebugErrorAlerts(false)) {
return false;
}
+ return mWifiChip.stopLoggingToDebugRingBuffer();
}
}
@@ -2277,20 +1044,13 @@ public class WifiVendorHal {
.c(verboseLevel).c(flags).c(maxIntervalInSec).c(minDataSizeInBytes).c(ringName)
.flush();
synchronized (sLock) {
- if (mIWifiChip == null) return boolResult(false);
- try {
- // note - flags are not used
- WifiStatus status = mIWifiChip.startLoggingToDebugRingBuffer(
- ringName,
- verboseLevel,
- maxIntervalInSec,
- minDataSizeInBytes
- );
- return ok(status);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ if (mWifiChip == null) return false;
+ return mWifiChip.startLoggingToDebugRingBuffer(
+ ringName,
+ verboseLevel,
+ maxIntervalInSec,
+ minDataSizeInBytes
+ );
}
}
@@ -2333,16 +1093,12 @@ public class WifiVendorHal {
private void requestChipDebugInfo() {
mDriverDescription = null;
mFirmwareDescription = null;
- try {
- if (mIWifiChip == null) return;
- mIWifiChip.requestChipDebugInfo((status, chipDebugInfo) -> {
- if (!ok(status)) return;
- mDriverDescription = chipDebugInfo.driverDescription;
- mFirmwareDescription = chipDebugInfo.firmwareDescription;
- });
- } catch (RemoteException e) {
- handleRemoteException(e);
- return;
+ synchronized (sLock) {
+ if (mWifiChip == null) return;
+ WifiChip.ChipDebugInfo info = mWifiChip.requestChipDebugInfo();
+ if (info == null) return;
+ mDriverDescription = info.driverDescription;
+ mFirmwareDescription = info.firmwareDescription;
}
mLog.info("Driver: % Firmware: %")
.c(mDriverDescription)
@@ -2351,77 +1107,19 @@ public class WifiVendorHal {
}
/**
- * Creates RingBufferStatus from the Hal version
- */
- private static WifiNative.RingBufferStatus ringBufferStatus(WifiDebugRingBufferStatus h) {
- WifiNative.RingBufferStatus ans = new WifiNative.RingBufferStatus();
- ans.name = h.ringName;
- ans.flag = frameworkRingBufferFlagsFromHal(h.flags);
- ans.ringBufferId = h.ringId;
- ans.ringBufferByteSize = h.sizeInBytes;
- ans.verboseLevel = h.verboseLevel;
- // Remaining fields are unavailable
- // writtenBytes;
- // readBytes;
- // writtenRecords;
- return ans;
- }
-
- /**
- * Translates a hal wifiDebugRingBufferFlag to the WifiNative version
- */
- private static int frameworkRingBufferFlagsFromHal(int wifiDebugRingBufferFlag) {
- BitMask checkoff = new BitMask(wifiDebugRingBufferFlag);
- int flags = 0;
- if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES)) {
- flags |= WifiNative.RingBufferStatus.HAS_BINARY_ENTRIES;
- }
- if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES)) {
- flags |= WifiNative.RingBufferStatus.HAS_ASCII_ENTRIES;
- }
- if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES)) {
- flags |= WifiNative.RingBufferStatus.HAS_PER_PACKET_ENTRIES;
- }
- if (checkoff.value != 0) {
- throw new IllegalArgumentException("Unknown WifiDebugRingBufferFlag " + checkoff.value);
- }
- return flags;
- }
-
- /**
- * Creates array of RingBufferStatus from the Hal version
- */
- private static WifiNative.RingBufferStatus[] makeRingBufferStatusArray(
- ArrayList<WifiDebugRingBufferStatus> ringBuffers) {
- WifiNative.RingBufferStatus[] ans = new WifiNative.RingBufferStatus[ringBuffers.size()];
- int i = 0;
- for (WifiDebugRingBufferStatus b : ringBuffers) {
- ans[i++] = ringBufferStatus(b);
- }
- return ans;
- }
-
- /**
* API to get the status of all ring buffers supported by driver
*/
public WifiNative.RingBufferStatus[] getRingBufferStatus() {
- class AnswerBox {
- public WifiNative.RingBufferStatus[] value = null;
- }
- AnswerBox ans = new AnswerBox();
synchronized (sLock) {
- if (mIWifiChip == null) return null;
- try {
- mIWifiChip.getDebugRingBuffersStatus((status, ringBuffers) -> {
- if (!ok(status)) return;
- ans.value = makeRingBufferStatusArray(ringBuffers);
- });
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
+ if (mWifiChip == null) return null;
+ List<WifiNative.RingBufferStatus> statusList = mWifiChip.getDebugRingBuffersStatus();
+ if (statusList == null) return null;
+
+ WifiNative.RingBufferStatus[] statusArray =
+ new WifiNative.RingBufferStatus[statusList.size()];
+ statusList.toArray(statusArray);
+ return statusArray;
}
- return ans.value;
}
/**
@@ -2430,14 +1128,8 @@ public class WifiVendorHal {
public boolean getRingBufferData(String ringName) {
enter("ringName %").c(ringName).flush();
synchronized (sLock) {
- if (mIWifiChip == null) return boolResult(false);
- try {
- WifiStatus status = mIWifiChip.forceDumpToDebugRingBuffer(ringName);
- return ok(status);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ if (mWifiChip == null) return false;
+ return mWifiChip.forceDumpToDebugRingBuffer(ringName);
}
}
@@ -2446,18 +1138,8 @@ public class WifiVendorHal {
*/
public boolean flushRingBufferData() {
synchronized (sLock) {
- if (mIWifiChip == null) return boolResult(false);
- android.hardware.wifi.V1_3.IWifiChip iWifiChipV13 = getWifiChipForV1_3Mockable();
- if (iWifiChipV13 != null) {
- try {
- WifiStatus status = iWifiChipV13.flushRingBufferToFile();
- return ok(status);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- return false;
+ if (mWifiChip == null) return false;
+ return mWifiChip.flushRingBufferToFile();
}
}
@@ -2465,46 +1147,20 @@ public class WifiVendorHal {
* Request vendor debug info from the firmware
*/
public byte[] getFwMemoryDump() {
- class AnswerBox {
- public byte[] value;
- }
- AnswerBox ans = new AnswerBox();
synchronized (sLock) {
- if (mIWifiChip == null) return (null);
- try {
- mIWifiChip.requestFirmwareDebugDump((status, blob) -> {
- if (!ok(status)) return;
- ans.value = NativeUtil.byteArrayFromArrayList(blob);
- });
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
+ if (mWifiChip == null) return null;
+ return mWifiChip.requestFirmwareDebugDump();
}
- return ans.value;
}
/**
* Request vendor debug info from the driver
*/
public byte[] getDriverStateDump() {
- class AnswerBox {
- public byte[] value;
- }
- AnswerBox ans = new AnswerBox();
synchronized (sLock) {
- if (mIWifiChip == null) return (null);
- try {
- mIWifiChip.requestDriverDebugDump((status, blob) -> {
- if (!ok(status)) return;
- ans.value = NativeUtil.byteArrayFromArrayList(blob);
- });
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
+ if (mWifiChip == null) return (null);
+ return mWifiChip.requestDriverDebugDump();
}
- return ans.value;
}
/**
@@ -2517,84 +1173,9 @@ public class WifiVendorHal {
*/
public boolean startPktFateMonitoring(@NonNull String ifaceName) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return boolResult(false);
- try {
- WifiStatus status = iface.startDebugPacketFateMonitoring();
- return ok(status);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- }
-
- private byte halToFrameworkPktFateFrameType(int type) {
- switch (type) {
- case WifiDebugPacketFateFrameType.UNKNOWN:
- return WifiLoggerHal.FRAME_TYPE_UNKNOWN;
- case WifiDebugPacketFateFrameType.ETHERNET_II:
- return WifiLoggerHal.FRAME_TYPE_ETHERNET_II;
- case WifiDebugPacketFateFrameType.MGMT_80211:
- return WifiLoggerHal.FRAME_TYPE_80211_MGMT;
- default:
- throw new IllegalArgumentException("bad " + type);
- }
- }
-
- private byte halToFrameworkRxPktFate(int type) {
- switch (type) {
- case WifiDebugRxPacketFate.SUCCESS:
- return WifiLoggerHal.RX_PKT_FATE_SUCCESS;
- case WifiDebugRxPacketFate.FW_QUEUED:
- return WifiLoggerHal.RX_PKT_FATE_FW_QUEUED;
- case WifiDebugRxPacketFate.FW_DROP_FILTER:
- return WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER;
- case WifiDebugRxPacketFate.FW_DROP_INVALID:
- return WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID;
- case WifiDebugRxPacketFate.FW_DROP_NOBUFS:
- return WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS;
- case WifiDebugRxPacketFate.FW_DROP_OTHER:
- return WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER;
- case WifiDebugRxPacketFate.DRV_QUEUED:
- return WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED;
- case WifiDebugRxPacketFate.DRV_DROP_FILTER:
- return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER;
- case WifiDebugRxPacketFate.DRV_DROP_INVALID:
- return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID;
- case WifiDebugRxPacketFate.DRV_DROP_NOBUFS:
- return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS;
- case WifiDebugRxPacketFate.DRV_DROP_OTHER:
- return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER;
- default:
- throw new IllegalArgumentException("bad " + type);
- }
- }
-
- private byte halToFrameworkTxPktFate(int type) {
- switch (type) {
- case WifiDebugTxPacketFate.ACKED:
- return WifiLoggerHal.TX_PKT_FATE_ACKED;
- case WifiDebugTxPacketFate.SENT:
- return WifiLoggerHal.TX_PKT_FATE_SENT;
- case WifiDebugTxPacketFate.FW_QUEUED:
- return WifiLoggerHal.TX_PKT_FATE_FW_QUEUED;
- case WifiDebugTxPacketFate.FW_DROP_INVALID:
- return WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID;
- case WifiDebugTxPacketFate.FW_DROP_NOBUFS:
- return WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS;
- case WifiDebugTxPacketFate.FW_DROP_OTHER:
- return WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER;
- case WifiDebugTxPacketFate.DRV_QUEUED:
- return WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED;
- case WifiDebugTxPacketFate.DRV_DROP_INVALID:
- return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID;
- case WifiDebugTxPacketFate.DRV_DROP_NOBUFS:
- return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS;
- case WifiDebugTxPacketFate.DRV_DROP_OTHER:
- return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER;
- default:
- throw new IllegalArgumentException("bad " + type);
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
+ return iface.startDebugPacketFateMonitoring();
}
}
@@ -2609,27 +1190,9 @@ public class WifiVendorHal {
*/
public List<TxFateReport> getTxPktFates(@NonNull String ifaceName) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return objResult(new ArrayList<>());
- try {
- List<TxFateReport> reportBufs = new ArrayList<>();
- iface.getDebugTxPacketFates((status, fates) -> {
- if (!ok(status)) return;
- for (WifiDebugTxPacketFateReport fate : fates) {
- if (reportBufs.size() >= WifiLoggerHal.MAX_FATE_LOG_LEN) break;
- byte code = halToFrameworkTxPktFate(fate.fate);
- long us = fate.frameInfo.driverTimestampUsec;
- byte type = halToFrameworkPktFateFrameType(fate.frameInfo.frameType);
- byte[] frame = NativeUtil.byteArrayFromArrayList(
- fate.frameInfo.frameContent);
- reportBufs.add(new TxFateReport(code, us, type, frame));
- }
- });
- return reportBufs;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return new ArrayList<>();
- }
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return new ArrayList<>();
+ return iface.getDebugTxPacketFates();
}
}
@@ -2644,27 +1207,9 @@ public class WifiVendorHal {
*/
public List<RxFateReport> getRxPktFates(@NonNull String ifaceName) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return objResult(new ArrayList<>());
- try {
- List<RxFateReport> reportBufs = new ArrayList<>();
- iface.getDebugRxPacketFates((status, fates) -> {
- if (!ok(status)) return;
- for (WifiDebugRxPacketFateReport fate : fates) {
- if (reportBufs.size() >= WifiLoggerHal.MAX_FATE_LOG_LEN) break;
- byte code = halToFrameworkRxPktFate(fate.fate);
- long us = fate.frameInfo.driverTimestampUsec;
- byte type = halToFrameworkPktFateFrameType(fate.frameInfo.frameType);
- byte[] frame = NativeUtil.byteArrayFromArrayList(
- fate.frameInfo.frameContent);
- reportBufs.add(new RxFateReport(code, us, type, frame));
- }
- });
- return reportBufs;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return new ArrayList<>();
- }
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return new ArrayList<>();
+ return iface.getDebugRxPacketFates();
}
}
@@ -2672,38 +1217,37 @@ public class WifiVendorHal {
* Start sending the specified keep alive packets periodically.
*
* @param ifaceName Name of the interface.
- * @param slot
- * @param srcMac
- * @param dstMac
- * @param keepAlivePacket
- * @param protocol
- * @param periodInMs
+ * @param slot Command ID to use for this invocation.
+ * @param srcAddr Source MAC address of the packet.
+ * @param dstAddr Destination MAC address of the packet.
+ * @param packet IP packet contents to be transmitted.
+ * @param protocol Ether type to be set in the ethernet frame transmitted.
+ * @param periodInMs Interval at which this packet must be transmitted.
* @return 0 for success, -1 for error
*/
public int startSendingOffloadedPacket(
- @NonNull String ifaceName, int slot, byte[] srcMac, byte[] dstMac,
+ @NonNull String ifaceName, int slot, byte[] srcAddr, byte[] dstAddr,
byte[] packet, int protocol, int periodInMs) {
enter("slot=% periodInMs=%").c(slot).c(periodInMs).flush();
-
- ArrayList<Byte> data = NativeUtil.byteArrayToArrayList(packet);
-
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
+ WifiStaIface iface = getStaIface(ifaceName);
if (iface == null) return -1;
+ MacAddress srcMac, dstMac;
try {
- WifiStatus status = iface.startSendingKeepAlivePackets(
+ srcMac = MacAddress.fromBytes(srcAddr);
+ dstMac = MacAddress.fromBytes(dstAddr);
+ } catch (IllegalArgumentException e) {
+ mLog.info("Invalid MacAddress in startSendingOffloadedPacket").flush();
+ return -1;
+ }
+ boolean success = iface.startSendingKeepAlivePackets(
slot,
- data,
+ packet,
(short) protocol,
srcMac,
dstMac,
periodInMs);
- if (!ok(status)) return -1;
- return 0;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return -1;
- }
+ return success ? 0 : -1;
}
}
@@ -2718,16 +1262,10 @@ public class WifiVendorHal {
enter("slot=%").c(slot).flush();
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
+ WifiStaIface iface = getStaIface(ifaceName);
if (iface == null) return -1;
- try {
- WifiStatus status = iface.stopSendingKeepAlivePackets(slot);
- if (!ok(status)) return -1;
- return 0;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return -1;
- }
+ boolean success = iface.stopSendingKeepAlivePackets(slot);
+ return success ? 0 : -1;
}
}
@@ -2757,19 +1295,12 @@ public class WifiVendorHal {
if (maxRssi <= minRssi) return -1;
if (rssiEventHandler == null) return -1;
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
+ WifiStaIface iface = getStaIface(ifaceName);
if (iface == null) return -1;
- try {
- iface.stopRssiMonitoring(sRssiMonCmdId);
- WifiStatus status;
- status = iface.startRssiMonitoring(sRssiMonCmdId, maxRssi, minRssi);
- if (!ok(status)) return -1;
- mWifiRssiEventHandler = rssiEventHandler;
- return 0;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return -1;
- }
+ iface.stopRssiMonitoring(sRssiMonCmdId);
+ if (!iface.startRssiMonitoring(sRssiMonCmdId, maxRssi, minRssi)) return -1;
+ mWifiRssiEventHandler = rssiEventHandler;
+ return 0;
}
}
@@ -2782,80 +1313,22 @@ public class WifiVendorHal {
public int stopRssiMonitoring(@NonNull String ifaceName) {
synchronized (sLock) {
mWifiRssiEventHandler = null;
- IWifiStaIface iface = getStaIface(ifaceName);
+ WifiStaIface iface = getStaIface(ifaceName);
if (iface == null) return -1;
- try {
- WifiStatus status = iface.stopRssiMonitoring(sRssiMonCmdId);
- if (!ok(status)) return -1;
- return 0;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return -1;
- }
+ boolean success = iface.stopRssiMonitoring(sRssiMonCmdId);
+ return success ? 0 : -1;
}
}
- //TODO - belongs in NativeUtil
- private static int[] intsFromArrayList(ArrayList<Integer> a) {
- if (a == null) return null;
- int[] b = new int[a.size()];
- int i = 0;
- for (Integer e : a) b[i++] = e;
- return b;
- }
-
- /**
- * Translates from Hal version of wake reason stats to the framework version of same
- *
- * @param h - Hal version of wake reason stats
- * @return framework version of same
- */
- private static WlanWakeReasonAndCounts halToFrameworkWakeReasons(
- WifiDebugHostWakeReasonStats h) {
- if (h == null) return null;
- WlanWakeReasonAndCounts ans = new WlanWakeReasonAndCounts();
- ans.totalCmdEventWake = h.totalCmdEventWakeCnt;
- ans.totalDriverFwLocalWake = h.totalDriverFwLocalWakeCnt;
- ans.totalRxDataWake = h.totalRxPacketWakeCnt;
- ans.rxUnicast = h.rxPktWakeDetails.rxUnicastCnt;
- ans.rxMulticast = h.rxPktWakeDetails.rxMulticastCnt;
- ans.rxBroadcast = h.rxPktWakeDetails.rxBroadcastCnt;
- ans.icmp = h.rxIcmpPkWakeDetails.icmpPkt;
- ans.icmp6 = h.rxIcmpPkWakeDetails.icmp6Pkt;
- ans.icmp6Ra = h.rxIcmpPkWakeDetails.icmp6Ra;
- ans.icmp6Na = h.rxIcmpPkWakeDetails.icmp6Na;
- ans.icmp6Ns = h.rxIcmpPkWakeDetails.icmp6Ns;
- ans.ipv4RxMulticast = h.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt;
- ans.ipv6Multicast = h.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt;
- ans.otherRxMulticast = h.rxMulticastPkWakeDetails.otherRxMulticastAddrCnt;
- ans.cmdEventWakeCntArray = intsFromArrayList(h.cmdEventWakeCntPerType);
- ans.driverFWLocalWakeCntArray = intsFromArrayList(h.driverFwLocalWakeCntPerType);
- return ans;
- }
-
/**
* Fetch the host wakeup reasons stats from wlan driver.
*
* @return the |WlanWakeReasonAndCounts| from the wlan driver, or null on failure.
*/
public WlanWakeReasonAndCounts getWlanWakeReasonCount() {
- class AnswerBox {
- public WifiDebugHostWakeReasonStats value = null;
- }
- AnswerBox ans = new AnswerBox();
synchronized (sLock) {
- if (mIWifiChip == null) return null;
- try {
- mIWifiChip.getDebugHostWakeReasonStats((status, stats) -> {
- if (ok(status)) {
- ans.value = stats;
- }
- });
- return halToFrameworkWakeReasons(ans.value);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
+ if (mWifiChip == null) return null;
+ return mWifiChip.getDebugHostWakeReasonStats();
}
}
@@ -2869,17 +1342,10 @@ public class WifiVendorHal {
public boolean configureNeighborDiscoveryOffload(@NonNull String ifaceName, boolean enabled) {
enter("enabled=%").c(enabled).flush();
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return boolResult(false);
- try {
- WifiStatus status = iface.enableNdOffload(enabled);
- if (!ok(status)) return false;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
+ return iface.enableNdOffload(enabled);
}
- return true;
}
// Firmware roaming control.
@@ -2893,26 +1359,9 @@ public class WifiVendorHal {
@Nullable
public WifiNative.RoamingCapabilities getRoamingCapabilities(@NonNull String ifaceName) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return nullResult();
- try {
- Mutable<Boolean> ok = new Mutable<>(false);
- WifiNative.RoamingCapabilities out = new WifiNative.RoamingCapabilities();
- iface.getRoamingCapabilities((status, cap) -> {
- if (!ok(status)) return;
- out.maxBlocklistSize = cap.maxBlacklistSize;
- out.maxAllowlistSize = cap.maxWhitelistSize;
- ok.value = true;
- });
- if (ok.value) {
- return out;
- } else {
- return null;
- }
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- }
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return null;
+ return iface.getRoamingCapabilities();
}
}
@@ -2927,33 +1376,9 @@ public class WifiVendorHal {
public @WifiNative.RoamingEnableStatus int enableFirmwareRoaming(@NonNull String ifaceName,
@WifiNative.RoamingEnableState int state) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
+ WifiStaIface iface = getStaIface(ifaceName);
if (iface == null) return WifiNative.SET_FIRMWARE_ROAMING_FAILURE;
- try {
- byte val;
- switch (state) {
- case WifiNative.DISABLE_FIRMWARE_ROAMING:
- val = StaRoamingState.DISABLED;
- break;
- case WifiNative.ENABLE_FIRMWARE_ROAMING:
- val = StaRoamingState.ENABLED;
- break;
- default:
- mLog.err("enableFirmwareRoaming invalid argument %").c(state).flush();
- return WifiNative.SET_FIRMWARE_ROAMING_FAILURE;
- }
- WifiStatus status = iface.setRoamingState(val);
- if (ok(status)) {
- return WifiNative.SET_FIRMWARE_ROAMING_SUCCESS;
- } else if (status.code == WifiStatusCode.ERROR_BUSY) {
- return WifiNative.SET_FIRMWARE_ROAMING_BUSY;
- } else {
- return WifiNative.SET_FIRMWARE_ROAMING_FAILURE;
- }
- } catch (RemoteException e) {
- handleRemoteException(e);
- return WifiNative.SET_FIRMWARE_ROAMING_FAILURE;
- }
+ return iface.setRoamingState(state);
}
}
@@ -2966,20 +1391,19 @@ public class WifiVendorHal {
*/
public boolean configureRoaming(@NonNull String ifaceName, WifiNative.RoamingConfig config) {
synchronized (sLock) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return boolResult(false);
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
try {
- StaRoamingConfig roamingConfig = new StaRoamingConfig();
-
- // parse the blacklist BSSIDs if any
+ // parse the blocklist BSSIDs if any
+ List<MacAddress> bssidBlocklist = new ArrayList<>();
if (config.blocklistBssids != null) {
for (String bssid : config.blocklistBssids) {
- byte[] mac = NativeUtil.macAddressToByteArray(bssid);
- roamingConfig.bssidBlacklist.add(mac);
+ bssidBlocklist.add(MacAddress.fromString(bssid));
}
}
- // parse the whitelist SSIDs if any
+ // parse the allowlist SSIDs if any
+ List<byte[]> ssidAllowlist = new ArrayList<>();
if (config.allowlistSsids != null) {
for (String ssidStr : config.allowlistSsids) {
for (WifiSsid originalSsid : mSsidTranslator.getAllPossibleOriginalSsids(
@@ -2988,240 +1412,17 @@ public class WifiVendorHal {
// SSIDs with less than 32 byte length this is due to HAL definition of
// SSID declared it as 32-byte fixed length array. Thus pad additional
// bytes with 0's to pass SSIDs as byte arrays of 32 length
- roamingConfig.ssidWhitelist.add(
+ ssidAllowlist.add(
Arrays.copyOf(originalSsid.getBytes(), 32));
}
}
}
- WifiStatus status = iface.configureRoaming(roamingConfig);
- if (!ok(status)) return false;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
+ return iface.configureRoaming(bssidBlocklist, ssidAllowlist);
} catch (IllegalArgumentException e) {
mLog.err("Illegal argument for roaming configuration").c(e.toString()).flush();
return false;
}
- return true;
- }
- }
-
- /**
- * Method to mock out the V1_1 IWifiChip retrieval in unit tests.
- *
- * @return 1.1 IWifiChip object if the device is running the 1.1 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_1.IWifiChip getWifiChipForV1_1Mockable() {
- if (mIWifiChip == null) return null;
- return android.hardware.wifi.V1_1.IWifiChip.castFrom(mIWifiChip);
- }
-
- /**
- * Method to mock out the V1_2 IWifiChip retrieval in unit tests.
- *
- * @return 1.2 IWifiChip object if the device is running the 1.2 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_2.IWifiChip getWifiChipForV1_2Mockable() {
- if (mIWifiChip == null) return null;
- return android.hardware.wifi.V1_2.IWifiChip.castFrom(mIWifiChip);
- }
-
- /**
- * Method to mock out the V1_3 IWifiChip retrieval in unit tests.
- *
- * @return 1.3 IWifiChip object if the device is running the 1.3 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_3.IWifiChip getWifiChipForV1_3Mockable() {
- if (mIWifiChip == null) return null;
- return android.hardware.wifi.V1_3.IWifiChip.castFrom(mIWifiChip);
- }
-
- /**
- * Method to mock out the V1_4 IWifiChip retrieval in unit tests.
- *
- * @return 1.4 IWifiChip object if the device is running the 1.4 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_4.IWifiChip getWifiChipForV1_4Mockable() {
- if (mIWifiChip == null) return null;
- return android.hardware.wifi.V1_4.IWifiChip.castFrom(mIWifiChip);
- }
-
- /**
- * Method to mock out the V1_5 IWifiChip retrieval in unit tests.
- *
- * @return 1.5 IWifiChip object if the device is running the 1.5 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_5.IWifiChip getWifiChipForV1_5Mockable() {
- if (mIWifiChip == null) return null;
- return android.hardware.wifi.V1_5.IWifiChip.castFrom(mIWifiChip);
- }
-
- /**
- * Method to mock out the V1_6 IWifiChip retrieval in unit tests.
- *
- * @return 1.6 IWifiChip object if the device is running the 1.6 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_6.IWifiChip getWifiChipForV1_6Mockable() {
- if (mIWifiChip == null) return null;
- return android.hardware.wifi.V1_6.IWifiChip.castFrom(mIWifiChip);
- }
-
- /**
- * Method to mock out the V1_2 IWifiStaIface retrieval in unit tests.
- *
- * @param ifaceName Name of the interface
- * @return 1.2 IWifiStaIface object if the device is running the 1.2 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_2.IWifiStaIface getWifiStaIfaceForV1_2Mockable(
- @NonNull String ifaceName) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return null;
- return android.hardware.wifi.V1_2.IWifiStaIface.castFrom(iface);
- }
-
- /**
- * Method to mock out the V1_3 IWifiStaIface retrieval in unit tests.
- *
- * @param ifaceName Name of the interface
- * @return 1.3 IWifiStaIface object if the device is running the 1.3 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_3.IWifiStaIface getWifiStaIfaceForV1_3Mockable(
- @NonNull String ifaceName) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return null;
- return android.hardware.wifi.V1_3.IWifiStaIface.castFrom(iface);
- }
-
- /**
- * Method to mock out the V1_5 IWifiStaIface retrieval in unit tests.
- *
- * @param ifaceName Name of the interface
- * @return 1.5 IWifiStaIface object if the device is running the 1.5 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_5.IWifiStaIface getWifiStaIfaceForV1_5Mockable(
- @NonNull String ifaceName) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return null;
- return android.hardware.wifi.V1_5.IWifiStaIface.castFrom(iface);
- }
-
- /**
- * Method to mock out the V1_6 IWifiStaIface retrieval in unit tests.
- *
- * @param ifaceName Name of the interface
- * @return 1.6 IWifiStaIface object if the device is running the 1.6 wifi hal service, null
- * otherwise.
- */
- protected android.hardware.wifi.V1_6.IWifiStaIface getWifiStaIfaceForV1_6Mockable(
- @NonNull String ifaceName) {
- IWifiStaIface iface = getStaIface(ifaceName);
- if (iface == null) return null;
- return android.hardware.wifi.V1_6.IWifiStaIface.castFrom(iface);
- }
-
- protected android.hardware.wifi.V1_4.IWifiApIface getWifiApIfaceForV1_4Mockable(
- String ifaceName) {
- IWifiApIface iface = getApIface(ifaceName);
- if (iface == null) return null;
- return android.hardware.wifi.V1_4.IWifiApIface.castFrom(iface);
- }
-
- protected android.hardware.wifi.V1_5.IWifiApIface getWifiApIfaceForV1_5Mockable(
- String ifaceName) {
- IWifiApIface iface = getApIface(ifaceName);
- if (iface == null) return null;
- return android.hardware.wifi.V1_5.IWifiApIface.castFrom(iface);
- }
-
- /**
- * sarPowerBackoffRequired_1_1()
- * This method checks if we need to backoff wifi Tx power due to SAR requirements.
- * It handles the case when the device is running the V1_1 version of WifiChip HAL
- * In that HAL version, it is required to perform wifi Tx power backoff only if
- * a voice call is ongoing.
- */
- private boolean sarPowerBackoffRequired_1_1(SarInfo sarInfo) {
- /* As long as no voice call is active (in case voice call is supported),
- * no backoff is needed */
- if (sarInfo.sarVoiceCallSupported) {
- return (sarInfo.isVoiceCall || sarInfo.isEarPieceActive);
- } else {
- return false;
- }
- }
-
- /**
- * frameworkToHalTxPowerScenario_1_1()
- * This method maps the information inside the SarInfo instance into a SAR scenario
- * when device is running the V1_1 version of WifiChip HAL.
- * In this HAL version, only one scenario is defined which is for VOICE_CALL (if voice call is
- * supported).
- * Otherwise, an exception is thrown.
- */
- private int frameworkToHalTxPowerScenario_1_1(SarInfo sarInfo) {
- if (sarInfo.sarVoiceCallSupported && (sarInfo.isVoiceCall || sarInfo.isEarPieceActive)) {
- return android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL;
- } else {
- throw new IllegalArgumentException("bad scenario: voice call not active/supported");
- }
- }
-
- /**
- * sarPowerBackoffRequired_1_2()
- * This method checks if we need to backoff wifi Tx power due to SAR requirements.
- * It handles the case when the device is running the V1_2 version of WifiChip HAL
- */
- private boolean sarPowerBackoffRequired_1_2(SarInfo sarInfo) {
- if (sarInfo.sarSapSupported && sarInfo.isWifiSapEnabled) {
- return true;
- }
- if (sarInfo.sarVoiceCallSupported && (sarInfo.isVoiceCall || sarInfo.isEarPieceActive)) {
- return true;
- }
- return false;
- }
-
- /**
- * frameworkToHalTxPowerScenario_1_2()
- * This method maps the information inside the SarInfo instance into a SAR scenario
- * when device is running the V1_2 version of WifiChip HAL.
- * If SAR SoftAP input is supported,
- * we make these assumptions:
- * - All voice calls are treated as if device is near the head.
- * - SoftAP scenario is treated as if device is near the body.
- * In case SoftAP is not supported, then we should revert to the V1_1 HAL
- * behavior, and the only valid scenario would be when a voice call is ongoing.
- */
- private int frameworkToHalTxPowerScenario_1_2(SarInfo sarInfo) {
- if (sarInfo.sarSapSupported && sarInfo.sarVoiceCallSupported) {
- if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) {
- return android.hardware.wifi.V1_2.IWifiChip
- .TxPowerScenario.ON_HEAD_CELL_ON;
- } else if (sarInfo.isWifiSapEnabled) {
- return android.hardware.wifi.V1_2.IWifiChip
- .TxPowerScenario.ON_BODY_CELL_ON;
- } else {
- throw new IllegalArgumentException("bad scenario: no voice call/softAP active");
- }
- } else if (sarInfo.sarVoiceCallSupported) {
- /* SAR SoftAP input not supported, act like V1_1 */
- if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) {
- return android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL;
- } else {
- throw new IllegalArgumentException("bad scenario: voice call not active");
- }
- } else {
- throw new IllegalArgumentException("Invalid case: voice call not supported");
}
}
@@ -3241,116 +1442,8 @@ public class WifiVendorHal {
*/
public boolean selectTxPowerScenario(SarInfo sarInfo) {
synchronized (sLock) {
- // First attempt to get a V_1_2 instance of the Wifi HAL.
- android.hardware.wifi.V1_2.IWifiChip iWifiChipV12 = getWifiChipForV1_2Mockable();
- if (iWifiChipV12 != null) {
- return selectTxPowerScenario_1_2(iWifiChipV12, sarInfo);
- }
-
- // Now attempt to get a V_1_1 instance of the Wifi HAL.
- android.hardware.wifi.V1_1.IWifiChip iWifiChipV11 = getWifiChipForV1_1Mockable();
- if (iWifiChipV11 != null) {
- return selectTxPowerScenario_1_1(iWifiChipV11, sarInfo);
- }
-
- // HAL version does not support SAR
- return false;
- }
- }
-
- private boolean selectTxPowerScenario_1_1(
- android.hardware.wifi.V1_1.IWifiChip iWifiChip, SarInfo sarInfo) {
- WifiStatus status;
- try {
- if (sarPowerBackoffRequired_1_1(sarInfo)) {
- // Power backoff is needed, so calculate the required scenario,
- // and attempt to set it.
- int halScenario = frameworkToHalTxPowerScenario_1_1(sarInfo);
- if (sarInfo.setSarScenarioNeeded(halScenario)) {
- status = iWifiChip.selectTxPowerScenario(halScenario);
- if (ok(status)) {
- mLog.d("Setting SAR scenario to " + halScenario);
- return true;
- } else {
- mLog.e("Failed to set SAR scenario to " + halScenario);
- return false;
- }
- }
-
- // Reaching here means setting SAR scenario would be redundant,
- // do nothing and return with success.
- return true;
- }
-
- // We don't need to perform power backoff, so attempt to reset SAR scenario.
- if (sarInfo.resetSarScenarioNeeded()) {
- status = iWifiChip.resetTxPowerScenario();
- if (ok(status)) {
- mLog.d("Resetting SAR scenario");
- return true;
- } else {
- mLog.e("Failed to reset SAR scenario");
- return false;
- }
- }
-
- // Resetting SAR scenario would be redundant,
- // do nothing and return with success.
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- } catch (IllegalArgumentException e) {
- mLog.err("Illegal argument for selectTxPowerScenario_1_1()").c(e.toString()).flush();
- return false;
- }
- }
-
- private boolean selectTxPowerScenario_1_2(
- android.hardware.wifi.V1_2.IWifiChip iWifiChip, SarInfo sarInfo) {
- WifiStatus status;
- try {
- if (sarPowerBackoffRequired_1_2(sarInfo)) {
- // Power backoff is needed, so calculate the required scenario,
- // and attempt to set it.
- int halScenario = frameworkToHalTxPowerScenario_1_2(sarInfo);
- if (sarInfo.setSarScenarioNeeded(halScenario)) {
- status = iWifiChip.selectTxPowerScenario_1_2(halScenario);
- if (ok(status)) {
- mLog.d("Setting SAR scenario to " + halScenario);
- return true;
- } else {
- mLog.e("Failed to set SAR scenario to " + halScenario);
- return false;
- }
- }
-
- // Reaching here means setting SAR scenario would be redundant,
- // do nothing and return with success.
- return true;
- }
-
- // We don't need to perform power backoff, so attempt to reset SAR scenario.
- if (sarInfo.resetSarScenarioNeeded()) {
- status = iWifiChip.resetTxPowerScenario();
- if (ok(status)) {
- mLog.d("Resetting SAR scenario");
- return true;
- } else {
- mLog.e("Failed to reset SAR scenario");
- return false;
- }
- }
-
- // Resetting SAR scenario would be redundant,
- // do nothing and return with success.
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- } catch (IllegalArgumentException e) {
- mLog.err("Illegal argument for selectTxPowerScenario_1_2()").c(e.toString()).flush();
- return false;
+ if (mWifiChip == null) return false;
+ return mWifiChip.selectTxPowerScenario(sarInfo);
}
}
@@ -3361,32 +1454,8 @@ public class WifiVendorHal {
*/
public boolean setLowLatencyMode(boolean enabled) {
synchronized (sLock) {
- android.hardware.wifi.V1_3.IWifiChip iWifiChipV13 = getWifiChipForV1_3Mockable();
- if (iWifiChipV13 != null) {
- try {
- int mode;
- if (enabled) {
- mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.LOW;
- } else {
- mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.NORMAL;
- }
-
- WifiStatus status = iWifiChipV13.setLatencyMode(mode);
- if (ok(status)) {
- mVerboseLog.d("Setting low-latency mode to " + enabled);
- return true;
- } else {
- mLog.e("Failed to set low-latency mode to " + enabled);
- return false;
- }
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
-
- // HAL version does not support this api
- return false;
+ if (mWifiChip == null) return false;
+ return mWifiChip.setLowLatencyMode(enabled);
}
}
@@ -3470,30 +1539,10 @@ public class WifiVendorHal {
* @return true for success
*/
public boolean setMultiStaPrimaryConnection(@NonNull String ifaceName) {
- if (TextUtils.isEmpty(ifaceName)) return boolResult(false);
+ if (TextUtils.isEmpty(ifaceName)) return false;
synchronized (sLock) {
- try {
- android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 = getWifiChipForV1_5Mockable();
- if (iWifiChipV15 == null) return boolResult(false);
- WifiStatus status = iWifiChipV15.setMultiStaPrimaryConnection(ifaceName);
- if (!ok(status)) return false;
- return true;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- }
-
- private byte frameworkMultiStaUseCaseToHidl(@WifiNative.MultiStaUseCase int useCase)
- throws IllegalArgumentException {
- switch (useCase) {
- case WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY:
- return MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY;
- case WifiNative.DUAL_STA_NON_TRANSIENT_UNBIASED:
- return MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED;
- default:
- throw new IllegalArgumentException("Invalid use case " + useCase);
+ if (mWifiChip == null) return false;
+ return mWifiChip.setMultiStaPrimaryConnection(ifaceName);
}
}
@@ -3505,20 +1554,8 @@ public class WifiVendorHal {
*/
public boolean setMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) {
synchronized (sLock) {
- try {
- android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 = getWifiChipForV1_5Mockable();
- if (iWifiChipV15 == null) return boolResult(false);
- WifiStatus status = iWifiChipV15.setMultiStaUseCase(
- frameworkMultiStaUseCaseToHidl(useCase));
- if (!ok(status)) return false;
- return true;
- } catch (IllegalArgumentException e) {
- mLog.e("Invalid use case " + e);
- return boolResult(false);
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
+ if (mWifiChip == null) return false;
+ return mWifiChip.setMultiStaUseCase(useCase);
}
}
@@ -3531,102 +1568,16 @@ public class WifiVendorHal {
*/
public boolean setScanMode(@NonNull String ifaceName, boolean enable) {
synchronized (sLock) {
- try {
- android.hardware.wifi.V1_5.IWifiStaIface iface =
- getWifiStaIfaceForV1_5Mockable(ifaceName);
- if (iface != null) {
- WifiStatus status = iface.setScanMode(enable);
- if (!ok(status)) return false;
- return true;
- }
- return false;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- }
-
- // This creates a blob of IE elements from the array received.
- // TODO: This ugly conversion can be removed if we put IE elements in ScanResult.
- private static byte[] hidlIeArrayToFrameworkIeBlob(ArrayList<WifiInformationElement> ies) {
- if (ies == null || ies.isEmpty()) return new byte[0];
- ArrayList<Byte> ieBlob = new ArrayList<>();
- for (WifiInformationElement ie : ies) {
- ieBlob.add(ie.id);
- ieBlob.addAll(ie.data);
- }
- return NativeUtil.byteArrayFromArrayList(ieBlob);
- }
-
- // This is only filling up the fields of Scan Result used by Gscan clients.
- private ScanResult hidlToFrameworkScanResult(StaScanResult scanResult) {
- if (scanResult == null) return null;
- WifiSsid originalSsid = WifiSsid.fromBytes(
- NativeUtil.byteArrayFromArrayList(scanResult.ssid));
- MacAddress bssid;
- try {
- bssid = MacAddress.fromString(NativeUtil.macAddressFromByteArray(scanResult.bssid));
- } catch (IllegalArgumentException e) {
- mLog.e("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.rssi;
- frameworkScanResult.frequency = scanResult.frequency;
- frameworkScanResult.timestamp = scanResult.timeStampInUs;
- return frameworkScanResult;
- }
-
- private ScanResult[] hidlToFrameworkScanResults(ArrayList<StaScanResult> scanResults) {
- if (scanResults == null || scanResults.isEmpty()) return new ScanResult[0];
- ScanResult[] frameworkScanResults = new ScanResult[scanResults.size()];
- int i = 0;
- for (StaScanResult scanResult : scanResults) {
- ScanResult frameworkScanResult = hidlToFrameworkScanResult(scanResult);
- if (frameworkScanResult == null) {
- mLog.e("hidlToFrameworkScanResults: unable to convert hidl to framework scan"
- + " result!");
- continue;
- }
- frameworkScanResults[i++] = frameworkScanResult;
+ WifiStaIface iface = getStaIface(ifaceName);
+ if (iface == null) return false;
+ return iface.setScanMode(enable);
}
- return frameworkScanResults;
- }
-
- /**
- * This just returns whether the scan was interrupted or not.
- */
- private static int hidlToFrameworkScanDataFlags(int flag) {
- if (flag == StaScanDataFlagMask.INTERRUPTED) {
- return 1;
- } else {
- return 0;
- }
- }
-
- private WifiScanner.ScanData[] hidlToFrameworkScanDatas(
- int cmdId, ArrayList<StaScanData> scanDatas) {
- if (scanDatas == null || scanDatas.isEmpty()) return new WifiScanner.ScanData[0];
- WifiScanner.ScanData[] frameworkScanDatas = new WifiScanner.ScanData[scanDatas.size()];
- int i = 0;
- for (StaScanData scanData : scanDatas) {
- int flags = hidlToFrameworkScanDataFlags(scanData.flags);
- ScanResult[] frameworkScanResults = hidlToFrameworkScanResults(scanData.results);
- frameworkScanDatas[i++] =
- new WifiScanner.ScanData(cmdId, flags, scanData.bucketsScanned,
- WifiScanner.WIFI_BAND_UNSPECIFIED, frameworkScanResults);
- }
- return frameworkScanDatas;
}
/**
* Callback for events on the STA interface.
*/
- private class StaIfaceEventCallback extends IWifiStaIfaceEventCallback.Stub {
+ private class StaIfaceEventCallback implements WifiStaIface.Callback {
@Override
public void onBackgroundScanFailure(int cmdId) {
mVerboseLog.d("onBackgroundScanFailure " + cmdId);
@@ -3640,23 +1591,18 @@ public class WifiVendorHal {
@Override
public void onBackgroundFullScanResult(
- int cmdId, int bucketsScanned, StaScanResult result) {
+ int cmdId, int bucketsScanned, ScanResult result) {
mVerboseLog.d("onBackgroundFullScanResult " + cmdId);
WifiNative.ScanEventHandler eventHandler;
synchronized (sLock) {
if (mScan == null || cmdId != mScan.cmdId) return;
eventHandler = mScan.eventHandler;
}
- ScanResult frameworkScanResult = hidlToFrameworkScanResult(result);
- if (frameworkScanResult == null) {
- mLog.e("onBackgroundFullScanResult: unable to convert hidl to framework scan"
- + " result!");
- }
- eventHandler.onFullScanResult(frameworkScanResult, bucketsScanned);
+ eventHandler.onFullScanResult(result, bucketsScanned);
}
@Override
- public void onBackgroundScanResults(int cmdId, ArrayList<StaScanData> scanDatas) {
+ public void onBackgroundScanResults(int cmdId, WifiScanner.ScanData[] scanDatas) {
mVerboseLog.d("onBackgroundScanResults " + cmdId);
WifiNative.ScanEventHandler eventHandler;
// WifiScanner currently uses the results callback to fetch the scan results.
@@ -3665,7 +1611,7 @@ public class WifiVendorHal {
synchronized (sLock) {
if (mScan == null || cmdId != mScan.cmdId) return;
eventHandler = mScan.eventHandler;
- mScan.latestScanResults = hidlToFrameworkScanDatas(cmdId, scanDatas);
+ mScan.latestScanResults = scanDatas;
}
eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
}
@@ -3685,14 +1631,14 @@ public class WifiVendorHal {
/**
* Callback for events on the chip.
*/
- private class ChipEventCallback extends IWifiChipEventCallback.Stub {
+ private class ChipEventCallback implements WifiChip.Callback {
@Override
public void onChipReconfigured(int modeId) {
mVerboseLog.d("onChipReconfigured " + modeId);
}
@Override
- public void onChipReconfigureFailure(WifiStatus status) {
+ public void onChipReconfigureFailure(int status) {
mVerboseLog.d("onChipReconfigureFailure " + status);
}
@@ -3707,9 +1653,7 @@ public class WifiVendorHal {
@Override
public void onDebugRingBufferDataAvailable(
- WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data) {
- //TODO(b/35875078) Reinstate logging when execessive callbacks are fixed
- // mVerboseLog.d("onDebugRingBufferDataAvailable " + status);
+ WifiNative.RingBufferStatus status, byte[] data) {
mHalEventHandler.post(() -> {
WifiNative.WifiLoggerEventHandler eventHandler;
synchronized (sLock) {
@@ -3732,12 +1676,11 @@ public class WifiVendorHal {
// The problem here is that the two threads acquire the locks in opposite order.
// If, for example, T2.2 executes between T1.2 and 1.4, then T1 and T2
// will be deadlocked.
- int sizeBefore = data.size();
+ int sizeBefore = data.length;
boolean conversionFailure = false;
try {
- eventHandler.onRingBufferData(
- ringBufferStatus(status), NativeUtil.byteArrayFromArrayList(data));
- int sizeAfter = data.size();
+ eventHandler.onRingBufferData(status, data);
+ int sizeAfter = data.length;
if (sizeAfter != sizeBefore) {
conversionFailure = true;
}
@@ -3749,13 +1692,13 @@ public class WifiVendorHal {
+ "onDebugRingBufferDataAvailable. "
+ "The input ArrayList |data| is potentially corrupted. "
+ "Starting size=" + sizeBefore + ", "
- + "final size=" + data.size());
+ + "final size=" + data.length);
}
});
}
@Override
- public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData) {
+ public void onDebugErrorAlert(int errorCode, byte[] debugData) {
mLog.w("onDebugErrorAlert " + errorCode);
mHalEventHandler.post(() -> {
WifiNative.WifiLoggerEventHandler eventHandler;
@@ -3765,61 +1708,12 @@ public class WifiVendorHal {
}
// See comment in onDebugRingBufferDataAvailable(), for an explanation
// of why this callback is invoked without |sLock| held.
- eventHandler.onWifiAlert(
- errorCode, NativeUtil.byteArrayFromArrayList(debugData));
+ eventHandler.onWifiAlert(errorCode, debugData);
});
}
- }
-
- private boolean areSameIfaceNames(List<IfaceInfo> ifaceList1, List<IfaceInfo> ifaceList2) {
- List<String> ifaceNamesList1 = ifaceList1
- .stream()
- .map(i -> i.name)
- .collect(Collectors.toList());
- List<String> ifaceNamesList2 = ifaceList2
- .stream()
- .map(i -> i.name)
- .collect(Collectors.toList());
- return ifaceNamesList1.containsAll(ifaceNamesList2);
- }
-
- /**
- * Callback for events on the 1.2 chip.
- */
- private class ChipEventCallbackV12 extends
- android.hardware.wifi.V1_2.IWifiChipEventCallback.Stub {
- @Override
- public void onChipReconfigured(int modeId) {
- mIWifiChipEventCallback.onChipReconfigured(modeId);
- }
-
- @Override
- public void onChipReconfigureFailure(WifiStatus status) {
- mIWifiChipEventCallback.onChipReconfigureFailure(status);
- }
-
- public void onIfaceAdded(int type, String name) {
- mIWifiChipEventCallback.onIfaceAdded(type, name);
- }
-
- @Override
- public void onIfaceRemoved(int type, String name) {
- mIWifiChipEventCallback.onIfaceRemoved(type, name);
- }
@Override
- public void onDebugRingBufferDataAvailable(
- WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data) {
- mIWifiChipEventCallback.onDebugRingBufferDataAvailable(status, data);
- }
-
- @Override
- public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData) {
- mIWifiChipEventCallback.onDebugErrorAlert(errorCode, debugData);
- }
-
- @Override
- public void onRadioModeChange(ArrayList<RadioModeInfo> radioModeInfoList) {
+ public void onRadioModeChange(List<WifiChip.RadioModeInfo> radioModeInfoList) {
mVerboseLog.d("onRadioModeChange " + radioModeInfoList);
WifiNative.VendorHalRadioModeChangeEventHandler handler;
synchronized (sLock) {
@@ -3831,8 +1725,8 @@ public class WifiVendorHal {
mLog.e("Unexpected number of radio info in list " + radioModeInfoList.size());
return;
}
- RadioModeInfo radioModeInfo0 = radioModeInfoList.get(0);
- RadioModeInfo radioModeInfo1 =
+ WifiChip.RadioModeInfo radioModeInfo0 = radioModeInfoList.get(0);
+ WifiChip.RadioModeInfo radioModeInfo1 =
radioModeInfoList.size() == 2 ? radioModeInfoList.get(1) : null;
// Number of ifaces on each radio should be equal.
if (radioModeInfo1 != null
@@ -3867,8 +1761,8 @@ public class WifiVendorHal {
}
// 2 ifaces time sharing on 1 radio.
} else if (radioModeInfoList.size() == 1 && numIfacesOnEachRadio == 2) {
- IfaceInfo ifaceInfo0 = radioModeInfo0.ifaceInfos.get(0);
- IfaceInfo ifaceInfo1 = radioModeInfo0.ifaceInfos.get(1);
+ WifiChip.IfaceInfo ifaceInfo0 = radioModeInfo0.ifaceInfos.get(0);
+ WifiChip.IfaceInfo ifaceInfo1 = radioModeInfo0.ifaceInfos.get(1);
if (ifaceInfo0.channel != ifaceInfo1.channel) {
runnable = () -> {
handler.onMcc(radioModeInfo0.bandInfo);
@@ -3885,113 +1779,17 @@ public class WifiVendorHal {
}
}
- /**
- * Callback for events on the 1.4 chip.
- */
- private class ChipEventCallbackV14 extends
- android.hardware.wifi.V1_4.IWifiChipEventCallback.Stub {
- @Override
- public void onChipReconfigured(int modeId) {
- mIWifiChipEventCallback.onChipReconfigured(modeId);
- }
-
- @Override
- public void onChipReconfigureFailure(WifiStatus status) {
- mIWifiChipEventCallback.onChipReconfigureFailure(status);
- }
-
- public void onIfaceAdded(int type, String name) {
- mIWifiChipEventCallback.onIfaceAdded(type, name);
- }
-
- @Override
- public void onIfaceRemoved(int type, String name) {
- mIWifiChipEventCallback.onIfaceRemoved(type, name);
- }
-
- @Override
- public void onDebugRingBufferDataAvailable(
- WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data) {
- mIWifiChipEventCallback.onDebugRingBufferDataAvailable(status, data);
- }
-
- @Override
- public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData) {
- mIWifiChipEventCallback.onDebugErrorAlert(errorCode, debugData);
- }
-
- @Override
- public void onRadioModeChange(
- ArrayList<android.hardware.wifi.V1_2.IWifiChipEventCallback.RadioModeInfo>
- radioModeInfoList) {
- mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfoList);
- }
-
- @Override
- public void onRadioModeChange_1_4(ArrayList<RadioModeInfo> radioModeInfoList) {
- mVerboseLog.d("onRadioModeChange_1_4 " + radioModeInfoList);
- WifiNative.VendorHalRadioModeChangeEventHandler handler;
- synchronized (sLock) {
- if (mRadioModeChangeEventHandler == null || radioModeInfoList == null) return;
- handler = mRadioModeChangeEventHandler;
- }
- // Should only contain 1 or 2 radio infos.
- if (radioModeInfoList.size() == 0 || radioModeInfoList.size() > 2) {
- mLog.e("Unexpected number of radio info in list " + radioModeInfoList.size());
- return;
- }
- RadioModeInfo radioModeInfo0 = radioModeInfoList.get(0);
- RadioModeInfo radioModeInfo1 =
- radioModeInfoList.size() == 2 ? radioModeInfoList.get(1) : null;
- // Number of ifaces on each radio should be equal.
- if (radioModeInfo1 != null
- && radioModeInfo0.ifaceInfos.size() != radioModeInfo1.ifaceInfos.size()) {
- mLog.e("Unexpected number of iface info in list "
- + radioModeInfo0.ifaceInfos.size() + ", "
- + radioModeInfo1.ifaceInfos.size());
- return;
- }
- int numIfacesOnEachRadio = radioModeInfo0.ifaceInfos.size();
- // Only 1 or 2 ifaces should be present on each radio.
- if (numIfacesOnEachRadio == 0 || numIfacesOnEachRadio > 2) {
- mLog.e("Unexpected number of iface info in list " + numIfacesOnEachRadio);
- return;
- }
- Runnable runnable = null;
- // 2 ifaces simultaneous on 2 radios.
- if (radioModeInfoList.size() == 2 && numIfacesOnEachRadio == 1) {
- // Iface on radio0 should be different from the iface on radio1 for DBS & SBS.
- if (areSameIfaceNames(radioModeInfo0.ifaceInfos, radioModeInfo1.ifaceInfos)) {
- mLog.e("Unexpected for both radio infos to have same iface");
- return;
- }
- if (radioModeInfo0.bandInfo != radioModeInfo1.bandInfo) {
- runnable = () -> {
- handler.onDbs();
- };
- } else {
- runnable = () -> {
- handler.onSbs(radioModeInfo0.bandInfo);
- };
- }
- // 2 ifaces time sharing on 1 radio.
- } else if (radioModeInfoList.size() == 1 && numIfacesOnEachRadio == 2) {
- IfaceInfo ifaceInfo0 = radioModeInfo0.ifaceInfos.get(0);
- IfaceInfo ifaceInfo1 = radioModeInfo0.ifaceInfos.get(1);
- if (ifaceInfo0.channel != ifaceInfo1.channel) {
- runnable = () -> {
- handler.onMcc(radioModeInfo0.bandInfo);
- };
- } else {
- runnable = () -> {
- handler.onScc(radioModeInfo0.bandInfo);
- };
- }
- } else {
- // Not concurrency scenario, uninteresting...
- }
- if (runnable != null) mHalEventHandler.post(runnable);
- }
+ private boolean areSameIfaceNames(List<WifiChip.IfaceInfo> ifaceList1,
+ List<WifiChip.IfaceInfo> ifaceList2) {
+ List<String> ifaceNamesList1 = ifaceList1
+ .stream()
+ .map(i -> i.name)
+ .collect(Collectors.toList());
+ List<String> ifaceNamesList2 = ifaceList2
+ .stream()
+ .map(i -> i.name)
+ .collect(Collectors.toList());
+ return ifaceNamesList1.containsAll(ifaceNamesList2);
}
/**
@@ -4024,105 +1822,9 @@ public class WifiVendorHal {
*/
public boolean startSubsystemRestart() {
synchronized (sLock) {
- android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 = getWifiChipForV1_5Mockable();
- if (iWifiChipV15 != null) {
- try {
- return ok(iWifiChipV15.triggerSubsystemRestart());
- } catch (RemoteException e) {
- handleRemoteException(e);
- return false;
- }
- }
- // HAL version does not support this api
- return false;
- }
- }
-
- /**
- * Convert framework's operational mode to HAL's operational mode.
- */
- private int frameworkToHalIfaceMode(@WifiAvailableChannel.OpMode int mode) {
- int halMode = 0;
- if ((mode & WifiAvailableChannel.OP_MODE_STA) != 0) {
- halMode |= WifiIfaceMode.IFACE_MODE_STA;
- }
- if ((mode & WifiAvailableChannel.OP_MODE_SAP) != 0) {
- halMode |= WifiIfaceMode.IFACE_MODE_SOFTAP;
- }
- if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI) != 0) {
- halMode |= WifiIfaceMode.IFACE_MODE_P2P_CLIENT;
- }
- if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO) != 0) {
- halMode |= WifiIfaceMode.IFACE_MODE_P2P_GO;
- }
- if ((mode & WifiAvailableChannel.OP_MODE_WIFI_AWARE) != 0) {
- halMode |= WifiIfaceMode.IFACE_MODE_NAN;
- }
- if ((mode & WifiAvailableChannel.OP_MODE_TDLS) != 0) {
- halMode |= WifiIfaceMode.IFACE_MODE_TDLS;
- }
- return halMode;
- }
-
- /**
- * Convert from HAL's operational mode to framework's operational mode.
- */
- private @WifiAvailableChannel.OpMode int frameworkFromHalIfaceMode(int halMode) {
- int mode = 0;
- if ((halMode & WifiIfaceMode.IFACE_MODE_STA) != 0) {
- mode |= WifiAvailableChannel.OP_MODE_STA;
- }
- if ((halMode & WifiIfaceMode.IFACE_MODE_SOFTAP) != 0) {
- mode |= WifiAvailableChannel.OP_MODE_SAP;
- }
- if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_CLIENT) != 0) {
- mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI;
- }
- if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_GO) != 0) {
- mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO;
- }
- if ((halMode & WifiIfaceMode.IFACE_MODE_NAN) != 0) {
- mode |= WifiAvailableChannel.OP_MODE_WIFI_AWARE;
- }
- if ((halMode & WifiIfaceMode.IFACE_MODE_TDLS) != 0) {
- mode |= WifiAvailableChannel.OP_MODE_TDLS;
- }
- return mode;
- }
-
- /**
- * Convert framework's WifiAvailableChannel.FILTER_* to HAL's UsableChannelFilter.
- */
- private int frameworkToHalUsableFilter(@WifiAvailableChannel.Filter int filter) {
- int halFilter = 0; // O implies no additional filter other than regulatory (default)
-
- if ((filter & WifiAvailableChannel.FILTER_CONCURRENCY) != 0) {
- halFilter |= UsableChannelFilter.CONCURRENCY;
- }
- if ((filter & WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE) != 0) {
- halFilter |= UsableChannelFilter.CELLULAR_COEXISTENCE;
+ if (mWifiChip == null) return false;
+ return mWifiChip.triggerSubsystemRestart();
}
-
- return halFilter;
- }
-
- /**
- * Convert framework's WifiAvailableChannel.FILTER_* to HAL's UsableChannelFilter 1.6.
- */
- private int frameworkToHalUsableFilter_1_6(@WifiAvailableChannel.Filter int filter) {
- int halFilter = 0; // O implies no additional filter other than regulatory (default)
-
- if ((filter & WifiAvailableChannel.FILTER_CONCURRENCY) != 0) {
- halFilter |= UsableChannelFilter.CONCURRENCY;
- }
- if ((filter & WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE) != 0) {
- halFilter |= UsableChannelFilter.CELLULAR_COEXISTENCE;
- }
- if ((filter & WifiAvailableChannel.FILTER_NAN_INSTANT_MODE) != 0) {
- halFilter |= UsableChannelFilter.NAN_INSTANT_MODE;
- }
-
- return halFilter;
}
/**
@@ -4133,52 +1835,8 @@ public class WifiVendorHal {
@WifiAvailableChannel.OpMode int mode,
@WifiAvailableChannel.Filter int filter) {
synchronized (sLock) {
- try {
- android.hardware.wifi.V1_5.IWifiChip iWifiChipV15 = null;
- android.hardware.wifi.V1_6.IWifiChip iWifiChipV16 = getWifiChipForV1_6Mockable();
- if (iWifiChipV16 == null) {
- iWifiChipV15 = getWifiChipForV1_5Mockable();
- if (iWifiChipV15 == null) {
- return null;
- }
- }
-
- Mutable<List<WifiAvailableChannel>> answer = new Mutable<>();
-
- if (iWifiChipV16 != null) {
- iWifiChipV16.getUsableChannels_1_6(
- makeWifiBandFromFrameworkBand(band),
- frameworkToHalIfaceMode(mode),
- frameworkToHalUsableFilter_1_6(filter), (status, channels) -> {
- if (!ok(status)) return;
- answer.value = new ArrayList<>();
- for (android.hardware.wifi.V1_6.WifiUsableChannel ch : channels) {
- answer.value.add(new WifiAvailableChannel(ch.channel,
- frameworkFromHalIfaceMode(ch.ifaceModeMask)));
- }
- });
- } else {
- iWifiChipV15.getUsableChannels(
- makeWifiBandFromFrameworkBand(band),
- frameworkToHalIfaceMode(mode),
- frameworkToHalUsableFilter(filter), (status, channels) -> {
- if (!ok(status)) return;
- answer.value = new ArrayList<>();
- for (android.hardware.wifi.V1_5.WifiUsableChannel ch : channels) {
- answer.value.add(new WifiAvailableChannel(ch.channel,
- frameworkFromHalIfaceMode(ch.ifaceModeMask)));
- }
- });
- }
-
- return answer.value;
- } catch (RemoteException e) {
- handleRemoteException(e);
- return null;
- } catch (IllegalArgumentException e) {
- mLog.e("Illegal argument for getUsableChannels() " + e);
- return null;
- }
+ if (mWifiChip == null) return null;
+ return mWifiChip.getUsableChannels(band, mode, filter);
}
}
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
index 9e199c7850..b13ae386a9 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
@@ -19,8 +19,6 @@ package com.android.server.wifi.aware;
import static android.net.RouteInfo.RTN_UNICAST;
import android.content.Context;
-import android.hardware.wifi.V1_0.NanDataPathChannelCfg;
-import android.hardware.wifi.V1_0.NanStatusType;
import android.net.ConnectivityManager;
import android.net.IpPrefix;
import android.net.LinkAddress;
@@ -56,6 +54,8 @@ import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.hal.WifiNanIface.NanDataPathChannelCfg;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
import com.android.server.wifi.util.NetdWrapper;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
@@ -747,7 +747,7 @@ public class WifiAwareDataPathStateManager {
NETWORK_FACTORY_SCORE_AVAIL, naConfig, mNetworkFactory.getProvider(), nnri);
mNiWrapper.setConnected(nnri.networkAgent);
}
- mAwareMetrics.recordNdpStatus(NanStatusType.SUCCESS, isOutOfBand, ndpInfo.startTimestamp);
+ mAwareMetrics.recordNdpStatus(NanStatusCode.SUCCESS, isOutOfBand, ndpInfo.startTimestamp);
mAwareMetrics.recordNdpCreation(nnri.uid, nnri.packageName, mNetworkRequestsCache);
}
@@ -875,7 +875,7 @@ public class WifiAwareDataPathStateManager {
}
AwareNetworkRequestInformation nnri = nnriE.getValue();
NdpInfo ndpInfo = nnri.ndpInfos.get(ndpId);
- mAwareMetrics.recordNdpStatus(NanStatusType.INTERNAL_FAILURE,
+ mAwareMetrics.recordNdpStatus(NanStatusCode.INTERNAL_FAILURE,
nnri.networkSpecifier.isOutOfBand(), ndpInfo.startTimestamp);
mMgr.endDataPath(ndpId);
nnri.ndpInfos.remove(ndpId);
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java b/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java
index 557ef0110d..d06132e775 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java
@@ -20,7 +20,6 @@ import static com.android.server.wifi.aware.WifiAwareStateManager.INSTANT_MODE_2
import static com.android.server.wifi.aware.WifiAwareStateManager.INSTANT_MODE_5GHZ;
import static com.android.server.wifi.aware.WifiAwareStateManager.INSTANT_MODE_DISABLED;
-import android.hardware.wifi.V1_0.NanStatusType;
import android.net.wifi.WifiScanner;
import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
import android.net.wifi.aware.PublishConfig;
@@ -32,6 +31,8 @@ import android.util.LocalLog;
import android.util.Log;
import android.util.SparseArray;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -168,7 +169,7 @@ public class WifiAwareDiscoverySessionState {
*/
public void terminate() {
try {
- mCallback.onSessionTerminated(NanStatusType.SUCCESS);
+ mCallback.onSessionTerminated(NanStatusCode.SUCCESS);
} catch (RemoteException e) {
Log.w(TAG,
"onSessionTerminatedLocal onSessionTerminated(): RemoteException (FYI): " + e);
@@ -204,7 +205,7 @@ public class WifiAwareDiscoverySessionState {
if (!mIsPublishSession) {
Log.e(TAG, "A SUBSCRIBE session is being used to publish");
try {
- mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ mCallback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.e(TAG, "updatePublish: RemoteException=" + e);
}
@@ -215,7 +216,7 @@ public class WifiAwareDiscoverySessionState {
boolean success = mWifiAwareNativeApi.publish(transactionId, mPubSubId, config);
if (!success) {
try {
- mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ mCallback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.w(TAG, "updatePublish onSessionConfigFail(): RemoteException (FYI): " + e);
}
@@ -235,7 +236,7 @@ public class WifiAwareDiscoverySessionState {
if (mIsPublishSession) {
Log.e(TAG, "A PUBLISH session is being used to subscribe");
try {
- mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ mCallback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.e(TAG, "updateSubscribe: RemoteException=" + e);
}
@@ -246,7 +247,7 @@ public class WifiAwareDiscoverySessionState {
boolean success = mWifiAwareNativeApi.subscribe(transactionId, mPubSubId, config);
if (!success) {
try {
- mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ mCallback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.w(TAG, "updateSubscribe onSessionConfigFail(): RemoteException (FYI): " + e);
}
@@ -272,7 +273,7 @@ public class WifiAwareDiscoverySessionState {
Log.e(TAG, "sendMessage: attempting to send a message to an address which didn't "
+ "match/contact us");
try {
- mCallback.onMessageSendFail(messageId, NanStatusType.INTERNAL_FAILURE);
+ mCallback.onMessageSendFail(messageId, NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.e(TAG, "sendMessage: RemoteException=" + e);
}
@@ -283,7 +284,7 @@ public class WifiAwareDiscoverySessionState {
peerInfo.mInstanceId, peerInfo.mMac, message, messageId);
if (!success) {
try {
- mCallback.onMessageSendFail(messageId, NanStatusType.INTERNAL_FAILURE);
+ mCallback.onMessageSendFail(messageId, NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.e(TAG, "sendMessage: RemoteException=" + e);
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java b/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java
index 75b3ef96b6..c935c9fc86 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java
@@ -21,7 +21,6 @@ import static android.net.wifi.aware.WifiAwareNetworkSpecifier.NETWORK_SPECIFIER
import static android.net.wifi.aware.WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB;
import static android.net.wifi.aware.WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
-import android.hardware.wifi.V1_0.NanStatusType;
import android.net.wifi.aware.WifiAwareNetworkSpecifier;
import android.text.TextUtils;
import android.util.Log;
@@ -30,6 +29,7 @@ import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.util.MetricsUtils;
@@ -229,7 +229,7 @@ public class WifiAwareMetrics {
data.mUsesIdentityCallback |= usesIdentityCallback;
data.mMaxConcurrentAttaches = Math.max(data.mMaxConcurrentAttaches,
currentConcurrentCount);
- recordAttachStatus(NanStatusType.SUCCESS);
+ recordAttachStatus(NanStatusCode.SUCCESS);
}
}
@@ -363,7 +363,7 @@ public class WifiAwareMetrics {
addNanHalStatusToHistogram(status, mSubscribeStatusData);
}
- if (status == NanStatusType.NO_RESOURCES_AVAILABLE) {
+ if (status == NanStatusCode.NO_RESOURCES_AVAILABLE) {
mAppsWithDiscoverySessionResourceFailure.add(uid);
}
}
@@ -474,7 +474,7 @@ public class WifiAwareMetrics {
addNanHalStatusToHistogram(status, mInBandNdpStatusData);
}
- if (status == NanStatusType.SUCCESS) {
+ if (status == NanStatusCode.SUCCESS) {
long creationTime = mClock.getElapsedSinceBootMillis() - startTimestamp;
MetricsUtils.addValueToLogHistogram(creationTime, mNdpCreationTimeDuration,
DURATION_LOG_HISTOGRAM);
@@ -828,7 +828,7 @@ public class WifiAwareMetrics {
* Adds the NanStatusType to the histogram (translating to the proto enumeration of the status).
*/
public static void addNanHalStatusToHistogram(int halStatus, SparseIntArray histogram) {
- int protoStatus = convertNanStatusTypeToProtoEnum(halStatus);
+ int protoStatus = convertNanStatusCodeToProtoEnum(halStatus);
int newValue = histogram.get(protoStatus) + 1;
histogram.put(protoStatus, newValue);
}
@@ -852,38 +852,38 @@ public class WifiAwareMetrics {
}
/**
- * Convert a HAL NanStatusType enum to a Metrics proto enum NanStatusTypeEnum.
+ * Convert a NanStatusCode to a Metrics proto enum NanStatusCodeEnum.
*/
- public static int convertNanStatusTypeToProtoEnum(int nanStatusType) {
- switch (nanStatusType) {
- case NanStatusType.SUCCESS:
+ public static int convertNanStatusCodeToProtoEnum(int nanStatusCode) {
+ switch (nanStatusCode) {
+ case NanStatusCode.SUCCESS:
return WifiMetricsProto.WifiAwareLog.SUCCESS;
- case NanStatusType.INTERNAL_FAILURE:
+ case NanStatusCode.INTERNAL_FAILURE:
return WifiMetricsProto.WifiAwareLog.INTERNAL_FAILURE;
- case NanStatusType.PROTOCOL_FAILURE:
+ case NanStatusCode.PROTOCOL_FAILURE:
return WifiMetricsProto.WifiAwareLog.PROTOCOL_FAILURE;
- case NanStatusType.INVALID_SESSION_ID:
+ case NanStatusCode.INVALID_SESSION_ID:
return WifiMetricsProto.WifiAwareLog.INVALID_SESSION_ID;
- case NanStatusType.NO_RESOURCES_AVAILABLE:
+ case NanStatusCode.NO_RESOURCES_AVAILABLE:
return WifiMetricsProto.WifiAwareLog.NO_RESOURCES_AVAILABLE;
- case NanStatusType.INVALID_ARGS:
+ case NanStatusCode.INVALID_ARGS:
return WifiMetricsProto.WifiAwareLog.INVALID_ARGS;
- case NanStatusType.INVALID_PEER_ID:
+ case NanStatusCode.INVALID_PEER_ID:
return WifiMetricsProto.WifiAwareLog.INVALID_PEER_ID;
- case NanStatusType.INVALID_NDP_ID:
+ case NanStatusCode.INVALID_NDP_ID:
return WifiMetricsProto.WifiAwareLog.INVALID_NDP_ID;
- case NanStatusType.NAN_NOT_ALLOWED:
+ case NanStatusCode.NAN_NOT_ALLOWED:
return WifiMetricsProto.WifiAwareLog.NAN_NOT_ALLOWED;
- case NanStatusType.NO_OTA_ACK:
+ case NanStatusCode.NO_OTA_ACK:
return WifiMetricsProto.WifiAwareLog.NO_OTA_ACK;
- case NanStatusType.ALREADY_ENABLED:
+ case NanStatusCode.ALREADY_ENABLED:
return WifiMetricsProto.WifiAwareLog.ALREADY_ENABLED;
- case NanStatusType.FOLLOWUP_TX_QUEUE_FULL:
+ case NanStatusCode.FOLLOWUP_TX_QUEUE_FULL:
return WifiMetricsProto.WifiAwareLog.FOLLOWUP_TX_QUEUE_FULL;
- case NanStatusType.UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
+ case NanStatusCode.UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
return WifiMetricsProto.WifiAwareLog.UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
default:
- Log.e(TAG, "Unrecognized NanStatusType: " + nanStatusType);
+ Log.e(TAG, "Unrecognized NanStatusCode: " + nanStatusCode);
return WifiMetricsProto.WifiAwareLog.UNKNOWN_HAL_STATUS;
}
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
index 8af9409556..811e94064a 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
@@ -16,51 +16,29 @@
package com.android.server.wifi.aware;
-import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128;
-import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256;
-import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
-import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
-
-import android.hardware.wifi.V1_0.IWifiNanIface;
-import android.hardware.wifi.V1_0.NanBandIndex;
-import android.hardware.wifi.V1_0.NanBandSpecificConfig;
-import android.hardware.wifi.V1_0.NanConfigRequest;
-import android.hardware.wifi.V1_0.NanDataPathSecurityType;
-import android.hardware.wifi.V1_0.NanEnableRequest;
-import android.hardware.wifi.V1_0.NanInitiateDataPathRequest;
-import android.hardware.wifi.V1_0.NanMatchAlg;
-import android.hardware.wifi.V1_0.NanPublishRequest;
-import android.hardware.wifi.V1_0.NanRangingIndication;
-import android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest;
-import android.hardware.wifi.V1_0.NanSubscribeRequest;
-import android.hardware.wifi.V1_0.NanTransmitFollowupRequest;
-import android.hardware.wifi.V1_0.NanTxType;
-import android.hardware.wifi.V1_0.WifiStatus;
-import android.hardware.wifi.V1_0.WifiStatusCode;
-import android.hardware.wifi.V1_6.NanCipherSuiteType;
+import android.net.MacAddress;
import android.net.wifi.aware.AwareParams;
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.net.wifi.util.HexEncoding;
-import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseIntArray;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.BasicShellCommandHandler;
+import com.android.server.wifi.hal.WifiNanIface;
+import com.android.server.wifi.hal.WifiNanIface.PowerParameters;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
- * Translates Wi-Fi Aware requests from the framework to the HAL (HIDL).
+ * Translates Wi-Fi Aware requests from the framework to the HAL.
*
* Delegates the management of the NAN interface to WifiAwareNativeManager.
*/
@@ -69,9 +47,6 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
private static final boolean VDBG = false; // STOPSHIP if true
private boolean mVerboseLoggingEnabled = false;
- @VisibleForTesting
- static final String SERVICE_NAME_FOR_OOB_DATA_PATH = "Wi-Fi Aware Data Path";
-
private final WifiAwareNativeManager mHal;
private SparseIntArray mTransactionIds; // VDBG only!
@@ -105,42 +80,6 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
mTransactionIds.append(transactionId, count + 1);
}
- /**
- * (HIDL) Cast the input to a 1.2 NAN interface (possibly resulting in a null).
- *
- * Separate function so can be mocked in unit tests.
- */
- public android.hardware.wifi.V1_2.IWifiNanIface mockableCastTo_1_2(IWifiNanIface iface) {
- return android.hardware.wifi.V1_2.IWifiNanIface.castFrom(iface);
- }
-
- /**
- * (HIDL) Cast the input to a 1.4 NAN interface (possibly resulting in a null).
- *
- * Separate function so can be mocked in unit tests.
- */
- public android.hardware.wifi.V1_4.IWifiNanIface mockableCastTo_1_4(IWifiNanIface iface) {
- return android.hardware.wifi.V1_4.IWifiNanIface.castFrom(iface);
- }
-
- /**
- * (HIDL) Cast the input to a 1.5 NAN interface (possibly resulting in a null).
- *
- * Separate function so can be mocked in unit tests.
- */
- public android.hardware.wifi.V1_5.IWifiNanIface mockableCastTo_1_5(IWifiNanIface iface) {
- return android.hardware.wifi.V1_5.IWifiNanIface.castFrom(iface);
- }
-
- /**
- * (HIDL) Cast the input to a 1.6 NAN interface (possibly resulting in a null).
- *
- * Separate function so can be mocked in unit tests.
- */
- public android.hardware.wifi.V1_6.IWifiNanIface mockableCastTo_1_6(IWifiNanIface iface) {
- return android.hardware.wifi.V1_6.IWifiNanIface.castFrom(iface);
- }
-
/*
* Parameters settable through the shell command.
* see wifi/1.0/types.hal NanBandSpecificConfig.discoveryWindowIntervalVal and
@@ -160,7 +99,6 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
private static final int PARAM_DW_5GHZ_INACTIVE = 0; // 0 = disabled
private static final int PARAM_DW_5GHZ_IDLE = 0; // == inactive
- // TODO:
/* package */ static final String PARAM_DW_6GHZ = "dw_6ghz";
private static final int PARAM_DW_6GHZ_DEFAULT = 1; // 1 -> DW=1, latency=512ms
private static final int PARAM_DW_6GHZ_INACTIVE = 0; // 0 = disabled
@@ -389,31 +327,12 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
if (mVerboseLoggingEnabled) Log.v(TAG, "getCapabilities: transactionId=" + transactionId);
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "getCapabilities: null interface");
return false;
}
- android.hardware.wifi.V1_5.IWifiNanIface iface15 = mockableCastTo_1_5(iface);
-
-
- try {
- WifiStatus status;
- if (iface15 == null) {
- status = iface.getCapabilitiesRequest(transactionId);
- } else {
- status = iface15.getCapabilitiesRequest_1_5(transactionId);
- }
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "getCapabilities: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "getCapabilities: exception: " + e);
- return false;
- }
+ return iface.getCapabilities(transactionId);
}
/**
@@ -443,283 +362,17 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
+ ", instantModeChannel=" + instantModeChannel);
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "enableAndConfigure: null interface");
return false;
}
- android.hardware.wifi.V1_2.IWifiNanIface iface12 = mockableCastTo_1_2(iface);
- android.hardware.wifi.V1_4.IWifiNanIface iface14 = mockableCastTo_1_4(iface);
- android.hardware.wifi.V1_5.IWifiNanIface iface15 = mockableCastTo_1_5(iface);
- android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6(iface);
- android.hardware.wifi.V1_2.NanConfigRequestSupplemental configSupplemental12 =
- new android.hardware.wifi.V1_2.NanConfigRequestSupplemental();
- android.hardware.wifi.V1_5.NanConfigRequestSupplemental configSupplemental15 =
- new android.hardware.wifi.V1_5.NanConfigRequestSupplemental();
- android.hardware.wifi.V1_6.NanConfigRequestSupplemental configSupplemental16 =
- new android.hardware.wifi.V1_6.NanConfigRequestSupplemental();
- if (iface12 != null || iface14 != null) {
- configSupplemental12.discoveryBeaconIntervalMs = 0;
- configSupplemental12.numberOfSpatialStreamsInDiscovery = 0;
- configSupplemental12.enableDiscoveryWindowEarlyTermination = false;
- configSupplemental12.enableRanging = rangingEnabled;
- }
-
- if (iface15 != null) {
- configSupplemental15.V1_2 = configSupplemental12;
- configSupplemental15.enableInstantCommunicationMode = isInstantCommunicationEnabled;
- }
- if (iface16 != null) {
- configSupplemental16.V1_5 = configSupplemental15;
- configSupplemental16.instantModeChannel = instantModeChannel;
- }
-
- NanBandSpecificConfig config24 = new NanBandSpecificConfig();
- config24.rssiClose = 60;
- config24.rssiMiddle = 70;
- config24.rssiCloseProximity = 60;
- config24.dwellTimeMs = (byte) 200;
- config24.scanPeriodSec = 20;
- if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]
- == ConfigRequest.DW_INTERVAL_NOT_INIT) {
- config24.validDiscoveryWindowIntervalVal = false;
- } else {
- config24.validDiscoveryWindowIntervalVal = true;
- config24.discoveryWindowIntervalVal =
- (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
- .NAN_BAND_24GHZ];
- }
-
- NanBandSpecificConfig config5 = new NanBandSpecificConfig();
- config5.rssiClose = 60;
- config5.rssiMiddle = 75;
- config5.rssiCloseProximity = 60;
- config5.dwellTimeMs = (byte) 200;
- config5.scanPeriodSec = 20;
- if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]
- == ConfigRequest.DW_INTERVAL_NOT_INIT) {
- config5.validDiscoveryWindowIntervalVal = false;
- } else {
- config5.validDiscoveryWindowIntervalVal = true;
- config5.discoveryWindowIntervalVal =
- (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
- .NAN_BAND_5GHZ];
- }
-
- // TODO: b/145609058
- // Need to review values for this config, currently it is a copy from config5
- NanBandSpecificConfig config6 = new NanBandSpecificConfig();
- config6.rssiClose = 60;
- config6.rssiMiddle = 75;
- config6.rssiCloseProximity = 60;
- config6.dwellTimeMs = (byte) 200;
- config6.scanPeriodSec = 20;
- if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ]
- == ConfigRequest.DW_INTERVAL_NOT_INIT) {
- config6.validDiscoveryWindowIntervalVal = false;
- } else {
- config6.validDiscoveryWindowIntervalVal = true;
- config6.discoveryWindowIntervalVal =
- (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
- .NAN_BAND_6GHZ];
- }
-
- try {
- WifiStatus status;
- if (initialConfiguration) {
- if (iface14 != null || iface15 != null || iface16 != null) {
- // translate framework to HIDL configuration (V_1.4)
- android.hardware.wifi.V1_4.NanEnableRequest req =
- new android.hardware.wifi.V1_4.NanEnableRequest();
-
- req.operateInBand[NanBandIndex.NAN_BAND_24GHZ] = true;
- req.operateInBand[NanBandIndex.NAN_BAND_5GHZ] = configRequest.mSupport5gBand;
- req.operateInBand[android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] =
- configRequest.mSupport6gBand;
- req.hopCountMax = 2;
- req.configParams.masterPref = (byte) configRequest.mMasterPreference;
- req.configParams.disableDiscoveryAddressChangeIndication =
- !notifyIdentityChange;
- req.configParams.disableStartedClusterIndication = !notifyIdentityChange;
- req.configParams.disableJoinedClusterIndication = !notifyIdentityChange;
- req.configParams.includePublishServiceIdsInBeacon = true;
- req.configParams.numberOfPublishServiceIdsInBeacon = 0;
- req.configParams.includeSubscribeServiceIdsInBeacon = true;
- req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
- req.configParams.rssiWindowSize = 8;
- req.configParams.macAddressRandomizationIntervalSec =
- mExternalSetParams.getOrDefault(PARAM_MAC_RANDOM_INTERVAL_SEC,
- mSettableParameters.get(PARAM_MAC_RANDOM_INTERVAL_SEC));
-
- req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
- req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
- req.configParams.bandSpecificConfig[
- android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] = config6;
-
- req.debugConfigs.validClusterIdVals = true;
- req.debugConfigs.clusterIdTopRangeVal = (short) configRequest.mClusterHigh;
- req.debugConfigs.clusterIdBottomRangeVal = (short) configRequest.mClusterLow;
- req.debugConfigs.validIntfAddrVal = false;
- req.debugConfigs.validOuiVal = false;
- req.debugConfigs.ouiVal = 0;
- req.debugConfigs.validRandomFactorForceVal = false;
- req.debugConfigs.randomFactorForceVal = 0;
- req.debugConfigs.validHopCountForceVal = false;
- req.debugConfigs.hopCountForceVal = 0;
- req.debugConfigs.validDiscoveryChannelVal = false;
- req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_24GHZ] = 0;
- req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_5GHZ] = 0;
- req.debugConfigs.discoveryChannelMhzVal[
- android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] = 0;
- req.debugConfigs.validUseBeaconsInBandVal = false;
- req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
- req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
- req.debugConfigs.useBeaconsInBandVal[
- android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] = true;
- req.debugConfigs.validUseSdfInBandVal = false;
- req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
- req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
- req.debugConfigs.useSdfInBandVal[
- android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] = true;
- updateConfigForPowerSettings14(req.configParams, configSupplemental12,
- isInteractive, isIdle);
-
- if (iface16 != null) {
- status = iface16.enableRequest_1_6(transactionId, req,
- configSupplemental16);
- } else if (iface15 != null) {
- status = iface15.enableRequest_1_5(transactionId, req,
- configSupplemental15);
- } else {
- status = iface14.enableRequest_1_4(transactionId, req,
- configSupplemental12);
- }
- } else {
- // translate framework to HIDL configuration (before V_1.4)
- NanEnableRequest req = new NanEnableRequest();
-
- req.operateInBand[NanBandIndex.NAN_BAND_24GHZ] = true;
- req.operateInBand[NanBandIndex.NAN_BAND_5GHZ] = configRequest.mSupport5gBand;
- req.hopCountMax = 2;
- req.configParams.masterPref = (byte) configRequest.mMasterPreference;
- req.configParams.disableDiscoveryAddressChangeIndication =
- !notifyIdentityChange;
- req.configParams.disableStartedClusterIndication = !notifyIdentityChange;
- req.configParams.disableJoinedClusterIndication = !notifyIdentityChange;
- req.configParams.includePublishServiceIdsInBeacon = true;
- req.configParams.numberOfPublishServiceIdsInBeacon = 0;
- req.configParams.includeSubscribeServiceIdsInBeacon = true;
- req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
- req.configParams.rssiWindowSize = 8;
- req.configParams.macAddressRandomizationIntervalSec =
- mExternalSetParams.getOrDefault(PARAM_MAC_RANDOM_INTERVAL_SEC,
- mSettableParameters.get(PARAM_MAC_RANDOM_INTERVAL_SEC));
-
- req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
- req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
-
- req.debugConfigs.validClusterIdVals = true;
- req.debugConfigs.clusterIdTopRangeVal = (short) configRequest.mClusterHigh;
- req.debugConfigs.clusterIdBottomRangeVal = (short) configRequest.mClusterLow;
- req.debugConfigs.validIntfAddrVal = false;
- req.debugConfigs.validOuiVal = false;
- req.debugConfigs.ouiVal = 0;
- req.debugConfigs.validRandomFactorForceVal = false;
- req.debugConfigs.randomFactorForceVal = 0;
- req.debugConfigs.validHopCountForceVal = false;
- req.debugConfigs.hopCountForceVal = 0;
- req.debugConfigs.validDiscoveryChannelVal = false;
- req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_24GHZ] = 0;
- req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_5GHZ] = 0;
- req.debugConfigs.validUseBeaconsInBandVal = false;
- req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
- req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
- req.debugConfigs.validUseSdfInBandVal = false;
- req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
- req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
-
- updateConfigForPowerSettings(req.configParams, configSupplemental12,
- isInteractive, isIdle);
-
- if (iface12 != null) {
- status = iface12.enableRequest_1_2(transactionId, req,
- configSupplemental12);
- } else {
- status = iface.enableRequest(transactionId, req);
- }
- }
- } else {
- if (iface14 != null || iface15 != null || iface16 != null) {
- android.hardware.wifi.V1_4.NanConfigRequest req =
- new android.hardware.wifi.V1_4.NanConfigRequest();
- req.masterPref = (byte) configRequest.mMasterPreference;
- req.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
- req.disableStartedClusterIndication = !notifyIdentityChange;
- req.disableJoinedClusterIndication = !notifyIdentityChange;
- req.includePublishServiceIdsInBeacon = true;
- req.numberOfPublishServiceIdsInBeacon = 0;
- req.includeSubscribeServiceIdsInBeacon = true;
- req.numberOfSubscribeServiceIdsInBeacon = 0;
- req.rssiWindowSize = 8;
- req.macAddressRandomizationIntervalSec =
- mExternalSetParams.getOrDefault(PARAM_MAC_RANDOM_INTERVAL_SEC,
- mSettableParameters.get(PARAM_MAC_RANDOM_INTERVAL_SEC));
-
- req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
- req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
- req.bandSpecificConfig[android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] =
- config6;
-
- updateConfigForPowerSettings14(req, configSupplemental12,
- isInteractive, isIdle);
- if (iface16 != null) {
- status = iface16.configRequest_1_6(transactionId, req,
- configSupplemental16);
- } else if (iface15 != null) {
- status = iface15.configRequest_1_5(transactionId, req,
- configSupplemental15);
- } else {
- status = iface14.configRequest_1_4(transactionId, req,
- configSupplemental12);
- }
- } else {
- NanConfigRequest req = new NanConfigRequest();
- req.masterPref = (byte) configRequest.mMasterPreference;
- req.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
- req.disableStartedClusterIndication = !notifyIdentityChange;
- req.disableJoinedClusterIndication = !notifyIdentityChange;
- req.includePublishServiceIdsInBeacon = true;
- req.numberOfPublishServiceIdsInBeacon = 0;
- req.includeSubscribeServiceIdsInBeacon = true;
- req.numberOfSubscribeServiceIdsInBeacon = 0;
- req.rssiWindowSize = 8;
- req.macAddressRandomizationIntervalSec =
- mExternalSetParams.getOrDefault(PARAM_MAC_RANDOM_INTERVAL_SEC,
- mSettableParameters.get(PARAM_MAC_RANDOM_INTERVAL_SEC));
-
- req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
- req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
-
- updateConfigForPowerSettings(req, configSupplemental12, isInteractive, isIdle);
-
- if (iface12 != null) {
- status = iface12.configRequest_1_2(transactionId, req,
- configSupplemental12);
- } else {
- status = iface.configRequest(transactionId, req);
- }
- }
- }
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "enableAndConfigure: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "enableAndConfigure: exception: " + e);
- return false;
- }
+ return iface.enableAndConfigure(transactionId, configRequest, notifyIdentityChange,
+ initialConfiguration, rangingEnabled,
+ isInstantCommunicationEnabled, instantModeChannel,
+ mExternalSetParams.getOrDefault(PARAM_MAC_RANDOM_INTERVAL_SEC,
+ mSettableParameters.get(PARAM_MAC_RANDOM_INTERVAL_SEC)),
+ getPowerParameters(isInteractive, isIdle));
}
/**
@@ -732,24 +385,13 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
if (mVerboseLoggingEnabled) Log.d(TAG, "disable");
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "disable: null interface");
return false;
}
-
- try {
- WifiStatus status = iface.disableRequest(transactionId);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "disable: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "disable: exception: " + e);
- return false;
- }
+ boolean result = iface.disable(transactionId);
+ return result;
}
/**
@@ -768,132 +410,12 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
}
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "publish: null interface");
return false;
}
-
- android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6(iface);
- if (iface16 == null) {
- NanPublishRequest req = new NanPublishRequest();
- req.baseConfigs.sessionId = publishId;
- req.baseConfigs.ttlSec = (short) publishConfig.mTtlSec;
- req.baseConfigs.discoveryWindowPeriod = 1;
- req.baseConfigs.discoveryCount = 0;
- convertNativeByteArrayToArrayList(publishConfig.mServiceName,
- req.baseConfigs.serviceName);
- req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_NEVER;
- convertNativeByteArrayToArrayList(publishConfig.mServiceSpecificInfo,
- req.baseConfigs.serviceSpecificInfo);
- convertNativeByteArrayToArrayList(publishConfig.mMatchFilter,
- publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
- ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
- req.baseConfigs.useRssiThreshold = false;
- req.baseConfigs.disableDiscoveryTerminationIndication =
- !publishConfig.mEnableTerminateNotification;
- req.baseConfigs.disableMatchExpirationIndication = true;
- req.baseConfigs.disableFollowupReceivedIndication = false;
-
- req.autoAcceptDataPathRequests = false;
-
- req.baseConfigs.rangingRequired = publishConfig.mEnableRanging;
-
- req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
- WifiAwareDataPathSecurityConfig securityConfig = publishConfig.getSecurityConfig();
- if (securityConfig != null) {
- req.baseConfigs.securityConfig.cipherType = getHalCipherSuiteType(
- securityConfig.getCipherSuite());
- if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
- req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.PMK;
- copyArray(securityConfig.getPmk(), req.baseConfigs.securityConfig.pmk);
- }
- if (securityConfig.getPskPassphrase() != null
- && securityConfig.getPskPassphrase().length() != 0) {
- req.baseConfigs.securityConfig.securityType =
- NanDataPathSecurityType.PASSPHRASE;
- convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
- req.baseConfigs.securityConfig.passphrase);
- }
- }
-
- req.publishType = publishConfig.mPublishType;
- req.txType = NanTxType.BROADCAST;
-
- try {
- WifiStatus status = iface.startPublishRequest(transactionId, req);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "publish: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "publish: exception: " + e);
- return false;
- }
- } else {
- android.hardware.wifi.V1_6.NanPublishRequest req =
- new android.hardware.wifi.V1_6.NanPublishRequest();
- req.baseConfigs.sessionId = publishId;
- req.baseConfigs.ttlSec = (short) publishConfig.mTtlSec;
- req.baseConfigs.discoveryWindowPeriod = 1;
- req.baseConfigs.discoveryCount = 0;
- convertNativeByteArrayToArrayList(publishConfig.mServiceName,
- req.baseConfigs.serviceName);
- req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_NEVER;
- convertNativeByteArrayToArrayList(publishConfig.mServiceSpecificInfo,
- req.baseConfigs.serviceSpecificInfo);
- convertNativeByteArrayToArrayList(publishConfig.mMatchFilter,
- publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
- ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
- req.baseConfigs.useRssiThreshold = false;
- req.baseConfigs.disableDiscoveryTerminationIndication =
- !publishConfig.mEnableTerminateNotification;
- req.baseConfigs.disableMatchExpirationIndication = true;
- req.baseConfigs.disableFollowupReceivedIndication = false;
-
- req.autoAcceptDataPathRequests = false;
-
- req.baseConfigs.rangingRequired = publishConfig.mEnableRanging;
-
- req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
- WifiAwareDataPathSecurityConfig securityConfig = publishConfig.getSecurityConfig();
- if (securityConfig != null) {
- req.baseConfigs.securityConfig.cipherType = getHalCipherSuiteType(
- securityConfig.getCipherSuite());
- if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
- req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.PMK;
- copyArray(securityConfig.getPmk(), req.baseConfigs.securityConfig.pmk);
- }
- if (securityConfig.getPskPassphrase() != null
- && securityConfig.getPskPassphrase().length() != 0) {
- req.baseConfigs.securityConfig.securityType =
- NanDataPathSecurityType.PASSPHRASE;
- convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
- req.baseConfigs.securityConfig.passphrase);
- }
- if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) {
- copyArray(securityConfig.getPmkId(), req.baseConfigs.securityConfig.scid);
- }
- }
-
- req.publishType = publishConfig.mPublishType;
- req.txType = NanTxType.BROADCAST;
-
- try {
- WifiStatus status = iface16.startPublishRequest_1_6(transactionId, req);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "publish: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "publish: exception: " + e);
- return false;
- }
- }
+ return iface.publish(transactionId, publishId, publishConfig);
}
/**
@@ -913,63 +435,12 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
}
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "subscribe: null interface");
return false;
}
-
- NanSubscribeRequest req = new NanSubscribeRequest();
- req.baseConfigs.sessionId = subscribeId;
- req.baseConfigs.ttlSec = (short) subscribeConfig.mTtlSec;
- req.baseConfigs.discoveryWindowPeriod = 1;
- req.baseConfigs.discoveryCount = 0;
- convertNativeByteArrayToArrayList(subscribeConfig.mServiceName,
- req.baseConfigs.serviceName);
- req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_ONCE;
- convertNativeByteArrayToArrayList(subscribeConfig.mServiceSpecificInfo,
- req.baseConfigs.serviceSpecificInfo);
- convertNativeByteArrayToArrayList(subscribeConfig.mMatchFilter,
- subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
- ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
- req.baseConfigs.useRssiThreshold = false;
- req.baseConfigs.disableDiscoveryTerminationIndication =
- !subscribeConfig.mEnableTerminateNotification;
- req.baseConfigs.disableMatchExpirationIndication = false;
- req.baseConfigs.disableFollowupReceivedIndication = false;
-
- req.baseConfigs.rangingRequired =
- subscribeConfig.mMinDistanceMmSet || subscribeConfig.mMaxDistanceMmSet;
- req.baseConfigs.configRangingIndications = 0;
- // TODO: b/69428593 remove correction factors once HAL converted from CM to MM
- if (subscribeConfig.mMinDistanceMmSet) {
- req.baseConfigs.distanceEgressCm = (short) Math.min(
- subscribeConfig.mMinDistanceMm / 10, Short.MAX_VALUE);
- req.baseConfigs.configRangingIndications |= NanRangingIndication.EGRESS_MET_MASK;
- }
- if (subscribeConfig.mMaxDistanceMmSet) {
- req.baseConfigs.distanceIngressCm = (short) Math.min(
- subscribeConfig.mMaxDistanceMm / 10, Short.MAX_VALUE);
- req.baseConfigs.configRangingIndications |= NanRangingIndication.INGRESS_MET_MASK;
- }
-
- // TODO: configure security
- req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
-
- req.subscribeType = subscribeConfig.mSubscribeType;
-
- try {
- WifiStatus status = iface.startSubscribeRequest(transactionId, req);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "subscribe: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "subscribe: exception: " + e);
- return false;
- }
+ return iface.subscribe(transactionId, subscribeId, subscribeConfig);
}
/**
@@ -999,31 +470,18 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
}
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "sendMessage: null interface");
return false;
}
- NanTransmitFollowupRequest req = new NanTransmitFollowupRequest();
- req.discoverySessionId = pubSubId;
- req.peerId = requestorInstanceId;
- copyArray(dest, req.addr);
- req.isHighPriority = false;
- req.shouldUseDiscoveryWindow = true;
- convertNativeByteArrayToArrayList(message, req.serviceSpecificInfo);
- req.disableFollowupResultIndication = false;
-
try {
- WifiStatus status = iface.transmitFollowupRequest(transactionId, req);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "sendMessage: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "sendMessage: exception: " + e);
+ MacAddress destMac = MacAddress.fromBytes(dest);
+ return iface.sendMessage(
+ transactionId, pubSubId, requestorInstanceId, destMac, message);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Invalid dest mac received: " + Arrays.toString(dest));
return false;
}
}
@@ -1042,24 +500,12 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
}
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "stopPublish: null interface");
return false;
}
-
- try {
- WifiStatus status = iface.stopPublishRequest(transactionId, pubSubId);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "stopPublish: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "stopPublish: exception: " + e);
- return false;
- }
+ return iface.stopPublish(transactionId, pubSubId);
}
/**
@@ -1076,24 +522,12 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
}
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "stopSubscribe: null interface");
return false;
}
-
- try {
- WifiStatus status = iface.stopSubscribeRequest(transactionId, pubSubId);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "stopSubscribe: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "stopSubscribe: exception: " + e);
- return false;
- }
+ return iface.stopSubscribe(transactionId, pubSubId);
}
/**
@@ -1109,24 +543,12 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
+ "interfaceName=" + interfaceName);
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "createAwareNetworkInterface: null interface");
return false;
}
-
- try {
- WifiStatus status = iface.createDataInterfaceRequest(transactionId, interfaceName);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "createAwareNetworkInterface: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "createAwareNetworkInterface: exception: " + e);
- return false;
- }
+ return iface.createAwareNetworkInterface(transactionId, interfaceName);
}
/**
@@ -1141,24 +563,12 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
+ "interfaceName=" + interfaceName);
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "deleteAwareNetworkInterface: null interface");
return false;
}
-
- try {
- WifiStatus status = iface.deleteDataInterfaceRequest(transactionId, interfaceName);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "deleteAwareNetworkInterface: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "deleteAwareNetworkInterface: exception: " + e);
- return false;
- }
+ return iface.deleteAwareNetworkInterface(transactionId, interfaceName);
}
/**
@@ -1194,113 +604,22 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
}
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "initiateDataPath: null interface");
return false;
}
- if (capabilities == null) {
- Log.e(TAG, "initiateDataPath: null capabilities");
+ try {
+ MacAddress peerMac = MacAddress.fromBytes(peer);
+ return iface.initiateDataPath(transactionId, peerId, channelRequestType, channel,
+ peerMac, interfaceName, isOutOfBand, appInfo, capabilities, securityConfig);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Invalid peer mac received: " + Arrays.toString(peer));
return false;
}
-
- android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6(iface);
-
- if (iface16 == null) {
- NanInitiateDataPathRequest req = new NanInitiateDataPathRequest();
- req.peerId = peerId;
- copyArray(peer, req.peerDiscMacAddr);
- req.channelRequestType = channelRequestType;
- req.channel = channel;
- req.ifaceName = interfaceName;
- req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
- if (securityConfig != null) {
- req.securityConfig.cipherType = getHalCipherSuiteType(
- securityConfig.getCipherSuite());
- if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
-
- req.securityConfig.securityType = NanDataPathSecurityType.PMK;
- copyArray(securityConfig.getPmk(), req.securityConfig.pmk);
- }
- if (securityConfig.getPskPassphrase() != null
- && securityConfig.getPskPassphrase().length() != 0) {
- req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
- convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
- req.securityConfig.passphrase);
- }
- }
-
- if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
- convertNativeByteArrayToArrayList(
- SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(StandardCharsets.UTF_8),
- req.serviceNameOutOfBand);
- }
- convertNativeByteArrayToArrayList(appInfo, req.appInfo);
-
- try {
- WifiStatus status = iface.initiateDataPathRequest(transactionId, req);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "initiateDataPath: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "initiateDataPath: exception: " + e);
- return false;
- }
- } else {
- android.hardware.wifi.V1_6.NanInitiateDataPathRequest req =
- new android.hardware.wifi.V1_6.NanInitiateDataPathRequest();
- req.peerId = peerId;
- copyArray(peer, req.peerDiscMacAddr);
- req.channelRequestType = channelRequestType;
- req.channel = channel;
- req.ifaceName = interfaceName;
- req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
- if (securityConfig != null) {
- req.securityConfig.cipherType = getHalCipherSuiteType(
- securityConfig.getCipherSuite());
- if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
- req.securityConfig.securityType = NanDataPathSecurityType.PMK;
- copyArray(securityConfig.getPmk(), req.securityConfig.pmk);
- }
- if (securityConfig.getPskPassphrase() != null
- && securityConfig.getPskPassphrase().length() != 0) {
- req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
- convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
- req.securityConfig.passphrase);
- }
- if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) {
- copyArray(securityConfig.getPmkId(), req.securityConfig.scid);
- }
- }
-
- if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
- convertNativeByteArrayToArrayList(
- SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(StandardCharsets.UTF_8),
- req.serviceNameOutOfBand);
- }
- convertNativeByteArrayToArrayList(appInfo, req.appInfo);
-
- try {
- WifiStatus status = iface16.initiateDataPathRequest_1_6(transactionId, req);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "initiateDataPath_1_6: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "initiateDataPath_1_6: exception: " + e);
- return false;
- }
- }
}
-
-
/**
* Responds to a data request from a peer. Security is provided by either PMK or Passphrase (not
* both) - if both are null then an open (unencrypted) link is set up.
@@ -1328,107 +647,13 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
}
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "respondToDataPathRequest: null interface");
return false;
}
-
- if (capabilities == null) {
- Log.e(TAG, "respondToDataPathRequest: null capabilities");
- return false;
- }
-
- android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6(iface);
-
- if (iface16 == null) {
- NanRespondToDataPathIndicationRequest req = new NanRespondToDataPathIndicationRequest();
- req.acceptRequest = accept;
- req.ndpInstanceId = ndpId;
- req.ifaceName = interfaceName;
- req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
- if (securityConfig != null) {
- req.securityConfig.cipherType = getHalCipherSuiteType(
- securityConfig.getCipherSuite());
- if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
-
- req.securityConfig.securityType = NanDataPathSecurityType.PMK;
- copyArray(securityConfig.getPmk(), req.securityConfig.pmk);
- }
- if (securityConfig.getPskPassphrase() != null
- && securityConfig.getPskPassphrase().length() != 0) {
- req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
- convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
- req.securityConfig.passphrase);
- }
- }
-
- if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
- convertNativeByteArrayToArrayList(
- SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(StandardCharsets.UTF_8),
- req.serviceNameOutOfBand);
- }
- convertNativeByteArrayToArrayList(appInfo, req.appInfo);
-
- try {
- WifiStatus status = iface.respondToDataPathIndicationRequest(transactionId, req);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "respondToDataPathRequest: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "respondToDataPathRequest: exception: " + e);
- return false;
- }
- } else {
- android.hardware.wifi.V1_6.NanRespondToDataPathIndicationRequest req =
- new android.hardware.wifi.V1_6.NanRespondToDataPathIndicationRequest();
- req.acceptRequest = accept;
- req.ndpInstanceId = ndpId;
- req.ifaceName = interfaceName;
- req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
- if (securityConfig != null) {
- req.securityConfig.cipherType = getHalCipherSuiteType(
- securityConfig.getCipherSuite());
- if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
-
- req.securityConfig.securityType = NanDataPathSecurityType.PMK;
- copyArray(securityConfig.getPmk(), req.securityConfig.pmk);
- }
- if (securityConfig.getPskPassphrase() != null
- && securityConfig.getPskPassphrase().length() != 0) {
- req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
- convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
- req.securityConfig.passphrase);
- }
- if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) {
- copyArray(securityConfig.getPmkId(), req.securityConfig.scid);
- }
- }
-
- if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
- convertNativeByteArrayToArrayList(
- SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(StandardCharsets.UTF_8),
- req.serviceNameOutOfBand);
- }
- convertNativeByteArrayToArrayList(appInfo, req.appInfo);
-
- try {
- WifiStatus status = iface16
- .respondToDataPathIndicationRequest_1_6(transactionId, req);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "respondToDataPathRequest_1_6: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "respondToDataPathRequest_1_6: exception: " + e);
- return false;
- }
- }
+ return iface.respondToDataPathRequest(transactionId, accept, ndpId, interfaceName, appInfo,
+ isOutOfBand, capabilities, securityConfig);
}
/**
@@ -1444,35 +669,22 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
}
recordTransactionId(transactionId);
- IWifiNanIface iface = mHal.getWifiNanIface();
+ WifiNanIface iface = mHal.getWifiNanIface();
if (iface == null) {
Log.e(TAG, "endDataPath: null interface");
return false;
}
-
- try {
- WifiStatus status = iface.terminateDataPathRequest(transactionId, ndpId);
- if (status.code == WifiStatusCode.SUCCESS) {
- return true;
- } else {
- Log.e(TAG, "endDataPath: error: " + statusString(status));
- return false;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "endDataPath: exception: " + e);
- return false;
- }
+ return iface.endDataPath(transactionId, ndpId);
}
-
// utilities
/**
- * Update the NAN configuration to reflect the current power settings (before V1.4)
+ * Create a PowerParameters object to pass our cached parameters to the HAL.
*/
- private void updateConfigForPowerSettings(NanConfigRequest req,
- android.hardware.wifi.V1_2.NanConfigRequestSupplemental configSupplemental12,
+ private PowerParameters getPowerParameters(
boolean isInteractive, boolean isIdle) {
+ PowerParameters params = new PowerParameters();
String key = POWER_PARAM_DEFAULT_KEY;
if (isIdle) {
key = POWER_PARAM_IDLE_KEY;
@@ -1480,46 +692,16 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
key = POWER_PARAM_INACTIVE_KEY;
}
- updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ],
- getSettablePowerParameters(key, PARAM_DW_5GHZ));
- updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ],
- getSettablePowerParameters(key, PARAM_DW_24GHZ));
-
- configSupplemental12.discoveryBeaconIntervalMs = getSettablePowerParameters(key,
+ params.discoveryWindow24Ghz = getSettablePowerParameters(key, PARAM_DW_24GHZ);
+ params.discoveryWindow5Ghz = getSettablePowerParameters(key, PARAM_DW_5GHZ);
+ params.discoveryWindow6Ghz = getSettablePowerParameters(key, PARAM_DW_6GHZ);
+ params.discoveryBeaconIntervalMs = getSettablePowerParameters(key,
PARAM_DISCOVERY_BEACON_INTERVAL_MS);
- configSupplemental12.numberOfSpatialStreamsInDiscovery = getSettablePowerParameters(key,
+ params.numberOfSpatialStreamsInDiscovery = getSettablePowerParameters(key,
PARAM_NUM_SS_IN_DISCOVERY);
- configSupplemental12.enableDiscoveryWindowEarlyTermination = getSettablePowerParameters(key,
+ params.enableDiscoveryWindowEarlyTermination = getSettablePowerParameters(key,
PARAM_ENABLE_DW_EARLY_TERM) != 0;
- }
-
- /**
- * Update the NAN configuration to reflect the current power settings (V1.4)
- */
- private void updateConfigForPowerSettings14(android.hardware.wifi.V1_4.NanConfigRequest req,
- android.hardware.wifi.V1_2.NanConfigRequestSupplemental configSupplemental12,
- boolean isInteractive, boolean isIdle) {
- String key = POWER_PARAM_DEFAULT_KEY;
- if (isIdle) {
- key = POWER_PARAM_IDLE_KEY;
- } else if (!isInteractive) {
- key = POWER_PARAM_INACTIVE_KEY;
- }
-
- updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ],
- getSettablePowerParameters(key, PARAM_DW_5GHZ));
- updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ],
- getSettablePowerParameters(key, PARAM_DW_24GHZ));
- updateSingleConfigForPowerSettings(req.bandSpecificConfig[
- android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ],
- getSettablePowerParameters(key, PARAM_DW_6GHZ));
-
- configSupplemental12.discoveryBeaconIntervalMs = getSettablePowerParameters(key,
- PARAM_DISCOVERY_BEACON_INTERVAL_MS);
- configSupplemental12.numberOfSpatialStreamsInDiscovery = getSettablePowerParameters(key,
- PARAM_NUM_SS_IN_DISCOVERY);
- configSupplemental12.enableDiscoveryWindowEarlyTermination =
- getSettablePowerParameters(key, PARAM_ENABLE_DW_EARLY_TERM) != 0;
+ return params;
}
private int getSettablePowerParameters(String state, String key) {
@@ -1529,74 +711,6 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
return mSettablePowerParameters.get(state).get(key);
}
- private void updateSingleConfigForPowerSettings(NanBandSpecificConfig cfg, int override) {
- if (override != -1) {
- cfg.validDiscoveryWindowIntervalVal = true;
- cfg.discoveryWindowIntervalVal = (byte) override;
- }
- }
-
- /**
- * Returns the HAL cipher suite.
- */
- private int getHalCipherSuiteType(int frameworkCipherSuites) {
- switch (frameworkCipherSuites) {
- case WIFI_AWARE_CIPHER_SUITE_NCS_SK_128:
- return NanCipherSuiteType.SHARED_KEY_128_MASK;
- case WIFI_AWARE_CIPHER_SUITE_NCS_SK_256:
- return NanCipherSuiteType.SHARED_KEY_256_MASK;
- case WIFI_AWARE_CIPHER_SUITE_NCS_PK_128:
- return NanCipherSuiteType.PUBLIC_KEY_128_MASK;
- case WIFI_AWARE_CIPHER_SUITE_NCS_PK_256:
- return NanCipherSuiteType.PUBLIC_KEY_256_MASK;
- }
- return NanCipherSuiteType.NONE;
- }
-
- /**
- * Converts a byte[] to an ArrayList<Byte>. Fills in the entries of the 'to' array if
- * provided (non-null), otherwise creates and returns a new ArrayList<>.
- *
- * @param from The input byte[] to convert from.
- * @param to An optional ArrayList<> to fill in from 'from'.
- *
- * @return A newly allocated ArrayList<> if 'to' is null, otherwise null.
- */
- private ArrayList<Byte> convertNativeByteArrayToArrayList(byte[] from, ArrayList<Byte> to) {
- if (from == null) {
- from = new byte[0];
- }
-
- if (to == null) {
- to = new ArrayList<>(from.length);
- } else {
- to.ensureCapacity(from.length);
- }
- for (int i = 0; i < from.length; ++i) {
- to.add(from[i]);
- }
- return to;
- }
-
- private void copyArray(byte[] from, byte[] to) {
- if (from == null || to == null || from.length != to.length) {
- Log.e(TAG, "copyArray error: from=" + from + ", to=" + to);
- return;
- }
- for (int i = 0; i < from.length; ++i) {
- to[i] = from[i];
- }
- }
-
- private static String statusString(WifiStatus status) {
- if (status == null) {
- return "status=null";
- }
- StringBuilder sb = new StringBuilder();
- sb.append(status.code).append(" (").append(status.description).append(")");
- return sb.toString();
- }
-
/**
* Dump the internal state of the class.
*/
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
index 63296e638b..79496a104e 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
@@ -16,30 +16,15 @@
package com.android.server.wifi.aware;
-import android.hardware.wifi.V1_0.NanClusterEventInd;
-import android.hardware.wifi.V1_0.NanClusterEventType;
-import android.hardware.wifi.V1_0.NanDataPathConfirmInd;
-import android.hardware.wifi.V1_0.NanDataPathRequestInd;
-import android.hardware.wifi.V1_0.NanFollowupReceivedInd;
-import android.hardware.wifi.V1_0.NanMatchInd;
-import android.hardware.wifi.V1_0.NanStatusType;
-import android.hardware.wifi.V1_0.WifiNanStatus;
-import android.hardware.wifi.V1_2.NanDataPathScheduleUpdateInd;
-import android.hardware.wifi.V1_6.IWifiNanIfaceEventCallback;
-import android.hardware.wifi.V1_6.NanCipherSuiteType;
-import android.hardware.wifi.V1_6.WifiChannelWidthInMhz;
-import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiAnnotations;
-import android.net.wifi.aware.Characteristics;
import android.net.wifi.aware.WifiAwareChannelInfo;
-import android.net.wifi.util.HexEncoding;
-import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.modules.utils.BasicShellCommandHandler;
+import com.android.server.wifi.hal.WifiNanIface;
+import com.android.server.wifi.hal.WifiNanIface.NanClusterEventType;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
import org.json.JSONArray;
import org.json.JSONException;
@@ -48,21 +33,16 @@ import org.json.JSONObject;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
/**
- * Manages the callbacks from Wi-Fi Aware HIDL (HAL).
+ * Manages the callbacks from Wi-Fi Aware HAL.
*/
-public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub implements
+public class WifiAwareNativeCallback implements WifiNanIface.Callback,
WifiAwareShellCommand.DelegatedShellCommand {
private static final String TAG = "WifiAwareNativeCallback";
private boolean mVerboseHalLoggingEnabled = false;
- /* package */ boolean mIsHal12OrLater = false;
- /* package */ boolean mIsHal15OrLater = false;
- /* package */ boolean mIsHal16OrLater = false;
-
private final WifiAwareStateManager mWifiAwareStateManager;
public WifiAwareNativeCallback(WifiAwareStateManager wifiAwareStateManager) {
@@ -172,602 +152,198 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
}
@Override
- public void notifyCapabilitiesResponse(short id, WifiNanStatus status,
- android.hardware.wifi.V1_0.NanCapabilities capabilities) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyCapabilitiesResponse: id=" + id + ", status=" + statusString(status)
- + ", capabilities=" + capabilities);
- }
-
- if (mIsHal15OrLater) {
- Log.wtf(TAG, "notifyCapabilitiesResponse should not be called by a >=1.5 HAL!");
- }
-
- if (status.status == NanStatusType.SUCCESS) {
- Capabilities frameworkCapabilities = toFrameworkCapability10(capabilities);
-
- mWifiAwareStateManager.onCapabilitiesUpdateResponse(id, frameworkCapabilities);
- } else {
- Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " ("
- + status.description + ")");
- }
- }
-
- @Override
- public void notifyCapabilitiesResponse_1_5(short id, WifiNanStatus status,
- android.hardware.wifi.V1_5.NanCapabilities capabilities) throws RemoteException {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyCapabilitiesResponse_1_5: id=" + id + ", status="
- + statusString(status) + ", capabilities=" + capabilities);
- }
-
- if (!mIsHal15OrLater) {
- Log.wtf(TAG, "notifyCapabilitiesResponse_1_5 should not be called by a <1.5 HAL!");
- return;
- }
-
- if (status.status == NanStatusType.SUCCESS) {
- Capabilities frameworkCapabilities = toFrameworkCapability10(capabilities.V1_0);
- frameworkCapabilities.isInstantCommunicationModeSupported =
- capabilities.instantCommunicationModeSupportFlag;
-
- mWifiAwareStateManager.onCapabilitiesUpdateResponse(id, frameworkCapabilities);
- } else {
- Log.e(TAG, "notifyCapabilitiesResponse_1_5: error code=" + status.status + " ("
- + status.description + ")");
- }
- }
-
- @Override
- public void notifyCapabilitiesResponse_1_6(short id, WifiNanStatus status,
- android.hardware.wifi.V1_6.NanCapabilities capabilities) throws RemoteException {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyCapabilitiesResponse_1_6: id=" + id + ", status="
- + statusString(status) + ", capabilities=" + capabilities);
- }
-
- if (!mIsHal16OrLater) {
- Log.wtf(TAG, "notifyCapabilitiesResponse_1_6 should not be called by a <1.6 HAL!");
- return;
- }
-
- if (status.status == NanStatusType.SUCCESS) {
- Capabilities frameworkCapabilities = toFrameworkCapability1_6(capabilities);
-
- mWifiAwareStateManager.onCapabilitiesUpdateResponse(id, frameworkCapabilities);
- } else {
- Log.e(TAG, "notifyCapabilitiesResponse_1_6: error code=" + status.status + " ("
- + status.description + ")");
- }
- }
-
- private Capabilities toFrameworkCapability1_6(
- android.hardware.wifi.V1_6.NanCapabilities capabilities) {
- Capabilities frameworkCapabilities = new Capabilities();
- frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters;
- frameworkCapabilities.maxPublishes = capabilities.maxPublishes;
- frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes;
- frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen;
- frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen;
- frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen;
- frameworkCapabilities.maxServiceSpecificInfoLen =
- capabilities.maxServiceSpecificInfoLen;
- frameworkCapabilities.maxExtendedServiceSpecificInfoLen =
- capabilities.maxExtendedServiceSpecificInfoLen;
- frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces;
- frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions;
- frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen;
- frameworkCapabilities.maxQueuedTransmitMessages =
- capabilities.maxQueuedTransmitFollowupMsgs;
- frameworkCapabilities.maxSubscribeInterfaceAddresses =
- capabilities.maxSubscribeInterfaceAddresses;
- frameworkCapabilities.supportedCipherSuites = toPublicCipherSuites(
- capabilities.supportedCipherSuites);
- frameworkCapabilities.isInstantCommunicationModeSupported =
- capabilities.instantCommunicationModeSupportFlag;
- return frameworkCapabilities;
- }
-
- private Capabilities toFrameworkCapability10(
- android.hardware.wifi.V1_0.NanCapabilities capabilities) {
- Capabilities frameworkCapabilities = new Capabilities();
- frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters;
- frameworkCapabilities.maxPublishes = capabilities.maxPublishes;
- frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes;
- frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen;
- frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen;
- frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen;
- frameworkCapabilities.maxServiceSpecificInfoLen =
- capabilities.maxServiceSpecificInfoLen;
- frameworkCapabilities.maxExtendedServiceSpecificInfoLen =
- capabilities.maxExtendedServiceSpecificInfoLen;
- frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces;
- frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions;
- frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen;
- frameworkCapabilities.maxQueuedTransmitMessages =
- capabilities.maxQueuedTransmitFollowupMsgs;
- frameworkCapabilities.maxSubscribeInterfaceAddresses =
- capabilities.maxSubscribeInterfaceAddresses;
- frameworkCapabilities.supportedCipherSuites = toPublicCipherSuites(
- capabilities.supportedCipherSuites);
- frameworkCapabilities.isInstantCommunicationModeSupported = false;
- return frameworkCapabilities;
- }
-
- private int toPublicCipherSuites(int nativeCipherSuites) {
- int publicCipherSuites = 0;
-
- if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_128_MASK) != 0) {
- publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
- }
- if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_256_MASK) != 0) {
- publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
- }
- if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_128_MASK) != 0) {
- publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128;
- }
- if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_256_MASK) != 0) {
- publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256;
- }
-
- return publicCipherSuites;
+ public void notifyCapabilitiesResponse(short id, Capabilities capabilities) {
+ mWifiAwareStateManager.onCapabilitiesUpdateResponse(id, capabilities);
}
@Override
- public void notifyEnableResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyEnableResponse: id=" + id + ", status=" + statusString(status));
- }
-
- if (status.status == NanStatusType.ALREADY_ENABLED) {
- Log.wtf(TAG, "notifyEnableResponse: id=" + id + ", already enabled!?");
- }
-
- if (status.status == NanStatusType.SUCCESS
- || status.status == NanStatusType.ALREADY_ENABLED) {
+ public void notifyEnableResponse(short id, int status) {
+ if (status == NanStatusCode.SUCCESS
+ || status == NanStatusCode.ALREADY_ENABLED) {
mWifiAwareStateManager.onConfigSuccessResponse(id);
} else {
- mWifiAwareStateManager.onConfigFailedResponse(id, status.status);
+ mWifiAwareStateManager.onConfigFailedResponse(id, status);
}
}
@Override
- public void notifyConfigResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyConfigResponse: id=" + id + ", status=" + statusString(status));
- }
-
- if (status.status == NanStatusType.SUCCESS) {
+ public void notifyConfigResponse(short id, int status) {
+ if (status == NanStatusCode.SUCCESS) {
mWifiAwareStateManager.onConfigSuccessResponse(id);
} else {
- mWifiAwareStateManager.onConfigFailedResponse(id, status.status);
+ mWifiAwareStateManager.onConfigFailedResponse(id, status);
}
}
@Override
- public void notifyDisableResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyDisableResponse: id=" + id + ", status=" + statusString(status));
- }
-
- if (status.status != NanStatusType.SUCCESS) {
- Log.e(TAG, "notifyDisableResponse: failure - code=" + status.status + " ("
- + status.description + ")");
- }
- mWifiAwareStateManager.onDisableResponse(id, status.status);
+ public void notifyDisableResponse(short id, int status) {
+ mWifiAwareStateManager.onDisableResponse(id, status);
}
@Override
- public void notifyStartPublishResponse(short id, WifiNanStatus status, byte publishId) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyStartPublishResponse: id=" + id + ", status=" + statusString(status)
- + ", publishId=" + publishId);
- }
-
- if (status.status == NanStatusType.SUCCESS) {
+ public void notifyStartPublishResponse(short id, int status, byte publishId) {
+ if (status == NanStatusCode.SUCCESS) {
mWifiAwareStateManager.onSessionConfigSuccessResponse(id, true, publishId);
} else {
- mWifiAwareStateManager.onSessionConfigFailResponse(id, true, status.status);
- }
- }
-
- @Override
- public void notifyStopPublishResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyStopPublishResponse: id=" + id + ", status=" + statusString(status));
- }
-
- if (status.status == NanStatusType.SUCCESS) {
- // NOP
- } else {
- Log.e(TAG, "notifyStopPublishResponse: failure - code=" + status.status + " ("
- + status.description + ")");
+ mWifiAwareStateManager.onSessionConfigFailResponse(id, true, status);
}
}
@Override
- public void notifyStartSubscribeResponse(short id, WifiNanStatus status, byte subscribeId) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyStartSubscribeResponse: id=" + id + ", status=" + statusString(status)
- + ", subscribeId=" + subscribeId);
- }
-
- if (status.status == NanStatusType.SUCCESS) {
+ public void notifyStartSubscribeResponse(short id, int status, byte subscribeId) {
+ if (status == NanStatusCode.SUCCESS) {
mWifiAwareStateManager.onSessionConfigSuccessResponse(id, false, subscribeId);
} else {
- mWifiAwareStateManager.onSessionConfigFailResponse(id, false, status.status);
+ mWifiAwareStateManager.onSessionConfigFailResponse(id, false, status);
}
}
@Override
- public void notifyStopSubscribeResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyStopSubscribeResponse: id=" + id + ", status="
- + statusString(status));
- }
-
- if (status.status == NanStatusType.SUCCESS) {
- // NOP
- } else {
- Log.e(TAG, "notifyStopSubscribeResponse: failure - code=" + status.status + " ("
- + status.description + ")");
- }
- }
-
- @Override
- public void notifyTransmitFollowupResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyTransmitFollowupResponse: id=" + id + ", status="
- + statusString(status));
- }
-
- if (status.status == NanStatusType.SUCCESS) {
+ public void notifyTransmitFollowupResponse(short id, int status) {
+ if (status == NanStatusCode.SUCCESS) {
mWifiAwareStateManager.onMessageSendQueuedSuccessResponse(id);
} else {
- mWifiAwareStateManager.onMessageSendQueuedFailResponse(id, status.status);
+ mWifiAwareStateManager.onMessageSendQueuedFailResponse(id, status);
}
}
@Override
- public void notifyCreateDataInterfaceResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyCreateDataInterfaceResponse: id=" + id + ", status="
- + statusString(status));
- }
-
+ public void notifyCreateDataInterfaceResponse(short id, int status) {
mWifiAwareStateManager.onCreateDataPathInterfaceResponse(id,
- status.status == NanStatusType.SUCCESS, status.status);
+ status == NanStatusCode.SUCCESS, status);
}
@Override
- public void notifyDeleteDataInterfaceResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyDeleteDataInterfaceResponse: id=" + id + ", status="
- + statusString(status));
- }
-
+ public void notifyDeleteDataInterfaceResponse(short id, int status) {
mWifiAwareStateManager.onDeleteDataPathInterfaceResponse(id,
- status.status == NanStatusType.SUCCESS, status.status);
+ status == NanStatusCode.SUCCESS, status);
}
@Override
- public void notifyInitiateDataPathResponse(short id, WifiNanStatus status,
+ public void notifyInitiateDataPathResponse(short id, int status,
int ndpInstanceId) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyInitiateDataPathResponse: id=" + id + ", status="
- + statusString(status) + ", ndpInstanceId=" + ndpInstanceId);
- }
-
- if (status.status == NanStatusType.SUCCESS) {
+ if (status == NanStatusCode.SUCCESS) {
mWifiAwareStateManager.onInitiateDataPathResponseSuccess(id, ndpInstanceId);
} else {
- mWifiAwareStateManager.onInitiateDataPathResponseFail(id, status.status);
+ mWifiAwareStateManager.onInitiateDataPathResponseFail(id, status);
}
}
@Override
- public void notifyRespondToDataPathIndicationResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyRespondToDataPathIndicationResponse: id=" + id
- + ", status=" + statusString(status));
- }
-
+ public void notifyRespondToDataPathIndicationResponse(short id, int status) {
mWifiAwareStateManager.onRespondToDataPathSetupRequestResponse(id,
- status.status == NanStatusType.SUCCESS, status.status);
+ status == NanStatusCode.SUCCESS, status);
}
@Override
- public void notifyTerminateDataPathResponse(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "notifyTerminateDataPathResponse: id=" + id + ", status="
- + statusString(status));
- }
-
- mWifiAwareStateManager.onEndDataPathResponse(id, status.status == NanStatusType.SUCCESS,
- status.status);
+ public void notifyTerminateDataPathResponse(short id, int status) {
+ mWifiAwareStateManager.onEndDataPathResponse(id, status == NanStatusCode.SUCCESS,
+ status);
}
@Override
- public void eventClusterEvent(NanClusterEventInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventClusterEvent: eventType=" + event.eventType + ", addr="
- + String.valueOf(HexEncoding.encode(event.addr)));
- }
+ public void eventClusterEvent(int eventType, byte[] addr) {
incrementCbCount(CB_EV_CLUSTER);
-
- if (event.eventType == NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED) {
- mWifiAwareStateManager.onInterfaceAddressChangeNotification(event.addr);
- } else if (event.eventType == NanClusterEventType.STARTED_CLUSTER) {
+ if (eventType == NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED) {
+ mWifiAwareStateManager.onInterfaceAddressChangeNotification(addr);
+ } else if (eventType == NanClusterEventType.STARTED_CLUSTER) {
mWifiAwareStateManager.onClusterChangeNotification(
- WifiAwareClientState.CLUSTER_CHANGE_EVENT_STARTED, event.addr);
- } else if (event.eventType == NanClusterEventType.JOINED_CLUSTER) {
+ WifiAwareClientState.CLUSTER_CHANGE_EVENT_STARTED, addr);
+ } else if (eventType == NanClusterEventType.JOINED_CLUSTER) {
mWifiAwareStateManager.onClusterChangeNotification(
- WifiAwareClientState.CLUSTER_CHANGE_EVENT_JOINED, event.addr);
+ WifiAwareClientState.CLUSTER_CHANGE_EVENT_JOINED, addr);
} else {
- Log.e(TAG, "eventClusterEvent: invalid eventType=" + event.eventType);
+ Log.e(TAG, "eventClusterEvent: invalid eventType=" + eventType);
}
}
@Override
- public void eventDisabled(WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) Log.v(TAG, "eventDisabled: status=" + statusString(status));
+ public void eventDisabled(int status) {
incrementCbCount(CB_EV_DISABLED);
-
- mWifiAwareStateManager.onAwareDownNotification(status.status);
+ mWifiAwareStateManager.onAwareDownNotification(status);
}
@Override
- public void eventPublishTerminated(byte sessionId, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventPublishTerminated: sessionId=" + sessionId + ", status="
- + statusString(status));
- }
+ public void eventPublishTerminated(byte sessionId, int status) {
incrementCbCount(CB_EV_PUBLISH_TERMINATED);
-
- mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, true);
+ mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status, true);
}
@Override
- public void eventSubscribeTerminated(byte sessionId, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventSubscribeTerminated: sessionId=" + sessionId + ", status="
- + statusString(status));
- }
+ public void eventSubscribeTerminated(byte sessionId, int status) {
incrementCbCount(CB_EV_SUBSCRIBE_TERMINATED);
-
- mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, false);
- }
-
- @Override
- public void eventMatch(NanMatchInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventMatch: discoverySessionId=" + event.discoverySessionId + ", peerId="
- + event.peerId + ", addr=" + String.valueOf(HexEncoding.encode(event.addr))
- + ", serviceSpecificInfo=" + Arrays.toString(
- convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
- + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size())
- + ", matchFilter=" + Arrays.toString(
- convertArrayListToNativeByteArray(event.matchFilter)) + ", mf.size()=" + (
- event.matchFilter == null ? 0 : event.matchFilter.size())
- + ", rangingIndicationType=" + event.rangingIndicationType
- + ", rangingMeasurementInCm=" + event.rangingMeasurementInCm);
- }
- incrementCbCount(CB_EV_MATCH);
-
- // TODO: b/69428593 get rid of conversion once HAL moves from CM to MM
- mWifiAwareStateManager.onMatchNotification(event.discoverySessionId, event.peerId,
- event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo),
- convertArrayListToNativeByteArray(event.matchFilter), event.rangingIndicationType,
- event.rangingMeasurementInCm * 10, new byte[0], 0);
+ mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status, false);
}
@Override
- public void eventMatch_1_6(android.hardware.wifi.V1_6.NanMatchInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventMatch_1_6: discoverySessionId=" + event.discoverySessionId
- + ", peerId=" + event.peerId
- + ", addr=" + String.valueOf(HexEncoding.encode(event.addr))
- + ", serviceSpecificInfo=" + Arrays.toString(
- convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
- + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size())
- + ", matchFilter=" + Arrays.toString(
- convertArrayListToNativeByteArray(event.matchFilter)) + ", mf.size()=" + (
- event.matchFilter == null ? 0 : event.matchFilter.size())
- + ", rangingIndicationType=" + event.rangingIndicationType
- + ", rangingMeasurementInCm=" + event.rangingMeasurementInMm + ", "
- + "scid=" + Arrays.toString(convertArrayListToNativeByteArray(event.scid)));
- }
+ public void eventMatch(byte discoverySessionId, int peerId, byte[] addr,
+ byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndicationType,
+ int rangingMeasurementInMm, byte[] scid, int peerCipherType) {
incrementCbCount(CB_EV_MATCH);
-
- // TODO: b/69428593 get rid of conversion once HAL moves from CM to MM
- mWifiAwareStateManager.onMatchNotification(event.discoverySessionId, event.peerId,
- event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo),
- convertArrayListToNativeByteArray(event.matchFilter), event.rangingIndicationType,
- event.rangingMeasurementInMm,
- convertArrayListToNativeByteArray(event.scid),
- toPublicCipherSuites(event.peerCipherType));
+ mWifiAwareStateManager.onMatchNotification(discoverySessionId, peerId,
+ addr, serviceSpecificInfo, matchFilter, rangingIndicationType,
+ rangingMeasurementInMm, scid, peerCipherType);
}
@Override
public void eventMatchExpired(byte discoverySessionId, int peerId) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventMatchExpired: discoverySessionId=" + discoverySessionId
- + ", peerId=" + peerId);
- }
incrementCbCount(CB_EV_MATCH_EXPIRED);
mWifiAwareStateManager.onMatchExpiredNotification(discoverySessionId, peerId);
}
@Override
- public void eventFollowupReceived(NanFollowupReceivedInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventFollowupReceived: discoverySessionId=" + event.discoverySessionId
- + ", peerId=" + event.peerId + ", addr=" + String.valueOf(
- HexEncoding.encode(event.addr)) + ", serviceSpecificInfo=" + Arrays.toString(
- convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
- + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size()));
- }
+ public void eventFollowupReceived(byte discoverySessionId, int peerId, byte[] addr,
+ byte[] serviceSpecificInfo) {
incrementCbCount(CB_EV_FOLLOWUP_RECEIVED);
-
- mWifiAwareStateManager.onMessageReceivedNotification(event.discoverySessionId, event.peerId,
- event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo));
+ mWifiAwareStateManager.onMessageReceivedNotification(discoverySessionId, peerId,
+ addr, serviceSpecificInfo);
}
@Override
- public void eventTransmitFollowup(short id, WifiNanStatus status) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventTransmitFollowup: id=" + id + ", status=" + statusString(status));
- }
+ public void eventTransmitFollowup(short id, int status) {
incrementCbCount(CB_EV_TRANSMIT_FOLLOWUP);
-
- if (status.status == NanStatusType.SUCCESS) {
+ if (status == NanStatusCode.SUCCESS) {
mWifiAwareStateManager.onMessageSendSuccessNotification(id);
} else {
- mWifiAwareStateManager.onMessageSendFailNotification(id, status.status);
+ mWifiAwareStateManager.onMessageSendFailNotification(id, status);
}
}
@Override
- public void eventDataPathRequest(NanDataPathRequestInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId
- + ", peerDiscMacAddr=" + String.valueOf(
- HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId="
- + event.ndpInstanceId + ", appInfo.size()=" + event.appInfo.size());
- }
+ public void eventDataPathRequest(byte discoverySessionId, byte[] peerDiscMacAddr,
+ int ndpInstanceId, byte[] appInfo) {
incrementCbCount(CB_EV_DATA_PATH_REQUEST);
-
- mWifiAwareStateManager.onDataPathRequestNotification(event.discoverySessionId,
- event.peerDiscMacAddr, event.ndpInstanceId,
- convertArrayListToNativeByteArray(event.appInfo));
+ mWifiAwareStateManager.onDataPathRequestNotification(discoverySessionId,
+ peerDiscMacAddr, ndpInstanceId, appInfo);
}
@Override
- public void eventDataPathConfirm(NanDataPathConfirmInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "onDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId
- + ", peerNdiMacAddr=" + String.valueOf(HexEncoding.encode(event.peerNdiMacAddr))
- + ", dataPathSetupSuccess=" + event.dataPathSetupSuccess + ", reason="
- + event.status.status + ", appInfo.size()=" + event.appInfo.size());
- }
- if (mIsHal12OrLater) {
- Log.wtf(TAG, "eventDataPathConfirm should not be called by a >=1.2 HAL!");
- }
+ public void eventDataPathConfirm(int status, int ndpInstanceId, boolean dataPathSetupSuccess,
+ byte[] peerNdiMacAddr, byte[] appInfo,
+ List<WifiAwareChannelInfo> channelInfos) {
incrementCbCount(CB_EV_DATA_PATH_CONFIRM);
-
- mWifiAwareStateManager.onDataPathConfirmNotification(event.ndpInstanceId,
- event.peerNdiMacAddr, event.dataPathSetupSuccess, event.status.status,
- convertArrayListToNativeByteArray(event.appInfo), null);
- }
-
- @Override
- public void eventDataPathConfirm_1_2(android.hardware.wifi.V1_2.NanDataPathConfirmInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventDataPathConfirm_1_2: ndpInstanceId=" + event.V1_0.ndpInstanceId
- + ", peerNdiMacAddr=" + String.valueOf(
- HexEncoding.encode(event.V1_0.peerNdiMacAddr)) + ", dataPathSetupSuccess="
- + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status
- + ", appInfo.size()=" + event.V1_0.appInfo.size()
- + ", channelInfo" + event.channelInfo);
- }
- if (!mIsHal12OrLater) {
- Log.wtf(TAG, "eventDataPathConfirm_1_2 should not be called by a <1.2 HAL!");
- return;
- }
-
- List<WifiAwareChannelInfo> wifiAwareChannelInfos =
- convertHalChannelInfo_1_2(event.channelInfo);
- incrementCbCount(CB_EV_DATA_PATH_CONFIRM);
- mChannelInfoPerNdp.put(event.V1_0.ndpInstanceId, wifiAwareChannelInfos);
-
- mWifiAwareStateManager.onDataPathConfirmNotification(event.V1_0.ndpInstanceId,
- event.V1_0.peerNdiMacAddr, event.V1_0.dataPathSetupSuccess,
- event.V1_0.status.status, convertArrayListToNativeByteArray(event.V1_0.appInfo),
- wifiAwareChannelInfos);
- }
-
- @Override
- public void eventDataPathConfirm_1_6(android.hardware.wifi.V1_6.NanDataPathConfirmInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventDataPathConfirm_1_6: ndpInstanceId=" + event.V1_0.ndpInstanceId
- + ", peerNdiMacAddr=" + String.valueOf(
- HexEncoding.encode(event.V1_0.peerNdiMacAddr)) + ", dataPathSetupSuccess="
- + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status
- + ", appInfo.size()=" + event.V1_0.appInfo.size()
- + ", channelInfo" + event.channelInfo);
- }
- if (!mIsHal16OrLater) {
- Log.wtf(TAG, "eventDataPathConfirm_1_6 should not be called by a <1.6 HAL!");
- return;
- }
-
- List<WifiAwareChannelInfo> wifiAwareChannelInfos =
- convertHalChannelInfo_1_6(event.channelInfo);
- incrementCbCount(CB_EV_DATA_PATH_CONFIRM);
- mChannelInfoPerNdp.put(event.V1_0.ndpInstanceId, wifiAwareChannelInfos);
-
- mWifiAwareStateManager.onDataPathConfirmNotification(event.V1_0.ndpInstanceId,
- event.V1_0.peerNdiMacAddr, event.V1_0.dataPathSetupSuccess,
- event.V1_0.status.status, convertArrayListToNativeByteArray(event.V1_0.appInfo),
- wifiAwareChannelInfos);
- }
-
- @Override
- public void eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventDataPathScheduleUpdate: peerMac="
- + MacAddress.fromBytes(event.peerDiscoveryAddress).toString()
- + ", ndpIds=" + event.ndpInstanceIds + ", channelInfo=" + event.channelInfo);
+ if (channelInfos != null) {
+ mChannelInfoPerNdp.put(ndpInstanceId, channelInfos);
}
- if (!mIsHal12OrLater) {
- Log.wtf(TAG, "eventDataPathScheduleUpdate should not be called by a <1.2 HAL!");
- return;
- }
-
- List<WifiAwareChannelInfo> wifiAwareChannelInfos =
- convertHalChannelInfo_1_2(event.channelInfo);
- incrementCbCount(CB_EV_DATA_PATH_SCHED_UPDATE);
- for (int ndpInstanceId : event.ndpInstanceIds) {
- mChannelInfoPerNdp.put(ndpInstanceId, wifiAwareChannelInfos);
- }
-
- mWifiAwareStateManager.onDataPathScheduleUpdateNotification(event.peerDiscoveryAddress,
- event.ndpInstanceIds, wifiAwareChannelInfos);
+ mWifiAwareStateManager.onDataPathConfirmNotification(ndpInstanceId,
+ peerNdiMacAddr, dataPathSetupSuccess, status, appInfo, channelInfos);
}
@Override
- public void eventDataPathScheduleUpdate_1_6(
- android.hardware.wifi.V1_6.NanDataPathScheduleUpdateInd event) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG, "eventDataPathScheduleUpdate_1_6: peerMac="
- + MacAddress.fromBytes(event.peerDiscoveryAddress).toString()
- + ", ndpIds=" + event.ndpInstanceIds + ", channelInfo=" + event.channelInfo);
- }
- if (!mIsHal16OrLater) {
- Log.wtf(TAG, "eventDataPathScheduleUpdate_1_6 should not be called by a <1.6 HAL!");
- return;
- }
-
- List<WifiAwareChannelInfo> wifiAwareChannelInfos =
- convertHalChannelInfo_1_6(event.channelInfo);
+ public void eventDataPathScheduleUpdate(byte[] peerDiscoveryAddress,
+ ArrayList<Integer> ndpInstanceIds, List<WifiAwareChannelInfo> channelInfo) {
incrementCbCount(CB_EV_DATA_PATH_SCHED_UPDATE);
- for (int ndpInstanceId : event.ndpInstanceIds) {
- mChannelInfoPerNdp.put(ndpInstanceId, wifiAwareChannelInfos);
+ for (int ndpInstanceId : ndpInstanceIds) {
+ mChannelInfoPerNdp.put(ndpInstanceId, channelInfo);
}
-
- mWifiAwareStateManager.onDataPathScheduleUpdateNotification(event.peerDiscoveryAddress,
- event.ndpInstanceIds, wifiAwareChannelInfos);
+ mWifiAwareStateManager.onDataPathScheduleUpdateNotification(peerDiscoveryAddress,
+ ndpInstanceIds, channelInfo);
}
@Override
public void eventDataPathTerminated(int ndpInstanceId) {
- if (mVerboseHalLoggingEnabled) {
- Log.v(TAG,
- "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId);
- }
incrementCbCount(CB_EV_DATA_PATH_TERMINATED);
mChannelInfoPerNdp.remove(ndpInstanceId);
-
mWifiAwareStateManager.onDataPathEndNotification(ndpInstanceId);
}
@@ -791,34 +367,6 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
// utilities
/**
- * Converts an ArrayList<Byte> to a byte[].
- *
- * @param from The input ArrayList<Byte></Byte> to convert from.
- *
- * @return A newly allocated byte[].
- */
- private byte[] convertArrayListToNativeByteArray(ArrayList<Byte> from) {
- if (from == null) {
- return null;
- }
-
- byte[] to = new byte[from.size()];
- for (int i = 0; i < from.size(); ++i) {
- to[i] = from.get(i);
- }
- return to;
- }
-
- private static String statusString(WifiNanStatus status) {
- if (status == null) {
- return "status=null";
- }
- StringBuilder sb = new StringBuilder();
- sb.append(status.status).append(" (").append(status.description).append(")");
- return sb.toString();
- }
-
- /**
* Transfer the channel Info dict into a Json String which can be decoded by Json reader.
* The Format is: "{ndpInstanceId: [{"channelFreq": channelFreq,
* "channelBandwidth": channelBandwidth, "numSpatialStreams": numSpatialStreams}]}"
@@ -843,56 +391,4 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
}
return channelInfoJson.toString();
}
-
- /**
- * Convert HAL channelBandwidth to framework enum
- */
- private @WifiAnnotations.ChannelWidth 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 V1_2 NanDataPathChannelInfo to WifiAwareChannelInfo
- */
- private List<WifiAwareChannelInfo> convertHalChannelInfo_1_2(
- List<android.hardware.wifi.V1_2.NanDataPathChannelInfo> channelInfos) {
- List<WifiAwareChannelInfo> wifiAwareChannelInfos = new ArrayList<>();
- if (channelInfos == null) {
- return null;
- }
- for (android.hardware.wifi.V1_2.NanDataPathChannelInfo channelInfo : channelInfos) {
- wifiAwareChannelInfos.add(new WifiAwareChannelInfo(channelInfo.channelFreq,
- getChannelBandwidthFromHal(channelInfo.channelBandwidth),
- channelInfo.numSpatialStreams));
- }
- return wifiAwareChannelInfos;
- }
- /**
- * Convert HAL V1_6 NanDataPathChannelInfo to WifiAwareChannelInfo
- */
- private List<WifiAwareChannelInfo> convertHalChannelInfo_1_6(
- List<android.hardware.wifi.V1_6.NanDataPathChannelInfo> channelInfos) {
- List<WifiAwareChannelInfo> wifiAwareChannelInfos = new ArrayList<>();
- if (channelInfos == null) {
- return null;
- }
- for (android.hardware.wifi.V1_6.NanDataPathChannelInfo channelInfo : channelInfos) {
- wifiAwareChannelInfos.add(new WifiAwareChannelInfo(channelInfo.channelFreq,
- getChannelBandwidthFromHal(channelInfo.channelBandwidth),
- channelInfo.numSpatialStreams));
- }
- return wifiAwareChannelInfos;
- }
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
index 682c2f8668..5d9b3feb61 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
@@ -17,22 +17,19 @@
package com.android.server.wifi.aware;
import android.annotation.NonNull;
-import android.hardware.wifi.V1_0.IWifiNanIface;
-import android.hardware.wifi.V1_0.WifiStatus;
-import android.hardware.wifi.V1_0.WifiStatusCode;
import android.os.Handler;
-import android.os.RemoteException;
import android.os.WorkSource;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.HalDeviceManager;
+import com.android.server.wifi.hal.WifiNanIface;
import java.io.FileDescriptor;
import java.io.PrintWriter;
/**
- * Manages the interface to Wi-Fi Aware HIDL (HAL).
+ * Manages the interface to the Wi-Fi Aware HAL.
*/
public class WifiAwareNativeManager {
private static final String TAG = "WifiAwareNativeManager";
@@ -45,7 +42,7 @@ public class WifiAwareNativeManager {
private HalDeviceManager mHalDeviceManager;
private Handler mHandler;
private WifiAwareNativeCallback mWifiAwareNativeCallback;
- private IWifiNanIface mWifiNanIface = null;
+ private WifiNanIface mWifiNanIface = null;
private InterfaceDestroyedListener mInterfaceDestroyedListener;
private int mReferenceCount = 0;
@@ -62,33 +59,9 @@ public class WifiAwareNativeManager {
*/
public void enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled) {
mVerboseHalLoggingEnabled = halVerboseEnabled;
- }
-
- /**
- * (HIDL) Cast the input to a 1.2 NAN interface (possibly resulting in a null).
- *
- * Separate function so can be mocked in unit tests.
- */
- public android.hardware.wifi.V1_2.IWifiNanIface mockableCastTo_1_2(IWifiNanIface iface) {
- return android.hardware.wifi.V1_2.IWifiNanIface.castFrom(iface);
- }
-
- /**
- * (HIDL) Cast the input to a 1.5 NAN interface (possibly resulting in a null).
- *
- * Separate function so can be mocked in unit tests.
- */
- public android.hardware.wifi.V1_5.IWifiNanIface mockableCastTo_1_5(IWifiNanIface iface) {
- return android.hardware.wifi.V1_5.IWifiNanIface.castFrom(iface);
- }
-
- /**
- * (HIDL) Cast the input to a 1.6 NAN interface (possibly resulting in a null).
- *
- * Separate function so can be mocked in unit tests.
- */
- public android.hardware.wifi.V1_6.IWifiNanIface mockableCastTo_1_6(IWifiNanIface iface) {
- return android.hardware.wifi.V1_6.IWifiNanIface.castFrom(iface);
+ if (mWifiNanIface != null) {
+ mWifiNanIface.enableVerboseLogging(mVerboseHalLoggingEnabled);
+ }
}
/**
@@ -119,11 +92,11 @@ public class WifiAwareNativeManager {
}
/**
- * Returns the native HAL WifiNanIface through which commands to the NAN HAL are dispatched.
+ * Returns the WifiNanIface through which commands to the NAN HAL are dispatched.
* Return may be null if not initialized/available.
*/
@VisibleForTesting
- public IWifiNanIface getWifiNanIface() {
+ public WifiNanIface getWifiNanIface() {
synchronized (mLock) {
return mWifiNanIface;
}
@@ -135,8 +108,8 @@ public class WifiAwareNativeManager {
public void tryToGetAware(@NonNull WorkSource requestorWs) {
synchronized (mLock) {
if (mVerboseHalLoggingEnabled) {
- Log.d(TAG, "tryToGetAware: mWifiNanIface=" + mWifiNanIface + ", mReferenceCount="
- + mReferenceCount + ", requestorWs=" + requestorWs);
+ Log.d(TAG, "tryToGetAware: mWifiNanIface=" + mWifiNanIface
+ + ", mReferenceCount=" + mReferenceCount + ", requestorWs=" + requestorWs);
}
if (mWifiNanIface != null) {
@@ -150,48 +123,22 @@ public class WifiAwareNativeManager {
}
mInterfaceDestroyedListener = new InterfaceDestroyedListener();
- IWifiNanIface iface = mHalDeviceManager.createNanIface(mInterfaceDestroyedListener,
+ WifiNanIface iface = mHalDeviceManager.createNanIface(mInterfaceDestroyedListener,
mHandler, requestorWs);
if (iface == null) {
- Log.e(TAG, "Was not able to obtain an IWifiNanIface (even though enabled!?)");
+ Log.e(TAG, "Was not able to obtain a WifiNanIface (even though enabled!?)");
awareIsDown(true);
} else {
- if (mVerboseHalLoggingEnabled) Log.v(TAG, "Obtained an IWifiNanIface");
-
- try {
- android.hardware.wifi.V1_2.IWifiNanIface iface12 = mockableCastTo_1_2(iface);
- android.hardware.wifi.V1_5.IWifiNanIface iface15 = mockableCastTo_1_5(iface);
- android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6(iface);
- WifiStatus status;
- if (iface16 != null) {
- mWifiAwareNativeCallback.mIsHal12OrLater = true;
- mWifiAwareNativeCallback.mIsHal15OrLater = true;
- mWifiAwareNativeCallback.mIsHal16OrLater = true;
- status = iface16.registerEventCallback_1_6(mWifiAwareNativeCallback);
- } else if (iface15 != null) {
- mWifiAwareNativeCallback.mIsHal12OrLater = true;
- mWifiAwareNativeCallback.mIsHal15OrLater = true;
- status = iface15.registerEventCallback_1_5(mWifiAwareNativeCallback);
- } else if (iface12 != null) {
- mWifiAwareNativeCallback.mIsHal12OrLater = true;
- status = iface12.registerEventCallback_1_2(mWifiAwareNativeCallback);
- } else {
- status = iface.registerEventCallback(mWifiAwareNativeCallback);
- }
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "IWifiNanIface.registerEventCallback error: " + statusString(
- status));
- mHalDeviceManager.removeIface(iface);
- awareIsDown(false);
- return;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "IWifiNanIface.registerEventCallback exception: " + e);
+ if (mVerboseHalLoggingEnabled) Log.v(TAG, "Obtained a WifiNanIface");
+ if (!iface.registerFrameworkCallback(mWifiAwareNativeCallback)) {
+ Log.e(TAG, "Unable to register callback with WifiNanIface");
+ mHalDeviceManager.removeIface(iface);
awareIsDown(false);
return;
}
mWifiNanIface = iface;
mReferenceCount = 1;
+ mWifiNanIface.enableVerboseLogging(mVerboseHalLoggingEnabled);
}
}
}
@@ -245,15 +192,15 @@ public class WifiAwareNativeManager {
return false;
}
- return mHalDeviceManager.replaceRequestorWs(mWifiNanIface, requestorWs);
+ return mHalDeviceManager.replaceRequestorWsForNanIface(mWifiNanIface, requestorWs);
}
}
private void awareIsDown(boolean markAsAvailable) {
synchronized (mLock) {
if (mVerboseHalLoggingEnabled) {
- Log.d(TAG, "awareIsDown: mWifiNanIface=" + mWifiNanIface + ", mReferenceCount ="
- + mReferenceCount);
+ Log.d(TAG, "awareIsDown: mWifiNanIface=" + mWifiNanIface
+ + ", mReferenceCount =" + mReferenceCount);
}
mWifiNanIface = null;
mReferenceCount = 0;
@@ -268,8 +215,8 @@ public class WifiAwareNativeManager {
@Override
public void onDestroyed(@NonNull String ifaceName) {
if (mVerboseHalLoggingEnabled) {
- Log.d(TAG, "Interface was destroyed: mWifiNanIface=" + mWifiNanIface + ", active="
- + active);
+ Log.d(TAG, "Interface was destroyed: mWifiNanIface=" + mWifiNanIface
+ + ", active=" + active);
}
if (active && mWifiNanIface != null) {
awareIsDown(true);
@@ -277,15 +224,6 @@ public class WifiAwareNativeManager {
}
}
- private static String statusString(WifiStatus status) {
- if (status == null) {
- return "status=null";
- }
- StringBuilder sb = new StringBuilder();
- sb.append(status.code).append(" (").append(status.description).append(")");
- return sb.toString();
- }
-
/**
* Dump the internal state of the class.
*/
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
index 3555da355f..293bde69ca 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
@@ -23,7 +23,6 @@ import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.hardware.wifi.V1_0.NanStatusType;
import android.net.wifi.WifiManager;
import android.net.wifi.aware.AwareParams;
import android.net.wifi.aware.AwareResources;
@@ -56,6 +55,7 @@ import com.android.server.wifi.FrameworkFacade;
import com.android.server.wifi.InterfaceConflictManager;
import com.android.server.wifi.SystemBuildProperties;
import com.android.server.wifi.WifiSettingsConfigStore;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
import com.android.server.wifi.WifiThreadRunner;
import com.android.server.wifi.util.NetdWrapper;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -302,7 +302,7 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub {
} catch (RemoteException e) {
Log.e(TAG, "Error on linkToDeath - " + e);
try {
- callback.onConnectFail(NanStatusType.INTERNAL_FAILURE);
+ callback.onConnectFail(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e1) {
Log.e(TAG, "Error on onConnectFail()");
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index 76aeb89f9a..89d6a6eef7 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -25,7 +25,6 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.hardware.wifi.V1_0.NanStatusType;
import android.hardware.wifi.V1_0.WifiStatusCode;
import android.location.LocationManager;
import android.net.MacAddress;
@@ -75,6 +74,7 @@ import com.android.server.wifi.Clock;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.InterfaceConflictManager;
import com.android.server.wifi.WifiInjector;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
import com.android.server.wifi.util.NetdWrapper;
import com.android.server.wifi.util.WaitingState;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -261,6 +261,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
private boolean mCurrentIdentityNotification = false;
private boolean mCurrentRangingEnabled = false;
private boolean mInstantCommModeGlobalEnable = false;
+ private int mOverrideInstantMode = INSTANT_MODE_DISABLED;
private int mInstantCommModeClientRequest = INSTANT_MODE_DISABLED;
private static final int AWARE_BAND_2_INSTANT_COMMUNICATION_CHANNEL_FREQ = 2437; // Channel 6
private int mAwareBand5InstantCommunicationChannelFreq = -1; // -1 is not set, 0 is unsupported.
@@ -439,6 +440,22 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
pw_out.println(out.toString());
return 0;
}
+ case "set_override_instant_communication_mode": {
+ String arg = parentShell.getNextArgRequired();
+ if (TextUtils.equals(arg, "2G")) {
+ mOverrideInstantMode = INSTANT_MODE_24GHZ;
+ } else if (TextUtils.equals(arg, "5G")) {
+ mOverrideInstantMode = INSTANT_MODE_5GHZ;
+ } else {
+ pw_err.println("Unknown band -- " + arg);
+ return -1;
+ }
+ return 0;
+ }
+ case "clear_override_instant_communication_mode": {
+ mOverrideInstantMode = INSTANT_MODE_DISABLED;
+ return 0;
+ }
default:
pw_err.println("Unknown 'wifiaware state_mgr <cmd>'");
}
@@ -469,6 +486,10 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
+ "accept requests from ANY requestor (null peer spec)");
pw.println(" get_instant_communication_channel 2G|5G: get instant communication mode "
+ "channel available for the target band");
+ pw.println(" set_override_instant_communication_mode 2G|5G: override the instant "
+ + "communication mode to 'enabled' with the specified band");
+ pw.println(" clear_override_instant_communication_mode: clear the override of the instant "
+ + "communication mode");
}
/**
@@ -687,7 +708,10 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
public void requestMacAddresses(int uid, int[] peerIds,
IWifiAwareMacAddressProvider callback) {
mSm.getHandler().post(() -> {
- if (VDBG) Log.v(TAG, "requestMacAddresses: uid=" + uid + ", peerIds=" + peerIds);
+ if (VDBG) {
+ Log.v(TAG, "requestMacAddresses: uid=" + uid + ", peerIds="
+ + Arrays.toString(peerIds));
+ }
Map<Integer, MacAddrMapping> peerIdToMacMap = new HashMap<>();
for (int i = 0; i < mClients.size(); ++i) {
WifiAwareClientState client = mClients.valueAt(i);
@@ -1706,7 +1730,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
*/
onAwareDownLocal();
- if (reason != NanStatusType.SUCCESS) {
+ if (reason != NanStatusCode.SUCCESS) {
sendAwareStateChangedBroadcast(false);
}
break;
@@ -1752,7 +1776,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
int retryCount = sentMessage.getData()
.getInt(MESSAGE_BUNDLE_KEY_RETRY_COUNT);
- if (retryCount > 0 && reason == NanStatusType.NO_OTA_ACK) {
+ if (retryCount > 0 && reason == NanStatusCode.NO_OTA_ACK) {
if (mVerboseLoggingEnabled) {
Log.v(TAG,
"NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL: transactionId="
@@ -1883,9 +1907,9 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
// handling user rejection or possible conflict (pending command)
try {
callback.onConnectFail(
- NanStatusType.NO_RESOURCES_AVAILABLE);
+ NanStatusCode.NO_RESOURCES_AVAILABLE);
mAwareMetrics.recordAttachStatus(
- NanStatusType.NO_RESOURCES_AVAILABLE);
+ NanStatusCode.NO_RESOURCES_AVAILABLE);
} catch (RemoteException e) {
Log.w(TAG, "displayUserApprovalDialog user refusal: RemoteException "
+ "(FYI): " + e);
@@ -1981,7 +2005,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
+ " at messageId="
+ msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID));
}
- onMessageSendFailLocal(msg, NanStatusType.INTERNAL_FAILURE);
+ onMessageSendFailLocal(msg, NanStatusCode.INTERNAL_FAILURE);
waitForResponse = false;
break;
}
@@ -2190,7 +2214,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
Log.v(TAG, "processResponse: ON_MESSAGE_SEND_QUEUED_FAIL - blocking!");
}
int reason = (Integer) msg.obj;
- if (reason == NanStatusType.FOLLOWUP_TX_QUEUE_FULL) {
+ if (reason == NanStatusCode.FOLLOWUP_TX_QUEUE_FULL) {
Message sentMessage = mCurrentCommand.getData().getParcelable(
MESSAGE_BUNDLE_KEY_SENT_MESSAGE);
int arrivalSeq = sentMessage.getData().getInt(
@@ -2205,7 +2229,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
} else {
Message sentMessage = mCurrentCommand.getData().getParcelable(
MESSAGE_BUNDLE_KEY_SENT_MESSAGE);
- onMessageSendFailLocal(sentMessage, NanStatusType.INTERNAL_FAILURE);
+ onMessageSendFailLocal(sentMessage, NanStatusCode.INTERNAL_FAILURE);
if (!mSendQueueBlocked) {
transmitNextMessage();
}
@@ -2285,7 +2309,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
switch (msg.arg1) {
case COMMAND_TYPE_CONNECT:
case COMMAND_TYPE_DISCONNECT:
- onConfigFailedLocal(mCurrentCommand, NanStatusType.INTERNAL_FAILURE);
+ onConfigFailedLocal(mCurrentCommand, NanStatusCode.INTERNAL_FAILURE);
break;
case COMMAND_TYPE_RECONFIGURE:
@@ -2293,7 +2317,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
* Reconfigure timed-out. There is nothing to do but log the issue - which
* will be done in the callback.
*/
- onConfigFailedLocal(mCurrentCommand, NanStatusType.INTERNAL_FAILURE);
+ onConfigFailedLocal(mCurrentCommand, NanStatusCode.INTERNAL_FAILURE);
break;
case COMMAND_TYPE_TERMINATE_SESSION: {
Log.wtf(TAG, "processTimeout: TERMINATE_SESSION - shouldn't be waiting!");
@@ -2301,13 +2325,13 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
case COMMAND_TYPE_PUBLISH:
case COMMAND_TYPE_UPDATE_PUBLISH: {
- onSessionConfigFailLocal(mCurrentCommand, true, NanStatusType.INTERNAL_FAILURE);
+ onSessionConfigFailLocal(mCurrentCommand, true, NanStatusCode.INTERNAL_FAILURE);
break;
}
case COMMAND_TYPE_SUBSCRIBE:
case COMMAND_TYPE_UPDATE_SUBSCRIBE: {
onSessionConfigFailLocal(mCurrentCommand, false,
- NanStatusType.INTERNAL_FAILURE);
+ NanStatusCode.INTERNAL_FAILURE);
break;
}
case COMMAND_TYPE_ENQUEUE_SEND_MESSAGE: {
@@ -2317,7 +2341,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE: {
Message sentMessage = mCurrentCommand.getData().getParcelable(
MESSAGE_BUNDLE_KEY_SENT_MESSAGE);
- onMessageSendFailLocal(sentMessage, NanStatusType.INTERNAL_FAILURE);
+ onMessageSendFailLocal(sentMessage, NanStatusCode.INTERNAL_FAILURE);
mSendQueueBlocked = false;
transmitNextMessage();
break;
@@ -2372,7 +2396,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
"processTimeout: COMMAND_TYPE_RELEASE_AWARE - shouldn't be waiting!");
break;
case COMMAND_TYPE_DISABLE:
- onDisableResponseLocal(mCurrentCommand, NanStatusType.INTERNAL_FAILURE);
+ onDisableResponseLocal(mCurrentCommand, NanStatusCode.INTERNAL_FAILURE);
break;
default:
Log.wtf(TAG, "processTimeout: this isn't a COMMAND -- msg=" + msg);
@@ -2433,7 +2457,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
+ ", due to messageEnqueueTime=" + messageEnqueueTime
+ ", currentTime=" + currentTime);
}
- onMessageSendFailLocal(message, NanStatusType.INTERNAL_FAILURE);
+ onMessageSendFailLocal(message, NanStatusCode.INTERNAL_FAILURE);
it.remove();
first = false;
} else {
@@ -2528,8 +2552,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
if (!mUsageEnabled) {
Log.w(TAG, "connect(): called with mUsageEnabled=false");
try {
- callback.onConnectFail(NanStatusType.INTERNAL_FAILURE);
- mAwareMetrics.recordAttachStatus(NanStatusType.INTERNAL_FAILURE);
+ callback.onConnectFail(NanStatusCode.INTERNAL_FAILURE);
+ mAwareMetrics.recordAttachStatus(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.w(TAG, "connectLocal onConnectFail(): RemoteException (FYI): " + e);
}
@@ -2550,8 +2574,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
Log.e(TAG, "connectLocal: requested configRequest=" + configRequest
+ ", incompatible with current configurations");
try {
- callback.onConnectFail(NanStatusType.INTERNAL_FAILURE);
- mAwareMetrics.recordAttachStatus(NanStatusType.INTERNAL_FAILURE);
+ callback.onConnectFail(NanStatusCode.INTERNAL_FAILURE);
+ mAwareMetrics.recordAttachStatus(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.w(TAG, "connectLocal onConnectFail(): RemoteException (FYI): " + e);
}
@@ -2604,8 +2628,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
mWifiAwareNativeManager.releaseAware();
}
try {
- callback.onConnectFail(NanStatusType.INTERNAL_FAILURE);
- mAwareMetrics.recordAttachStatus(NanStatusType.INTERNAL_FAILURE);
+ callback.onConnectFail(NanStatusCode.INTERNAL_FAILURE);
+ mAwareMetrics.recordAttachStatus(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.w(TAG, "connectLocal onConnectFail(): RemoteException (FYI): " + e);
}
@@ -2727,7 +2751,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
if (client == null) {
Log.e(TAG, "publishLocal: no client exists for clientId=" + clientId);
try {
- callback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ callback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.w(TAG, "publishLocal onSessionConfigFail(): RemoteException (FYI): " + e);
}
@@ -2737,11 +2761,11 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
boolean success = mWifiAwareNativeApi.publish(transactionId, (byte) 0, publishConfig);
if (!success) {
try {
- callback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ callback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.w(TAG, "publishLocal onSessionConfigFail(): RemoteException (FYI): " + e);
}
- mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusType.INTERNAL_FAILURE,
+ mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.INTERNAL_FAILURE,
true);
}
@@ -2770,7 +2794,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
boolean status = session.updatePublish(transactionId, publishConfig);
if (!status) {
- mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusType.INTERNAL_FAILURE,
+ mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.INTERNAL_FAILURE,
true);
}
return status;
@@ -2784,7 +2808,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
WifiAwareClientState client = mClients.get(clientId);
if (client == null) {
try {
- callback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ callback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.w(TAG, "subscribeLocal onSessionConfigFail(): RemoteException (FYI): " + e);
}
@@ -2795,11 +2819,11 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
boolean success = mWifiAwareNativeApi.subscribe(transactionId, (byte) 0, subscribeConfig);
if (!success) {
try {
- callback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ callback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
} catch (RemoteException e) {
Log.w(TAG, "subscribeLocal onSessionConfigFail(): RemoteException (FYI): " + e);
}
- mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusType.INTERNAL_FAILURE,
+ mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.INTERNAL_FAILURE,
false);
}
@@ -2830,7 +2854,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
boolean status = session.updateSubscribe(transactionId, subscribeConfig);
if (!status) {
- mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusType.INTERNAL_FAILURE,
+ mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.INTERNAL_FAILURE,
false);
}
return status;
@@ -2910,7 +2934,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
channelRequestType, channel, peer, interfaceName, isOutOfBand,
appInfo, mCapabilities, networkSpecifier.getWifiAwareDataPathSecurityConfig());
if (!success) {
- mDataPathMgr.onDataPathInitiateFail(networkSpecifier, NanStatusType.INTERNAL_FAILURE);
+ mDataPathMgr.onDataPathInitiateFail(networkSpecifier, NanStatusCode.INTERNAL_FAILURE);
}
return success;
@@ -2927,7 +2951,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
boolean success = mWifiAwareNativeApi.respondToDataPathRequest(transactionId, accept, ndpId,
interfaceName, appInfo, isOutOfBand, mCapabilities, securityConfig);
if (!success) {
- mDataPathMgr.onRespondToDataPathRequest(ndpId, false, NanStatusType.INTERNAL_FAILURE);
+ mDataPathMgr.onRespondToDataPathRequest(ndpId, false, NanStatusCode.INTERNAL_FAILURE);
} else {
sendAwareResourcesChangedBroadcast();
}
@@ -3051,7 +3075,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
* - success: was waiting so that don't enable while disabling
* - fail: shouldn't happen (though can if already disabled for instance)
*/
- if (reason != NanStatusType.SUCCESS) {
+ if (reason != NanStatusCode.SUCCESS) {
Log.e(TAG, "onDisableResponseLocal: FAILED!? command=" + command + ", reason="
+ reason);
}
@@ -3128,7 +3152,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
} else {
mAwareMetrics.recordDiscoverySession(client.getUid(), mClients);
}
- mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusType.SUCCESS,
+ mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.SUCCESS,
completedCommand.arg1 == COMMAND_TYPE_PUBLISH);
sendAwareResourcesChangedBroadcast();
} else if (completedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH
@@ -3159,7 +3183,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
session.setRangingEnabled(isRangingEnabled);
session.setInstantModeEnabled(enableInstantMode);
session.setInstantModeBand(instantModeBand);
- mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusType.SUCCESS,
+ mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.SUCCESS,
completedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH);
} else {
Log.wtf(TAG,
@@ -3225,7 +3249,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
mAwareMetrics.recordDiscoveryStatus(client.getUid(), reason,
failedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH);
- if (reason == NanStatusType.INVALID_SESSION_ID) {
+ if (reason == NanStatusCode.INVALID_SESSION_ID) {
client.removeSession(sessionId);
// If Ranging enabled or instant mode require changes, reconfigure.
if (mCurrentRangingEnabled != doesAnyClientNeedRanging()
@@ -3666,6 +3690,9 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
private int getInstantModeFromAllClients() {
+ if (mOverrideInstantMode != INSTANT_MODE_DISABLED) {
+ return mOverrideInstantMode;
+ }
int instantMode = INSTANT_MODE_DISABLED;
for (int i = 0; i < mClients.size(); ++i) {
int currentClient = mClients.valueAt(i).getInstantMode((long) mContext.getResources()
diff --git a/service/java/com/android/server/wifi/hal/IWifiApIface.java b/service/java/com/android/server/wifi/hal/IWifiApIface.java
new file mode 100644
index 0000000000..0c8b019afd
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/IWifiApIface.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.net.MacAddress;
+
+import java.util.List;
+
+/** Abstraction of WifiApIface */
+public interface IWifiApIface {
+ /**
+ * Get the name of this interface.
+ *
+ * @return Name of this interface, or null on error.
+ */
+ String getName();
+
+ /**
+ * Get the names of the bridged AP instances.
+ *
+ * @return List containing the names of the bridged AP instances,
+ * or an empty vector for a non-bridged AP. Returns null
+ * if an error occurred.
+ */
+ List<String> getBridgedInstances();
+
+ /**
+ * Gets the factory MAC address of the interface.
+ *
+ * @return Factory MAC address of the interface, or null on error.
+ */
+ MacAddress getFactoryMacAddress();
+
+ /**
+ * Set the country code for this interface.
+ *
+ * @param countryCode two-letter country code (as ISO 3166).
+ * @return true if successful, false otherwise.
+ */
+ boolean setCountryCode(byte[] countryCode);
+
+ /**
+ * Reset all the AP interfaces' MAC address to the factory MAC address.
+ *
+ * @return true if successful, false otherwise.
+ */
+ boolean resetToFactoryMacAddress();
+
+ /**
+ * Check whether {@link #setMacAddress(MacAddress)} is supported by this HAL.
+ *
+ * @return true if supported, false otherwise.
+ */
+ boolean isSetMacAddressSupported();
+
+ /**
+ * Changes the MAC address of the interface to the given MAC address.
+ *
+ * @param mac MAC address to change to.
+ * @return true if successful, false otherwise.
+ */
+ boolean setMacAddress(MacAddress mac);
+}
diff --git a/service/java/com/android/server/wifi/hal/IWifiChip.java b/service/java/com/android/server/wifi/hal/IWifiChip.java
new file mode 100644
index 0000000000..3a2caf30b8
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/IWifiChip.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.Nullable;
+import android.net.wifi.CoexUnsafeChannel;
+import android.net.wifi.WifiAvailableChannel;
+import android.net.wifi.WifiScanner;
+
+import com.android.server.wifi.SarInfo;
+import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.WlanWakeReasonAndCounts;
+
+import java.util.List;
+
+/** Abstraction of WifiChip */
+public interface IWifiChip {
+ /**
+ * Configure the chip.
+ *
+ * @param modeId Mode that the chip must switch to, corresponding to the
+ * id property of the target ChipMode.
+ * @return true if successful, false otherwise.
+ */
+ boolean configureChip(int modeId);
+
+ /**
+ * Create an AP interface on the chip.
+ *
+ * @return {@link WifiApIface} object, or null if a failure occurred.
+ */
+ @Nullable
+ WifiApIface createApIface();
+
+ /**
+ * Create a bridged AP interface on the chip.
+ *
+ * @return {@link WifiApIface} object, or null if a failure occurred.
+ */
+ @Nullable
+ WifiApIface createBridgedApIface();
+
+ /**
+ * Create a NAN interface on the chip.
+ *
+ * @return {@link WifiNanIface} object, or null if a failure occurred.
+ */
+ @Nullable
+ WifiNanIface createNanIface();
+
+ /**
+ * Create a P2P interface on the chip.
+ *
+ * @return {@link WifiP2pIface} object, or null if a failure occurred.
+ */
+ @Nullable
+ WifiP2pIface createP2pIface();
+
+ /**
+ * Create an RTTController instance. Implementation will decide the iface to use for
+ * RTT operations.
+ *
+ * @return {@link WifiRttController} object, or null if a failure occurred.
+ */
+ @Nullable
+ WifiRttController createRttController();
+
+ /**
+ * Create a STA iface on the chip.
+ *
+ * @return {@link WifiStaIface} object, or null if a failure occurred.
+ */
+ @Nullable
+ WifiStaIface createStaIface();
+
+ /**
+ * Enable/disable alert notifications from the chip.
+ *
+ * @param enable true to enable, false to disable.
+ * @return true if successful, false otherwise.
+ */
+ boolean enableDebugErrorAlerts(boolean enable);
+
+ /**
+ * Flush debug ring buffer data to files.
+ *
+ * @return true if successful, false otherwise.
+ */
+ boolean flushRingBufferToFile();
+
+ /**
+ * Force dump data into the corresponding ring buffer.
+ *
+ * @param ringName Name of the ring for which data collection should be forced.
+ * @return true if successful, false otherwise.
+ */
+ boolean forceDumpToDebugRingBuffer(String ringName);
+
+ /**
+ * Get the AP interface corresponding to the provided ifaceName.
+ *
+ * @param ifaceName Name of the interface.
+ * @return {@link WifiApIface} if the interface exists, null otherwise.
+ */
+ @Nullable
+ WifiApIface getApIface(String ifaceName);
+
+ /**
+ * List all the AP iface names configured on the chip.
+ * The corresponding |WifiApIface| object for any iface
+ * can be retrieved using the |getApIface| method.
+ *
+ * @return List of all AP interface names on the chip, or null if an error occurred.
+ */
+ @Nullable
+ List<String> getApIfaceNames();
+
+ /**
+ * Get the set of operation modes that the chip supports.
+ *
+ * @return List of modes supported by the device, or null if an error occurred.
+ */
+ @Nullable
+ List<WifiChip.ChipMode> getAvailableModes();
+
+ /**
+ * Get the capabilities supported by this chip.
+ * Call if no interfaces have been created on this chip.
+ *
+ * Note: This method can still be called safely after ifaces have been created,
+ * but it is recommended to use {@link #getCapabilitiesAfterIfacesExist()} once
+ * any ifaces are up.
+ *
+ * @return {@link WifiChip.Response} where the value is a bitset of
+ * WifiManager.WIFI_FEATURE_* values.
+ */
+ WifiChip.Response<Long> getCapabilitiesBeforeIfacesExist();
+
+ /**
+ * Get the capabilities supported by this chip.
+ * Call if interfaces have been created on this chip.
+ *
+ * @return {@link WifiChip.Response} where the value is a bitset of
+ * WifiManager.WIFI_FEATURE_* values.
+ */
+ WifiChip.Response<Long> getCapabilitiesAfterIfacesExist();
+
+ /**
+ * Retrieve the Wi-Fi wakeup reason stats for debugging.
+ *
+ * @return {@link WlanWakeReasonAndCounts} object, or null if an error occurred.
+ */
+ @Nullable
+ WlanWakeReasonAndCounts getDebugHostWakeReasonStats();
+
+ /**
+ * Get the status of all ring buffers supported by driver.
+ *
+ * @return List of {@link WifiNative.RingBufferStatus} corresponding to the
+ * status of each ring buffer on the device, or null if an error occurred.
+ */
+ @Nullable
+ List<WifiNative.RingBufferStatus> getDebugRingBuffersStatus();
+
+ /**
+ * Get the ID assigned to this chip.
+ *
+ * @return Chip ID, or -1 if an error occurred.
+ */
+ int getId();
+
+ /**
+ * Get the current mode that the chip is in.
+ *
+ * @return {@link WifiChip.Response} where the value is the mode that the chip
+ * is currently configured to.
+ */
+ WifiChip.Response<Integer> getMode();
+
+ /**
+ * Get the NAN interface corresponding to the provided ifaceName.
+ *
+ * @param ifaceName Name of the interface.
+ * @return {@link WifiNanIface} if the interface exists, null otherwise.
+ */
+ @Nullable
+ WifiNanIface getNanIface(String ifaceName);
+
+ /**
+ * List all the NAN iface names configured on the chip.
+ * The corresponding |WifiNanIface| object for any iface
+ * can be retrieved using the |getNanIface| method.
+ *
+ * @return List of all NAN interface names on the chip, or null if an error occurred.
+ */
+ @Nullable
+ List<String> getNanIfaceNames();
+
+ /**
+ * Get the P2P interface corresponding to the provided ifaceName.
+ *
+ * @param ifaceName Name of the interface.
+ * @return {@link WifiP2pIface} if the interface exists, null otherwise.
+ */
+ @Nullable
+ WifiP2pIface getP2pIface(String ifaceName);
+
+ /**
+ * List all the P2P iface names configured on the chip.
+ * The corresponding |WifiP2pIface| object for any iface
+ * can be retrieved using the |getP2pIface| method.
+ *
+ * @return List of all P2P interface names on the chip, or null if an error occurred.
+ */
+ @Nullable
+ List<String> getP2pIfaceNames();
+
+ /**
+ * Get the STA interface corresponding to the provided ifaceName.
+ *
+ * @param ifaceName Name of the interface.
+ * @return {@link WifiStaIface} if the interface exists, null otherwise.
+ */
+ @Nullable
+ WifiStaIface getStaIface(String ifaceName);
+
+ /**
+ * List all the STA iface names configured on the chip.
+ * The corresponding |WifiStaIface| object for any iface
+ * can be retrieved using the |getStaIface| method.
+ *
+ * @return List of all P2P interface names on the chip, or null if an error occurred.
+ */
+ @Nullable
+ List<String> getStaIfaceNames();
+
+ /**
+ * Retrieve the list of all the possible radio combinations supported by this chip.
+ *
+ * @return |WifiRadioCombinationMatrix| representation of all the possible radio combinations,
+ * or null if an error occurred.
+ *
+ */
+ @Nullable
+ WifiChip.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
+
+ /**
+ * Retrieve a list of usable Wifi channels for the specified band and operational modes.
+ *
+ * @param band Band for which the list of usable channels is requested.
+ * @param mode Bitmask of modes that the caller is interested in.
+ * @param filter Bitmask of filters. Specifies whether driver should filter
+ * channels based on additional criteria. If no filter is specified,
+ * then the driver should return usable channels purely based on
+ * regulatory constraints.
+ * @return List of channels represented by {@link WifiAvailableChannel},
+ * or null if an error occurred.
+ */
+ @Nullable
+ List<WifiAvailableChannel> getUsableChannels(@WifiScanner.WifiBand int band,
+ @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter);
+
+ /**
+ * Register for chip event callbacks.
+ *
+ * @param callback Instance of {@link WifiChip.Callback}
+ * @return true if successful, false otherwise.
+ */
+ boolean registerCallback(WifiChip.Callback callback);
+
+ /**
+ * Removes the AP interface with the provided ifaceName.
+ *
+ * @param ifaceName Name of the iface.
+ * @return true if successful, false otherwise.
+ */
+ boolean removeApIface(String ifaceName);
+
+ /**
+ * Removes an instance of AP iface with name |ifaceName| from the
+ * bridged AP with name |brIfaceName|.
+ *
+ * Note: Use {@link #removeApIface(String)} with the |brIfaceName| to remove the bridged iface.
+ *
+ * @param brIfaceName Name of the bridged AP iface.
+ * @param ifaceName Name of the AP instance.
+ * @return true if successful, false otherwise.
+ */
+ boolean removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName);
+
+ /**
+ * Removes the NAN interface with the provided ifaceName.
+ *
+ * @param ifaceName Name of the iface.
+ * @return true if successful, false otherwise.
+ */
+ boolean removeNanIface(String ifaceName);
+
+ /**
+ * Removes the P2P interface with the provided ifaceName.
+ *
+ * @param ifaceName Name of the iface.
+ * @return true if successful, false otherwise.
+ */
+ boolean removeP2pIface(String ifaceName);
+
+ /**
+ * Removes the STA interface with the provided ifaceName.
+ *
+ * @param ifaceName Name of the iface.
+ * @return true if successful, false otherwise.
+ */
+ boolean removeStaIface(String ifaceName);
+
+ /**
+ * Request information about the chip.
+ *
+ * @return Instance of {@link WifiChip.ChipDebugInfo}, or null if an error occurred.
+ */
+ @Nullable
+ WifiChip.ChipDebugInfo requestChipDebugInfo();
+
+ /**
+ * Request vendor debug info from the driver.
+ *
+ * @return Byte array retrieved from the driver, or null if an error occurred.
+ */
+ @Nullable
+ byte[] requestDriverDebugDump();
+
+ /**
+ * Request vendor debug info from the firmware.
+ *
+ * @return Byte array retrieved from the firmware, or null if an error occurred.
+ */
+ @Nullable
+ byte[] requestFirmwareDebugDump();
+
+ /**
+ * Reset TX power levels.
+ *
+ * @return true if successful, false otherwise.
+ */
+ boolean resetTxPowerScenario();
+
+ /**
+ * Select one of the preset TX power scenarios.
+ *
+ * @param sarInfo SarInfo to select the proper scenario.
+ * @return true if successful, false otherwise.
+ */
+ boolean selectTxPowerScenario(SarInfo sarInfo);
+
+ /**
+ * Set the current coex unsafe channels to avoid and their restrictions.
+ *
+ * @param unsafeChannels List of {@link CoexUnsafeChannel} to avoid.
+ * @param restrictions int containing a bitwise-OR combination of
+ * {@link android.net.wifi.WifiManager.CoexRestriction}.
+ * @return true if successful, false otherwise.
+ */
+ boolean setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions);
+
+ /**
+ * Set the country code for this Wifi chip.
+ *
+ * @param code 2-byte country code to set (as defined in ISO 3166).
+ * @return true if successful, false otherwise.
+ */
+ boolean setCountryCode(byte[] code);
+
+ /**
+ * Enable/disable low-latency mode.
+ *
+ * @param enable true to enable, false to disable.
+ * @return true if successful, false otherwise.
+ */
+ boolean setLowLatencyMode(boolean enable);
+
+ /**
+ * Set primary connection when multiple STA ifaces are active.
+ *
+ * @param ifaceName Name of the interface.
+ * @return true if successful, false otherwise.
+ */
+ boolean setMultiStaPrimaryConnection(String ifaceName);
+
+ /**
+ * Set use-case when multiple STA ifaces are active.
+ *
+ * @param useCase use case from {@link WifiNative.MultiStaUseCase}.
+ * @return true if successful, false otherwise.
+ */
+ boolean setMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase);
+
+ /**
+ * Control debug data collection.
+ *
+ * @param ringName Name of the ring for which data collection is to start.
+ * @param verboseLevel 0 to 3, inclusive. 0 stops logging.
+ * @param maxIntervalInSec Maximum interval between reports; ignore if 0.
+ * @param minDataSizeInBytes Minimum data size in buffer for report; ignore if 0.
+ * @return true if successful, false otherwise.
+ */
+ boolean startLoggingToDebugRingBuffer(String ringName, int verboseLevel, int maxIntervalInSec,
+ int minDataSizeInBytes);
+
+ /**
+ * Stop the debug data collection for all ring buffers.
+ *
+ * @return true if successful, false otherwise.
+ */
+ boolean stopLoggingToDebugRingBuffer();
+
+ /**
+ * Trigger subsystem restart.
+ *
+ * Use if the framework detects a problem (e.g. connection failure),
+ * in order to attempt recovery.
+ *
+ * @return true if successful, false otherwise.
+ */
+ boolean triggerSubsystemRestart();
+}
diff --git a/service/java/com/android/server/wifi/hal/IWifiHal.java b/service/java/com/android/server/wifi/hal/IWifiHal.java
new file mode 100644
index 0000000000..bec614453a
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/IWifiHal.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.Nullable;
+
+import java.util.List;
+
+/** Abstraction of the root Wifi HAL */
+public interface IWifiHal {
+ /**
+ * Get the chip corresponding to the provided chipId.
+ *
+ * @param chipId ID of the chip.
+ * @return {@link WifiChip} if successful, null otherwise.
+ */
+ @Nullable
+ WifiChip getChip(int chipId);
+
+ /**
+ * Retrieves the list of all chip id's on the device.
+ * The corresponding |WifiChip| object for any chip can be
+ * retrieved using the |getChip| method.
+ *
+ * @return List of all chip id's on the device, or null if an error occurred.
+ */
+ @Nullable
+ List<Integer> getChipIds();
+
+ /**
+ * Register for HAL event callbacks.
+ *
+ * @param callback Instance of {@link WifiHal.Callback}
+ * @return true if successful, false otherwise.
+ */
+ boolean registerEventCallback(WifiHal.Callback callback);
+
+ /**
+ * Initialize the Wi-Fi HAL service. Must initialize before calling {@link #start()}
+ *
+ * @param deathRecipient Instance of {@link WifiHal.DeathRecipient}
+ */
+ void initialize(WifiHal.DeathRecipient deathRecipient);
+
+ /**
+ * Check if the initialization is complete and the HAL is ready to accept commands.
+ *
+ * @return true if initialization is complete, false otherwise.
+ */
+ boolean isInitializationComplete();
+
+ /**
+ * Check if the Wi-Fi HAL supported on this device.
+ *
+ * @return true if supported, false otherwise.
+ */
+ boolean isSupported();
+
+ /**
+ * Start the Wi-Fi HAL.
+ *
+ * @return {@link WifiHal.WifiStatusCode} indicating the result.
+ */
+ @WifiHal.WifiStatusCode int start();
+
+ /**
+ * Get the current state of the HAL.
+ *
+ * @return true if started, false otherwise.
+ */
+ boolean isStarted();
+
+ /**
+ * Stop the Wi-Fi HAL.
+ *
+ * Note: Calling stop() and then start() is a valid way of resetting state in
+ * the HAL, driver, and firmware.
+ *
+ * @return true if successful, false otherwise.
+ */
+ boolean stop();
+
+ /**
+ * Invalidate the Wi-Fi HAL. Call when a significant error occurred external to the root
+ * Wi-Fi HAL, for instance in a Wi-Fi chip retrieved from this HAL.
+ */
+ void invalidate();
+}
diff --git a/service/java/com/android/server/wifi/hal/IWifiNanIface.java b/service/java/com/android/server/wifi/hal/IWifiNanIface.java
new file mode 100644
index 0000000000..81b22b6eea
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/IWifiNanIface.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.Nullable;
+import android.net.MacAddress;
+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 com.android.server.wifi.aware.Capabilities;
+
+/** Abstraction of WifiNanIface */
+public interface IWifiNanIface {
+ /**
+ * Enable verbose logging.
+ */
+ void enableVerboseLogging(boolean verbose);
+
+ /**
+ * Get the underlying HIDL WifiNanIfaceObject.
+ * TODO: Remove this API. Will only be used temporarily until HalDeviceManager is refactored.
+ *
+ * @return HIDL IWifiNanIface object.
+ */
+ android.hardware.wifi.V1_0.IWifiNanIface getNanIface();
+
+ /**
+ * Register a framework callback to receive notifications from the HAL.
+ *
+ * @param callback Instance of {@link WifiNanIface.Callback}.
+ * @return true if successful, false otherwise
+ */
+ boolean registerFrameworkCallback(WifiNanIface.Callback callback);
+
+ /**
+ * Get the name of this interface.
+ *
+ * @return Name of this interface, or null on error.
+ */
+ @Nullable
+ String getName();
+
+ /**
+ * Query the firmware's capabilities.
+ *
+ * @param transactionId Transaction ID for the transaction - used in the async callback to
+ * match with the original request.
+ */
+ boolean getCapabilities(short transactionId);
+
+ /**
+ * Enable and configure Aware.
+ *
+ * @param transactionId Transaction ID for the transaction - used in the
+ * async callback to match with the original request.
+ * @param configRequest Requested Aware configuration.
+ * @param notifyIdentityChange Indicates whether to get address change callbacks.
+ * @param initialConfiguration Specifies whether initial configuration
+ * (true) or an update (false) to the configuration.
+ * @param rangingEnabled Indicates whether to enable ranging.
+ * @param isInstantCommunicationEnabled Indicates whether to enable instant communication
+ * @param instantModeChannel
+ * @param macAddressRandomizationIntervalSec
+ * @param powerParameters Instance of {@link WifiNanIface.PowerParameters} containing the
+ * parameters to use in our config request.
+ */
+ boolean enableAndConfigure(short transactionId, ConfigRequest configRequest,
+ boolean notifyIdentityChange, boolean initialConfiguration, boolean rangingEnabled,
+ boolean isInstantCommunicationEnabled, int instantModeChannel,
+ int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters);
+
+ /**
+ * Disable Aware.
+ *
+ * @param transactionId Transaction ID for the transaction -
+ * used in the async callback to match with the original request.
+ */
+ boolean disable(short transactionId);
+
+ /**
+ * Start or modify a service publish session.
+ *
+ * @param transactionId Transaction ID for the transaction -
+ * used in the async callback to match with the original request.
+ * @param publishId ID of the requested session - 0 to request a new publish
+ * session.
+ * @param publishConfig Configuration of the discovery session.
+ */
+ boolean publish(short transactionId, byte publishId, PublishConfig publishConfig);
+
+ /**
+ * Start or modify a service subscription session.
+ *
+ * @param transactionId Transaction ID for the transaction -
+ * used in the async callback to match with the original request.
+ * @param subscribeId ID of the requested session - 0 to request a new
+ * subscribe session.
+ * @param subscribeConfig Configuration of the discovery session.
+ */
+ boolean subscribe(short transactionId, byte subscribeId, SubscribeConfig subscribeConfig);
+
+ /**
+ * Send a message through an existing discovery session.
+ *
+ * @param transactionId Transaction ID for the transaction -
+ * used in the async callback to match with the original request.
+ * @param pubSubId ID of the existing publish/subscribe session.
+ * @param requestorInstanceId ID of the peer to communicate with - obtained
+ * through a previous discovery (match) operation with that peer.
+ * @param dest MAC address of the peer to communicate with - obtained
+ * together with requestorInstanceId.
+ * @param message Message.
+ */
+ boolean sendMessage(short transactionId, byte pubSubId, int requestorInstanceId,
+ MacAddress dest, byte[] message);
+
+ /**
+ * Terminate a publish discovery session.
+ *
+ * @param transactionId Transaction ID for the transaction -
+ * used in the async callback to match with the original request.
+ * @param pubSubId ID of the publish/subscribe session - obtained when
+ * creating a session.
+ */
+ boolean stopPublish(short transactionId, byte pubSubId);
+
+ /**
+ * Terminate a subscribe discovery session.
+ *
+ * @param transactionId transactionId Transaction ID for the transaction -
+ * used in the async callback to match with the original request.
+ * @param pubSubId ID of the publish/subscribe session - obtained when
+ * creating a session.
+ */
+ boolean stopSubscribe(short transactionId, byte pubSubId);
+
+ /**
+ * Create an Aware network interface. This only creates the Linux interface - it doesn't
+ * actually create the data connection.
+ *
+ * @param transactionId Transaction ID for the transaction - used in the async callback to
+ * match with the original request.
+ * @param interfaceName The name of the interface, e.g. "aware0".
+ */
+ boolean createAwareNetworkInterface(short transactionId, String interfaceName);
+
+ /**
+ * Deletes an Aware network interface. The data connection can (should?) be torn
+ * down previously.
+ *
+ * @param transactionId Transaction ID for the transaction - used in the async callback to
+ * match with the original request.
+ * @param interfaceName The name of the interface, e.g. "aware0".
+ */
+ boolean deleteAwareNetworkInterface(short transactionId, String interfaceName);
+
+ /**
+ * Initiates setting up a data-path between device and peer. Security is provided by either
+ * PMK or Passphrase (not both) - if both are null then an open (unencrypted) link is set up.
+ *
+ * @param transactionId Transaction ID for the transaction - used in the async callback to
+ * match with the original request.
+ * @param peerId ID of the peer ID to associate the data path with. A value of 0
+ * indicates that not associated with an existing session.
+ * @param channelRequestType Indicates whether the specified channel is available, if available
+ * requested or forced (resulting in failure if cannot be
+ * accommodated).
+ * @param channel The channel on which to set up the data-path.
+ * @param peer The MAC address of the peer to create a connection with.
+ * @param interfaceName The interface on which to create the data connection.
+ * @param isOutOfBand Is the data-path out-of-band (i.e. without a corresponding Aware discovery
+ * session).
+ * @param appInfo Arbitrary binary blob transmitted to the peer.
+ * @param capabilities The capabilities of the firmware.
+ * @param securityConfig Security config to encrypt the data-path
+ */
+ boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
+ int channel, MacAddress peer, String interfaceName,
+ boolean isOutOfBand, byte[] appInfo, Capabilities capabilities,
+ WifiAwareDataPathSecurityConfig securityConfig);
+
+ /**
+ * Responds to a data request from a peer. Security is provided by either PMK or Passphrase (not
+ * both) - if both are null then an open (unencrypted) link is set up.
+ *
+ * @param transactionId Transaction ID for the transaction - used in the async callback to
+ * match with the original request.
+ * @param accept Accept (true) or reject (false) the original call.
+ * @param ndpId The NDP (Aware data path) ID. Obtained from the request callback.
+ * @param interfaceName The interface on which the data path will be setup. Obtained from the
+ * request callback.
+ * @param appInfo Arbitrary binary blob transmitted to the peer.
+ * @param isOutOfBand Is the data-path out-of-band (i.e. without a corresponding Aware discovery
+ * session).
+ * @param capabilities The capabilities of the firmware.
+ * @param securityConfig Security config to encrypt the data-path
+ */
+ boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
+ String interfaceName, byte[] appInfo,
+ boolean isOutOfBand, Capabilities capabilities,
+ WifiAwareDataPathSecurityConfig securityConfig);
+
+ /**
+ * Terminate an existing data-path (does not delete the interface).
+ *
+ * @param transactionId Transaction ID for the transaction - used in the async callback to
+ * match with the original request.
+ * @param ndpId The NDP (Aware data path) ID to be terminated.
+ */
+ boolean endDataPath(short transactionId, int ndpId);
+}
diff --git a/service/java/com/android/server/wifi/hal/IWifiP2pIface.java b/service/java/com/android/server/wifi/hal/IWifiP2pIface.java
new file mode 100644
index 0000000000..367feecc5d
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/IWifiP2pIface.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+/** Abstraction of WifiP2pIface */
+public interface IWifiP2pIface {
+ /**
+ * Get the name of this interface.
+ *
+ * @return Name of this interface, or null on error.
+ */
+ String getName();
+}
diff --git a/service/java/com/android/server/wifi/hal/IWifiRttController.java b/service/java/com/android/server/wifi/hal/IWifiRttController.java
new file mode 100644
index 0000000000..9fa35ab096
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/IWifiRttController.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.net.wifi.rtt.RangingRequest;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+interface IWifiRttController {
+ /**
+ * Set up the IWifiRttController.
+ *
+ * @return true if successful, false otherwise.
+ */
+ boolean setup();
+
+ /**
+ * Enable/disable verbose logging.
+ */
+ void enableVerboseLogging(boolean verbose);
+
+ /**
+ * Register a callback to receive ranging results.
+ *
+ * @param callback Callback to register.
+ */
+ void registerRangingResultsCallback(
+ WifiRttController.RttControllerRangingResultsCallback callback);
+
+ /**
+ * Check whether the RTT controller is valid.
+ *
+ * @return true if the RTT controller is valid, false otherwise or if an error occurred.
+ */
+ boolean validate();
+
+ /**
+ * Get the RTT capabilities.
+ *
+ * @return Capabilities, or null if they could not be retrieved.
+ */
+ @Nullable
+ WifiRttController.Capabilities getRttCapabilities();
+
+ /**
+ * Issue a range request to the HAL.
+ *
+ * @param cmdId Command ID for the request. Will be used in the corresponding response from
+ * {@link HalDeviceManager.InterfaceRttControllerLifecycleCallback}
+ * onRangingResults()
+ * @param request Range request.
+ * @return true if successful, false otherwise.
+ */
+ boolean rangeRequest(int cmdId, RangingRequest request);
+
+ /**
+ * Cancel an outstanding ranging request.
+ *
+ * Note: No guarantees of execution. Can ignore any results which are returned for the
+ * canceled request.
+ *
+ * @param cmdId The cmdId issued with the original rangeRequest command.
+ * @param macAddresses A list of MAC addresses for which to cancel the operation.
+ * @return true for success, false for failure.
+ */
+ boolean rangeCancel(int cmdId, List<MacAddress> macAddresses);
+
+ /**
+ * Dump the internal state of the class.
+ */
+ void dump(PrintWriter pw);
+}
diff --git a/service/java/com/android/server/wifi/hal/IWifiStaIface.java b/service/java/com/android/server/wifi/hal/IWifiStaIface.java
new file mode 100644
index 0000000000..ed5451e162
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/IWifiStaIface.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.net.apf.ApfCapabilities;
+
+import com.android.server.wifi.WifiLinkLayerStats;
+import com.android.server.wifi.WifiLoggerHal;
+import com.android.server.wifi.WifiNative;
+
+import java.util.List;
+
+/** Abstraction of WifiStaIface */
+public interface IWifiStaIface {
+ /**
+ * Register for event callbacks.
+ *
+ * @param callback Instance of {@link WifiStaIface.Callback}
+ * @return true if successful, false otherwise.
+ */
+ boolean registerFrameworkCallback(WifiStaIface.Callback callback);
+
+ /**
+ * Get the name of this interface.
+ *
+ * @return Name of this interface, or null on error.
+ */
+ @Nullable
+ String getName();
+
+ /**
+ * Configure roaming control parameters.
+ *
+ * @param bssidBlocklist List of BSSIDs that are blocklisted for roaming.
+ * @param ssidAllowlist List of SSIDs that are allowlisted for roaming.
+ * @return true if successful, false otherwise.
+ */
+ boolean configureRoaming(List<MacAddress> bssidBlocklist, List<byte[]> ssidAllowlist);
+
+ /**
+ * Enable link layer stats collection.
+ *
+ * Radio statistics (once started) must not stop until disabled.
+ * Iface statistics (once started) reset and start afresh after each
+ * connection until disabled.
+ *
+ * @param debug true to enable field debug mode, false to disable. Driver
+ * must collect all statistics regardless of performance impact.
+ * @return true if successful, false otherwise.
+ */
+ boolean enableLinkLayerStatsCollection(boolean debug);
+
+ /**
+ * Enable/disable the neighbor discovery offload functionality in the firmware.
+ *
+ * @param enable true to enable, false to disable.
+ * @return true if successful, false otherwise.
+ */
+ boolean enableNdOffload(boolean enable);
+
+ /**
+ * Used to query additional information about the chip's APF capabilities.
+ *
+ * @return Instance of {@link ApfCapabilities}.
+ */
+ ApfCapabilities getApfPacketFilterCapabilities();
+
+ /**
+ * Used to query additional information about the chip's Background Scan capabilities.
+ *
+ * @return Instance of {@link WifiNative.ScanCapabilities}, or null on error.
+ */
+ @Nullable
+ WifiNative.ScanCapabilities getBackgroundScanCapabilities();
+
+ /**
+ * Get the capabilities supported by this STA iface.
+ *
+ * @return Bitset of WifiManager.WIFI_FEATURE_* values.
+ */
+ long getCapabilities();
+
+ /**
+ * Retrieve the fates of inbound packets.
+ * Reports the inbound frames for the most recent association (space allowing).
+ *
+ * @return List of RxFateReports up to size {@link WifiLoggerHal#MAX_FATE_LOG_LEN},
+ * or empty list on failure.
+ */
+ List<WifiNative.RxFateReport> getDebugRxPacketFates();
+
+ /**
+ * Retrieve fates of outbound packets.
+ * Reports the outbound frames for the most recent association (space allowing).
+ *
+ * @return List of TxFateReports up to size {@link WifiLoggerHal#MAX_FATE_LOG_LEN},
+ * or empty list on failure.
+ */
+ List<WifiNative.TxFateReport> getDebugTxPacketFates();
+
+ /**
+ * Get the factory MAC address of the STA interface.
+ *
+ * @return Factory MAC address of the STA interface, or null on error.
+ */
+ @Nullable
+ MacAddress getFactoryMacAddress();
+
+ /**
+ * Retrieve the latest link layer stats.
+ * Note: will fail if link layer stats collection has not been explicitly enabled.
+ *
+ * @return Instance of {@link WifiLinkLayerStats}, or null on error.
+ */
+ @Nullable
+ WifiLinkLayerStats getLinkLayerStats();
+
+ /**
+ * Get roaming control capabilities.
+ *
+ * @return Instance of {@link WifiNative.RoamingCapabilities}, or null on error.
+ */
+ @Nullable
+ WifiNative.RoamingCapabilities getRoamingCapabilities();
+
+ /**
+ * Install an APF program on this interface, replacing any existing program.
+ *
+ * @param program APF Program to be set.
+ * @return true if successful, false otherwise.
+ */
+ boolean installApfPacketFilter(byte[] program);
+
+ /**
+ * Read the APF program and data buffer on this interface.
+ *
+ * @return Buffer returned by the driver, or null if an error occurred.
+ */
+ @Nullable
+ byte[] readApfPacketFilterData();
+
+ /**
+ * Changes the MAC address of the interface to the given MAC address.
+ *
+ * @param mac MAC address to change to.
+ * @return true if successful, false otherwise.
+ */
+ boolean setMacAddress(MacAddress mac);
+
+ /**
+ * Enable/disable firmware roaming.
+ *
+ * @param state State of the roaming control.
+ * @return SET_FIRMWARE_ROAMING_SUCCESS, SET_FIRMWARE_ROAMING_FAILURE,
+ * or SET_FIRMWARE_ROAMING_BUSY
+ */
+ @WifiNative.RoamingEnableStatus int setRoamingState(@WifiNative.RoamingEnableState int state);
+
+ /**
+ * Enable/disable scan-only mode for this interface.
+ *
+ * @param enable True to enable scan only mode, false to disable.
+ * @return true if successful, false otherwise.
+ */
+ boolean setScanMode(boolean enable);
+
+ /**
+ * Starts a background scan.
+ * Note: any ongoing scan will be stopped first.
+ *
+ * @param cmdId Command ID to use for this invocation.
+ * @param params Background scan parameters.
+ * @return true if successful, false otherwise.
+ */
+ boolean startBackgroundScan(int cmdId, WifiStaIface.StaBackgroundScanParameters params);
+
+ /**
+ * Start packet fate monitoring. Once started, monitoring remains active until
+ * the HAL is unloaded.
+ *
+ * @return true if successful, false otherwise.
+ */
+ boolean startDebugPacketFateMonitoring();
+
+ /**
+ * Start RSSI monitoring on the currently connected access point.
+ *
+ * @param cmdId Command ID to use for this invocation.
+ * @param maxRssi Maximum RSSI threshold.
+ * @param minRssi Minimum RSSI threshold.
+ * @return true if successful, false otherwise.
+ */
+ boolean startRssiMonitoring(int cmdId, int maxRssi, int minRssi);
+
+ /**
+ * Start sending the specified keep-alive packets periodically.
+ *
+ * @param cmdId Command ID to use for this invocation.
+ * @param ipPacketData IP packet contents to be transmitted.
+ * @param etherType Ether type to be set in the ethernet frame transmitted.
+ * @param srcAddress Source MAC address of the packet.
+ * @param dstAddress Destination MAC address of the packet.
+ * @param periodInMs Interval at which this packet must be transmitted.
+ * @return true if successful, false otherwise.
+ */
+ boolean startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType,
+ MacAddress srcAddress, MacAddress dstAddress, int periodInMs);
+
+ /**
+ * Stop the current background scan.
+ *
+ * @param cmdId Command ID corresponding to the request.
+ * @return true if successful, false otherwise.
+ */
+ boolean stopBackgroundScan(int cmdId);
+
+ /**
+ * Stop RSSI monitoring.
+ *
+ * @param cmdId Command ID corresponding to the request.
+ * @return true if successful, false otherwise.
+ */
+ boolean stopRssiMonitoring(int cmdId);
+
+ /**
+ * Stop sending the specified keep-alive packets.
+ *
+ * @param cmdId Command ID corresponding to the request.
+ * @return true if successful, false otherwise.
+ */
+ boolean stopSendingKeepAlivePackets(int cmdId);
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiApIface.java b/service/java/com/android/server/wifi/hal/WifiApIface.java
new file mode 100644
index 0000000000..14992bfc82
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiApIface.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.util.Log;
+
+import com.android.server.wifi.util.NativeUtil;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * Wrapper around a WifiApIface.
+ * May be initialized using a HIDL or AIDL WifiApIface.
+ */
+public class WifiApIface implements WifiHal.WifiInterface {
+ private static final String TAG = "WifiApIface";
+ private final IWifiApIface mWifiApIface;
+
+ public WifiApIface(@NonNull android.hardware.wifi.V1_0.IWifiApIface apIface) {
+ mWifiApIface = createWifiApIfaceHidlImplMockable(apIface);
+ }
+
+ public WifiApIface(@NonNull android.hardware.wifi.IWifiApIface apIface) {
+ mWifiApIface = createWifiApIfaceAidlImplMockable(apIface);
+ }
+
+ protected WifiApIfaceHidlImpl createWifiApIfaceHidlImplMockable(
+ android.hardware.wifi.V1_0.IWifiApIface apIface) {
+ return new WifiApIfaceHidlImpl(apIface);
+ }
+
+ protected WifiApIfaceAidlImpl createWifiApIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiApIface apIface) {
+ return new WifiApIfaceAidlImpl(apIface);
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiApIface == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiApIface is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#getName()}
+ */
+ @Override
+ @Nullable
+ public String getName() {
+ return validateAndCall("getName", null,
+ () -> mWifiApIface.getName());
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#getBridgedInstances()}
+ */
+ public List<String> getBridgedInstances() {
+ return validateAndCall("getBridgedInstances", null,
+ () -> mWifiApIface.getBridgedInstances());
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#getFactoryMacAddress()}
+ */
+ public MacAddress getFactoryMacAddress() {
+ return validateAndCall("getFactoryMacAddress", null,
+ () -> mWifiApIface.getFactoryMacAddress());
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#setCountryCode(byte[])}
+ */
+ public boolean setCountryCode(String countryCode) {
+ if (countryCode == null || countryCode.length() != 2) {
+ Log.e(TAG, "Invalid country code " + countryCode);
+ return false;
+ }
+ try {
+ final byte[] code = NativeUtil.stringToByteArray(countryCode);
+ return validateAndCall("setCountryCode", false,
+ () -> mWifiApIface.setCountryCode(code));
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Invalid country code " + countryCode + ", error: " + e);
+ return false;
+ }
+
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#resetToFactoryMacAddress()}
+ */
+ public boolean resetToFactoryMacAddress() {
+ return validateAndCall("resetToFactoryMacAddress", false,
+ () -> mWifiApIface.resetToFactoryMacAddress());
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#isSetMacAddressSupported()}
+ */
+ public boolean isSetMacAddressSupported() {
+ return validateAndCall("isSetMacAddressSupported", false,
+ () -> mWifiApIface.isSetMacAddressSupported());
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#setMacAddress(MacAddress)}
+ */
+ public boolean setMacAddress(MacAddress mac) {
+ if (mac == null) {
+ Log.e(TAG, "setMacAddress received a null MAC address");
+ return false;
+ }
+ return validateAndCall("setMacAddress", false,
+ () -> mWifiApIface.setMacAddress(mac));
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiApIfaceAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiApIfaceAidlImpl.java
new file mode 100644
index 0000000000..f903a200c6
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiApIfaceAidlImpl.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * AIDL implementation of the IWifiApIface interface.
+ */
+public class WifiApIfaceAidlImpl implements IWifiApIface {
+ private static final String TAG = "WifiApIfaceAidlImpl";
+ private android.hardware.wifi.IWifiApIface mWifiApIface;
+ private final Object mLock = new Object();
+ private String mIfaceName;
+
+ public WifiApIfaceAidlImpl(@NonNull android.hardware.wifi.IWifiApIface apIface) {
+ mWifiApIface = apIface;
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#getName()}
+ */
+ @Override
+ @Nullable
+ public String getName() {
+ final String methodStr = "getName";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ if (mIfaceName != null) return mIfaceName;
+ try {
+ String ifaceName = mWifiApIface.getName();
+ mIfaceName = ifaceName;
+ return mIfaceName;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#getBridgedInstances()}
+ */
+ @Override
+ @Nullable
+ public List<String> getBridgedInstances() {
+ final String methodStr = "getBridgedInstances";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ String[] instances = mWifiApIface.getBridgedInstances();
+ if (instances == null) {
+ Log.e(TAG, methodStr + " received a null array from the HAL");
+ return null;
+ }
+ return Arrays.asList(instances);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#getFactoryMacAddress()}
+ */
+ @Override
+ @Nullable
+ public MacAddress getFactoryMacAddress() {
+ final String methodStr = "getFactoryMacAddress";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ try {
+ byte[] macBytes = mWifiApIface.getFactoryMacAddress();
+ return MacAddress.fromBytes(macBytes);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, methodStr + " received invalid MAC address: " + e);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#setCountryCode(byte[])}
+ */
+ @Override
+ public boolean setCountryCode(byte[] countryCode) {
+ final String methodStr = "setCountryCode";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiApIface.setCountryCode(countryCode);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#resetToFactoryMacAddress()}
+ */
+ @Override
+ public boolean resetToFactoryMacAddress() {
+ final String methodStr = "resetToFactoryMacAddress";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiApIface.resetToFactoryMacAddress();
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#isSetMacAddressSupported()}
+ */
+ @Override
+ public boolean isSetMacAddressSupported() {
+ return true; // supported by default in the AIDL HAL
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#setMacAddress(MacAddress)}
+ */
+ @Override
+ public boolean setMacAddress(MacAddress mac) {
+ final String methodStr = "setMacAddress";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiApIface.setMacAddress(mac.toByteArray());
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ private boolean checkIfaceAndLogFailure(String methodStr) {
+ if (mWifiApIface == null) {
+ Log.e(TAG, "Unable to call " + methodStr + " because iface is null.");
+ return false;
+ }
+ return true;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ mWifiApIface = null;
+ mIfaceName = null;
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ }
+
+ private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with service-specific exception: " + e);
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiApIfaceHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiApIfaceHidlImpl.java
new file mode 100644
index 0000000000..f872bf0f47
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiApIfaceHidlImpl.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.hardware.wifi.V1_0.WifiStatus;
+import android.hardware.wifi.V1_0.WifiStatusCode;
+import android.net.MacAddress;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.server.wifi.util.GeneralUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * HIDL implementation of the IWifiApIface interface.
+ */
+public class WifiApIfaceHidlImpl implements IWifiApIface {
+ private static final String TAG = "WifiApIfaceHidlImpl";
+ private android.hardware.wifi.V1_0.IWifiApIface mWifiApIface;
+ private String mIfaceName;
+
+ public WifiApIfaceHidlImpl(@NonNull android.hardware.wifi.V1_0.IWifiApIface apIface) {
+ mWifiApIface = apIface;
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#getName()}
+ */
+ public String getName() {
+ final String methodStr = "getName";
+ return validateAndCall(methodStr, null,
+ () -> getNameInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#getBridgedInstances()}
+ */
+ public List<String> getBridgedInstances() {
+ final String methodStr = "getBridgedInstances";
+ return validateAndCall(methodStr, null,
+ () -> getBridgedInstancesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#getFactoryMacAddress()}
+ */
+ public MacAddress getFactoryMacAddress() {
+ final String methodStr = "getFactoryMacAddress";
+ return validateAndCall(methodStr, null,
+ () -> getFactoryMacAddressInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#setCountryCode(byte[])}
+ */
+ public boolean setCountryCode(byte[] countryCode) {
+ final String methodStr = "setCountryCode";
+ return validateAndCall(methodStr, false,
+ () -> setCountryCodeInternal(methodStr, countryCode));
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#resetToFactoryMacAddress()}
+ *
+ * Note: If HAL < 1.5, will only reset the MAC address for this interface.
+ */
+ public boolean resetToFactoryMacAddress() {
+ final String methodStr = "resetToFactoryMacAddress";
+ return validateAndCall(methodStr, false,
+ () -> resetToFactoryMacAddressInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#isSetMacAddressSupported()}
+ */
+ public boolean isSetMacAddressSupported() {
+ if (mWifiApIface == null) return false;
+ return getWifiApIfaceV1_4Mockable() != null;
+ }
+
+ /**
+ * See comments for {@link IWifiApIface#setMacAddress(MacAddress)}
+ */
+ public boolean setMacAddress(MacAddress mac) {
+ final String methodStr = "setMacAddress";
+ return validateAndCall(methodStr, false,
+ () -> setMacAddressInternal(methodStr, mac));
+ }
+
+
+ // Internal Implementations
+
+ private String getNameInternal(String methodStr) {
+ if (mIfaceName != null) return mIfaceName;
+ GeneralUtil.Mutable<String> nameResp = new GeneralUtil.Mutable<>();
+ try {
+ mWifiApIface.getName((WifiStatus status, String name) -> {
+ if (isOk(status, methodStr)) {
+ nameResp.value = name;
+ mIfaceName = name;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return nameResp.value;
+ }
+
+ private List<String> getBridgedInstancesInternal(String methodStr) {
+ GeneralUtil.Mutable<List<String>> instancesResp = new GeneralUtil.Mutable<>();
+ try {
+ android.hardware.wifi.V1_5.IWifiApIface ap15 = getWifiApIfaceV1_5Mockable();
+ if (ap15 == null) return null;
+ ap15.getBridgedInstances((status, instances) -> {
+ if (isOk(status, methodStr)) {
+ instancesResp.value = new ArrayList<>(instances);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return instancesResp.value;
+ }
+
+ private MacAddress getFactoryMacAddressInternal(String methodStr) {
+ GeneralUtil.Mutable<MacAddress> macResp = new GeneralUtil.Mutable<>();
+ try {
+ android.hardware.wifi.V1_4.IWifiApIface ap14 = getWifiApIfaceV1_4Mockable();
+ if (ap14 == null) return null;
+ ap14.getFactoryMacAddress((status, macBytes) -> {
+ if (isOk(status, methodStr)) {
+ macResp.value = MacAddress.fromBytes(macBytes);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return macResp.value;
+ }
+
+ private boolean setCountryCodeInternal(String methodStr, byte[] countryCode) {
+ try {
+ WifiStatus status = mWifiApIface.setCountryCode(countryCode);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean resetToFactoryMacAddressInternal(String methodStr) {
+ try {
+ android.hardware.wifi.V1_5.IWifiApIface ap15 = getWifiApIfaceV1_5Mockable();
+ if (ap15 == null) {
+ MacAddress mac = getFactoryMacAddress();
+ return mac != null && setMacAddress(mac);
+ }
+ WifiStatus status = ap15.resetToFactoryMacAddress();
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean setMacAddressInternal(String methodStr, MacAddress mac) {
+ try {
+ android.hardware.wifi.V1_4.IWifiApIface ap14 = getWifiApIfaceV1_4Mockable();
+ if (ap14 == null) return false;
+ WifiStatus status = ap14.setMacAddress(mac.toByteArray());
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+
+ // Helper Functions
+
+ protected android.hardware.wifi.V1_4.IWifiApIface getWifiApIfaceV1_4Mockable() {
+ return android.hardware.wifi.V1_4.IWifiApIface.castFrom(mWifiApIface);
+ }
+
+ protected android.hardware.wifi.V1_5.IWifiApIface getWifiApIfaceV1_5Mockable() {
+ return android.hardware.wifi.V1_5.IWifiApIface.castFrom(mWifiApIface);
+ }
+
+ private boolean isOk(WifiStatus status, String methodStr) {
+ if (status.code == WifiStatusCode.SUCCESS) return true;
+ Log.e(TAG, methodStr + " failed with status: " + status);
+ return false;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ mWifiApIface = null;
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiApIface == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiApIface is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiChip.java b/service/java/com/android/server/wifi/hal/WifiChip.java
new file mode 100644
index 0000000000..ca759fc193
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiChip.java
@@ -0,0 +1,860 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.net.wifi.CoexUnsafeChannel;
+import android.net.wifi.WifiAvailableChannel;
+import android.net.wifi.WifiScanner;
+import android.util.Log;
+
+import com.android.server.wifi.SarInfo;
+import com.android.server.wifi.SsidTranslator;
+import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.WlanWakeReasonAndCounts;
+import com.android.server.wifi.util.GeneralUtil.Mutable;
+import com.android.server.wifi.util.NativeUtil;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * Wrapper around a WifiChip.
+ * May be initialized using a HIDL or AIDL WifiChip.
+ */
+public class WifiChip {
+ public static final String TAG = "WifiChip";
+ private IWifiChip mWifiChip;
+
+ /**
+ * Interface concurrency types used in reporting device concurrency capabilities.
+ */
+ public static final int IFACE_CONCURRENCY_TYPE_STA = 0;
+ public static final int IFACE_CONCURRENCY_TYPE_AP = 1;
+ public static final int IFACE_CONCURRENCY_TYPE_AP_BRIDGED = 2;
+ public static final int IFACE_CONCURRENCY_TYPE_P2P = 3;
+ public static final int IFACE_CONCURRENCY_TYPE_NAN = 4;
+
+ @IntDef(prefix = { "IFACE_CONCURRENCY_TYPE_" }, value = {
+ IFACE_CONCURRENCY_TYPE_STA,
+ IFACE_CONCURRENCY_TYPE_AP,
+ IFACE_CONCURRENCY_TYPE_AP_BRIDGED,
+ IFACE_CONCURRENCY_TYPE_P2P,
+ IFACE_CONCURRENCY_TYPE_NAN,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface IfaceConcurrencyType {}
+
+ /**
+ * Supported interface types.
+ */
+ public static final int IFACE_TYPE_STA = 0;
+ public static final int IFACE_TYPE_AP = 1;
+ public static final int IFACE_TYPE_P2P = 2;
+ public static final int IFACE_TYPE_NAN = 3;
+
+ @IntDef(prefix = { "IFACE_TYPE_" }, value = {
+ IFACE_TYPE_STA,
+ IFACE_TYPE_AP,
+ IFACE_TYPE_P2P,
+ IFACE_TYPE_NAN,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface IfaceType {}
+
+ /**
+ * Antenna configurations.
+ */
+ public static final int WIFI_ANTENNA_MODE_UNSPECIFIED = 0;
+ public static final int WIFI_ANTENNA_MODE_1X1 = 1;
+ public static final int WIFI_ANTENNA_MODE_2X2 = 2;
+ public static final int WIFI_ANTENNA_MODE_3X3 = 3;
+ public static final int WIFI_ANTENNA_MODE_4X4 = 4;
+
+ @IntDef(prefix = { "WIFI_ANTENNA_MODE_" }, value = {
+ WIFI_ANTENNA_MODE_UNSPECIFIED,
+ WIFI_ANTENNA_MODE_1X1,
+ WIFI_ANTENNA_MODE_2X2,
+ WIFI_ANTENNA_MODE_3X3,
+ WIFI_ANTENNA_MODE_4X4,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WifiAntennaMode {}
+
+ /**
+ * Response containing a value and a status code.
+ *
+ * @param <T> Type of value that should be returned.
+ */
+ public static class Response<T> {
+ private Mutable<T> mMutable;
+ private int mStatusCode;
+
+ public Response(T initialValue) {
+ mMutable = new Mutable<>(initialValue);
+ mStatusCode = WifiHal.WIFI_STATUS_ERROR_UNKNOWN;
+ }
+
+ public void setValue(T value) {
+ mMutable.value = value;
+ }
+
+ public T getValue() {
+ return mMutable.value;
+ }
+
+ public void setStatusCode(@WifiHal.WifiStatusCode int statusCode) {
+ mStatusCode = statusCode;
+ }
+
+ public @WifiHal.WifiStatusCode int getStatusCode() {
+ return mStatusCode;
+ }
+ }
+
+ /**
+ * Set of interface concurrency types, along with the maximum number of interfaces that can have
+ * one of the specified concurrency types for a given ChipConcurrencyCombination. See
+ * ChipConcurrencyCombination below for examples.
+ */
+ public static class ChipConcurrencyCombinationLimit {
+ public final int maxIfaces;
+ public final @IfaceConcurrencyType List<Integer> types;
+
+ public ChipConcurrencyCombinationLimit(int inMaxIfaces,
+ @IfaceConcurrencyType List<Integer> inTypes) {
+ maxIfaces = inMaxIfaces;
+ types = inTypes;
+ }
+
+ @Override
+ public String toString() {
+ return "{maxIfaces=" + maxIfaces + ", types=" + types + "}";
+ }
+ }
+
+ /**
+ * Set of interfaces that can operate concurrently when in a given mode.
+ *
+ * For example:
+ * [{STA} <= 2]
+ * At most two STA interfaces are supported
+ * [], [STA], [STA+STA]
+ *
+ * [{STA} <= 1, {NAN} <= 1, {AP_BRIDGED} <= 1]
+ * Any combination of STA, NAN, AP_BRIDGED
+ * [], [STA], [NAN], [AP_BRIDGED], [STA+NAN], [STA+AP_BRIDGED], [NAN+AP_BRIDGED],
+ * [STA+NAN+AP_BRIDGED]
+ *
+ * [{STA} <= 1, {NAN,P2P} <= 1]
+ * Optionally a STA and either NAN or P2P
+ * [], [STA], [STA+NAN], [STA+P2P], [NAN], [P2P]
+ * Not included [NAN+P2P], [STA+NAN+P2P]
+ *
+ * [{STA} <= 1, {STA,NAN} <= 1]
+ * Optionally a STA and either a second STA or a NAN
+ * [], [STA], [STA+NAN], [STA+STA], [NAN]
+ * Not included [STA+STA+NAN]
+ */
+ public static class ChipConcurrencyCombination {
+ public final List<ChipConcurrencyCombinationLimit> limits;
+
+ public ChipConcurrencyCombination(List<ChipConcurrencyCombinationLimit> inLimits) {
+ limits = inLimits;
+ }
+
+ @Override
+ public String toString() {
+ return "{limits=" + limits + "}";
+ }
+ }
+
+ /**
+ * A mode that the chip can be put in. A mode defines a set of constraints on
+ * the interfaces that can exist while in that mode. Modes define a unit of
+ * configuration where all interfaces must be torn down to switch to a
+ * different mode. Some HALs may only have a single mode, but an example where
+ * multiple modes would be required is if a chip has different firmwares with
+ * different capabilities.
+ *
+ * When in a mode, it must be possible to perform any combination of creating
+ * and removing interfaces as long as at least one of the
+ * ChipConcurrencyCombinations is satisfied. This means that if a chip has two
+ * available combinations, [{STA} <= 1] and [{AP_BRIDGED} <= 1] then it is expected
+ * that exactly one STA type or one AP_BRIDGED type can be created, but it
+ * is not expected that both a STA and AP_BRIDGED type could be created. If it
+ * was then there would be a single available combination
+ * [{STA} <=1, {AP_BRIDGED} <= 1].
+ *
+ * When switching between two available combinations it is expected that
+ * interfaces only supported by the initial combination must be removed until
+ * the target combination is also satisfied. At that point new interfaces
+ * satisfying only the target combination can be added (meaning the initial
+ * combination limits will no longer satisfied). The addition of these new
+ * interfaces must not impact the existence of interfaces that satisfy both
+ * combinations.
+ *
+ * For example, a chip with available combinations:
+ * [{STA} <= 2, {NAN} <=1] and [{STA} <=1, {NAN} <= 1, {AP_BRIDGED} <= 1}]
+ * If the chip currently has 3 interfaces STA, STA and NAN and wants to add an
+ * AP_BRIDGED interface in place of one of the STAs, then one of the STA interfaces
+ * must be removed first, and then the AP interface can be created after
+ * the STA has been torn down. During this process the remaining STA and NAN
+ * interfaces must not be removed/recreated.
+ *
+ * If a chip does not support this kind of reconfiguration in this mode then
+ * the combinations must be separated into two separate modes. Before
+ * switching modes, all interfaces must be torn down, the mode switch must be
+ * enacted, and when it completes the new interfaces must be brought up.
+ */
+ public static class ChipMode {
+ public final int id;
+ public final List<ChipConcurrencyCombination> availableCombinations;
+
+ public ChipMode(int inId, List<ChipConcurrencyCombination> inAvailableCombinations) {
+ id = inId;
+ availableCombinations = inAvailableCombinations;
+ }
+
+ @Override
+ public String toString() {
+ return "{id=" + id + ", availableCombinations=" + availableCombinations + "}";
+ }
+ }
+
+ /**
+ * Wifi radio configuration.
+ */
+ public static class WifiRadioConfiguration {
+ public final @WifiScanner.WifiBand int bandInfo;
+ public final @WifiAntennaMode int antennaMode;
+
+ public WifiRadioConfiguration(int inBandInfo, int inAntennaMode) {
+ bandInfo = inBandInfo;
+ antennaMode = inAntennaMode;
+ }
+
+ @Override
+ public String toString() {
+ return "{bandInfo=" + bandInfo + ", antennaMode=" + antennaMode + "}";
+ }
+ }
+
+ /**
+ * Wifi radio combination.
+ */
+ public static class WifiRadioCombination {
+ public final List<WifiRadioConfiguration> radioConfigurations;
+
+ public WifiRadioCombination(List<WifiRadioConfiguration> inRadioConfigurations) {
+ radioConfigurations = inRadioConfigurations;
+ }
+
+ @Override
+ public String toString() {
+ return "{radioConfigurations=" + radioConfigurations + "}";
+ }
+ }
+
+ /**
+ * Wifi radio combinations matrix.
+ */
+ public static class WifiRadioCombinationMatrix {
+ public final List<WifiRadioCombination> radioCombinations;
+
+ public WifiRadioCombinationMatrix(List<WifiRadioCombination> inRadioCombinations) {
+ radioCombinations = inRadioCombinations;
+ }
+
+ @Override
+ public String toString() {
+ return "{radioCombinations=" + radioCombinations + "}";
+ }
+ }
+
+ /**
+ * Information about the version of the driver and firmware running this chip.
+ *
+ * The information in these ASCII strings are vendor specific and does not
+ * need to follow any particular format. It may be dumped as part of the bug
+ * report.
+ */
+ public static class ChipDebugInfo {
+ public final String driverDescription;
+ public final String firmwareDescription;
+
+ public ChipDebugInfo(String inDriverDescription, String inFirmwareDescription) {
+ driverDescription = inDriverDescription;
+ firmwareDescription = inFirmwareDescription;
+ }
+ }
+
+ /**
+ * State of an iface operating on the radio chain (hardware MAC) on the device.
+ */
+ public static class IfaceInfo {
+ public final String name;
+ public final int channel;
+
+ public IfaceInfo(String inName, int inChannel) {
+ name = inName;
+ channel = inChannel;
+ }
+ }
+
+ /**
+ * State of a hardware radio chain (hardware MAC) on the device.
+ */
+ public static class RadioModeInfo {
+ public final int radioId;
+ public final @WifiScanner.WifiBand int bandInfo;
+ public final List<IfaceInfo> ifaceInfos;
+
+ public RadioModeInfo(int inRadioId, @WifiScanner.WifiBand int inBandInfo,
+ List<IfaceInfo> inIfaceInfos) {
+ radioId = inRadioId;
+ bandInfo = inBandInfo;
+ ifaceInfos = inIfaceInfos;
+ }
+ }
+
+ /**
+ * Framework callback object. Will get called when the equivalent events are received
+ * from the HAL.
+ */
+ public interface Callback {
+ /**
+ * Indicates that a chip reconfiguration failed. This is a fatal
+ * error and any iface objects available previously must be considered
+ * invalid. The client can attempt to recover by trying to reconfigure the
+ * chip again using {@link IWifiChip#configureChip(int)}.
+ *
+ * @param status Failure reason code.
+ */
+ void onChipReconfigureFailure(int status);
+
+ /**
+ * Indicates that the chip has been reconfigured successfully. At
+ * this point, the interfaces available in the mode must be able to be
+ * configured. When this is called, any previous iface objects must be
+ * considered invalid.
+ *
+ * @param modeId The mode that the chip switched to, corresponding to the id
+ * property of the target ChipMode.
+ */
+ void onChipReconfigured(int modeId);
+
+ /**
+ * Indicates that the chip has encountered a fatal error.
+ * Client must not attempt to parse either the errorCode or debugData.
+ * Must only be captured in a bugreport.
+ *
+ * @param errorCode Vendor defined error code.
+ * @param debugData Vendor defined data used for debugging.
+ */
+ void onDebugErrorAlert(int errorCode, byte[] debugData);
+
+ /**
+ * Reports debug ring buffer data.
+ *
+ * The ring buffer data collection is event based:
+ * - Driver calls this callback when new records are available, the
+ * |WifiDebugRingBufferStatus| passed up to framework in the callback
+ * indicates to framework if more data is available in the ring buffer.
+ * It is not expected that driver will necessarily always empty the ring
+ * immediately as data is available. Instead the driver will report data
+ * every X seconds, or if N bytes are available, based on the parameters
+ * set via |startLoggingToDebugRingBuffer|.
+ * - In the case where a bug report has to be captured, the framework will
+ * require driver to upload all data immediately. This is indicated to
+ * driver when framework calls |forceDumpToDebugRingBuffer|. The driver
+ * will start sending all available data in the indicated ring by repeatedly
+ * invoking this callback.
+ *
+ * @param status Status of the corresponding ring buffer. This should
+ * contain the name of the ring buffer on which the data is
+ * available.
+ * @param data Raw bytes of data sent by the driver. Must be dumped
+ * out to a bugreport and post processed.
+ */
+ void onDebugRingBufferDataAvailable(WifiNative.RingBufferStatus status, byte[] data);
+
+ /**
+ * Indicates that a new iface has been added to the chip.
+ *
+ * @param type Type of iface added.
+ * @param name Name of iface added.
+ */
+ void onIfaceAdded(@IfaceType int type, String name);
+
+ /**
+ * Indicates that an existing iface has been removed from the chip.
+ *
+ * @param type Type of iface removed.
+ * @param name Name of iface removed.
+ */
+ void onIfaceRemoved(@IfaceType int type, String name);
+
+ /**
+ * Indicates a radio mode change.
+ * Radio mode change could be a result of:
+ * a) Bringing up concurrent interfaces (ex. STA + AP).
+ * b) Change in operating band of one of the concurrent interfaces
+ * (ex. STA connection moved from 2.4G to 5G)
+ *
+ * @param radioModeInfos List of RadioModeInfo structures for each
+ * radio chain (hardware MAC) on the device.
+ */
+ void onRadioModeChange(List<RadioModeInfo> radioModeInfos);
+ }
+
+ public WifiChip(@NonNull android.hardware.wifi.V1_0.IWifiChip chip,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ mWifiChip = createWifiChipHidlImplMockable(chip, context, ssidTranslator);
+ }
+
+ public WifiChip(@NonNull android.hardware.wifi.IWifiChip chip,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ mWifiChip = createWifiChipAidlImplMockable(chip, context, ssidTranslator);
+ }
+
+ protected WifiChipHidlImpl createWifiChipHidlImplMockable(
+ @NonNull android.hardware.wifi.V1_0.IWifiChip chip,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ return new WifiChipHidlImpl(chip, context, ssidTranslator);
+ }
+
+ protected WifiChipAidlImpl createWifiChipAidlImplMockable(
+ @NonNull android.hardware.wifi.IWifiChip chip,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ return new WifiChipAidlImpl(chip, context, ssidTranslator);
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiChip == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiChip is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+
+ /**
+ * See comments for {@link IWifiChip#configureChip(int)}
+ */
+ public boolean configureChip(int modeId) {
+ return validateAndCall("configureChip", false,
+ () -> mWifiChip.configureChip(modeId));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createApIface()}
+ */
+ @Nullable
+ public WifiApIface createApIface() {
+ return validateAndCall("createApIface", null,
+ () -> mWifiChip.createApIface());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createBridgedApIface()}
+ */
+ @Nullable
+ public WifiApIface createBridgedApIface() {
+ return validateAndCall("createBridgedApIface", null,
+ () -> mWifiChip.createBridgedApIface());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createNanIface()}
+ */
+ @Nullable
+ public WifiNanIface createNanIface() {
+ return validateAndCall("createNanIface", null,
+ () -> mWifiChip.createNanIface());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createP2pIface()}
+ */
+ @Nullable
+ public WifiP2pIface createP2pIface() {
+ return validateAndCall("createP2pIface", null,
+ () -> mWifiChip.createP2pIface());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createRttController()}
+ */
+ @Nullable
+ public WifiRttController createRttController() {
+ return validateAndCall("createRttController", null,
+ () -> mWifiChip.createRttController());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createStaIface()}
+ */
+ @Nullable
+ public WifiStaIface createStaIface() {
+ return validateAndCall("createStaIface", null,
+ () -> mWifiChip.createStaIface());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#enableDebugErrorAlerts(boolean)}
+ */
+ public boolean enableDebugErrorAlerts(boolean enable) {
+ return validateAndCall("enableDebugErrorAlerts", false,
+ () -> mWifiChip.enableDebugErrorAlerts(enable));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#flushRingBufferToFile()}
+ */
+ public boolean flushRingBufferToFile() {
+ return validateAndCall("flushRingBufferToFile", false,
+ () -> mWifiChip.flushRingBufferToFile());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#forceDumpToDebugRingBuffer(String)}
+ */
+ public boolean forceDumpToDebugRingBuffer(String ringName) {
+ return validateAndCall("forceDumpToDebugRingBuffer", false,
+ () -> mWifiChip.forceDumpToDebugRingBuffer(ringName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getApIface(String)}
+ */
+ @Nullable
+ public WifiApIface getApIface(String ifaceName) {
+ return validateAndCall("getApIface", null,
+ () -> mWifiChip.getApIface(ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getApIfaceNames()}
+ */
+ @Nullable
+ public List<String> getApIfaceNames() {
+ return validateAndCall("getApIfaceNames", null,
+ () -> mWifiChip.getApIfaceNames());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getAvailableModes()}
+ */
+ @Nullable
+ public List<WifiChip.ChipMode> getAvailableModes() {
+ return validateAndCall("getAvailableModes", null,
+ () -> mWifiChip.getAvailableModes());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()}
+ */
+ public Response<Long> getCapabilitiesBeforeIfacesExist() {
+ return validateAndCall("getCapabilitiesBeforeIfacesExist", new Response<>(0L),
+ () -> mWifiChip.getCapabilitiesBeforeIfacesExist());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()}
+ */
+ public Response<Long> getCapabilitiesAfterIfacesExist() {
+ return validateAndCall("getCapabilitiesAfterIfacesExist", new Response<>(0L),
+ () -> mWifiChip.getCapabilitiesAfterIfacesExist());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getDebugHostWakeReasonStats()}
+ */
+ @Nullable
+ public WlanWakeReasonAndCounts getDebugHostWakeReasonStats() {
+ return validateAndCall("getDebugHostWakeReasonStats", null,
+ () -> mWifiChip.getDebugHostWakeReasonStats());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getDebugRingBuffersStatus()}
+ */
+ @Nullable
+ public List<WifiNative.RingBufferStatus> getDebugRingBuffersStatus() {
+ return validateAndCall("getDebugRingBuffersStatus", null,
+ () -> mWifiChip.getDebugRingBuffersStatus());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getId()}
+ */
+ public int getId() {
+ return validateAndCall("getId", -1, () -> mWifiChip.getId());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getMode()}
+ */
+ public Response<Integer> getMode() {
+ return validateAndCall("getMode", new Response<>(0), () -> mWifiChip.getMode());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getNanIface(String)}
+ */
+ @Nullable
+ public WifiNanIface getNanIface(String ifaceName) {
+ return validateAndCall("getNanIface", null,
+ () -> mWifiChip.getNanIface(ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getNanIfaceNames()}
+ */
+ @Nullable
+ public List<String> getNanIfaceNames() {
+ return validateAndCall("getNanIfaceNames", null,
+ () -> mWifiChip.getNanIfaceNames());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getP2pIface(String)}
+ */
+ @Nullable
+ public WifiP2pIface getP2pIface(String ifaceName) {
+ return validateAndCall("getP2pIface", null,
+ () -> mWifiChip.getP2pIface(ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getP2pIfaceNames()}
+ */
+ @Nullable
+ public List<String> getP2pIfaceNames() {
+ return validateAndCall("getP2pIfaceNames", null,
+ () -> mWifiChip.getP2pIfaceNames());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getStaIface(String)}
+ */
+ @Nullable
+ public WifiStaIface getStaIface(String ifaceName) {
+ return validateAndCall("getStaIface", null,
+ () -> mWifiChip.getStaIface(ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getStaIfaceNames()}
+ */
+ @Nullable
+ public List<String> getStaIfaceNames() {
+ return validateAndCall("getStaIfaceNames", null,
+ () -> mWifiChip.getStaIfaceNames());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getSupportedRadioCombinationsMatrix()}
+ */
+ @Nullable
+ public WifiChip.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix() {
+ return validateAndCall("getSupportedRadioCombinationsMatrix", null,
+ () -> mWifiChip.getSupportedRadioCombinationsMatrix());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getUsableChannels(int, int, int)}
+ */
+ @Nullable
+ public List<WifiAvailableChannel> getUsableChannels(@WifiScanner.WifiBand int band,
+ @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter) {
+ return validateAndCall("getUsableChannels", null,
+ () -> mWifiChip.getUsableChannels(band, mode, filter));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#registerCallback(Callback)}
+ */
+ public boolean registerCallback(WifiChip.Callback callback) {
+ return validateAndCall("registerCallback", false,
+ () -> mWifiChip.registerCallback(callback));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeApIface(String)}
+ */
+ public boolean removeApIface(String ifaceName) {
+ return validateAndCall("removeApIface", false,
+ () -> mWifiChip.removeApIface(ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeIfaceInstanceFromBridgedApIface(String, String)}
+ */
+ public boolean removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName) {
+ return validateAndCall("removeIfaceInstanceFromBridgedApIface", false,
+ () -> mWifiChip.removeIfaceInstanceFromBridgedApIface(brIfaceName, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeNanIface(String)}
+ */
+ public boolean removeNanIface(String ifaceName) {
+ return validateAndCall("removeNanIface", false,
+ () -> mWifiChip.removeNanIface(ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeP2pIface(String)}
+ */
+ public boolean removeP2pIface(String ifaceName) {
+ return validateAndCall("removeP2pIface", false,
+ () -> mWifiChip.removeP2pIface(ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeStaIface(String)}
+ */
+ public boolean removeStaIface(String ifaceName) {
+ return validateAndCall("removeStaIface", false,
+ () -> mWifiChip.removeStaIface(ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#requestChipDebugInfo()}
+ */
+ @Nullable
+ public WifiChip.ChipDebugInfo requestChipDebugInfo() {
+ return validateAndCall("requestChipDebugInfo", null,
+ () -> mWifiChip.requestChipDebugInfo());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#requestDriverDebugDump()}
+ */
+ @Nullable
+ public byte[] requestDriverDebugDump() {
+ return validateAndCall("requestDriverDebugDump", null,
+ () -> mWifiChip.requestDriverDebugDump());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#requestFirmwareDebugDump()}
+ */
+ @Nullable
+ public byte[] requestFirmwareDebugDump() {
+ return validateAndCall("requestFirmwareDebugDump", null,
+ () -> mWifiChip.requestFirmwareDebugDump());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#resetTxPowerScenario()}
+ */
+ public boolean resetTxPowerScenario() {
+ return validateAndCall("resetTxPowerScenario", false,
+ () -> mWifiChip.resetTxPowerScenario());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#selectTxPowerScenario(SarInfo)}
+ */
+ public boolean selectTxPowerScenario(SarInfo sarInfo) {
+ return validateAndCall("selectTxPowerScenario", false,
+ () -> mWifiChip.selectTxPowerScenario(sarInfo));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setCoexUnsafeChannels(List, int)}
+ */
+ public boolean setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions) {
+ return validateAndCall("setCoexUnsafeChannels", false,
+ () -> mWifiChip.setCoexUnsafeChannels(unsafeChannels, restrictions));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setCountryCode(byte[])}
+ */
+ public boolean setCountryCode(String countryCode) {
+ if (countryCode == null || countryCode.length() != 2) {
+ Log.e(TAG, "Invalid country code " + countryCode);
+ return false;
+ }
+ try {
+ final byte[] code = NativeUtil.stringToByteArray(countryCode);
+ return validateAndCall("setCountryCode", false,
+ () -> mWifiChip.setCountryCode(code));
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Invalid country code " + countryCode + ", error: " + e);
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setLowLatencyMode(boolean)}
+ */
+ public boolean setLowLatencyMode(boolean enable) {
+ return validateAndCall("setLowLatencyMode", false,
+ () -> mWifiChip.setLowLatencyMode(enable));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setMultiStaPrimaryConnection(String)}
+ */
+ public boolean setMultiStaPrimaryConnection(String ifaceName) {
+ return validateAndCall("setMultiStaPrimaryConnection", false,
+ () -> mWifiChip.setMultiStaPrimaryConnection(ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setMultiStaUseCase(int)}
+ */
+ public boolean setMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) {
+ return validateAndCall("setMultiStaUseCase", false,
+ () -> mWifiChip.setMultiStaUseCase(useCase));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#startLoggingToDebugRingBuffer(String, int, int, int)}
+ */
+ public boolean startLoggingToDebugRingBuffer(String ringName, int verboseLevel,
+ int maxIntervalInSec, int minDataSizeInBytes) {
+ return validateAndCall("startLoggingToDebugRingBuffer", false,
+ () -> mWifiChip.startLoggingToDebugRingBuffer(ringName, verboseLevel,
+ maxIntervalInSec, minDataSizeInBytes));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#stopLoggingToDebugRingBuffer()}
+ */
+ public boolean stopLoggingToDebugRingBuffer() {
+ return validateAndCall("stopLoggingToDebugRingBuffer", false,
+ () -> mWifiChip.stopLoggingToDebugRingBuffer());
+ }
+
+ /**
+ * See comments for {@link IWifiChip#triggerSubsystemRestart()}
+ */
+ public boolean triggerSubsystemRestart() {
+ return validateAndCall("triggerSubsystemRestart", false,
+ () -> mWifiChip.triggerSubsystemRestart());
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java
new file mode 100644
index 0000000000..4d24379d18
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java
@@ -0,0 +1,1623 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static android.net.wifi.CoexUnsafeChannel.POWER_CAP_NONE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.wifi.IWifiApIface;
+import android.hardware.wifi.IWifiChip.ChipCapabilityMask;
+import android.hardware.wifi.IWifiChip.CoexRestriction;
+import android.hardware.wifi.IWifiChip.LatencyMode;
+import android.hardware.wifi.IWifiChip.MultiStaUseCase;
+import android.hardware.wifi.IWifiChip.TxPowerScenario;
+import android.hardware.wifi.IWifiChip.UsableChannelFilter;
+import android.hardware.wifi.IWifiChipEventCallback;
+import android.hardware.wifi.IWifiNanIface;
+import android.hardware.wifi.IWifiP2pIface;
+import android.hardware.wifi.IWifiRttController;
+import android.hardware.wifi.IWifiStaIface;
+import android.hardware.wifi.IfaceConcurrencyType;
+import android.hardware.wifi.IfaceType;
+import android.hardware.wifi.WifiAntennaMode;
+import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiDebugHostWakeReasonStats;
+import android.hardware.wifi.WifiDebugRingBufferFlags;
+import android.hardware.wifi.WifiDebugRingBufferStatus;
+import android.hardware.wifi.WifiIfaceMode;
+import android.hardware.wifi.WifiRadioCombination;
+import android.hardware.wifi.WifiRadioCombinationMatrix;
+import android.hardware.wifi.WifiRadioConfiguration;
+import android.hardware.wifi.WifiUsableChannel;
+import android.net.wifi.CoexUnsafeChannel;
+import android.net.wifi.WifiAvailableChannel;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiScanner;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.server.wifi.SarInfo;
+import com.android.server.wifi.SsidTranslator;
+import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.WlanWakeReasonAndCounts;
+import com.android.server.wifi.util.BitMask;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * AIDL implementation of the WifiChip interface.
+ */
+public class WifiChipAidlImpl implements IWifiChip {
+ private static final String TAG = "WifiChipAidlImpl";
+ private android.hardware.wifi.IWifiChip mWifiChip;
+ private android.hardware.wifi.IWifiChipEventCallback mHalCallback;
+ private WifiChip.Callback mFrameworkCallback;
+ private final Object mLock = new Object();
+ private Context mContext;
+ private SsidTranslator mSsidTranslator;
+
+ public WifiChipAidlImpl(@NonNull android.hardware.wifi.IWifiChip chip,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ mWifiChip = chip;
+ mContext = context;
+ mSsidTranslator = ssidTranslator;
+ }
+
+ /**
+ * See comments for {@link IWifiChip#configureChip(int)}
+ */
+ @Override
+ public boolean configureChip(int modeId) {
+ final String methodStr = "configureChip";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.configureChip(modeId);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createApIface()}
+ */
+ @Override
+ @Nullable
+ public WifiApIface createApIface() {
+ final String methodStr = "createApIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiApIface iface = mWifiChip.createApIface();
+ return new WifiApIface(iface);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createBridgedApIface()}
+ */
+ @Override
+ @Nullable
+ public WifiApIface createBridgedApIface() {
+ final String methodStr = "createBridgedApIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiApIface iface = mWifiChip.createBridgedApIface();
+ return new WifiApIface(iface);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createNanIface()}
+ */
+ @Override
+ @Nullable
+ public WifiNanIface createNanIface() {
+ final String methodStr = "createNanIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiNanIface iface = mWifiChip.createNanIface();
+ return new WifiNanIface(iface);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createP2pIface()}
+ */
+ @Override
+ @Nullable
+ public WifiP2pIface createP2pIface() {
+ final String methodStr = "createP2pIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiP2pIface iface = mWifiChip.createP2pIface();
+ return new WifiP2pIface(iface);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createRttController()}
+ */
+ @Override
+ @Nullable
+ public WifiRttController createRttController() {
+ final String methodStr = "createRttController";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiRttController rttController = mWifiChip.createRttController(null);
+ return new WifiRttController(rttController);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createStaIface()}
+ */
+ @Override
+ @Nullable
+ public WifiStaIface createStaIface() {
+ final String methodStr = "createStaIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiStaIface iface = mWifiChip.createStaIface();
+ return new WifiStaIface(iface, mContext, mSsidTranslator);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#enableDebugErrorAlerts(boolean)}
+ */
+ @Override
+ public boolean enableDebugErrorAlerts(boolean enable) {
+ final String methodStr = "enableDebugErrorAlerts";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.enableDebugErrorAlerts(enable);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#flushRingBufferToFile()}
+ */
+ @Override
+ public boolean flushRingBufferToFile() {
+ final String methodStr = "flushRingBufferToFile";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.flushRingBufferToFile();
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#forceDumpToDebugRingBuffer(String)}
+ */
+ @Override
+ public boolean forceDumpToDebugRingBuffer(String ringName) {
+ final String methodStr = "forceDumpToDebugRingBuffer";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.forceDumpToDebugRingBuffer(ringName);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getApIface(String)}
+ */
+ @Override
+ @Nullable
+ public WifiApIface getApIface(String ifaceName) {
+ final String methodStr = "getApIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiApIface iface = mWifiChip.getApIface(ifaceName);
+ return new WifiApIface(iface);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getApIfaceNames()}
+ */
+ @Override
+ @Nullable
+ public List<String> getApIfaceNames() {
+ final String methodStr = "getApIfaceNames";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ String[] ifaceNames = mWifiChip.getApIfaceNames();
+ return Arrays.asList(ifaceNames);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getAvailableModes()}
+ */
+ @Override
+ @Nullable
+ public List<WifiChip.ChipMode> getAvailableModes() {
+ final String methodStr = "getAvailableModes";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ android.hardware.wifi.IWifiChip.ChipMode[] halModes = mWifiChip.getAvailableModes();
+ return halToFrameworkChipModeList(halModes);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()}
+ */
+ @Override
+ public WifiChip.Response<Long> getCapabilitiesBeforeIfacesExist() {
+ final String methodStr = "getCapabilitiesBeforeIfacesExist";
+ return getCapabilitiesInternal(methodStr);
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()}
+ */
+ @Override
+ public WifiChip.Response<Long> getCapabilitiesAfterIfacesExist() {
+ final String methodStr = "getCapabilitiesAfterIfacesExist";
+ return getCapabilitiesInternal(methodStr);
+ }
+
+ private WifiChip.Response<Long> getCapabilitiesInternal(String methodStr) {
+ // getCapabilities uses the same logic in AIDL, regardless of whether the call
+ // happens before or after any interfaces have been created.
+ WifiChip.Response<Long> capsResp = new WifiChip.Response<>(0L);
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return capsResp;
+ long halCaps = mWifiChip.getCapabilities();
+ capsResp.setValue(halToFrameworkChipCapabilityMask(halCaps));
+ capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ capsResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ // TODO: convert to framework status code once WifiHalAidlImpl exists
+ capsResp.setStatusCode(e.errorCode);
+ }
+ return capsResp;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getDebugHostWakeReasonStats()}
+ */
+ @Override
+ @Nullable
+ public WlanWakeReasonAndCounts getDebugHostWakeReasonStats() {
+ final String methodStr = "getDebugHostWakeReasonStats";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ WifiDebugHostWakeReasonStats stats = mWifiChip.getDebugHostWakeReasonStats();
+ return halToFrameworkWakeReasons(stats);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getDebugRingBuffersStatus()}
+ */
+ @Override
+ @Nullable
+ public List<WifiNative.RingBufferStatus> getDebugRingBuffersStatus() {
+ final String methodStr = "getDebugRingBuffersStatus";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ WifiDebugRingBufferStatus[] stats = mWifiChip.getDebugRingBuffersStatus();
+ return halToFrameworkRingBufferStatusList(stats);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ handleIllegalArgumentException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getId()}
+ */
+ @Override
+ public int getId() {
+ final String methodStr = "getId";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return -1;
+ return mWifiChip.getId();
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return -1;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getMode()}
+ */
+ @Override
+ public WifiChip.Response<Integer> getMode() {
+ final String methodStr = "getMode";
+ WifiChip.Response<Integer> modeResp = new WifiChip.Response<>(0);
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return modeResp;
+ int mode = mWifiChip.getMode();
+ modeResp.setValue(mode);
+ modeResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ modeResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ // TODO: convert to framework status code once WifiHalAidlImpl exists
+ modeResp.setStatusCode(e.errorCode);
+ }
+ return modeResp;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getNanIface(String)}
+ */
+ @Override
+ @Nullable
+ public WifiNanIface getNanIface(String ifaceName) {
+ final String methodStr = "getNanIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiNanIface iface = mWifiChip.getNanIface(ifaceName);
+ return new WifiNanIface(iface);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getNanIfaceNames()}
+ */
+ @Override
+ @Nullable
+ public List<String> getNanIfaceNames() {
+ final String methodStr = "getNanIfaceNames";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ String[] ifaceNames = mWifiChip.getNanIfaceNames();
+ return Arrays.asList(ifaceNames);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getP2pIface(String)}
+ */
+ @Override
+ @Nullable
+ public WifiP2pIface getP2pIface(String ifaceName) {
+ final String methodStr = "getP2pIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiP2pIface iface = mWifiChip.getP2pIface(ifaceName);
+ return new WifiP2pIface(iface);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getP2pIfaceNames()}
+ */
+ @Override
+ @Nullable
+ public List<String> getP2pIfaceNames() {
+ final String methodStr = "getP2pIfaceNames";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ String[] ifaceNames = mWifiChip.getP2pIfaceNames();
+ return Arrays.asList(ifaceNames);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getStaIface(String)}
+ */
+ @Override
+ @Nullable
+ public WifiStaIface getStaIface(String ifaceName) {
+ final String methodStr = "getStaIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ IWifiStaIface iface = mWifiChip.getStaIface(ifaceName);
+ return new WifiStaIface(iface, mContext, mSsidTranslator);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getStaIfaceNames()}
+ */
+ @Override
+ @Nullable
+ public List<String> getStaIfaceNames() {
+ final String methodStr = "getStaIfaceNames";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ String[] ifaceNames = mWifiChip.getStaIfaceNames();
+ return Arrays.asList(ifaceNames);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getSupportedRadioCombinationsMatrix()}
+ */
+ @Override
+ @Nullable
+ public WifiChip.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix() {
+ final String methodStr = "getSupportedRadioCombinationsMatrix";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ WifiRadioCombinationMatrix halMatrix =
+ mWifiChip.getSupportedRadioCombinationsMatrix();
+ return halToFrameworkRadioCombinationMatrix(halMatrix);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getUsableChannels(int, int, int)}
+ */
+ @Override
+ @Nullable
+ public List<WifiAvailableChannel> getUsableChannels(@WifiScanner.WifiBand int band,
+ @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter) {
+ final String methodStr = "getUsableChannels";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ WifiUsableChannel[] halChannels = mWifiChip.getUsableChannels(
+ frameworkToHalWifiBand(band),
+ frameworkToHalIfaceMode(mode),
+ frameworkToHalUsableFilter(filter));
+ List<WifiAvailableChannel> frameworkChannels = new ArrayList<>();
+ for (WifiUsableChannel ch : halChannels) {
+ frameworkChannels.add(new WifiAvailableChannel(
+ ch.channel, halToFrameworkIfaceMode(ch.ifaceModeMask)));
+ }
+ return frameworkChannels;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ handleIllegalArgumentException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#registerCallback(WifiChip.Callback)}
+ */
+ @Override
+ public boolean registerCallback(WifiChip.Callback callback) {
+ final String methodStr = "registerCallback";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ if (mFrameworkCallback != null) {
+ Log.e(TAG, "Framework callback is already registered");
+ return false;
+ } else if (callback == null) {
+ Log.e(TAG, "Cannot register a null callback");
+ return false;
+ }
+
+ try {
+ mHalCallback = new ChipEventCallback();
+ mWifiChip.registerEventCallback(mHalCallback);
+ mFrameworkCallback = callback;
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeApIface(String)}
+ */
+ @Override
+ public boolean removeApIface(String ifaceName) {
+ final String methodStr = "removeApIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.removeApIface(ifaceName);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeIfaceInstanceFromBridgedApIface(String, String)}
+ */
+ @Override
+ public boolean removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName) {
+ final String methodStr = "removeIfaceInstanceFromBridgedApIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.removeIfaceInstanceFromBridgedApIface(brIfaceName, ifaceName);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeNanIface(String)}
+ */
+ @Override
+ public boolean removeNanIface(String ifaceName) {
+ final String methodStr = "removeNanIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.removeNanIface(ifaceName);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeP2pIface(String)}
+ */
+ @Override
+ public boolean removeP2pIface(String ifaceName) {
+ final String methodStr = "removeP2pIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.removeP2pIface(ifaceName);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeStaIface(String)}
+ */
+ @Override
+ public boolean removeStaIface(String ifaceName) {
+ final String methodStr = "removeStaIface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.removeStaIface(ifaceName);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#requestChipDebugInfo()}
+ */
+ @Override
+ @Nullable
+ public WifiChip.ChipDebugInfo requestChipDebugInfo() {
+ final String methodStr = "requestChipDebugInfo";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ android.hardware.wifi.IWifiChip.ChipDebugInfo info =
+ mWifiChip.requestChipDebugInfo();
+ return new WifiChip.ChipDebugInfo(info.driverDescription, info.firmwareDescription);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#requestDriverDebugDump()}
+ */
+ @Override
+ @Nullable
+ public byte[] requestDriverDebugDump() {
+ final String methodStr = "requestDriverDebugDump";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ return mWifiChip.requestDriverDebugDump();
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#requestFirmwareDebugDump()}
+ */
+ @Override
+ @Nullable
+ public byte[] requestFirmwareDebugDump() {
+ final String methodStr = "requestFirmwareDebugDump";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ return mWifiChip.requestFirmwareDebugDump();
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#resetTxPowerScenario()}
+ */
+ @Override
+ public boolean resetTxPowerScenario() {
+ final String methodStr = "resetTxPowerScenario";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.resetTxPowerScenario();
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#selectTxPowerScenario(SarInfo)}
+ */
+ @Override
+ public boolean selectTxPowerScenario(SarInfo sarInfo) {
+ final String methodStr = "selectTxPowerScenario";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ if (sarPowerBackoffRequired(sarInfo)) {
+ // Power backoff is needed, so calculate and set the required scenario.
+ int halScenario = frameworkToHalTxPowerScenario(sarInfo);
+ if (sarInfo.setSarScenarioNeeded(halScenario)) {
+ Log.d(TAG, "Attempting to set SAR scenario to " + halScenario);
+ mWifiChip.selectTxPowerScenario(halScenario);
+ }
+ // Reaching here means that setting SAR scenario would be redundant,
+ // do nothing and return with success.
+ return true;
+ }
+
+ // We don't need to perform power backoff, so attempt to reset the SAR scenario.
+ if (sarInfo.resetSarScenarioNeeded()) {
+ Log.d(TAG, "Attempting to reset the SAR scenario");
+ mWifiChip.resetTxPowerScenario();
+ }
+
+ // If no if-statement was executed, then setting/resetting the SAR scenario would
+ // have been redundant. Do nothing and return with success.
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ handleIllegalArgumentException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setCoexUnsafeChannels(List, int)}
+ */
+ @Override
+ public boolean setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions) {
+ final String methodStr = "setCoexUnsafeChannels";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] halChannels =
+ frameworkToHalCoexUnsafeChannels(unsafeChannels);
+ int halRestrictions = frameworkToHalCoexRestrictions(restrictions);
+ mWifiChip.setCoexUnsafeChannels(halChannels, halRestrictions);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setCountryCode(byte[])}
+ */
+ @Override
+ public boolean setCountryCode(byte[] code) {
+ final String methodStr = "setCountryCode";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.setCountryCode(code);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setLowLatencyMode(boolean)}
+ */
+ @Override
+ public boolean setLowLatencyMode(boolean enable) {
+ final String methodStr = "setLowLatencyMode";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ int mode = enable ? LatencyMode.LOW : LatencyMode.NORMAL;
+ mWifiChip.setLatencyMode(mode);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setMultiStaPrimaryConnection(String)}
+ */
+ @Override
+ public boolean setMultiStaPrimaryConnection(String ifaceName) {
+ final String methodStr = "setMultiStaPrimaryConnection";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.setMultiStaPrimaryConnection(ifaceName);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setMultiStaUseCase(int)}
+ */
+ @Override
+ public boolean setMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) {
+ final String methodStr = "setMultiStaUseCase";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.setMultiStaUseCase(frameworkToHalMultiStaUseCase(useCase));
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ handleIllegalArgumentException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#startLoggingToDebugRingBuffer(String, int, int, int)}
+ */
+ @Override
+ public boolean startLoggingToDebugRingBuffer(String ringName, int verboseLevel,
+ int maxIntervalInSec, int minDataSizeInBytes) {
+ final String methodStr = "startLoggingToDebugRingBuffer";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.startLoggingToDebugRingBuffer(
+ ringName, verboseLevel, maxIntervalInSec, minDataSizeInBytes);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#stopLoggingToDebugRingBuffer()}
+ */
+ @Override
+ public boolean stopLoggingToDebugRingBuffer() {
+ final String methodStr = "stopLoggingToDebugRingBuffer";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.stopLoggingToDebugRingBuffer();
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiChip#triggerSubsystemRestart()}
+ */
+ @Override
+ public boolean triggerSubsystemRestart() {
+ final String methodStr = "triggerSubsystemRestart";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiChip.triggerSubsystemRestart();
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ private class ChipEventCallback extends IWifiChipEventCallback.Stub {
+ @Override
+ public void onChipReconfigured(int modeId) throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onChipReconfigured(modeId);
+ }
+
+ @Override
+ public void onChipReconfigureFailure(int statusCode) {
+ if (mFrameworkCallback == null) return;
+ // TODO: convert to framework status code once WifiHalAidlImpl exists
+ mFrameworkCallback.onChipReconfigureFailure(statusCode);
+ }
+
+ @Override
+ public void onIfaceAdded(int type, String name) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onIfaceAdded(halToFrameworkIfaceType(type), name);
+ }
+
+ @Override
+ public void onIfaceRemoved(int type, String name) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onIfaceRemoved(halToFrameworkIfaceType(type), name);
+ }
+
+ @Override
+ public void onDebugRingBufferDataAvailable(WifiDebugRingBufferStatus status, byte[] data) {
+ if (mFrameworkCallback == null) return;
+ try {
+ mFrameworkCallback.onDebugRingBufferDataAvailable(
+ halToFrameworkRingBufferStatus(status), data);
+ } catch (IllegalArgumentException e) {
+ handleIllegalArgumentException(e, "onDebugRingBufferDataAvailable");
+ }
+ }
+
+ @Override
+ public void onDebugErrorAlert(int errorCode, byte[] debugData) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onDebugErrorAlert(errorCode, debugData);
+ }
+
+ @Override
+ public void onRadioModeChange(RadioModeInfo[] radioModeInfoList) {
+ if (mFrameworkCallback == null) return;
+ List<WifiChip.RadioModeInfo> frameworkRadioModeInfos = new ArrayList<>();
+ for (RadioModeInfo radioInfo : radioModeInfoList) {
+ List<WifiChip.IfaceInfo> frameworkIfaceInfos = new ArrayList<>();
+ for (IfaceInfo ifaceInfo : radioInfo.ifaceInfos) {
+ frameworkIfaceInfos.add(
+ new WifiChip.IfaceInfo(ifaceInfo.name, ifaceInfo.channel));
+ }
+ frameworkRadioModeInfos.add(
+ new WifiChip.RadioModeInfo(
+ radioInfo.radioId, radioInfo.bandInfo, frameworkIfaceInfos));
+ }
+ mFrameworkCallback.onRadioModeChange(frameworkRadioModeInfos);
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return IWifiChipEventCallback.HASH;
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return IWifiChipEventCallback.VERSION;
+ }
+ }
+
+
+ // Utilities
+
+ private static @WifiChip.IfaceConcurrencyType int halToFrameworkIfaceConcurrencyType(int type) {
+ switch (type) {
+ case IfaceConcurrencyType.STA:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_STA;
+ case IfaceConcurrencyType.AP:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_AP;
+ case IfaceConcurrencyType.AP_BRIDGED:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED;
+ case IfaceConcurrencyType.P2P:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_P2P;
+ case IfaceConcurrencyType.NAN_IFACE:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_NAN;
+ default:
+ Log.e(TAG, "Invalid IfaceConcurrencyType received: " + type);
+ return -1;
+ }
+ }
+
+ private static @WifiChip.IfaceType int halToFrameworkIfaceType(int type) {
+ switch (type) {
+ case IfaceType.STA:
+ return WifiChip.IFACE_TYPE_STA;
+ case IfaceType.AP:
+ return WifiChip.IFACE_TYPE_AP;
+ case IfaceType.P2P:
+ return WifiChip.IFACE_TYPE_P2P;
+ case IfaceType.NAN_IFACE:
+ return WifiChip.IFACE_TYPE_NAN;
+ default:
+ Log.e(TAG, "Invalid IfaceType received: " + type);
+ return -1;
+ }
+ }
+
+ private static @Nullable List<WifiNative.RingBufferStatus> halToFrameworkRingBufferStatusList(
+ WifiDebugRingBufferStatus[] ringBuffers) throws IllegalArgumentException {
+ if (ringBuffers == null) return null;
+ List<WifiNative.RingBufferStatus> ans = new ArrayList<>();
+ for (WifiDebugRingBufferStatus b : ringBuffers) {
+ ans.add(halToFrameworkRingBufferStatus(b));
+ }
+ return ans;
+ }
+
+ private static WifiNative.RingBufferStatus halToFrameworkRingBufferStatus(
+ WifiDebugRingBufferStatus h) throws IllegalArgumentException {
+ WifiNative.RingBufferStatus ans = new WifiNative.RingBufferStatus();
+ ans.name = h.ringName;
+ ans.flag = halToFrameworkRingBufferFlags(h.flags);
+ ans.ringBufferId = h.ringId;
+ ans.ringBufferByteSize = h.sizeInBytes;
+ ans.verboseLevel = h.verboseLevel;
+ // Remaining fields are unavailable
+ // writtenBytes;
+ // readBytes;
+ // writtenRecords;
+ return ans;
+ }
+
+ private static int halToFrameworkRingBufferFlags(int wifiDebugRingBufferFlag)
+ throws IllegalArgumentException {
+ BitMask checkoff = new BitMask(wifiDebugRingBufferFlag);
+ int flags = 0;
+ if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES)) {
+ flags |= WifiNative.RingBufferStatus.HAS_BINARY_ENTRIES;
+ }
+ if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES)) {
+ flags |= WifiNative.RingBufferStatus.HAS_ASCII_ENTRIES;
+ }
+ if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES)) {
+ flags |= WifiNative.RingBufferStatus.HAS_PER_PACKET_ENTRIES;
+ }
+ if (checkoff.value != 0) {
+ throw new IllegalArgumentException("Unknown WifiDebugRingBufferFlag " + checkoff.value);
+ }
+ return flags;
+ }
+
+ private static WlanWakeReasonAndCounts halToFrameworkWakeReasons(
+ WifiDebugHostWakeReasonStats h) {
+ if (h == null) return null;
+ WlanWakeReasonAndCounts ans = new WlanWakeReasonAndCounts();
+ ans.totalCmdEventWake = h.totalCmdEventWakeCnt;
+ ans.totalDriverFwLocalWake = h.totalDriverFwLocalWakeCnt;
+ ans.totalRxDataWake = h.totalRxPacketWakeCnt;
+ ans.rxUnicast = h.rxPktWakeDetails.rxUnicastCnt;
+ ans.rxMulticast = h.rxPktWakeDetails.rxMulticastCnt;
+ ans.rxBroadcast = h.rxPktWakeDetails.rxBroadcastCnt;
+ ans.icmp = h.rxIcmpPkWakeDetails.icmpPkt;
+ ans.icmp6 = h.rxIcmpPkWakeDetails.icmp6Pkt;
+ ans.icmp6Ra = h.rxIcmpPkWakeDetails.icmp6Ra;
+ ans.icmp6Na = h.rxIcmpPkWakeDetails.icmp6Na;
+ ans.icmp6Ns = h.rxIcmpPkWakeDetails.icmp6Ns;
+ ans.ipv4RxMulticast = h.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt;
+ ans.ipv6Multicast = h.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt;
+ ans.otherRxMulticast = h.rxMulticastPkWakeDetails.otherRxMulticastAddrCnt;
+ ans.cmdEventWakeCntArray = h.cmdEventWakeCntPerType;
+ ans.driverFWLocalWakeCntArray = h.driverFwLocalWakeCntPerType;
+ return ans;
+ }
+
+ private static byte frameworkToHalMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase)
+ throws IllegalArgumentException {
+ switch (useCase) {
+ case WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY:
+ return MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+ case WifiNative.DUAL_STA_NON_TRANSIENT_UNBIASED:
+ return MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED;
+ default:
+ throw new IllegalArgumentException("Invalid use case " + useCase);
+ }
+ }
+
+ private static @NonNull android.hardware.wifi.IWifiChip.CoexUnsafeChannel[]
+ frameworkToHalCoexUnsafeChannels(
+ @NonNull List<android.net.wifi.CoexUnsafeChannel> frameworkUnsafeChannels) {
+ final ArrayList<android.hardware.wifi.IWifiChip.CoexUnsafeChannel> halList =
+ new ArrayList<>();
+ if (!SdkLevel.isAtLeastS()) {
+ return new android.hardware.wifi.IWifiChip.CoexUnsafeChannel[0];
+ }
+ for (android.net.wifi.CoexUnsafeChannel frameworkUnsafeChannel : frameworkUnsafeChannels) {
+ final android.hardware.wifi.IWifiChip.CoexUnsafeChannel halUnsafeChannel =
+ new android.hardware.wifi.IWifiChip.CoexUnsafeChannel();
+ switch (frameworkUnsafeChannel.getBand()) {
+ case (WifiScanner.WIFI_BAND_24_GHZ):
+ halUnsafeChannel.band = WifiBand.BAND_24GHZ;
+ break;
+ case (WifiScanner.WIFI_BAND_5_GHZ):
+ halUnsafeChannel.band = WifiBand.BAND_5GHZ;
+ break;
+ case (WifiScanner.WIFI_BAND_6_GHZ):
+ halUnsafeChannel.band = WifiBand.BAND_6GHZ;
+ break;
+ case (WifiScanner.WIFI_BAND_60_GHZ):
+ halUnsafeChannel.band = WifiBand.BAND_60GHZ;
+ break;
+ default:
+ Log.e(TAG, "Tried to set unsafe channel with unknown band: "
+ + frameworkUnsafeChannel.getBand());
+ continue;
+ }
+ halUnsafeChannel.channel = frameworkUnsafeChannel.getChannel();
+ final int powerCapDbm = frameworkUnsafeChannel.getPowerCapDbm();
+ if (powerCapDbm != POWER_CAP_NONE) {
+ halUnsafeChannel.powerCapDbm = powerCapDbm;
+ } else {
+ halUnsafeChannel.powerCapDbm =
+ android.hardware.wifi.IWifiChip.NO_POWER_CAP_CONSTANT;
+ }
+ halList.add(halUnsafeChannel);
+ }
+
+ android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] halArray =
+ new android.hardware.wifi.IWifiChip.CoexUnsafeChannel[halList.size()];
+ for (int i = 0; i < halList.size(); i++) {
+ halArray[i] = halList.get(i);
+ }
+ return halArray;
+ }
+
+ private static int frameworkToHalCoexRestrictions(
+ @WifiManager.CoexRestriction int restrictions) {
+ int halRestrictions = 0;
+ if (!SdkLevel.isAtLeastS()) {
+ return halRestrictions;
+ }
+ if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_DIRECT) != 0) {
+ halRestrictions |= CoexRestriction.WIFI_DIRECT;
+ }
+ if ((restrictions & WifiManager.COEX_RESTRICTION_SOFTAP) != 0) {
+ halRestrictions |= CoexRestriction.SOFTAP;
+ }
+ if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_AWARE) != 0) {
+ halRestrictions |= CoexRestriction.WIFI_AWARE;
+ }
+ return halRestrictions;
+ }
+
+ /**
+ * Check if we need to backoff wifi Tx power due to SAR requirements.
+ */
+ private static boolean sarPowerBackoffRequired(SarInfo sarInfo) {
+ if (sarInfo.sarSapSupported && sarInfo.isWifiSapEnabled) {
+ return true;
+ }
+ if (sarInfo.sarVoiceCallSupported && (sarInfo.isVoiceCall || sarInfo.isEarPieceActive)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Maps the information in the SarInfo instance to a TxPowerScenario.
+ * If SAR SoftAP input is supported, we make these assumptions:
+ * - All voice calls are treated as if device is near the head.
+ * - SoftAP scenario is treated as if device is near the body.
+ * If SoftAP is not supported, the only valid scenario is when a voice call is ongoing.
+ */
+ private static int frameworkToHalTxPowerScenario(SarInfo sarInfo)
+ throws IllegalArgumentException {
+ if (sarInfo.sarSapSupported && sarInfo.sarVoiceCallSupported) {
+ if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) {
+ return TxPowerScenario.ON_HEAD_CELL_ON;
+ } else if (sarInfo.isWifiSapEnabled) {
+ return TxPowerScenario.ON_BODY_CELL_ON;
+ } else {
+ throw new IllegalArgumentException("bad scenario: no voice call/softAP active");
+ }
+ } else if (sarInfo.sarVoiceCallSupported) {
+ if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) {
+ return TxPowerScenario.VOICE_CALL;
+ } else {
+ throw new IllegalArgumentException("bad scenario: voice call not active");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid case: voice call not supported");
+ }
+ }
+
+ private static int frameworkToHalWifiBand(int frameworkBand) throws IllegalArgumentException {
+ switch (frameworkBand) {
+ case WifiScanner.WIFI_BAND_UNSPECIFIED:
+ return WifiBand.BAND_UNSPECIFIED;
+ case WifiScanner.WIFI_BAND_24_GHZ:
+ return WifiBand.BAND_24GHZ;
+ case WifiScanner.WIFI_BAND_5_GHZ:
+ return WifiBand.BAND_5GHZ;
+ case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY:
+ return WifiBand.BAND_5GHZ_DFS;
+ case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS:
+ return WifiBand.BAND_5GHZ_WITH_DFS;
+ case WifiScanner.WIFI_BAND_BOTH:
+ return WifiBand.BAND_24GHZ_5GHZ;
+ case WifiScanner.WIFI_BAND_BOTH_WITH_DFS:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS;
+ case WifiScanner.WIFI_BAND_6_GHZ:
+ return WifiBand.BAND_6GHZ;
+ case WifiScanner.WIFI_BAND_24_5_6_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_6GHZ;
+ case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ;
+ case WifiScanner.WIFI_BAND_60_GHZ:
+ return WifiBand.BAND_60GHZ;
+ case WifiScanner.WIFI_BAND_24_5_6_60_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_6GHZ_60GHZ;
+ case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ;
+ case WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS:
+ default:
+ throw new IllegalArgumentException("bad band " + frameworkBand);
+ }
+ }
+
+ private static int frameworkToHalIfaceMode(@WifiAvailableChannel.OpMode int mode) {
+ int halMode = 0;
+ if ((mode & WifiAvailableChannel.OP_MODE_STA) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_STA;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_SAP) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_SOFTAP;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_P2P_CLIENT;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_P2P_GO;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_WIFI_AWARE) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_NAN;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_TDLS) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_TDLS;
+ }
+ return halMode;
+ }
+
+ private static @WifiAvailableChannel.OpMode int halToFrameworkIfaceMode(int halMode) {
+ int mode = 0;
+ if ((halMode & WifiIfaceMode.IFACE_MODE_STA) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_STA;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_SOFTAP) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_SAP;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_CLIENT) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_GO) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_NAN) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_WIFI_AWARE;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_TDLS) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_TDLS;
+ }
+ return mode;
+ }
+
+ private static int frameworkToHalUsableFilter(@WifiAvailableChannel.Filter int filter) {
+ int halFilter = 0; // O implies no additional filter other than regulatory (default)
+ if ((filter & WifiAvailableChannel.FILTER_CONCURRENCY) != 0) {
+ halFilter |= UsableChannelFilter.CONCURRENCY;
+ }
+ if ((filter & WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE) != 0) {
+ halFilter |= UsableChannelFilter.CELLULAR_COEXISTENCE;
+ }
+ if ((filter & WifiAvailableChannel.FILTER_NAN_INSTANT_MODE) != 0) {
+ halFilter |= UsableChannelFilter.NAN_INSTANT_MODE;
+ }
+
+ return halFilter;
+ }
+
+ private static boolean bitmapContains(long bitmap, long expectedBit) {
+ return (bitmap & expectedBit) != 0;
+ }
+
+ @VisibleForTesting
+ protected static long halToFrameworkChipCapabilityMask(long halCaps) {
+ long frameworkCaps = 0;
+ if (bitmapContains(halCaps, ChipCapabilityMask.SET_TX_POWER_LIMIT)) {
+ frameworkCaps |= WifiManager.WIFI_FEATURE_TX_POWER_LIMIT;
+ }
+ if (bitmapContains(halCaps, ChipCapabilityMask.D2D_RTT)) {
+ frameworkCaps |= WifiManager.WIFI_FEATURE_D2D_RTT;
+ }
+ if (bitmapContains(halCaps, ChipCapabilityMask.D2AP_RTT)) {
+ frameworkCaps |= WifiManager.WIFI_FEATURE_D2AP_RTT;
+ }
+ if (bitmapContains(halCaps, ChipCapabilityMask.SET_LATENCY_MODE)) {
+ frameworkCaps |= WifiManager.WIFI_FEATURE_LOW_LATENCY;
+ }
+ if (bitmapContains(halCaps, ChipCapabilityMask.P2P_RAND_MAC)) {
+ frameworkCaps |= WifiManager.WIFI_FEATURE_P2P_RAND_MAC;
+ }
+ if (bitmapContains(halCaps, ChipCapabilityMask.WIGIG)) {
+ frameworkCaps |= WifiManager.WIFI_FEATURE_INFRA_60G;
+ }
+ return frameworkCaps;
+ }
+
+ private static int halToFrameworkWifiBand(int halBand) {
+ int frameworkBand = 0;
+ if (bitmapContains(halBand, WifiBand.BAND_24GHZ)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_24_GHZ;
+ }
+ if (bitmapContains(halBand, WifiBand.BAND_5GHZ)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ;
+ }
+ if (bitmapContains(halBand, WifiBand.BAND_5GHZ_DFS)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY;
+ }
+ if (bitmapContains(halBand, WifiBand.BAND_6GHZ)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_6_GHZ;
+ }
+ if (bitmapContains(halBand, WifiBand.BAND_60GHZ)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_60_GHZ;
+ }
+ return frameworkBand;
+ }
+
+ private static @WifiChip.WifiAntennaMode int halToFrameworkAntennaMode(int mode) {
+ switch (mode) {
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_UNSPECIFIED:
+ return WifiChip.WIFI_ANTENNA_MODE_UNSPECIFIED;
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_1X1:
+ return WifiChip.WIFI_ANTENNA_MODE_1X1;
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_2X2:
+ return WifiChip.WIFI_ANTENNA_MODE_2X2;
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_3X3:
+ return WifiChip.WIFI_ANTENNA_MODE_3X3;
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_4X4:
+ return WifiChip.WIFI_ANTENNA_MODE_4X4;
+ default:
+ Log.e(TAG, "Invalid WifiAntennaMode: " + mode);
+ return WifiChip.WIFI_ANTENNA_MODE_UNSPECIFIED;
+ }
+ }
+
+ private static List<WifiChip.ChipMode> halToFrameworkChipModeList(
+ android.hardware.wifi.IWifiChip.ChipMode[] halModes) {
+ List<WifiChip.ChipMode> frameworkModes = new ArrayList<>();
+ for (android.hardware.wifi.IWifiChip.ChipMode halMode : halModes) {
+ frameworkModes.add(halToFrameworkChipMode(halMode));
+ }
+ return frameworkModes;
+ }
+
+ private static WifiChip.ChipMode halToFrameworkChipMode(
+ android.hardware.wifi.IWifiChip.ChipMode halMode) {
+ List<WifiChip.ChipConcurrencyCombination> frameworkCombos = new ArrayList<>();
+ for (android.hardware.wifi.IWifiChip.ChipConcurrencyCombination halCombo :
+ halMode.availableCombinations) {
+ frameworkCombos.add(halToFrameworkChipConcurrencyCombination(halCombo));
+ }
+ return new WifiChip.ChipMode(halMode.id, frameworkCombos);
+ }
+
+ private static WifiChip.ChipConcurrencyCombination halToFrameworkChipConcurrencyCombination(
+ android.hardware.wifi.IWifiChip.ChipConcurrencyCombination halCombo) {
+ List<WifiChip.ChipConcurrencyCombinationLimit> frameworkLimits = new ArrayList<>();
+ for (android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit halLimit :
+ halCombo.limits) {
+ frameworkLimits.add(halToFrameworkChipConcurrencyCombinationLimit(halLimit));
+ }
+ return new WifiChip.ChipConcurrencyCombination(frameworkLimits);
+ }
+
+ private static WifiChip.ChipConcurrencyCombinationLimit
+ halToFrameworkChipConcurrencyCombinationLimit(
+ android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit halLimit) {
+ List<Integer> frameworkTypes = new ArrayList<>();
+ for (int halType : halLimit.types) {
+ frameworkTypes.add(halToFrameworkIfaceConcurrencyType(halType));
+ }
+ return new WifiChip.ChipConcurrencyCombinationLimit(halLimit.maxIfaces, frameworkTypes);
+ }
+
+ private static WifiChip.WifiRadioCombinationMatrix halToFrameworkRadioCombinationMatrix(
+ WifiRadioCombinationMatrix halMatrix) {
+ List<WifiChip.WifiRadioCombination> frameworkCombos = new ArrayList<>();
+ for (WifiRadioCombination combo : halMatrix.radioCombinations) {
+ frameworkCombos.add(halToFrameworkRadioCombination(combo));
+ }
+ return new WifiChip.WifiRadioCombinationMatrix(frameworkCombos);
+ }
+
+ private static WifiChip.WifiRadioCombination halToFrameworkRadioCombination(
+ WifiRadioCombination halCombo) {
+ List<WifiChip.WifiRadioConfiguration> frameworkConfigs = new ArrayList<>();
+ for (WifiRadioConfiguration config : halCombo.radioConfigurations) {
+ frameworkConfigs.add(halToFrameworkRadioConfiguration(config));
+ }
+ return new WifiChip.WifiRadioCombination(frameworkConfigs);
+ }
+
+ private static WifiChip.WifiRadioConfiguration halToFrameworkRadioConfiguration(
+ WifiRadioConfiguration halConfig) {
+ return new WifiChip.WifiRadioConfiguration(halToFrameworkWifiBand(halConfig.bandInfo),
+ halToFrameworkAntennaMode(halConfig.antennaMode));
+ }
+
+ private boolean checkIfaceAndLogFailure(String methodStr) {
+ if (mWifiChip == null) {
+ Log.e(TAG, "Unable to call " + methodStr + " because iface is null.");
+ return false;
+ }
+ return true;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ mWifiChip = null;
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ }
+
+ private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with service-specific exception: " + e);
+ }
+
+ private void handleIllegalArgumentException(IllegalArgumentException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with illegal argument exception: " + e);
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiChipHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiChipHidlImpl.java
new file mode 100644
index 0000000000..4110bd06ca
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiChipHidlImpl.java
@@ -0,0 +1,2292 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static android.net.wifi.CoexUnsafeChannel.POWER_CAP_NONE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.hardware.wifi.V1_0.IWifiChipEventCallback;
+import android.hardware.wifi.V1_0.IfaceType;
+import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
+import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
+import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
+import android.hardware.wifi.V1_0.WifiStatus;
+import android.hardware.wifi.V1_0.WifiStatusCode;
+import android.hardware.wifi.V1_5.WifiBand;
+import android.hardware.wifi.V1_5.WifiIfaceMode;
+import android.hardware.wifi.V1_6.IfaceConcurrencyType;
+import android.hardware.wifi.V1_6.WifiAntennaMode;
+import android.hardware.wifi.V1_6.WifiRadioCombination;
+import android.hardware.wifi.V1_6.WifiRadioCombinationMatrix;
+import android.hardware.wifi.V1_6.WifiRadioConfiguration;
+import android.net.wifi.CoexUnsafeChannel;
+import android.net.wifi.WifiAvailableChannel;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiScanner;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.SparseIntArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.server.wifi.SarInfo;
+import com.android.server.wifi.SsidTranslator;
+import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.WlanWakeReasonAndCounts;
+import com.android.server.wifi.util.BitMask;
+import com.android.server.wifi.util.GeneralUtil.Mutable;
+import com.android.server.wifi.util.NativeUtil;
+import com.android.wifi.resources.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * HIDL implementation of the WifiChip interface.
+ */
+public class WifiChipHidlImpl implements IWifiChip {
+ private static final String TAG = "WifiChipHidlImpl";
+ private android.hardware.wifi.V1_0.IWifiChip mWifiChip;
+ private android.hardware.wifi.V1_0.IWifiChipEventCallback mHalCallback10;
+ private android.hardware.wifi.V1_2.IWifiChipEventCallback mHalCallback12;
+ private android.hardware.wifi.V1_4.IWifiChipEventCallback mHalCallback14;
+ private WifiChip.Callback mFrameworkCallback;
+ private Context mContext;
+ private SsidTranslator mSsidTranslator;
+ private boolean mIsBridgedSoftApSupported;
+ private boolean mIsStaWithBridgedSoftApConcurrencySupported;
+
+ public WifiChipHidlImpl(@NonNull android.hardware.wifi.V1_0.IWifiChip chip,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ mWifiChip = chip;
+ mContext = context;
+ mSsidTranslator = ssidTranslator;
+ Resources res = context.getResources();
+ mIsBridgedSoftApSupported = res.getBoolean(R.bool.config_wifiBridgedSoftApSupported);
+ mIsStaWithBridgedSoftApConcurrencySupported =
+ res.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported);
+ }
+
+ /**
+ * See comments for {@link IWifiChip#configureChip(int)}
+ */
+ @Override
+ public boolean configureChip(int modeId) {
+ String methodStr = "configureChip";
+ return validateAndCall(methodStr, false,
+ () -> configureChipInternal(methodStr, modeId));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createApIface()}
+ */
+ @Override
+ @Nullable
+ public WifiApIface createApIface() {
+ String methodStr = "createApIface";
+ return validateAndCall(methodStr, null,
+ () -> createApIfaceInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createBridgedApIface()}
+ */
+ @Override
+ @Nullable
+ public WifiApIface createBridgedApIface() {
+ String methodStr = "createBridgedApIface";
+ return validateAndCall(methodStr, null,
+ () -> createBridgedApIfaceInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createNanIface()}
+ */
+ @Override
+ @Nullable
+ public WifiNanIface createNanIface() {
+ String methodStr = "createNanIface";
+ return validateAndCall(methodStr, null,
+ () -> createNanIfaceInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createP2pIface()}
+ */
+ @Override
+ @Nullable
+ public WifiP2pIface createP2pIface() {
+ String methodStr = "createP2pIface";
+ return validateAndCall(methodStr, null,
+ () -> createP2pIfaceInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createRttController()}
+ */
+ @Override
+ @Nullable
+ public WifiRttController createRttController() {
+ String methodStr = "createRttController";
+ return validateAndCall(methodStr, null,
+ () -> createRttControllerInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#createStaIface()}
+ */
+ @Override
+ @Nullable
+ public WifiStaIface createStaIface() {
+ String methodStr = "createStaIface";
+ return validateAndCall(methodStr, null,
+ () -> createStaIfaceInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#enableDebugErrorAlerts(boolean)}
+ */
+ @Override
+ public boolean enableDebugErrorAlerts(boolean enable) {
+ String methodStr = "enableDebugErrorAlerts";
+ return validateAndCall(methodStr, false,
+ () -> enableDebugErrorAlertsInternal(methodStr, enable));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#flushRingBufferToFile()}
+ */
+ @Override
+ public boolean flushRingBufferToFile() {
+ String methodStr = "flushRingBufferToFile";
+ return validateAndCall(methodStr, false,
+ () -> flushRingBufferToFileInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#forceDumpToDebugRingBuffer(String)}
+ */
+ @Override
+ public boolean forceDumpToDebugRingBuffer(String ringName) {
+ String methodStr = "forceDumpToDebugRingBuffer";
+ return validateAndCall(methodStr, false,
+ () -> forceDumpToDebugRingBufferInternal(methodStr, ringName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getApIface(String)}
+ */
+ @Override
+ @Nullable
+ public WifiApIface getApIface(String ifaceName) {
+ String methodStr = "getApIface";
+ return validateAndCall(methodStr, null,
+ () -> getApIfaceInternal(methodStr, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getApIfaceNames()}
+ */
+ @Override
+ @Nullable
+ public List<String> getApIfaceNames() {
+ String methodStr = "getApIfaceNames";
+ return validateAndCall(methodStr, null,
+ () -> getApIfaceNamesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getAvailableModes()}
+ */
+ @Override
+ @Nullable
+ public List<WifiChip.ChipMode> getAvailableModes() {
+ String methodStr = "getAvailableModes";
+ return validateAndCall(methodStr, null,
+ () -> getAvailableModesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()}
+ */
+ @Override
+ public WifiChip.Response<Long> getCapabilitiesBeforeIfacesExist() {
+ String methodStr = "getCapabilitiesBeforeIfacesExist";
+ return validateAndCall(methodStr, new WifiChip.Response<>(0L),
+ () -> getCapabilitiesBeforeIfacesExistInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()}
+ */
+ @Override
+ public WifiChip.Response<Long> getCapabilitiesAfterIfacesExist() {
+ String methodStr = "getCapabilitiesAfterIfacesExist";
+ return validateAndCall(methodStr, new WifiChip.Response<>(0L),
+ () -> getCapabilitiesAfterIfacesExistInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getDebugHostWakeReasonStats()}
+ */
+ @Override
+ @Nullable
+ public WlanWakeReasonAndCounts getDebugHostWakeReasonStats() {
+ String methodStr = "getDebugHostWakeReasonStats";
+ return validateAndCall(methodStr, null,
+ () -> getDebugHostWakeReasonStatsInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getDebugRingBuffersStatus()}
+ */
+ @Override
+ @Nullable
+ public List<WifiNative.RingBufferStatus> getDebugRingBuffersStatus() {
+ String methodStr = "getDebugRingBuffersStatus";
+ return validateAndCall(methodStr, null,
+ () -> getDebugRingBuffersStatusInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getId()}
+ */
+ @Override
+ public int getId() {
+ String methodStr = "getId";
+ return validateAndCall(methodStr, -1, () -> getIdInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getMode()}
+ */
+ @Override
+ public WifiChip.Response<Integer> getMode() {
+ String methodStr = "getMode";
+ return validateAndCall(methodStr, new WifiChip.Response<>(0),
+ () -> getModeInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getNanIface(String)}
+ */
+ @Override
+ @Nullable
+ public WifiNanIface getNanIface(String ifaceName) {
+ String methodStr = "getNanIface";
+ return validateAndCall(methodStr, null,
+ () -> getNanIfaceInternal(methodStr, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getNanIfaceNames()}
+ */
+ @Override
+ @Nullable
+ public List<String> getNanIfaceNames() {
+ String methodStr = "getNanIfaceNames";
+ return validateAndCall(methodStr, null,
+ () -> getNanIfaceNamesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getP2pIface(String)}
+ */
+ @Override
+ @Nullable
+ public WifiP2pIface getP2pIface(String ifaceName) {
+ String methodStr = "getP2pIface";
+ return validateAndCall(methodStr, null,
+ () -> getP2pIfaceInternal(methodStr, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getP2pIfaceNames()}
+ */
+ @Override
+ @Nullable
+ public List<String> getP2pIfaceNames() {
+ String methodStr = "getP2pIfaceNames";
+ return validateAndCall(methodStr, null,
+ () -> getP2pIfaceNamesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getStaIface(String)}
+ */
+ @Override
+ @Nullable
+ public WifiStaIface getStaIface(String ifaceName) {
+ String methodStr = "getStaIface";
+ return validateAndCall(methodStr, null,
+ () -> getStaIfaceInternal(methodStr, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getStaIfaceNames()}
+ */
+ @Override
+ @Nullable
+ public List<String> getStaIfaceNames() {
+ String methodStr = "getStaIfaceNames";
+ return validateAndCall(methodStr, null,
+ () -> getStaIfaceNamesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getSupportedRadioCombinationsMatrix()}
+ */
+ @Override
+ @Nullable
+ public WifiChip.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix() {
+ String methodStr = "getSupportedRadioCombinationsMatrix";
+ return validateAndCall(methodStr, null,
+ () -> getSupportedRadioCombinationsMatrixInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#getUsableChannels(int, int, int)}
+ */
+ @Override
+ @Nullable
+ public List<WifiAvailableChannel> getUsableChannels(@WifiScanner.WifiBand int band,
+ @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter) {
+ String methodStr = "getUsableChannels";
+ return validateAndCall(methodStr, null,
+ () -> getUsableChannelsInternal(methodStr, band, mode, filter));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#registerCallback(WifiChip.Callback)}
+ */
+ @Override
+ public boolean registerCallback(WifiChip.Callback callback) {
+ String methodStr = "registerCallback";
+ return validateAndCall(methodStr, false,
+ () -> registerCallbackInternal(methodStr, callback));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeApIface(String)}
+ */
+ @Override
+ public boolean removeApIface(String ifaceName) {
+ String methodStr = "removeApIface";
+ return validateAndCall(methodStr, false,
+ () -> removeApIfaceInternal(methodStr, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeIfaceInstanceFromBridgedApIface(String, String)}
+ */
+ @Override
+ public boolean removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName) {
+ String methodStr = "removeIfaceInstanceFromBridgedApIface";
+ return validateAndCall(methodStr, false,
+ () -> removeIfaceInstanceFromBridgedApIfaceInternal(methodStr,
+ brIfaceName, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeNanIface(String)}
+ */
+ @Override
+ public boolean removeNanIface(String ifaceName) {
+ String methodStr = "removeNanIface";
+ return validateAndCall(methodStr, false,
+ () -> removeNanIfaceInternal(methodStr, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeP2pIface(String)}
+ */
+ @Override
+ public boolean removeP2pIface(String ifaceName) {
+ String methodStr = "removeP2pIface";
+ return validateAndCall(methodStr, false,
+ () -> removeP2pIfaceInternal(methodStr, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#removeStaIface(String)}
+ */
+ @Override
+ public boolean removeStaIface(String ifaceName) {
+ String methodStr = "removeStaIface";
+ return validateAndCall(methodStr, false,
+ () -> removeStaIfaceInternal(methodStr, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#requestChipDebugInfo()}
+ */
+ @Override
+ @Nullable
+ public WifiChip.ChipDebugInfo requestChipDebugInfo() {
+ String methodStr = "requestChipDebugInfo";
+ return validateAndCall(methodStr, null,
+ () -> requestChipDebugInfoInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#requestDriverDebugDump()}
+ */
+ @Override
+ @Nullable
+ public byte[] requestDriverDebugDump() {
+ String methodStr = "requestDriverDebugDump";
+ return validateAndCall(methodStr, null,
+ () -> requestDriverDebugDumpInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#requestFirmwareDebugDump()}
+ */
+ @Override
+ @Nullable
+ public byte[] requestFirmwareDebugDump() {
+ String methodStr = "requestFirmwareDebugDump";
+ return validateAndCall(methodStr, null,
+ () -> requestFirmwareDebugDumpInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#resetTxPowerScenario()}
+ */
+ @Override
+ public boolean resetTxPowerScenario() {
+ String methodStr = "resetTxPowerScenario";
+ return validateAndCall(methodStr, false,
+ () -> resetTxPowerScenarioInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#selectTxPowerScenario(SarInfo)}
+ */
+ @Override
+ public boolean selectTxPowerScenario(SarInfo sarInfo) {
+ String methodStr = "selectTxPowerScenario";
+ return validateAndCall(methodStr, false,
+ () -> selectTxPowerScenarioInternal(methodStr, sarInfo));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setCoexUnsafeChannels(List, int)}
+ */
+ @Override
+ public boolean setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions) {
+ String methodStr = "setCoexUnsafeChannels";
+ return validateAndCall(methodStr, false,
+ () -> setCoexUnsafeChannelsInternal(methodStr, unsafeChannels,
+ restrictions));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setCountryCode(byte[])}
+ */
+ @Override
+ public boolean setCountryCode(byte[] code) {
+ String methodStr = "setCountryCode";
+ return validateAndCall(methodStr, false,
+ () -> setCountryCodeInternal(methodStr, code));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setLowLatencyMode(boolean)}
+ */
+ @Override
+ public boolean setLowLatencyMode(boolean enable) {
+ String methodStr = "setLowLatencyMode";
+ return validateAndCall(methodStr, false,
+ () -> setLowLatencyModeInternal(methodStr, enable));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setMultiStaPrimaryConnection(String)}
+ */
+ @Override
+ public boolean setMultiStaPrimaryConnection(String ifaceName) {
+ String methodStr = "setMultiStaPrimaryConnection";
+ return validateAndCall(methodStr, false,
+ () -> setMultiStaPrimaryConnectionInternal(methodStr, ifaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#setMultiStaUseCase(int)}
+ */
+ @Override
+ public boolean setMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) {
+ String methodStr = "setMultiStaUseCase";
+ return validateAndCall(methodStr, false,
+ () -> setMultiStaUseCaseInternal(methodStr, useCase));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#startLoggingToDebugRingBuffer(String, int, int, int)}
+ */
+ @Override
+ public boolean startLoggingToDebugRingBuffer(String ringName, int verboseLevel,
+ int maxIntervalInSec, int minDataSizeInBytes) {
+ String methodStr = "startLoggingToDebugRingBuffer";
+ return validateAndCall(methodStr, false,
+ () -> startLoggingToDebugRingBufferInternal(methodStr, ringName,
+ verboseLevel, maxIntervalInSec, minDataSizeInBytes));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#stopLoggingToDebugRingBuffer()}
+ */
+ @Override
+ public boolean stopLoggingToDebugRingBuffer() {
+ String methodStr = "stopLoggingToDebugRingBuffer";
+ return validateAndCall(methodStr, false,
+ () -> stopLoggingToDebugRingBufferInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiChip#triggerSubsystemRestart()}
+ */
+ @Override
+ public boolean triggerSubsystemRestart() {
+ String methodStr = "triggerSubsystemRestart";
+ return validateAndCall(methodStr, false,
+ () -> triggerSubsystemRestartInternal(methodStr));
+ }
+
+
+ // Internal Implementations
+
+ private boolean configureChipInternal(String methodStr, int modeId) {
+ try {
+ WifiStatus status = mWifiChip.configureChip(modeId);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private WifiApIface createApIfaceInternal(String methodStr) {
+ Mutable<WifiApIface> ifaceResp = new Mutable<>();
+ try {
+ mWifiChip.createApIface((status, iface) -> {
+ if (isOk(status, methodStr)) {
+ ifaceResp.value = new WifiApIface(iface);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceResp.value;
+ }
+
+ private WifiApIface createBridgedApIfaceInternal(String methodStr) {
+ Mutable<WifiApIface> ifaceResp = new Mutable<>();
+ try {
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ if (chip15 == null) return null;
+ chip15.createBridgedApIface((status, iface) -> {
+ if (isOk(status, methodStr)) {
+ ifaceResp.value = new WifiApIface(iface);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceResp.value;
+ }
+
+ private WifiNanIface createNanIfaceInternal(String methodStr) {
+ Mutable<WifiNanIface> ifaceResp = new Mutable<>();
+ try {
+ mWifiChip.createNanIface((status, iface) -> {
+ if (isOk(status, methodStr)) {
+ ifaceResp.value = new WifiNanIface(iface);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceResp.value;
+ }
+
+ private WifiP2pIface createP2pIfaceInternal(String methodStr) {
+ Mutable<WifiP2pIface> ifaceResp = new Mutable<>();
+ try {
+ mWifiChip.createP2pIface((status, iface) -> {
+ if (isOk(status, methodStr)) {
+ ifaceResp.value = new WifiP2pIface(iface);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceResp.value;
+ }
+
+ private WifiRttController createRttControllerInternal(String methodStr) {
+ Mutable<WifiRttController> controllerResp = new Mutable<>();
+ try {
+ android.hardware.wifi.V1_6.IWifiChip chip16 = getWifiChipV1_6Mockable();
+ android.hardware.wifi.V1_4.IWifiChip chip14 = getWifiChipV1_4Mockable();
+ if (chip16 != null) {
+ chip16.createRttController_1_6(null, (status, controller) -> {
+ if (isOk(status, methodStr)) {
+ controllerResp.value = new WifiRttController(controller);
+ }
+ });
+ } else if (chip14 != null) {
+ chip14.createRttController_1_4(null, (status, controller) -> {
+ if (isOk(status, methodStr)) {
+ controllerResp.value = new WifiRttController(controller);
+ }
+ });
+ } else {
+ mWifiChip.createRttController(null, (status, controller) -> {
+ if (isOk(status, methodStr)) {
+ controllerResp.value = new WifiRttController(controller);
+ }
+ });
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return controllerResp.value;
+ }
+
+ private WifiStaIface createStaIfaceInternal(String methodStr) {
+ Mutable<WifiStaIface> ifaceResp = new Mutable<>();
+ try {
+ mWifiChip.createStaIface((status, iface) -> {
+ if (isOk(status, methodStr)) {
+ ifaceResp.value = new WifiStaIface(iface, mContext, mSsidTranslator);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceResp.value;
+ }
+
+ private boolean enableDebugErrorAlertsInternal(String methodStr, boolean enable) {
+ try {
+ WifiStatus status = mWifiChip.enableDebugErrorAlerts(enable);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean flushRingBufferToFileInternal(String methodStr) {
+ try {
+ android.hardware.wifi.V1_3.IWifiChip chip13 = getWifiChipV1_3Mockable();
+ if (chip13 == null) return false;
+ WifiStatus status = chip13.flushRingBufferToFile();
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean forceDumpToDebugRingBufferInternal(String methodStr, String ringName) {
+ try {
+ WifiStatus status = mWifiChip.forceDumpToDebugRingBuffer(ringName);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private WifiApIface getApIfaceInternal(String methodStr, String ifaceName) {
+ Mutable<WifiApIface> ifaceResp = new Mutable<>();
+ try {
+ mWifiChip.getApIface(ifaceName, (status, iface) -> {
+ if (isOk(status, methodStr)) {
+ ifaceResp.value = new WifiApIface(iface);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceResp.value;
+ }
+
+ private List<String> getApIfaceNamesInternal(String methodStr) {
+ Mutable<List<String>> ifaceNameResp = new Mutable<>();
+ try {
+ mWifiChip.getApIfaceNames((status, ifaceNames) -> {
+ if (isOk(status, methodStr)) {
+ ifaceNameResp.value = ifaceNames;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceNameResp.value;
+ }
+
+ private List<WifiChip.ChipMode> getAvailableModesInternal(String methodStr) {
+ Mutable<List<WifiChip.ChipMode>> modeResp = new Mutable<>();
+ try {
+ android.hardware.wifi.V1_6.IWifiChip chip16 = getWifiChipV1_6Mockable();
+ if (chip16 != null) {
+ chip16.getAvailableModes_1_6((status, modes) -> {
+ if (isOk(status, methodStr)) {
+ modeResp.value = halToFrameworkChipModeListV1_6(modes);
+ }
+ });
+ } else {
+ mWifiChip.getAvailableModes((status, modes) -> {
+ if (isOk(status, methodStr)) {
+ modeResp.value = halToFrameworkChipModeListV1_0(modes);
+ }
+ });
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return modeResp.value;
+ }
+
+ private WifiChip.Response<Long> getCapabilitiesBeforeIfacesExistInternal(String methodStr) {
+ WifiChip.Response<Long> capsResp = new WifiChip.Response<>(0L);
+ try {
+ // HAL newer than v1.5 supports getting capabilities before creating an interface.
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ if (chip15 != null) {
+ chip15.getCapabilities_1_5((status, caps) -> {
+ if (isOk(status, methodStr)) {
+ capsResp.setValue(wifiFeatureMaskFromChipCapabilities_1_5(caps));
+ capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
+ } else {
+ capsResp.setStatusCode(
+ WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
+ }
+ });
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ capsResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION);
+ }
+ return capsResp;
+ }
+
+ private WifiChip.Response<Long> getCapabilitiesAfterIfacesExistInternal(String methodStr) {
+ WifiChip.Response<Long> capsResp = new WifiChip.Response<>(0L);
+ try {
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ android.hardware.wifi.V1_3.IWifiChip chip13 = getWifiChipV1_3Mockable();
+ if (chip15 != null) {
+ chip15.getCapabilities_1_5((status, caps) -> {
+ if (isOk(status, methodStr)) {
+ capsResp.setValue(wifiFeatureMaskFromChipCapabilities_1_5(caps));
+ capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
+ } else {
+ capsResp.setStatusCode(
+ WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
+ }
+ });
+ } else if (chip13 != null) {
+ chip13.getCapabilities_1_3((status, caps) -> {
+ if (isOk(status, methodStr)) {
+ capsResp.setValue(wifiFeatureMaskFromChipCapabilities_1_3(caps));
+ capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
+ } else {
+ capsResp.setStatusCode(
+ WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
+ }
+ });
+ } else {
+ mWifiChip.getCapabilities((status, caps) -> {
+ if (isOk(status, methodStr)) {
+ capsResp.setValue((long) wifiFeatureMaskFromChipCapabilities(caps));
+ capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
+ } else {
+ capsResp.setStatusCode(
+ WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
+ }
+ });
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ capsResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION);
+ }
+ return capsResp;
+ }
+
+ private WlanWakeReasonAndCounts getDebugHostWakeReasonStatsInternal(String methodStr) {
+ Mutable<WlanWakeReasonAndCounts> debugResp = new Mutable<>();
+ try {
+ mWifiChip.getDebugHostWakeReasonStats((status, debugStats) -> {
+ if (isOk(status, methodStr)) {
+ debugResp.value = halToFrameworkWakeReasons(debugStats);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return debugResp.value;
+ }
+
+ private List<WifiNative.RingBufferStatus> getDebugRingBuffersStatusInternal(String methodStr) {
+ Mutable<List<WifiNative.RingBufferStatus>> ringBufResp = new Mutable<>();
+ try {
+ mWifiChip.getDebugRingBuffersStatus((status, ringBuffers) -> {
+ if (isOk(status, methodStr)) {
+ WifiNative.RingBufferStatus[] ringBufArray =
+ makeRingBufferStatusArray(ringBuffers);
+ ringBufResp.value = Arrays.asList(ringBufArray);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ringBufResp.value;
+ }
+
+ private int getIdInternal(String methodStr) {
+ Mutable<Integer> idResp = new Mutable<>(-1);
+ try {
+ mWifiChip.getId((status, id) -> {
+ if (isOk(status, methodStr)) {
+ idResp.value = id;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return idResp.value;
+ }
+
+ private WifiChip.Response<Integer> getModeInternal(String methodStr) {
+ WifiChip.Response<Integer> modeResp = new WifiChip.Response<>(0);
+ try {
+ mWifiChip.getMode((status, mode) -> {
+ if (isOk(status, methodStr)) {
+ modeResp.setValue(mode);
+ modeResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
+ } else {
+ modeResp.setStatusCode(
+ WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ modeResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION);
+ }
+ return modeResp;
+ }
+
+ private WifiNanIface getNanIfaceInternal(String methodStr, String ifaceName) {
+ Mutable<WifiNanIface> ifaceResp = new Mutable<>();
+ try {
+ mWifiChip.getNanIface(ifaceName, (status, iface) -> {
+ if (isOk(status, methodStr)) {
+ ifaceResp.value = new WifiNanIface(iface);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceResp.value;
+ }
+
+ private List<String> getNanIfaceNamesInternal(String methodStr) {
+ Mutable<List<String>> ifaceNameResp = new Mutable<>();
+ try {
+ mWifiChip.getNanIfaceNames((status, ifaceNames) -> {
+ if (isOk(status, methodStr)) {
+ ifaceNameResp.value = ifaceNames;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceNameResp.value;
+ }
+
+ private WifiP2pIface getP2pIfaceInternal(String methodStr, String ifaceName) {
+ Mutable<WifiP2pIface> ifaceResp = new Mutable<>();
+ try {
+ mWifiChip.getP2pIface(ifaceName, (status, iface) -> {
+ if (isOk(status, methodStr)) {
+ ifaceResp.value = new WifiP2pIface(iface);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceResp.value;
+ }
+
+ private List<String> getP2pIfaceNamesInternal(String methodStr) {
+ Mutable<List<String>> ifaceNameResp = new Mutable<>();
+ try {
+ mWifiChip.getP2pIfaceNames((status, ifaceNames) -> {
+ if (isOk(status, methodStr)) {
+ ifaceNameResp.value = ifaceNames;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceNameResp.value;
+ }
+
+ private WifiStaIface getStaIfaceInternal(String methodStr, String ifaceName) {
+ Mutable<WifiStaIface> ifaceResp = new Mutable<>();
+ try {
+ mWifiChip.getStaIface(ifaceName, (status, iface) -> {
+ if (isOk(status, methodStr)) {
+ ifaceResp.value = new WifiStaIface(iface, mContext, mSsidTranslator);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceResp.value;
+ }
+
+ private List<String> getStaIfaceNamesInternal(String methodStr) {
+ Mutable<List<String>> ifaceNameResp = new Mutable<>();
+ try {
+ mWifiChip.getStaIfaceNames((status, ifaceNames) -> {
+ if (isOk(status, methodStr)) {
+ ifaceNameResp.value = ifaceNames;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return ifaceNameResp.value;
+ }
+
+ private WifiChip.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrixInternal(
+ String methodStr) {
+ Mutable<WifiChip.WifiRadioCombinationMatrix> matrixResp = new Mutable<>();
+ try {
+ android.hardware.wifi.V1_6.IWifiChip chip16 = getWifiChipV1_6Mockable();
+ if (chip16 == null) return null;
+ chip16.getSupportedRadioCombinationsMatrix((status, matrix) -> {
+ matrixResp.value = halToFrameworkRadioCombinationMatrix(matrix);
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return matrixResp.value;
+ }
+
+ private List<WifiAvailableChannel> getUsableChannelsInternal(String methodStr,
+ @WifiScanner.WifiBand int band, @WifiAvailableChannel.OpMode int mode,
+ @WifiAvailableChannel.Filter int filter) {
+ Mutable<List<WifiAvailableChannel>> channelResp = new Mutable<>();
+ try {
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ android.hardware.wifi.V1_6.IWifiChip chip16 = getWifiChipV1_6Mockable();
+ if (chip15 == null && chip16 == null) return null;
+ if (chip16 != null) {
+ chip16.getUsableChannels_1_6(
+ frameworkToHalWifiBand(band),
+ frameworkToHalIfaceMode(mode),
+ frameworkToHalUsableFilter_1_6(filter),
+ (status, channels) -> {
+ if (isOk(status, methodStr)) {
+ channelResp.value = new ArrayList<>();
+ for (android.hardware.wifi.V1_6.WifiUsableChannel ch : channels) {
+ channelResp.value.add(new WifiAvailableChannel(ch.channel,
+ halToFrameworkIfaceMode(ch.ifaceModeMask)));
+ }
+ }
+ });
+ } else {
+ chip15.getUsableChannels(
+ frameworkToHalWifiBand(band),
+ frameworkToHalIfaceMode(mode),
+ frameworkToHalUsableFilter(filter),
+ (status, channels) -> {
+ if (isOk(status, methodStr)) {
+ channelResp.value = new ArrayList<>();
+ for (android.hardware.wifi.V1_5.WifiUsableChannel ch : channels) {
+ channelResp.value.add(new WifiAvailableChannel(ch.channel,
+ halToFrameworkIfaceMode(ch.ifaceModeMask)));
+ }
+ }
+ });
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return channelResp.value;
+ }
+
+ private boolean registerCallbackInternal(String methodStr, WifiChip.Callback callback) {
+ if (mFrameworkCallback != null) {
+ Log.e(TAG, "Framework callback is already registered");
+ return false;
+ } else if (callback == null) {
+ Log.e(TAG, "Cannot register a null callback");
+ return false;
+ }
+
+ try {
+ android.hardware.wifi.V1_2.IWifiChip chip12 = getWifiChipV1_2Mockable();
+ android.hardware.wifi.V1_4.IWifiChip chip14 = getWifiChipV1_4Mockable();
+ mHalCallback10 = new ChipEventCallback();
+ WifiStatus status;
+ if (chip14 != null) {
+ mHalCallback12 = new ChipEventCallbackV12();
+ mHalCallback14 = new ChipEventCallbackV14();
+ status = chip14.registerEventCallback_1_4(mHalCallback14);
+ } else if (chip12 != null) {
+ mHalCallback12 = new ChipEventCallbackV12();
+ status = chip12.registerEventCallback_1_2(mHalCallback12);
+ } else {
+ status = mWifiChip.registerEventCallback(mHalCallback10);
+ }
+ if (!isOk(status, methodStr)) return false;
+ mFrameworkCallback = callback;
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean removeApIfaceInternal(String methodStr, String ifaceName) {
+ try {
+ WifiStatus status = mWifiChip.removeApIface(ifaceName);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean removeIfaceInstanceFromBridgedApIfaceInternal(String methodStr,
+ String brIfaceName, String ifaceName) {
+ try {
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ if (chip15 == null) return false;
+ WifiStatus status =
+ chip15.removeIfaceInstanceFromBridgedApIface(brIfaceName, ifaceName);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean removeNanIfaceInternal(String methodStr, String ifaceName) {
+ try {
+ WifiStatus status = mWifiChip.removeNanIface(ifaceName);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean removeP2pIfaceInternal(String methodStr, String ifaceName) {
+ try {
+ WifiStatus status = mWifiChip.removeP2pIface(ifaceName);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean removeStaIfaceInternal(String methodStr, String ifaceName) {
+ try {
+ WifiStatus status = mWifiChip.removeStaIface(ifaceName);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private WifiChip.ChipDebugInfo requestChipDebugInfoInternal(String methodStr) {
+ Mutable<WifiChip.ChipDebugInfo> debugResp = new Mutable<>();
+ try {
+ mWifiChip.requestChipDebugInfo((status, halInfo) -> {
+ if (isOk(status, methodStr)) {
+ debugResp.value = new WifiChip.ChipDebugInfo(
+ halInfo.driverDescription, halInfo.firmwareDescription);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return debugResp.value;
+ }
+
+ private byte[] requestDriverDebugDumpInternal(String methodStr) {
+ Mutable<byte[]> debugResp = new Mutable<>();
+ try {
+ mWifiChip.requestDriverDebugDump((status, blob) -> {
+ if (isOk(status, methodStr)) {
+ debugResp.value = NativeUtil.byteArrayFromArrayList(blob);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return debugResp.value;
+ }
+
+ private byte[] requestFirmwareDebugDumpInternal(String methodStr) {
+ Mutable<byte[]> debugResp = new Mutable<>();
+ try {
+ mWifiChip.requestFirmwareDebugDump((status, blob) -> {
+ if (isOk(status, methodStr)) {
+ debugResp.value = NativeUtil.byteArrayFromArrayList(blob);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return debugResp.value;
+ }
+
+ private boolean resetTxPowerScenarioInternal(String methodStr) {
+ try {
+ android.hardware.wifi.V1_1.IWifiChip chip11 = getWifiChipV1_1Mockable();
+ android.hardware.wifi.V1_2.IWifiChip chip12 = getWifiChipV1_2Mockable();
+ if (chip11 == null && chip12 == null) return false;
+ WifiStatus status;
+ if (chip12 != null) {
+ status = chip12.resetTxPowerScenario();
+ } else {
+ status = chip11.resetTxPowerScenario();
+ }
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean selectTxPowerScenarioInternal(String methodStr, SarInfo sarInfo) {
+ if (getWifiChipV1_2Mockable() != null) {
+ return selectTxPowerScenarioInternal_1_2(methodStr, sarInfo);
+ } else if (getWifiChipV1_1Mockable() != null) {
+ return selectTxPowerScenarioInternal_1_1(methodStr, sarInfo);
+ }
+ return false;
+ }
+
+ private boolean selectTxPowerScenarioInternal_1_1(String methodStr, SarInfo sarInfo) {
+ methodStr += "_1_1";
+ try {
+ WifiStatus status;
+ android.hardware.wifi.V1_1.IWifiChip chip11 = getWifiChipV1_1Mockable();
+
+ if (sarPowerBackoffRequired_1_1(sarInfo)) {
+ // Power backoff is needed, so calculate the required scenario
+ // and attempt to set it.
+ int halScenario = frameworkToHalTxPowerScenario_1_1(sarInfo);
+ if (sarInfo.setSarScenarioNeeded(halScenario)) {
+ Log.d(TAG, "Attempting to set SAR scenario to " + halScenario);
+ status = chip11.selectTxPowerScenario(halScenario);
+ return isOk(status, methodStr);
+ }
+ // Reaching here means setting SAR scenario would be redundant,
+ // do nothing and return with success.
+ return true;
+ }
+
+ // We don't need to perform power backoff, so attempt to reset the SAR scenario.
+ if (sarInfo.resetSarScenarioNeeded()) {
+ status = chip11.resetTxPowerScenario();
+ Log.d(TAG, "Attempting to reset the SAR scenario");
+ return isOk(status, methodStr);
+ }
+
+ // Resetting SAR scenario would be redundant; do nothing and return with success.
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "IllegalArgumentException in " + methodStr);
+ return false;
+ }
+ }
+
+ private boolean selectTxPowerScenarioInternal_1_2(String methodStr, SarInfo sarInfo) {
+ methodStr += "_1_2";
+ try {
+ WifiStatus status;
+ android.hardware.wifi.V1_2.IWifiChip chip12 = getWifiChipV1_2Mockable();
+
+ if (sarPowerBackoffRequired_1_2(sarInfo)) {
+ // Power backoff is needed, so calculate the required scenario
+ // and attempt to set it.
+ int halScenario = frameworkToHalTxPowerScenario_1_2(sarInfo);
+ if (sarInfo.setSarScenarioNeeded(halScenario)) {
+ Log.d(TAG, "Attempting to set SAR scenario to " + halScenario);
+ status = chip12.selectTxPowerScenario_1_2(halScenario);
+ return isOk(status, methodStr);
+ }
+ // Reaching here means setting SAR scenario would be redundant,
+ // do nothing and return with success.
+ return true;
+ }
+
+ // We don't need to perform power backoff, so attempt to reset the SAR scenario.
+ if (sarInfo.resetSarScenarioNeeded()) {
+ status = chip12.resetTxPowerScenario();
+ Log.d(TAG, "Attempting to reset the SAR scenario");
+ return isOk(status, methodStr);
+ }
+
+ // Resetting SAR scenario would be redundant; do nothing and return with success.
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "IllegalArgumentException in " + methodStr);
+ return false;
+ }
+ }
+
+ private boolean setCoexUnsafeChannelsInternal(String methodStr,
+ List<CoexUnsafeChannel> unsafeChannels, int restrictions) {
+ try {
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ if (chip15 == null) return false;
+ WifiStatus status = chip15.setCoexUnsafeChannels(
+ frameworkCoexUnsafeChannelsToHidl(unsafeChannels),
+ frameworkCoexRestrictionsToHidl(restrictions));
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean setCountryCodeInternal(String methodStr, byte[] code) {
+ try {
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ if (chip15 == null) return false;
+ WifiStatus status = chip15.setCountryCode(code);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean setLowLatencyModeInternal(String methodStr, boolean enable) {
+ try {
+ android.hardware.wifi.V1_3.IWifiChip chip13 = getWifiChipV1_3Mockable();
+ if (chip13 == null) return false;
+ int mode;
+ if (enable) {
+ mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.LOW;
+ } else {
+ mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.NORMAL;
+ }
+ WifiStatus status = chip13.setLatencyMode(mode);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean setMultiStaPrimaryConnectionInternal(String methodStr, String ifaceName) {
+ try {
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ if (chip15 == null) return false;
+ WifiStatus status = chip15.setMultiStaPrimaryConnection(ifaceName);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean setMultiStaUseCaseInternal(String methodStr,
+ @WifiNative.MultiStaUseCase int useCase) {
+ try {
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ if (chip15 == null) return false;
+ WifiStatus status = chip15.setMultiStaUseCase(frameworkMultiStaUseCaseToHidl(useCase));
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Invalid argument " + useCase + " in " + methodStr);
+ }
+ return false;
+ }
+
+ private boolean startLoggingToDebugRingBufferInternal(String methodStr, String ringName,
+ int verboseLevel, int maxIntervalInSec, int minDataSizeInBytes) {
+ try {
+ WifiStatus status = mWifiChip.startLoggingToDebugRingBuffer(ringName, verboseLevel,
+ maxIntervalInSec, minDataSizeInBytes);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean stopLoggingToDebugRingBufferInternal(String methodStr) {
+ try {
+ WifiStatus status = mWifiChip.stopLoggingToDebugRingBuffer();
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean triggerSubsystemRestartInternal(String methodStr) {
+ try {
+ android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
+ if (chip15 == null) return false;
+ WifiStatus status = chip15.triggerSubsystemRestart();
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ /**
+ * Callback for events on the chip.
+ */
+ private class ChipEventCallback extends IWifiChipEventCallback.Stub {
+ @Override
+ public void onChipReconfigured(int modeId) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onChipReconfigured(modeId);
+ }
+
+ @Override
+ public void onChipReconfigureFailure(WifiStatus status) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onChipReconfigureFailure(
+ WifiHalHidlImpl.halToFrameworkWifiStatusCode(status.code));
+ }
+
+ @Override
+ public void onIfaceAdded(int type, String name) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onIfaceAdded(halToFrameworkIfaceType(type), name);
+ }
+
+ @Override
+ public void onIfaceRemoved(int type, String name) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onIfaceRemoved(halToFrameworkIfaceType(type), name);
+ }
+
+ @Override
+ public void onDebugRingBufferDataAvailable(
+ WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onDebugRingBufferDataAvailable(
+ halToFrameworkRingBufferStatus(status),
+ NativeUtil.byteArrayFromArrayList(data));
+ }
+
+ @Override
+ public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onDebugErrorAlert(errorCode,
+ NativeUtil.byteArrayFromArrayList(debugData));
+ }
+ }
+
+ /**
+ * Callback for events on the 1.2 chip.
+ */
+ private class ChipEventCallbackV12 extends
+ android.hardware.wifi.V1_2.IWifiChipEventCallback.Stub {
+ @Override
+ public void onChipReconfigured(int modeId) throws RemoteException {
+ mHalCallback10.onChipReconfigured(modeId);
+ }
+
+ @Override
+ public void onChipReconfigureFailure(WifiStatus status) throws RemoteException {
+ mHalCallback10.onChipReconfigureFailure(status);
+ }
+
+ public void onIfaceAdded(int type, String name) throws RemoteException {
+ mHalCallback10.onIfaceAdded(type, name);
+ }
+
+ @Override
+ public void onIfaceRemoved(int type, String name) throws RemoteException {
+ mHalCallback10.onIfaceRemoved(type, name);
+ }
+
+ @Override
+ public void onDebugRingBufferDataAvailable(
+ WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data)
+ throws RemoteException {
+ mHalCallback10.onDebugRingBufferDataAvailable(status, data);
+ }
+
+ @Override
+ public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData)
+ throws RemoteException {
+ mHalCallback10.onDebugErrorAlert(errorCode, debugData);
+ }
+
+ @Override
+ public void onRadioModeChange(ArrayList<RadioModeInfo> radioModeInfoList) {
+ if (mFrameworkCallback == null) return;
+ List<WifiChip.RadioModeInfo> frameworkRadioModeInfos = new ArrayList<>();
+ for (RadioModeInfo radioInfo : radioModeInfoList) {
+ List<WifiChip.IfaceInfo> frameworkIfaceInfos = new ArrayList<>();
+ for (IfaceInfo ifaceInfo : radioInfo.ifaceInfos) {
+ frameworkIfaceInfos.add(
+ new WifiChip.IfaceInfo(ifaceInfo.name, ifaceInfo.channel));
+ }
+ frameworkRadioModeInfos.add(
+ new WifiChip.RadioModeInfo(
+ radioInfo.radioId, radioInfo.bandInfo, frameworkIfaceInfos));
+ }
+ mFrameworkCallback.onRadioModeChange(frameworkRadioModeInfos);
+ }
+ }
+
+ /**
+ * Callback for events on the 1.4 chip.
+ */
+ private class ChipEventCallbackV14 extends
+ android.hardware.wifi.V1_4.IWifiChipEventCallback.Stub {
+ @Override
+ public void onChipReconfigured(int modeId) throws RemoteException {
+ mHalCallback10.onChipReconfigured(modeId);
+ }
+
+ @Override
+ public void onChipReconfigureFailure(WifiStatus status) throws RemoteException {
+ mHalCallback10.onChipReconfigureFailure(status);
+ }
+
+ public void onIfaceAdded(int type, String name) throws RemoteException {
+ mHalCallback10.onIfaceAdded(type, name);
+ }
+
+ @Override
+ public void onIfaceRemoved(int type, String name) throws RemoteException {
+ mHalCallback10.onIfaceRemoved(type, name);
+ }
+
+ @Override
+ public void onDebugRingBufferDataAvailable(
+ WifiDebugRingBufferStatus status, java.util.ArrayList<Byte> data)
+ throws RemoteException {
+ mHalCallback10.onDebugRingBufferDataAvailable(status, data);
+ }
+
+ @Override
+ public void onDebugErrorAlert(int errorCode, java.util.ArrayList<Byte> debugData)
+ throws RemoteException {
+ mHalCallback10.onDebugErrorAlert(errorCode, debugData);
+ }
+
+ @Override
+ public void onRadioModeChange(
+ ArrayList<android.hardware.wifi.V1_2.IWifiChipEventCallback.RadioModeInfo>
+ radioModeInfoList) throws RemoteException {
+ mHalCallback12.onRadioModeChange(radioModeInfoList);
+ }
+
+ @Override
+ public void onRadioModeChange_1_4(ArrayList<RadioModeInfo> radioModeInfoList) {
+ if (mFrameworkCallback == null) return;
+ List<WifiChip.RadioModeInfo> frameworkRadioModeInfos = new ArrayList<>();
+ for (RadioModeInfo radioInfo : radioModeInfoList) {
+ List<WifiChip.IfaceInfo> frameworkIfaceInfos = new ArrayList<>();
+ for (IfaceInfo ifaceInfo : radioInfo.ifaceInfos) {
+ frameworkIfaceInfos.add(
+ new WifiChip.IfaceInfo(ifaceInfo.name, ifaceInfo.channel));
+ }
+ frameworkRadioModeInfos.add(
+ new WifiChip.RadioModeInfo(
+ radioInfo.radioId, radioInfo.bandInfo, frameworkIfaceInfos));
+ }
+ mFrameworkCallback.onRadioModeChange(frameworkRadioModeInfos);
+ }
+ }
+
+
+ // Helper Functions
+
+ protected boolean isBridgedSoftApSupportedMockable() {
+ return mIsBridgedSoftApSupported;
+ }
+
+ protected boolean isStaWithBridgedSoftApConcurrencySupportedMockable() {
+ return mIsStaWithBridgedSoftApConcurrencySupported;
+ }
+
+ private static final SparseIntArray IFACE_TYPE_TO_CONCURRENCY_TYPE_MAP = new SparseIntArray() {{
+ put(IfaceType.STA, android.hardware.wifi.V1_6.IfaceConcurrencyType.STA);
+ put(IfaceType.AP, android.hardware.wifi.V1_6.IfaceConcurrencyType.AP);
+ put(IfaceType.P2P, android.hardware.wifi.V1_6.IfaceConcurrencyType.P2P);
+ put(IfaceType.NAN, android.hardware.wifi.V1_6.IfaceConcurrencyType.NAN);
+ }};
+
+ private List<android.hardware.wifi.V1_6.IWifiChip.ChipMode> upgradeV1_0ChipModesToV1_6(
+ List<android.hardware.wifi.V1_0.IWifiChip.ChipMode> oldChipModes) {
+ ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> newChipModes = new ArrayList<>();
+ for (android.hardware.wifi.V1_0.IWifiChip.ChipMode oldChipMode : oldChipModes) {
+ android.hardware.wifi.V1_6.IWifiChip.ChipMode newChipMode =
+ new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
+ newChipMode.id = oldChipMode.id;
+ newChipMode.availableCombinations = new ArrayList<>();
+ for (android.hardware.wifi.V1_0.IWifiChip.ChipIfaceCombination oldCombo
+ : oldChipMode.availableCombinations) {
+ android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination
+ newCombo = new android.hardware.wifi.V1_6.IWifiChip
+ .ChipConcurrencyCombination();
+ newCombo.limits = new ArrayList<>();
+ // Define a duplicate combination list with AP converted to AP_BRIDGED
+ android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination
+ newComboWithBridgedAp =
+ new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
+ newComboWithBridgedAp.limits = new ArrayList<>();
+ android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit
+ bridgedApLimit = new android.hardware.wifi.V1_6.IWifiChip
+ .ChipConcurrencyCombinationLimit();
+ bridgedApLimit.maxIfaces = 1;
+ bridgedApLimit.types = new ArrayList<>();
+ bridgedApLimit.types.add(IfaceConcurrencyType.AP_BRIDGED);
+ newComboWithBridgedAp.limits.add(bridgedApLimit);
+
+ boolean apInCombo = false;
+ // Populate both the combo with AP_BRIDGED and the combo without AP_BRIDGED
+ for (android.hardware.wifi.V1_0.IWifiChip.ChipIfaceCombinationLimit oldLimit
+ : oldCombo.limits) {
+ android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit newLimit =
+ new android.hardware.wifi.V1_6
+ .IWifiChip.ChipConcurrencyCombinationLimit();
+ newLimit.types = new ArrayList<>();
+ newLimit.maxIfaces = oldLimit.maxIfaces;
+ for (int oldType : oldLimit.types) {
+ newLimit.types.add(IFACE_TYPE_TO_CONCURRENCY_TYPE_MAP.get(oldType));
+ }
+ newCombo.limits.add(newLimit);
+
+ android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit
+ newLimitForBridgedApCombo = new android.hardware.wifi.V1_6.IWifiChip
+ .ChipConcurrencyCombinationLimit();
+ newLimitForBridgedApCombo.types = new ArrayList<>(newLimit.types);
+ newLimitForBridgedApCombo.maxIfaces = newLimit.maxIfaces;
+ if (newLimitForBridgedApCombo.types.contains(IfaceConcurrencyType.AP)) {
+ // Skip the limit if it contains AP, since this corresponds to the
+ // AP_BRIDGED in the duplicate AP_BRIDGED combo.
+ apInCombo = true;
+ } else if (!isStaWithBridgedSoftApConcurrencySupportedMockable()
+ && newLimitForBridgedApCombo.types.contains(IfaceConcurrencyType.STA)) {
+ // Don't include STA in the AP_BRIDGED combo if STA + AP_BRIDGED is not
+ // supported.
+ newLimitForBridgedApCombo.types.remove((Integer) IfaceConcurrencyType.STA);
+ if (!newLimitForBridgedApCombo.types.isEmpty()) {
+ newComboWithBridgedAp.limits.add(newLimitForBridgedApCombo);
+ }
+ } else {
+ newComboWithBridgedAp.limits.add(newLimitForBridgedApCombo);
+ }
+ }
+ newChipMode.availableCombinations.add(newCombo);
+ if (isBridgedSoftApSupportedMockable() && apInCombo) {
+ newChipMode.availableCombinations.add(newComboWithBridgedAp);
+ }
+ }
+ newChipModes.add(newChipMode);
+ }
+ return newChipModes;
+ }
+
+ private List<WifiChip.ChipMode> halToFrameworkChipModeListV1_0(
+ List<android.hardware.wifi.V1_0.IWifiChip.ChipMode> halModes) {
+ List<android.hardware.wifi.V1_6.IWifiChip.ChipMode> modes16 =
+ upgradeV1_0ChipModesToV1_6(halModes);
+ return halToFrameworkChipModeListV1_6(modes16);
+ }
+
+ private static List<WifiChip.ChipMode> halToFrameworkChipModeListV1_6(
+ List<android.hardware.wifi.V1_6.IWifiChip.ChipMode> halModes) {
+ List<WifiChip.ChipMode> frameworkModes = new ArrayList<>();
+ for (android.hardware.wifi.V1_6.IWifiChip.ChipMode halMode : halModes) {
+ frameworkModes.add(halToFrameworkChipModeV1_6(halMode));
+ }
+ return frameworkModes;
+ }
+
+ private static WifiChip.ChipMode halToFrameworkChipModeV1_6(
+ android.hardware.wifi.V1_6.IWifiChip.ChipMode halMode) {
+ List<WifiChip.ChipConcurrencyCombination> frameworkCombos = new ArrayList<>();
+ for (android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination halCombo :
+ halMode.availableCombinations) {
+ frameworkCombos.add(halToFrameworkChipConcurrencyCombinationV1_6(halCombo));
+ }
+ return new WifiChip.ChipMode(halMode.id, frameworkCombos);
+ }
+
+ private static WifiChip.ChipConcurrencyCombination halToFrameworkChipConcurrencyCombinationV1_6(
+ android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination halCombo) {
+ List<WifiChip.ChipConcurrencyCombinationLimit> frameworkLimits = new ArrayList<>();
+ for (android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit halLimit :
+ halCombo.limits) {
+ frameworkLimits.add(halToFrameworkChipConcurrencyCombinationLimitV1_6(halLimit));
+ }
+ return new WifiChip.ChipConcurrencyCombination(frameworkLimits);
+ }
+
+ private static WifiChip.ChipConcurrencyCombinationLimit
+ halToFrameworkChipConcurrencyCombinationLimitV1_6(
+ android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit halLimit) {
+ List<Integer> frameworkTypes = new ArrayList<>();
+ for (int halType : halLimit.types) {
+ frameworkTypes.add(halToFrameworkIfaceConcurrencyType(halType));
+ }
+ return new WifiChip.ChipConcurrencyCombinationLimit(halLimit.maxIfaces, frameworkTypes);
+ }
+
+ private static @WifiChip.IfaceConcurrencyType int halToFrameworkIfaceConcurrencyType(int type) {
+ switch (type) {
+ case IfaceConcurrencyType.STA:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_STA;
+ case IfaceConcurrencyType.AP:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_AP;
+ case IfaceConcurrencyType.AP_BRIDGED:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED;
+ case IfaceConcurrencyType.P2P:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_P2P;
+ case IfaceConcurrencyType.NAN:
+ return WifiChip.IFACE_CONCURRENCY_TYPE_NAN;
+ default:
+ Log.e(TAG, "Invalid IfaceConcurrencyType received: " + type);
+ return -1;
+ }
+ }
+
+ private static @WifiChip.IfaceType int halToFrameworkIfaceType(int type) {
+ switch (type) {
+ case IfaceType.STA:
+ return WifiChip.IFACE_TYPE_STA;
+ case IfaceType.AP:
+ return WifiChip.IFACE_TYPE_AP;
+ case IfaceType.P2P:
+ return WifiChip.IFACE_TYPE_P2P;
+ case IfaceType.NAN:
+ return WifiChip.IFACE_TYPE_NAN;
+ default:
+ Log.e(TAG, "Invalid IfaceType received: " + type);
+ return -1;
+ }
+ }
+
+ private static final long[][] sChipFeatureCapabilityTranslation = {
+ {WifiManager.WIFI_FEATURE_TX_POWER_LIMIT,
+ android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT
+ },
+ {WifiManager.WIFI_FEATURE_D2D_RTT,
+ android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
+ },
+ {WifiManager.WIFI_FEATURE_D2AP_RTT,
+ android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2AP_RTT
+ }
+ };
+
+ /**
+ * Translation table used by getSupportedFeatureSet for translating IWifiChip caps for
+ * additional capabilities introduced in V1.5
+ */
+ private static final long[][] sChipFeatureCapabilityTranslation15 = {
+ {WifiManager.WIFI_FEATURE_INFRA_60G,
+ android.hardware.wifi.V1_5.IWifiChip.ChipCapabilityMask.WIGIG
+ }
+ };
+
+ /**
+ * Translation table used by getSupportedFeatureSet for translating IWifiChip caps for
+ * additional capabilities introduced in V1.3
+ */
+ private static final long[][] sChipFeatureCapabilityTranslation13 = {
+ {WifiManager.WIFI_FEATURE_LOW_LATENCY,
+ android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.SET_LATENCY_MODE
+ },
+ {WifiManager.WIFI_FEATURE_P2P_RAND_MAC,
+ android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.P2P_RAND_MAC
+ }
+
+ };
+
+ /**
+ * Feature bit mask translation for Chip V1.1
+ *
+ * @param capabilities bitmask defined IWifiChip.ChipCapabilityMask
+ * @return bitmask defined by WifiManager.WIFI_FEATURE_*
+ */
+ @VisibleForTesting
+ int wifiFeatureMaskFromChipCapabilities(int capabilities) {
+ int features = 0;
+ for (int i = 0; i < sChipFeatureCapabilityTranslation.length; i++) {
+ if ((capabilities & sChipFeatureCapabilityTranslation[i][1]) != 0) {
+ features |= sChipFeatureCapabilityTranslation[i][0];
+ }
+ }
+ return features;
+ }
+
+ /**
+ * Feature bit mask translation for Chip V1.5
+ *
+ * @param capabilities bitmask defined IWifiChip.ChipCapabilityMask
+ * @return bitmask defined by WifiManager.WIFI_FEATURE_*
+ */
+ @VisibleForTesting
+ long wifiFeatureMaskFromChipCapabilities_1_5(int capabilities) {
+ // First collect features from previous versions
+ long features = wifiFeatureMaskFromChipCapabilities_1_3(capabilities);
+
+ // Next collect features for V1_5 version
+ for (int i = 0; i < sChipFeatureCapabilityTranslation15.length; i++) {
+ if ((capabilities & sChipFeatureCapabilityTranslation15[i][1]) != 0) {
+ features |= sChipFeatureCapabilityTranslation15[i][0];
+ }
+ }
+ return features;
+ }
+
+ /**
+ * Feature bit mask translation for Chip V1.3
+ *
+ * @param capabilities bitmask defined IWifiChip.ChipCapabilityMask
+ * @return bitmask defined by WifiManager.WIFI_FEATURE_*
+ */
+ @VisibleForTesting
+ long wifiFeatureMaskFromChipCapabilities_1_3(int capabilities) {
+ // First collect features from previous versions
+ long features = wifiFeatureMaskFromChipCapabilities(capabilities);
+
+ // Next collect features for V1_3 version
+ for (int i = 0; i < sChipFeatureCapabilityTranslation13.length; i++) {
+ if ((capabilities & sChipFeatureCapabilityTranslation13[i][1]) != 0) {
+ features |= sChipFeatureCapabilityTranslation13[i][0];
+ }
+ }
+ return features;
+ }
+
+ /**
+ * Translates from Hal version of wake reason stats to the framework version of same
+ *
+ * @param h - Hal version of wake reason stats
+ * @return framework version of same
+ */
+ private static WlanWakeReasonAndCounts halToFrameworkWakeReasons(
+ WifiDebugHostWakeReasonStats h) {
+ if (h == null) return null;
+ WlanWakeReasonAndCounts ans = new WlanWakeReasonAndCounts();
+ ans.totalCmdEventWake = h.totalCmdEventWakeCnt;
+ ans.totalDriverFwLocalWake = h.totalDriverFwLocalWakeCnt;
+ ans.totalRxDataWake = h.totalRxPacketWakeCnt;
+ ans.rxUnicast = h.rxPktWakeDetails.rxUnicastCnt;
+ ans.rxMulticast = h.rxPktWakeDetails.rxMulticastCnt;
+ ans.rxBroadcast = h.rxPktWakeDetails.rxBroadcastCnt;
+ ans.icmp = h.rxIcmpPkWakeDetails.icmpPkt;
+ ans.icmp6 = h.rxIcmpPkWakeDetails.icmp6Pkt;
+ ans.icmp6Ra = h.rxIcmpPkWakeDetails.icmp6Ra;
+ ans.icmp6Na = h.rxIcmpPkWakeDetails.icmp6Na;
+ ans.icmp6Ns = h.rxIcmpPkWakeDetails.icmp6Ns;
+ ans.ipv4RxMulticast = h.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt;
+ ans.ipv6Multicast = h.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt;
+ ans.otherRxMulticast = h.rxMulticastPkWakeDetails.otherRxMulticastAddrCnt;
+ ans.cmdEventWakeCntArray = intsFromArrayList(h.cmdEventWakeCntPerType);
+ ans.driverFWLocalWakeCntArray = intsFromArrayList(h.driverFwLocalWakeCntPerType);
+ return ans;
+ }
+
+ /**
+ * Creates array of RingBufferStatus from the Hal version
+ */
+ private static WifiNative.RingBufferStatus[] makeRingBufferStatusArray(
+ ArrayList<WifiDebugRingBufferStatus> ringBuffers) {
+ WifiNative.RingBufferStatus[] ans = new WifiNative.RingBufferStatus[ringBuffers.size()];
+ int i = 0;
+ for (WifiDebugRingBufferStatus b : ringBuffers) {
+ ans[i++] = halToFrameworkRingBufferStatus(b);
+ }
+ return ans;
+ }
+
+ /**
+ * Creates RingBufferStatus from the Hal version
+ */
+ private static WifiNative.RingBufferStatus halToFrameworkRingBufferStatus(
+ WifiDebugRingBufferStatus h) {
+ WifiNative.RingBufferStatus ans = new WifiNative.RingBufferStatus();
+ ans.name = h.ringName;
+ ans.flag = frameworkRingBufferFlagsFromHal(h.flags);
+ ans.ringBufferId = h.ringId;
+ ans.ringBufferByteSize = h.sizeInBytes;
+ ans.verboseLevel = h.verboseLevel;
+ // Remaining fields are unavailable
+ // writtenBytes;
+ // readBytes;
+ // writtenRecords;
+ return ans;
+ }
+
+ /**
+ * Translates a hal wifiDebugRingBufferFlag to the WifiNative version
+ */
+ private static int frameworkRingBufferFlagsFromHal(int wifiDebugRingBufferFlag) {
+ BitMask checkoff = new BitMask(wifiDebugRingBufferFlag);
+ int flags = 0;
+ if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES)) {
+ flags |= WifiNative.RingBufferStatus.HAS_BINARY_ENTRIES;
+ }
+ if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES)) {
+ flags |= WifiNative.RingBufferStatus.HAS_ASCII_ENTRIES;
+ }
+ if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES)) {
+ flags |= WifiNative.RingBufferStatus.HAS_PER_PACKET_ENTRIES;
+ }
+ if (checkoff.value != 0) {
+ throw new IllegalArgumentException("Unknown WifiDebugRingBufferFlag " + checkoff.value);
+ }
+ return flags;
+ }
+
+ private static WifiChip.WifiRadioCombinationMatrix halToFrameworkRadioCombinationMatrix(
+ WifiRadioCombinationMatrix halMatrix) {
+ List<WifiChip.WifiRadioCombination> frameworkCombos = new ArrayList<>();
+ for (WifiRadioCombination combo : halMatrix.radioCombinations) {
+ frameworkCombos.add(halToFrameworkRadioCombination(combo));
+ }
+ return new WifiChip.WifiRadioCombinationMatrix(frameworkCombos);
+ }
+
+ private static WifiChip.WifiRadioCombination halToFrameworkRadioCombination(
+ WifiRadioCombination halCombo) {
+ List<WifiChip.WifiRadioConfiguration> frameworkConfigs = new ArrayList<>();
+ for (WifiRadioConfiguration config : halCombo.radioConfigurations) {
+ frameworkConfigs.add(halToFrameworkRadioConfiguration(config));
+ }
+ return new WifiChip.WifiRadioCombination(frameworkConfigs);
+ }
+
+ private static WifiChip.WifiRadioConfiguration halToFrameworkRadioConfiguration(
+ WifiRadioConfiguration halConfig) {
+ return new WifiChip.WifiRadioConfiguration(halToFrameworkWifiBand(halConfig.bandInfo),
+ halToFrameworkAntennaMode(halConfig.antennaMode));
+ }
+
+ /**
+ * Makes the Hal flavor of WifiScanner's band indication
+ *
+ * Note: This method is only used by background scan which does not
+ * support 6GHz, hence band combinations including 6GHz are considered invalid
+ *
+ * @param frameworkBand one of WifiScanner.WIFI_BAND_*
+ * @return A WifiBand value
+ * @throws IllegalArgumentException if frameworkBand is not recognized
+ */
+ private static int frameworkToHalWifiBand(int frameworkBand) {
+ switch (frameworkBand) {
+ case WifiScanner.WIFI_BAND_UNSPECIFIED:
+ return WifiBand.BAND_UNSPECIFIED;
+ case WifiScanner.WIFI_BAND_24_GHZ:
+ return WifiBand.BAND_24GHZ;
+ case WifiScanner.WIFI_BAND_5_GHZ:
+ return WifiBand.BAND_5GHZ;
+ case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY:
+ return WifiBand.BAND_5GHZ_DFS;
+ case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS:
+ return WifiBand.BAND_5GHZ_WITH_DFS;
+ case WifiScanner.WIFI_BAND_BOTH:
+ return WifiBand.BAND_24GHZ_5GHZ;
+ case WifiScanner.WIFI_BAND_BOTH_WITH_DFS:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS;
+ case WifiScanner.WIFI_BAND_6_GHZ:
+ return WifiBand.BAND_6GHZ;
+ case WifiScanner.WIFI_BAND_24_5_6_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_6GHZ;
+ case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ;
+ case WifiScanner.WIFI_BAND_60_GHZ:
+ return WifiBand.BAND_60GHZ;
+ case WifiScanner.WIFI_BAND_24_5_6_60_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_6GHZ_60GHZ;
+ case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ;
+ case WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS:
+ default:
+ throw new IllegalArgumentException("bad band " + frameworkBand);
+ }
+ }
+
+ private static boolean bitmapContains(int bitmap, int expectedBit) {
+ return (bitmap & expectedBit) != 0;
+ }
+
+ private static int halToFrameworkWifiBand(int halBand) {
+ int frameworkBand = 0;
+ if (bitmapContains(halBand, WifiBand.BAND_24GHZ)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_24_GHZ;
+ }
+ if (bitmapContains(halBand, WifiBand.BAND_5GHZ)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ;
+ }
+ if (bitmapContains(halBand, WifiBand.BAND_5GHZ_DFS)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY;
+ }
+ if (bitmapContains(halBand, WifiBand.BAND_6GHZ)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_6_GHZ;
+ }
+ if (bitmapContains(halBand, WifiBand.BAND_60GHZ)) {
+ frameworkBand |= WifiScanner.WIFI_BAND_60_GHZ;
+ }
+ return frameworkBand;
+ }
+
+ private static @WifiChip.WifiAntennaMode int halToFrameworkAntennaMode(int mode) {
+ switch (mode) {
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_UNSPECIFIED:
+ return WifiChip.WIFI_ANTENNA_MODE_UNSPECIFIED;
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_1X1:
+ return WifiChip.WIFI_ANTENNA_MODE_1X1;
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_2X2:
+ return WifiChip.WIFI_ANTENNA_MODE_2X2;
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_3X3:
+ return WifiChip.WIFI_ANTENNA_MODE_3X3;
+ case WifiAntennaMode.WIFI_ANTENNA_MODE_4X4:
+ return WifiChip.WIFI_ANTENNA_MODE_4X4;
+ default:
+ Log.e(TAG, "Invalid WifiAntennaMode: " + mode);
+ return -1;
+ }
+ }
+
+ /**
+ * Convert framework's operational mode to HAL's operational mode.
+ */
+ private int frameworkToHalIfaceMode(@WifiAvailableChannel.OpMode int mode) {
+ int halMode = 0;
+ if ((mode & WifiAvailableChannel.OP_MODE_STA) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_STA;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_SAP) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_SOFTAP;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_P2P_CLIENT;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_P2P_GO;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_WIFI_AWARE) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_NAN;
+ }
+ if ((mode & WifiAvailableChannel.OP_MODE_TDLS) != 0) {
+ halMode |= WifiIfaceMode.IFACE_MODE_TDLS;
+ }
+ return halMode;
+ }
+
+ /**
+ * Convert framework's WifiAvailableChannel.FILTER_* to HAL's UsableChannelFilter.
+ */
+ private int frameworkToHalUsableFilter(@WifiAvailableChannel.Filter int filter) {
+ int halFilter = 0; // O implies no additional filter other than regulatory (default)
+
+ if ((filter & WifiAvailableChannel.FILTER_CONCURRENCY) != 0) {
+ halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter.CONCURRENCY;
+ }
+ if ((filter & WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE) != 0) {
+ halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter
+ .CELLULAR_COEXISTENCE;
+ }
+
+ return halFilter;
+ }
+
+ /**
+ * Convert framework's WifiAvailableChannel.FILTER_* to HAL's UsableChannelFilter 1.6.
+ */
+ private int frameworkToHalUsableFilter_1_6(@WifiAvailableChannel.Filter int filter) {
+ int halFilter = 0; // O implies no additional filter other than regulatory (default)
+
+ if ((filter & WifiAvailableChannel.FILTER_CONCURRENCY) != 0) {
+ halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter.CONCURRENCY;
+ }
+ if ((filter & WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE) != 0) {
+ halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter
+ .CELLULAR_COEXISTENCE;
+ }
+ if ((filter & WifiAvailableChannel.FILTER_NAN_INSTANT_MODE) != 0) {
+ halFilter |= android.hardware.wifi.V1_6.IWifiChip.UsableChannelFilter.NAN_INSTANT_MODE;
+ }
+
+ return halFilter;
+ }
+
+ /**
+ * Convert from HAL's operational mode to framework's operational mode.
+ */
+ private @WifiAvailableChannel.OpMode int halToFrameworkIfaceMode(int halMode) {
+ int mode = 0;
+ if ((halMode & WifiIfaceMode.IFACE_MODE_STA) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_STA;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_SOFTAP) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_SAP;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_CLIENT) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_GO) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_NAN) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_WIFI_AWARE;
+ }
+ if ((halMode & WifiIfaceMode.IFACE_MODE_TDLS) != 0) {
+ mode |= WifiAvailableChannel.OP_MODE_TDLS;
+ }
+ return mode;
+ }
+
+ @NonNull
+ private ArrayList<android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel>
+ frameworkCoexUnsafeChannelsToHidl(
+ @NonNull List<android.net.wifi.CoexUnsafeChannel> frameworkUnsafeChannels) {
+ final ArrayList<android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel> hidlList =
+ new ArrayList<>();
+ if (!SdkLevel.isAtLeastS()) {
+ return hidlList;
+ }
+ for (android.net.wifi.CoexUnsafeChannel frameworkUnsafeChannel : frameworkUnsafeChannels) {
+ final android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel hidlUnsafeChannel =
+ new android.hardware.wifi.V1_5.IWifiChip.CoexUnsafeChannel();
+ switch (frameworkUnsafeChannel.getBand()) {
+ case (WifiScanner.WIFI_BAND_24_GHZ):
+ hidlUnsafeChannel.band = WifiBand.BAND_24GHZ;
+ break;
+ case (WifiScanner.WIFI_BAND_5_GHZ):
+ hidlUnsafeChannel.band = WifiBand.BAND_5GHZ;
+ break;
+ case (WifiScanner.WIFI_BAND_6_GHZ):
+ hidlUnsafeChannel.band = WifiBand.BAND_6GHZ;
+ break;
+ case (WifiScanner.WIFI_BAND_60_GHZ):
+ hidlUnsafeChannel.band = WifiBand.BAND_60GHZ;
+ break;
+ default:
+ Log.e(TAG, "Tried to set unsafe channel with unknown band: "
+ + frameworkUnsafeChannel.getBand());
+ continue;
+ }
+ hidlUnsafeChannel.channel = frameworkUnsafeChannel.getChannel();
+ final int powerCapDbm = frameworkUnsafeChannel.getPowerCapDbm();
+ if (powerCapDbm != POWER_CAP_NONE) {
+ hidlUnsafeChannel.powerCapDbm = powerCapDbm;
+ } else {
+ hidlUnsafeChannel.powerCapDbm =
+ android.hardware.wifi.V1_5.IWifiChip.PowerCapConstant.NO_POWER_CAP;
+ }
+ hidlList.add(hidlUnsafeChannel);
+ }
+ return hidlList;
+ }
+
+ private int frameworkCoexRestrictionsToHidl(@WifiManager.CoexRestriction int restrictions) {
+ int hidlRestrictions = 0;
+ if (!SdkLevel.isAtLeastS()) {
+ return hidlRestrictions;
+ }
+ if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_DIRECT) != 0) {
+ hidlRestrictions |= android.hardware.wifi.V1_5.IWifiChip.CoexRestriction.WIFI_DIRECT;
+ }
+ if ((restrictions & WifiManager.COEX_RESTRICTION_SOFTAP) != 0) {
+ hidlRestrictions |= android.hardware.wifi.V1_5.IWifiChip.CoexRestriction.SOFTAP;
+ }
+ if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_AWARE) != 0) {
+ hidlRestrictions |= android.hardware.wifi.V1_5.IWifiChip.CoexRestriction.WIFI_AWARE;
+ }
+ return hidlRestrictions;
+ }
+
+ private byte frameworkMultiStaUseCaseToHidl(@WifiNative.MultiStaUseCase int useCase)
+ throws IllegalArgumentException {
+ switch (useCase) {
+ case WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY:
+ return android.hardware.wifi.V1_5.IWifiChip
+ .MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+ case WifiNative.DUAL_STA_NON_TRANSIENT_UNBIASED:
+ return android.hardware.wifi.V1_5.IWifiChip
+ .MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED;
+ default:
+ throw new IllegalArgumentException("Invalid use case " + useCase);
+ }
+ }
+
+ /**
+ * This method checks if we need to backoff wifi Tx power due to SAR requirements.
+ * It handles the case when the device is running the V1_1 version of WifiChip HAL
+ * In that HAL version, it is required to perform wifi Tx power backoff only if
+ * a voice call is ongoing.
+ */
+ private static boolean sarPowerBackoffRequired_1_1(SarInfo sarInfo) {
+ /* As long as no voice call is active (in case voice call is supported),
+ * no backoff is needed
+ */
+ if (sarInfo.sarVoiceCallSupported) {
+ return (sarInfo.isVoiceCall || sarInfo.isEarPieceActive);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * This method maps the information inside the SarInfo instance into a SAR scenario
+ * when device is running the V1_1 version of WifiChip HAL.
+ * In this HAL version, only one scenario is defined which is for VOICE_CALL (if voice call is
+ * supported).
+ * Otherwise, an exception is thrown.
+ */
+ private static int frameworkToHalTxPowerScenario_1_1(SarInfo sarInfo) {
+ if (sarInfo.sarVoiceCallSupported && (sarInfo.isVoiceCall || sarInfo.isEarPieceActive)) {
+ return android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL;
+ } else {
+ throw new IllegalArgumentException("bad scenario: voice call not active/supported");
+ }
+ }
+
+ /**
+ * This method checks if we need to backoff wifi Tx power due to SAR requirements.
+ * It handles the case when the device is running the V1_2 version of WifiChip HAL
+ */
+ private static boolean sarPowerBackoffRequired_1_2(SarInfo sarInfo) {
+ if (sarInfo.sarSapSupported && sarInfo.isWifiSapEnabled) {
+ return true;
+ }
+ if (sarInfo.sarVoiceCallSupported && (sarInfo.isVoiceCall || sarInfo.isEarPieceActive)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * This method maps the information inside the SarInfo instance into a SAR scenario
+ * when device is running the V1_2 version of WifiChip HAL.
+ * If SAR SoftAP input is supported,
+ * we make these assumptions:
+ * - All voice calls are treated as if device is near the head.
+ * - SoftAP scenario is treated as if device is near the body.
+ * In case SoftAP is not supported, then we should revert to the V1_1 HAL
+ * behavior, and the only valid scenario would be when a voice call is ongoing.
+ */
+ private static int frameworkToHalTxPowerScenario_1_2(SarInfo sarInfo) {
+ if (sarInfo.sarSapSupported && sarInfo.sarVoiceCallSupported) {
+ if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) {
+ return android.hardware.wifi.V1_2.IWifiChip
+ .TxPowerScenario.ON_HEAD_CELL_ON;
+ } else if (sarInfo.isWifiSapEnabled) {
+ return android.hardware.wifi.V1_2.IWifiChip
+ .TxPowerScenario.ON_BODY_CELL_ON;
+ } else {
+ throw new IllegalArgumentException("bad scenario: no voice call/softAP active");
+ }
+ } else if (sarInfo.sarVoiceCallSupported) {
+ /* SAR SoftAP input not supported, act like V1_1 */
+ if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) {
+ return android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL;
+ } else {
+ throw new IllegalArgumentException("bad scenario: voice call not active");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid case: voice call not supported");
+ }
+ }
+
+ protected android.hardware.wifi.V1_1.IWifiChip getWifiChipV1_1Mockable() {
+ return android.hardware.wifi.V1_1.IWifiChip.castFrom(mWifiChip);
+ }
+
+ protected android.hardware.wifi.V1_2.IWifiChip getWifiChipV1_2Mockable() {
+ return android.hardware.wifi.V1_2.IWifiChip.castFrom(mWifiChip);
+ }
+
+ protected android.hardware.wifi.V1_3.IWifiChip getWifiChipV1_3Mockable() {
+ return android.hardware.wifi.V1_3.IWifiChip.castFrom(mWifiChip);
+ }
+
+ protected android.hardware.wifi.V1_4.IWifiChip getWifiChipV1_4Mockable() {
+ return android.hardware.wifi.V1_4.IWifiChip.castFrom(mWifiChip);
+ }
+
+ protected android.hardware.wifi.V1_5.IWifiChip getWifiChipV1_5Mockable() {
+ return android.hardware.wifi.V1_5.IWifiChip.castFrom(mWifiChip);
+ }
+
+ protected android.hardware.wifi.V1_6.IWifiChip getWifiChipV1_6Mockable() {
+ return android.hardware.wifi.V1_6.IWifiChip.castFrom(mWifiChip);
+ }
+
+ private static int[] intsFromArrayList(ArrayList<Integer> a) {
+ if (a == null) return null;
+ int[] b = new int[a.size()];
+ int i = 0;
+ for (Integer e : a) b[i++] = e;
+ return b;
+ }
+
+ private boolean isOk(WifiStatus status, String methodStr) {
+ if (status.code == WifiStatusCode.SUCCESS) return true;
+ Log.e(TAG, methodStr + " failed with status: " + status);
+ return false;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ mWifiChip = null;
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiChip == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiChip is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiHal.java b/service/java/com/android/server/wifi/hal/WifiHal.java
new file mode 100644
index 0000000000..05203d48bd
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiHal.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.SsidTranslator;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * Wrapper around the root Wifi HAL.
+ * Depending on the service available, may initialize using HIDL or AIDL.
+ */
+public class WifiHal {
+ private static final String TAG = "WifiHal";
+ private IWifiHal mWifiHal;
+
+ /**
+ * Wifi operation status codes.
+ */
+ public static final int WIFI_STATUS_SUCCESS = 0;
+ public static final int WIFI_STATUS_ERROR_WIFI_CHIP_INVALID = 1;
+ public static final int WIFI_STATUS_ERROR_WIFI_IFACE_INVALID = 2;
+ public static final int WIFI_STATUS_ERROR_WIFI_RTT_CONTROLLER_INVALID = 3;
+ public static final int WIFI_STATUS_ERROR_NOT_SUPPORTED = 4;
+ public static final int WIFI_STATUS_ERROR_NOT_AVAILABLE = 5;
+ public static final int WIFI_STATUS_ERROR_NOT_STARTED = 6;
+ public static final int WIFI_STATUS_ERROR_INVALID_ARGS = 7;
+ public static final int WIFI_STATUS_ERROR_BUSY = 8;
+ public static final int WIFI_STATUS_ERROR_UNKNOWN = 9;
+ public static final int WIFI_STATUS_ERROR_REMOTE_EXCEPTION = 10;
+
+ @IntDef(prefix = { "WIFI_STATUS_" }, value = {
+ WIFI_STATUS_SUCCESS,
+ WIFI_STATUS_ERROR_WIFI_CHIP_INVALID,
+ WIFI_STATUS_ERROR_WIFI_IFACE_INVALID,
+ WIFI_STATUS_ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ WIFI_STATUS_ERROR_NOT_SUPPORTED,
+ WIFI_STATUS_ERROR_NOT_AVAILABLE,
+ WIFI_STATUS_ERROR_NOT_STARTED,
+ WIFI_STATUS_ERROR_INVALID_ARGS,
+ WIFI_STATUS_ERROR_BUSY,
+ WIFI_STATUS_ERROR_UNKNOWN,
+ WIFI_STATUS_ERROR_REMOTE_EXCEPTION,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WifiStatusCode {}
+
+ /**
+ * Interface that can be created by the Wi-Fi HAL.
+ */
+ public interface WifiInterface {
+ /**
+ * Get the name of this interface.
+ */
+ String getName();
+ }
+
+ /**
+ * Framework callback object. Will get called when the equivalent events are received
+ * from the HAL.
+ */
+ public interface Callback {
+ /**
+ * Called when the Wi-Fi system failed in a way that caused it be disabled.
+ * Calling start again must restart Wi-Fi as if stop then start was called
+ * (full state reset). When this event is received, all WifiChip & WifiIface
+ * objects retrieved after the last call to start will be considered invalid.
+ *
+ * @param status Failure reason code.
+ */
+ void onFailure(@WifiStatusCode int status);
+
+ /**
+ * Called in response to a call to start, indicating that the operation
+ * completed. After this callback the HAL must be fully operational.
+ */
+ void onStart();
+
+ /**
+ * Called in response to a call to stop, indicating that the operation
+ * completed. When this event is received, all WifiChip objects retrieved
+ * after the last call to start will be considered invalid.
+ */
+ void onStop();
+
+ /**
+ * Must be called when the Wi-Fi subsystem restart completes.
+ * Once this event is received, the framework must fully reset the Wi-Fi stack state.
+ *
+ * @param status Status code.
+ */
+ void onSubsystemRestart(@WifiStatusCode int status);
+ }
+
+ /**
+ * Framework death recipient object. Called if the death recipient registered with the HAL
+ * indicates that the service died.
+ */
+ public interface DeathRecipient {
+ /**
+ * Called on service death.
+ */
+ void onDeath();
+ }
+
+ public WifiHal(@NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ mWifiHal = createWifiHalMockable(context, ssidTranslator);
+ }
+
+ @VisibleForTesting
+ protected IWifiHal createWifiHalMockable(@NonNull Context context,
+ @NonNull SsidTranslator ssidTranslator) {
+ if (WifiHalAidlImpl.serviceDeclared()) {
+ return new WifiHalAidlImpl(context, ssidTranslator);
+ } else if (WifiHalHidlImpl.serviceDeclared()) {
+ return new WifiHalHidlImpl(context, ssidTranslator);
+ } else {
+ Log.e(TAG, "No HIDL or AIDL service available for the Wifi Vendor HAL.");
+ return null;
+ }
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiHal == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiHal is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+
+ /**
+ * See comments for {@link IWifiHal#getChip(int)}
+ */
+ @Nullable
+ public WifiChip getChip(int chipId) {
+ return validateAndCall("getChip", null,
+ () -> mWifiHal.getChip(chipId));
+ }
+
+ /**
+ * See comments for {@link IWifiHal#getChipIds()}
+ */
+ @Nullable
+ public List<Integer> getChipIds() {
+ return validateAndCall("getChipIds", null,
+ () -> mWifiHal.getChipIds());
+ }
+
+ /**
+ * See comments for {@link IWifiHal#registerEventCallback(Callback)}
+ */
+ public boolean registerEventCallback(Callback callback) {
+ return validateAndCall("registerEventCallback", false,
+ () -> mWifiHal.registerEventCallback(callback));
+ }
+
+ /**
+ * See comments for {@link IWifiHal#initialize(DeathRecipient)}
+ */
+ public void initialize(WifiHal.DeathRecipient deathRecipient) {
+ if (mWifiHal != null) {
+ mWifiHal.initialize(deathRecipient);
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#isInitializationComplete()}
+ */
+ public boolean isInitializationComplete() {
+ return validateAndCall("isInitializationComplete", false,
+ () -> mWifiHal.isInitializationComplete());
+ }
+
+ /**
+ * See comments for {@link IWifiHal#isSupported()}
+ */
+ public boolean isSupported() {
+ return validateAndCall("isSupported", false,
+ () -> mWifiHal.isSupported());
+ }
+
+ /**
+ * See comments for {@link IWifiHal#start()}
+ */
+ public @WifiStatusCode int start() {
+ return validateAndCall("start", WIFI_STATUS_ERROR_UNKNOWN,
+ () -> mWifiHal.start());
+ }
+
+ /**
+ * See comments for {@link IWifiHal#isStarted()}
+ */
+ public boolean isStarted() {
+ return validateAndCall("isStarted", false,
+ () -> mWifiHal.isStarted());
+ }
+
+ /**
+ * See comments for {@link IWifiHal#stop()}
+ */
+ public boolean stop() {
+ return validateAndCall("stop", false,
+ () -> mWifiHal.stop());
+ }
+
+ /**
+ * See comments for {@link IWifiHal#invalidate()}
+ */
+ public void invalidate() {
+ if (mWifiHal != null) {
+ mWifiHal.invalidate();
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiHalAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiHalAidlImpl.java
new file mode 100644
index 0000000000..1ba9a79c6a
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiHalAidlImpl.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.wifi.IWifiChip;
+import android.hardware.wifi.IWifiEventCallback;
+import android.hardware.wifi.WifiStatusCode;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.server.wifi.SsidTranslator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * AIDL implementation of the IWifiHal interface.
+ */
+public class WifiHalAidlImpl implements IWifiHal {
+ private static final String TAG = "WifiHalAidlImpl";
+ private static final String HAL_INSTANCE_NAME =
+ android.hardware.wifi.IWifi.DESCRIPTOR + "/default";
+
+ private android.hardware.wifi.IWifi mWifi;
+ private Context mContext;
+ private SsidTranslator mSsidTranslator;
+ private IWifiEventCallback mHalCallback;
+ private WifiHal.Callback mFrameworkCallback;
+ private DeathRecipient mServiceDeathRecipient;
+ private WifiHal.DeathRecipient mFrameworkDeathRecipient;
+ private final Object mLock = new Object();
+
+ public WifiHalAidlImpl(@NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ Log.i(TAG, "Creating the Wifi HAL using the AIDL implementation");
+ mContext = context;
+ mSsidTranslator = ssidTranslator;
+ mServiceDeathRecipient = new WifiDeathRecipient();
+ mHalCallback = new WifiEventCallback();
+ }
+
+ /**
+ * See comments for {@link IWifiHal#getChip(int)}
+ */
+ @Override
+ @Nullable
+ public WifiChip getChip(int chipId) {
+ final String methodStr = "getChip";
+ synchronized (mLock) {
+ try {
+ if (!checkWifiAndLogFailure(methodStr)) return null;
+ IWifiChip chip = mWifi.getChip(chipId);
+ return new WifiChip(chip, mContext, mSsidTranslator);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#getChipIds()}
+ */
+ @Override
+ @Nullable
+ public List<Integer> getChipIds() {
+ final String methodStr = "getChipIds";
+ synchronized (mLock) {
+ try {
+ if (!checkWifiAndLogFailure(methodStr)) return null;
+ int[] chipIdArray = mWifi.getChipIds();
+ List<Integer> chipIdList = new ArrayList<>();
+ for (int id : chipIdArray) {
+ chipIdList.add(id);
+ }
+ return chipIdList;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#registerEventCallback(WifiHal.Callback)}
+ */
+ @Override
+ public boolean registerEventCallback(WifiHal.Callback callback) {
+ synchronized (mLock) {
+ if (mFrameworkCallback != null) {
+ Log.e(TAG, "Framework callback is already registered");
+ return false;
+ } else if (callback == null) {
+ Log.e(TAG, "Cannot register a null callback");
+ return false;
+ }
+ if (!registerHalCallback()) return false;
+ mFrameworkCallback = callback;
+ return true;
+ }
+ }
+
+ private boolean registerHalCallback() {
+ final String methodStr = "registerHalCallback";
+ try {
+ mWifi.registerEventCallback(mHalCallback);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+
+ /**
+ * See comments for {@link IWifiHal#isInitializationComplete()}
+ */
+ @Override
+ public boolean isInitializationComplete() {
+ synchronized (mLock) {
+ return mWifi != null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#isSupported()}
+ */
+ @Override
+ public boolean isSupported() {
+ return serviceDeclared();
+ }
+
+ /**
+ * Indicates whether the AIDL service is declared.
+ */
+ protected static boolean serviceDeclared() {
+ // Service Manager API ServiceManager#isDeclared is supported after U.
+ return SdkLevel.isAtLeastU() ? ServiceManager.isDeclared(HAL_INSTANCE_NAME) : false;
+ }
+
+ /**
+ * See comments for {@link IWifiHal#start()}
+ */
+ @Override
+ public @WifiHal.WifiStatusCode int start() {
+ final String methodStr = "start";
+ synchronized (mLock) {
+ try {
+ if (!checkWifiAndLogFailure(methodStr)) return WifiHal.WIFI_STATUS_ERROR_UNKNOWN;
+ mWifi.start();
+ return WifiHal.WIFI_STATUS_SUCCESS;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION;
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ return halToFrameworkWifiStatusCode(e.errorCode);
+ }
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#isStarted()}
+ */
+ @Override
+ public boolean isStarted() {
+ final String methodStr = "isStarted";
+ synchronized (mLock) {
+ try {
+ if (!checkWifiAndLogFailure(methodStr)) return false;
+ return mWifi.isStarted();
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#stop()}
+ */
+ @Override
+ public boolean stop() {
+ synchronized (mLock) {
+ if (!checkWifiAndLogFailure("stop")) return false;
+ boolean result = stopInternal();
+ return result;
+ }
+ }
+
+ private boolean stopInternal() {
+ final String methodStr = "stopInternal";
+ try {
+ mWifi.stop();
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+
+ /**
+ * See comments for {@link IWifiHal#initialize(WifiHal.DeathRecipient)}
+ */
+ @Override
+ public void initialize(WifiHal.DeathRecipient deathRecipient) {
+ final String methodStr = "initialize";
+ synchronized (mLock) {
+ if (mWifi != null) {
+ Log.i(TAG, "Service is already initialized");
+ return;
+ }
+
+ mWifi = getWifiServiceMockable();
+ if (mWifi == null) {
+ Log.e(TAG, "Unable to obtain the IWifi binder");
+ return;
+ }
+ Log.i(TAG, "Obtained the IWifi binder. Local Version: "
+ + android.hardware.wifi.IWifi.VERSION);
+
+ try {
+ Log.i(TAG, "Remote Version: " + mWifi.getInterfaceVersion());
+ IBinder serviceBinder = getServiceBinderMockable();
+ if (serviceBinder == null) {
+ Log.e(TAG, "Unable to obtain the service binder");
+ return;
+ }
+ serviceBinder.linkToDeath(mServiceDeathRecipient, /* flags= */ 0);
+ mFrameworkDeathRecipient = deathRecipient;
+
+ // Stop wifi just in case. Stop will invalidate the callbacks, so re-register them.
+ stopInternal();
+ registerHalCallback();
+ Log.i(TAG, "Initialization was successful");
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#invalidate()}
+ */
+ public void invalidate() {
+ synchronized (mLock) {
+ mWifi = null;
+ }
+ }
+
+ private class WifiEventCallback extends IWifiEventCallback.Stub {
+ @Override
+ public void onStart() throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onStart();
+ }
+
+ @Override
+ public void onStop() throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onStop();
+ }
+
+ @Override
+ public void onFailure(int statusCode) throws RemoteException {
+ synchronized (mLock) {
+ mWifi = null;
+ }
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onFailure(halToFrameworkWifiStatusCode(statusCode));
+ }
+
+ @Override
+ public void onSubsystemRestart(int statusCode) throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onSubsystemRestart(halToFrameworkWifiStatusCode(statusCode));
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return IWifiEventCallback.HASH;
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return IWifiEventCallback.VERSION;
+ }
+ }
+
+ private class WifiDeathRecipient implements DeathRecipient {
+ @Override
+ public void binderDied() {
+ synchronized (mLock) {
+ Log.w(TAG, "IWifi binder died.");
+ mWifi = null;
+ if (mFrameworkDeathRecipient != null) {
+ mFrameworkDeathRecipient.onDeath();
+ }
+ }
+ }
+ }
+
+
+ // Utilities
+
+ protected static @WifiHal.WifiStatusCode int halToFrameworkWifiStatusCode(int code) {
+ switch (code) {
+ case WifiStatusCode.SUCCESS:
+ return WifiHal.WIFI_STATUS_SUCCESS;
+ case WifiStatusCode.ERROR_WIFI_CHIP_INVALID:
+ return WifiHal.WIFI_STATUS_ERROR_WIFI_CHIP_INVALID;
+ case WifiStatusCode.ERROR_WIFI_IFACE_INVALID:
+ return WifiHal.WIFI_STATUS_ERROR_WIFI_IFACE_INVALID;
+ case WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID:
+ return WifiHal.WIFI_STATUS_ERROR_WIFI_RTT_CONTROLLER_INVALID;
+ case WifiStatusCode.ERROR_NOT_SUPPORTED:
+ return WifiHal.WIFI_STATUS_ERROR_NOT_SUPPORTED;
+ case WifiStatusCode.ERROR_NOT_AVAILABLE:
+ return WifiHal.WIFI_STATUS_ERROR_NOT_AVAILABLE;
+ case WifiStatusCode.ERROR_NOT_STARTED:
+ return WifiHal.WIFI_STATUS_ERROR_NOT_STARTED;
+ case WifiStatusCode.ERROR_INVALID_ARGS:
+ return WifiHal.WIFI_STATUS_ERROR_INVALID_ARGS;
+ case WifiStatusCode.ERROR_BUSY:
+ return WifiHal.WIFI_STATUS_ERROR_BUSY;
+ case WifiStatusCode.ERROR_UNKNOWN:
+ return WifiHal.WIFI_STATUS_ERROR_UNKNOWN;
+ default:
+ Log.e(TAG, "Invalid WifiStatusCode received: " + code);
+ return WifiHal.WIFI_STATUS_ERROR_UNKNOWN;
+ }
+ }
+
+ @VisibleForTesting
+ protected android.hardware.wifi.IWifi getWifiServiceMockable() {
+ try {
+ return android.hardware.wifi.IWifi.Stub.asInterface(
+ ServiceManager.waitForDeclaredService(HAL_INSTANCE_NAME));
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to get IWifi service, " + e);
+ return null;
+ }
+ }
+
+ @VisibleForTesting
+ protected IBinder getServiceBinderMockable() {
+ if (mWifi == null) return null;
+ return mWifi.asBinder();
+ }
+
+ private boolean checkWifiAndLogFailure(String methodStr) {
+ if (mWifi == null) {
+ Log.e(TAG, "Unable to call " + methodStr + " because IWifi is null.");
+ return false;
+ }
+ return true;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ mWifi = null;
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ }
+
+ private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with service-specific exception: " + e);
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiHalHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiHalHidlImpl.java
new file mode 100644
index 0000000000..f9fe456211
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiHalHidlImpl.java
@@ -0,0 +1,591 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.wifi.V1_0.IWifi;
+import android.hardware.wifi.V1_0.WifiStatus;
+import android.hardware.wifi.V1_0.WifiStatusCode;
+import android.hidl.manager.V1_0.IServiceNotification;
+import android.hidl.manager.V1_2.IServiceManager;
+import android.os.IHwBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.server.wifi.SsidTranslator;
+import com.android.server.wifi.util.GeneralUtil.Mutable;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * HIDL implementation of the IWifiHal interface.
+ */
+public class WifiHalHidlImpl implements IWifiHal {
+ private static final String TAG = "WifiHalHidlImpl";
+ private IServiceManager mServiceManager;
+ private android.hardware.wifi.V1_0.IWifi mWifi;
+ private Context mContext;
+ private SsidTranslator mSsidTranslator;
+ private android.hardware.wifi.V1_0.IWifiEventCallback mHalCallback10;
+ private android.hardware.wifi.V1_5.IWifiEventCallback mHalCallback15;
+ private WifiHal.Callback mFrameworkCallback;
+ private ServiceManagerDeathRecipient mServiceManagerDeathRecipient;
+ private WifiDeathRecipient mWifiDeathRecipient;
+ private WifiHal.DeathRecipient mFrameworkDeathRecipient;
+ private boolean mIsVendorHalSupported;
+
+ private final Object mLock = new Object();
+
+ public WifiHalHidlImpl(@NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ Log.i(TAG, "Creating the Wifi HAL using the HIDL implementation");
+ mContext = context;
+ mSsidTranslator = ssidTranslator;
+ mServiceManagerDeathRecipient = new ServiceManagerDeathRecipient();
+ mWifiDeathRecipient = new WifiDeathRecipient();
+ mHalCallback10 = new WifiEventCallback();
+ mHalCallback15 = new WifiEventCallbackV15();
+ }
+
+ /**
+ * See comments for {@link IWifiHal#getChip(int)}
+ */
+ @Override
+ @Nullable
+ public WifiChip getChip(int chipId) {
+ synchronized (mLock) {
+ final String methodStr = "getChip";
+ return validateAndCall(methodStr, null,
+ () -> getChipInternal(methodStr, chipId));
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#getChipIds()}
+ */
+ @Override
+ @Nullable
+ public List<Integer> getChipIds() {
+ synchronized (mLock) {
+ final String methodStr = "getChipIds";
+ return validateAndCall(methodStr, null,
+ () -> getChipIdsInternal(methodStr));
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#registerEventCallback(WifiHal.Callback)}
+ */
+ @Override
+ public boolean registerEventCallback(WifiHal.Callback callback) {
+ synchronized (mLock) {
+ final String methodStr = "registerEventCallback";
+ return validateAndCall(methodStr, false,
+ () -> registerEventCallbackInternal(callback));
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#isInitializationComplete()}
+ */
+ @Override
+ public boolean isInitializationComplete() {
+ synchronized (mLock) {
+ return mWifi != null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#isSupported()}
+ */
+ @Override
+ public boolean isSupported() {
+ synchronized (mLock) {
+ return mIsVendorHalSupported;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#start()}
+ */
+ @Override
+ public @WifiHal.WifiStatusCode int start() {
+ synchronized (mLock) {
+ final String methodStr = "start";
+ return validateAndCall(methodStr, WifiHal.WIFI_STATUS_ERROR_UNKNOWN,
+ () -> startInternal(methodStr));
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#isStarted()}
+ */
+ @Override
+ public boolean isStarted() {
+ synchronized (mLock) {
+ final String methodStr = "isStarted";
+ return validateAndCall(methodStr, false,
+ () -> isStartedInternal(methodStr));
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#stop()}
+ */
+ @Override
+ public boolean stop() {
+ synchronized (mLock) {
+ final String methodStr = "stop";
+ boolean result = validateAndCall(methodStr, false,
+ () -> stopInternal(methodStr));
+ return result;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#initialize(WifiHal.DeathRecipient)}
+ */
+ @Override
+ public void initialize(WifiHal.DeathRecipient deathRecipient) {
+ synchronized (mLock) {
+ Log.i(TAG, "Initializing the WiFi HAL");
+ mFrameworkDeathRecipient = deathRecipient;
+ initServiceManagerIfNecessaryLocked();
+ if (mIsVendorHalSupported) {
+ initWifiIfNecessaryLocked();
+ }
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiHal#invalidate()}
+ */
+ public void invalidate() {
+ synchronized (mLock) {
+ mWifi = null;
+ }
+ }
+
+
+ // Internal Implementations
+
+ private WifiChip getChipInternal(String methodStr, int chipId) {
+ Mutable<WifiChip> chipResp = new Mutable<>();
+ try {
+ mWifi.getChip(chipId, (status, chip) -> {
+ if (isOk(status, methodStr)) {
+ chipResp.value = new WifiChip(chip, mContext, mSsidTranslator);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return chipResp.value;
+ }
+
+ private List<Integer> getChipIdsInternal(String methodStr) {
+ Mutable<List<Integer>> chipIdResp = new Mutable<>();
+ try {
+ mWifi.getChipIds((status, chipIds) -> {
+ if (isOk(status, methodStr)) {
+ chipIdResp.value = chipIds;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return chipIdResp.value;
+ }
+
+ private boolean registerEventCallbackInternal(WifiHal.Callback callback) {
+ if (mFrameworkCallback != null) {
+ Log.e(TAG, "Framework callback is already registered");
+ return false;
+ } else if (callback == null) {
+ Log.e(TAG, "Cannot register a null callback");
+ return false;
+ }
+
+ if (!registerHalCallback()) return false;
+ mFrameworkCallback = callback;
+ return true;
+ }
+
+ private boolean registerHalCallback() {
+ final String methodStr = "registerHalCallback";
+ try {
+ android.hardware.wifi.V1_5.IWifi wifi15 = getWifiV1_5Mockable();
+ WifiStatus status;
+ if (wifi15 != null) {
+ status = wifi15.registerEventCallback_1_5(mHalCallback15);
+ } else {
+ status = mWifi.registerEventCallback(mHalCallback10);
+ }
+
+ if (!isOk(status, methodStr)) {
+ Log.e(TAG, "Unable to register HAL callback");
+ mWifi = null;
+ return false;
+ }
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private @WifiHal.WifiStatusCode int startInternal(String methodStr) {
+ try {
+ WifiStatus status = mWifi.start();
+ return halToFrameworkWifiStatusCode(status.code);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return WifiHal.WIFI_STATUS_ERROR_UNKNOWN;
+ }
+ }
+
+ private boolean isStartedInternal(String methodStr) {
+ try {
+ return mWifi.isStarted();
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean stopInternal(String methodStr) {
+ try {
+ WifiStatus status = mWifi.stop();
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private class WifiEventCallback extends android.hardware.wifi.V1_0.IWifiEventCallback.Stub {
+ @Override
+ public void onStart() throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onStart();
+ }
+
+ @Override
+ public void onStop() throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onStop();
+ }
+
+ @Override
+ public void onFailure(WifiStatus status) throws RemoteException {
+ synchronized (mLock) {
+ mWifi = null;
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onFailure(halToFrameworkWifiStatusCode(status.code));
+ }
+ }
+ }
+
+ private class WifiEventCallbackV15 extends android.hardware.wifi.V1_5.IWifiEventCallback.Stub {
+ @Override
+ public void onStart() throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mHalCallback10.onStart();
+ }
+
+ @Override
+ public void onStop() throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mHalCallback10.onStop();
+ }
+
+ @Override
+ public void onFailure(WifiStatus status) throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mHalCallback10.onFailure(status);
+ }
+
+ @Override
+ public void onSubsystemRestart(WifiStatus status) throws RemoteException {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onSubsystemRestart(halToFrameworkWifiStatusCode(status.code));
+ }
+ }
+
+ private class ServiceManagerDeathRecipient implements IHwBinder.DeathRecipient {
+ @Override
+ public void serviceDied(long cookie) {
+ Log.wtf(TAG, "IServiceManager died: cookie=" + cookie);
+ mServiceManager = null;
+ // theoretically can call initServiceManager again here - but
+ // there's no point since most likely system is going to reboot
+ }
+ }
+
+ private class WifiDeathRecipient implements IHwBinder.DeathRecipient {
+ @Override
+ public void serviceDied(long cookie) {
+ synchronized (mLock) {
+ Log.e(TAG, "IWifi HAL service died! Have a listener for it ... cookie="
+ + cookie);
+ mWifi = null;
+ if (mFrameworkDeathRecipient != null) {
+ mFrameworkDeathRecipient.onDeath();
+ }
+ // don't restart: wait for registration notification
+ }
+ }
+ }
+
+ private final IServiceNotification mServiceNotificationCallback =
+ new IServiceNotification.Stub() {
+ @Override
+ public void onRegistration(String fqName, String name, boolean preexisting) {
+ synchronized (mLock) {
+ Log.d(TAG, "IWifi registration notification: fqName=" + fqName
+ + ", name=" + name + ", preexisting=" + preexisting);
+ initWifiIfNecessaryLocked();
+ }
+ }
+ };
+
+
+ // Helper Functions
+
+ private void initServiceManagerIfNecessaryLocked() {
+ if (mServiceManager != null) {
+ Log.i(TAG, "mServiceManager already exists");
+ return;
+ }
+ Log.i(TAG, "initServiceManagerIfNecessaryLocked");
+
+ // Failures of IServiceManager are most likely system breaking.
+ // Behavior here will be to WTF and continue.
+ mServiceManager = getServiceManagerMockable();
+ if (mServiceManager == null) {
+ Log.wtf(TAG, "Failed to get IServiceManager instance");
+ return;
+ }
+
+ try {
+ if (!mServiceManager.linkToDeath(mServiceManagerDeathRecipient, 0)) {
+ Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
+ mServiceManager = null;
+ return;
+ }
+ if (!mServiceManager.registerForNotifications(IWifi.kInterfaceName, "",
+ mServiceNotificationCallback)) {
+ Log.wtf(TAG, "Failed to register a listener for IWifi service");
+ mServiceManager = null;
+ }
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Exception while operating on IServiceManager: " + e);
+ mServiceManager = null;
+ return;
+ }
+ mIsVendorHalSupported = isSupportedInternal();
+ }
+
+ private void initWifiIfNecessaryLocked() {
+ if (mWifi != null) {
+ Log.i(TAG, "mWifi already exists");
+ return;
+ }
+ Log.i(TAG, "initWifiIfNecessaryLocked");
+
+ try {
+ mWifi = getWifiServiceMockable();
+ if (mWifi == null) {
+ Log.e(TAG, "IWifi not (yet) available - but have a listener for it ...");
+ return;
+ }
+
+ if (!mWifi.linkToDeath(mWifiDeathRecipient, /* don't care */ 0)) {
+ Log.e(TAG, "Error on linkToDeath on IWifi - will retry later");
+ return;
+ }
+
+ // Stop wifi just in case. Stop will invalidate the callbacks, so re-register them.
+ stopInternal("stop");
+ registerHalCallback();
+ Log.i(TAG, "mWifi was retrieved. HAL is running version " + getVersion());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while operating on IWifi: " + e);
+ }
+ }
+
+ /**
+ * Uses the IServiceManager to query if the vendor HAL is present in the VINTF for the device
+ * or not.
+ * @return true if supported, false otherwise.
+ */
+ private boolean isSupportedInternal() {
+ if (mServiceManager == null) {
+ Log.e(TAG, "isSupported: called but mServiceManager is null!?");
+ return false;
+ }
+ try {
+ List<String> wifiServices =
+ mServiceManager.listManifestByInterface(IWifi.kInterfaceName);
+ return !wifiServices.isEmpty();
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Exception while operating on IServiceManager: " + e);
+ return false;
+ }
+ }
+
+ /**
+ * Indicates whether the HIDL service is declared. Uses the IServiceManager to check
+ * if the device is running a version >= V1_0 of the HAL from the VINTF for the device.
+ */
+ protected static boolean serviceDeclared() {
+ try {
+ IServiceManager serviceManager = getServiceManagerMockable();
+ if (serviceManager == null) {
+ Log.e(TAG, "Unable to get service manager to check for service.");
+ return false;
+ }
+ String interfaceName = android.hardware.wifi.V1_0.IWifi.kInterfaceName;
+ if (serviceManager.getTransport(interfaceName, "default")
+ != IServiceManager.Transport.EMPTY) {
+ return true;
+ }
+ return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to check for existence of HIDL service.");
+ return false;
+ }
+ }
+
+ private String getVersion() {
+ if (checkHalVersionByInterfaceName(
+ android.hardware.wifi.V1_6.IWifi.kInterfaceName)) {
+ return "1.6";
+ } else if (checkHalVersionByInterfaceName(
+ android.hardware.wifi.V1_5.IWifi.kInterfaceName)) {
+ return "1.5";
+ } else if (checkHalVersionByInterfaceName(
+ android.hardware.wifi.V1_4.IWifi.kInterfaceName)) {
+ return "1.4";
+ } else if (checkHalVersionByInterfaceName(
+ android.hardware.wifi.V1_3.IWifi.kInterfaceName)) {
+ return "1.3";
+ } else if (checkHalVersionByInterfaceName(
+ android.hardware.wifi.V1_2.IWifi.kInterfaceName)) {
+ return "1.2";
+ } else if (checkHalVersionByInterfaceName(
+ android.hardware.wifi.V1_1.IWifi.kInterfaceName)) {
+ return "1.1";
+ } else {
+ // Service exists, so at least V1_0 is supported
+ return "1.0";
+ }
+ }
+
+ /**
+ * Use the IServiceManager to check if the device is running V1_X of the HAL
+ * from the VINTF for the device.
+ *
+ * @return true if HAL version is V1_X, false otherwise.
+ */
+ private boolean checkHalVersionByInterfaceName(String interfaceName) {
+ if (interfaceName == null) return false;
+ if (mServiceManager == null) {
+ Log.e(TAG, "checkHalVersionByInterfaceName called but mServiceManager is null!?");
+ return false;
+ }
+ try {
+ return (mServiceManager.getTransport(interfaceName, "default")
+ != IServiceManager.Transport.EMPTY);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while operating on IServiceManager: " + e);
+ handleRemoteException(e, "getTransport");
+ return false;
+ }
+ }
+
+ protected static @WifiHal.WifiStatusCode int halToFrameworkWifiStatusCode(int code) {
+ switch (code) {
+ case WifiStatusCode.SUCCESS:
+ return WifiHal.WIFI_STATUS_SUCCESS;
+ case WifiStatusCode.ERROR_WIFI_CHIP_INVALID:
+ return WifiHal.WIFI_STATUS_ERROR_WIFI_CHIP_INVALID;
+ case WifiStatusCode.ERROR_WIFI_IFACE_INVALID:
+ return WifiHal.WIFI_STATUS_ERROR_WIFI_IFACE_INVALID;
+ case WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID:
+ return WifiHal.WIFI_STATUS_ERROR_WIFI_RTT_CONTROLLER_INVALID;
+ case WifiStatusCode.ERROR_NOT_SUPPORTED:
+ return WifiHal.WIFI_STATUS_ERROR_NOT_SUPPORTED;
+ case WifiStatusCode.ERROR_NOT_AVAILABLE:
+ return WifiHal.WIFI_STATUS_ERROR_NOT_AVAILABLE;
+ case WifiStatusCode.ERROR_NOT_STARTED:
+ return WifiHal.WIFI_STATUS_ERROR_NOT_STARTED;
+ case WifiStatusCode.ERROR_INVALID_ARGS:
+ return WifiHal.WIFI_STATUS_ERROR_INVALID_ARGS;
+ case WifiStatusCode.ERROR_BUSY:
+ return WifiHal.WIFI_STATUS_ERROR_BUSY;
+ case WifiStatusCode.ERROR_UNKNOWN:
+ return WifiHal.WIFI_STATUS_ERROR_UNKNOWN;
+ default:
+ Log.e(TAG, "Invalid WifiStatusCode received: " + code);
+ return WifiHal.WIFI_STATUS_ERROR_UNKNOWN;
+ }
+ }
+
+ protected android.hardware.wifi.V1_5.IWifi getWifiV1_5Mockable() {
+ return android.hardware.wifi.V1_5.IWifi.castFrom(mWifi);
+ }
+
+ protected static IServiceManager getServiceManagerMockable() {
+ try {
+ return IServiceManager.getService();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception getting IServiceManager: " + e);
+ return null;
+ }
+ }
+
+ protected IWifi getWifiServiceMockable() {
+ try {
+ return IWifi.getService(true /* retry */);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception getting IWifi service: " + e);
+ return null;
+ }
+ }
+
+ private boolean isOk(WifiStatus status, String methodStr) {
+ if (status.code == WifiStatusCode.SUCCESS) return true;
+ Log.e(TAG, methodStr + " failed with status: " + status);
+ return false;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ mWifi = null;
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifi == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifi is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIface.java b/service/java/com/android/server/wifi/hal/WifiNanIface.java
new file mode 100644
index 0000000000..1f89a9c96a
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiNanIface.java
@@ -0,0 +1,701 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.net.wifi.aware.ConfigRequest;
+import android.net.wifi.aware.PublishConfig;
+import android.net.wifi.aware.SubscribeConfig;
+import android.net.wifi.aware.WifiAwareChannelInfo;
+import android.net.wifi.aware.WifiAwareDataPathSecurityConfig;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.aware.Capabilities;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * Wrapper class for IWifiNanIface HAL calls.
+ */
+public class WifiNanIface implements WifiHal.WifiInterface {
+ private static final String TAG = "WifiNanIface";
+ private IWifiNanIface mWifiNanIface;
+
+ @VisibleForTesting
+ static final String SERVICE_NAME_FOR_OOB_DATA_PATH = "Wi-Fi Aware Data Path";
+
+ /**
+ * Event types for a cluster event indication.
+ */
+ public static class NanClusterEventType {
+ public static final int DISCOVERY_MAC_ADDRESS_CHANGED = 0;
+ public static final int STARTED_CLUSTER = 1;
+ public static final int JOINED_CLUSTER = 2;
+
+ /**
+ * Convert NanClusterEventType from HIDL to framework.
+ */
+ public static int fromHidl(int code) {
+ switch (code) {
+ case android.hardware.wifi.V1_0.NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED:
+ return DISCOVERY_MAC_ADDRESS_CHANGED;
+ case android.hardware.wifi.V1_0.NanClusterEventType.STARTED_CLUSTER:
+ return STARTED_CLUSTER;
+ case android.hardware.wifi.V1_0.NanClusterEventType.JOINED_CLUSTER:
+ return JOINED_CLUSTER;
+ default:
+ Log.e(TAG, "Unknown NanClusterEventType received from HIDL: " + code);
+ return -1;
+ }
+ }
+
+ /**
+ * Convert NanClusterEventType from AIDL to framework.
+ */
+ public static int fromAidl(int code) {
+ switch (code) {
+ case android.hardware.wifi.NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED:
+ return DISCOVERY_MAC_ADDRESS_CHANGED;
+ case android.hardware.wifi.NanClusterEventType.STARTED_CLUSTER:
+ return STARTED_CLUSTER;
+ case android.hardware.wifi.NanClusterEventType.JOINED_CLUSTER:
+ return JOINED_CLUSTER;
+ default:
+ Log.e(TAG, "Unknown NanClusterEventType received from HIDL: " + code);
+ return -1;
+ }
+ }
+ }
+
+ /**
+ * NAN DP (data-path) channel config options.
+ */
+ public static class NanDataPathChannelCfg {
+ public static final int CHANNEL_NOT_REQUESTED = 0;
+ public static final int REQUEST_CHANNEL_SETUP = 1;
+ public static final int FORCE_CHANNEL_SETUP = 2;
+
+ /**
+ * Convert NanDataPathChannelCfg from framework to HIDL.
+ */
+ public static int toHidl(int code) {
+ switch (code) {
+ case CHANNEL_NOT_REQUESTED:
+ return android.hardware.wifi.V1_0.NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED;
+ case REQUEST_CHANNEL_SETUP:
+ return android.hardware.wifi.V1_0.NanDataPathChannelCfg.REQUEST_CHANNEL_SETUP;
+ case FORCE_CHANNEL_SETUP:
+ return android.hardware.wifi.V1_0.NanDataPathChannelCfg.FORCE_CHANNEL_SETUP;
+ default:
+ Log.e(TAG, "Unknown NanDataPathChannelCfg received from framework: " + code);
+ return -1;
+ }
+ }
+
+ /**
+ * Convert NanDataPathChannelCfg from framework to AIDL.
+ */
+ public static int toAidl(int code) {
+ switch (code) {
+ case CHANNEL_NOT_REQUESTED:
+ return android.hardware.wifi.NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED;
+ case REQUEST_CHANNEL_SETUP:
+ return android.hardware.wifi.NanDataPathChannelCfg.REQUEST_CHANNEL_SETUP;
+ case FORCE_CHANNEL_SETUP:
+ return android.hardware.wifi.NanDataPathChannelCfg.FORCE_CHANNEL_SETUP;
+ default:
+ Log.e(TAG, "Unknown NanDataPathChannelCfg received from framework: " + code);
+ return -1;
+ }
+ }
+ }
+
+ /**
+ * Ranging in the context of discovery session indication controls.
+ */
+ public static class NanRangingIndication {
+ public static final int CONTINUOUS_INDICATION_MASK = 1 << 0;
+ public static final int INGRESS_MET_MASK = 1 << 1;
+ public static final int EGRESS_MET_MASK = 1 << 2;
+
+ /**
+ * Convert NanRangingIndication from HIDL to framework.
+ */
+ public static int fromHidl(int rangingInd) {
+ int frameworkRangingInd = 0;
+ if ((android.hardware.wifi.V1_0.NanRangingIndication.CONTINUOUS_INDICATION_MASK
+ & rangingInd) != 0) {
+ frameworkRangingInd |= CONTINUOUS_INDICATION_MASK;
+ }
+ if ((android.hardware.wifi.V1_0.NanRangingIndication.INGRESS_MET_MASK
+ & rangingInd) != 0) {
+ frameworkRangingInd |= INGRESS_MET_MASK;
+ }
+ if ((android.hardware.wifi.V1_0.NanRangingIndication.EGRESS_MET_MASK
+ & rangingInd) != 0) {
+ frameworkRangingInd |= EGRESS_MET_MASK;
+ }
+ return frameworkRangingInd;
+ }
+
+ /**
+ * Convert NanRangingIndication from AIDL to framework.
+ */
+ public static int fromAidl(int rangingInd) {
+ int frameworkRangingInd = 0;
+ if ((android.hardware.wifi.NanRangingIndication.CONTINUOUS_INDICATION_MASK
+ & rangingInd) != 0) {
+ frameworkRangingInd |= CONTINUOUS_INDICATION_MASK;
+ }
+ if ((android.hardware.wifi.NanRangingIndication.INGRESS_MET_MASK
+ & rangingInd) != 0) {
+ frameworkRangingInd |= INGRESS_MET_MASK;
+ }
+ if ((android.hardware.wifi.NanRangingIndication.EGRESS_MET_MASK
+ & rangingInd) != 0) {
+ frameworkRangingInd |= EGRESS_MET_MASK;
+ }
+ return frameworkRangingInd;
+ }
+ }
+
+ /**
+ * NAN API response codes used in request notifications and events.
+ */
+ public static class NanStatusCode {
+ public static final int SUCCESS = 0;
+ public static final int INTERNAL_FAILURE = 1;
+ public static final int PROTOCOL_FAILURE = 2;
+ public static final int INVALID_SESSION_ID = 3;
+ public static final int NO_RESOURCES_AVAILABLE = 4;
+ public static final int INVALID_ARGS = 5;
+ public static final int INVALID_PEER_ID = 6;
+ public static final int INVALID_NDP_ID = 7;
+ public static final int NAN_NOT_ALLOWED = 8;
+ public static final int NO_OTA_ACK = 9;
+ public static final int ALREADY_ENABLED = 10;
+ public static final int FOLLOWUP_TX_QUEUE_FULL = 11;
+ public static final int UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12;
+
+ /**
+ * Convert NanStatusCode from HIDL to framework.
+ */
+ public static int fromHidl(int code) {
+ switch (code) {
+ case android.hardware.wifi.V1_0.NanStatusType.SUCCESS:
+ return SUCCESS;
+ case android.hardware.wifi.V1_0.NanStatusType.INTERNAL_FAILURE:
+ return INTERNAL_FAILURE;
+ case android.hardware.wifi.V1_0.NanStatusType.PROTOCOL_FAILURE:
+ return PROTOCOL_FAILURE;
+ case android.hardware.wifi.V1_0.NanStatusType.INVALID_SESSION_ID:
+ return INVALID_SESSION_ID;
+ case android.hardware.wifi.V1_0.NanStatusType.NO_RESOURCES_AVAILABLE:
+ return NO_RESOURCES_AVAILABLE;
+ case android.hardware.wifi.V1_0.NanStatusType.INVALID_ARGS:
+ return INVALID_ARGS;
+ case android.hardware.wifi.V1_0.NanStatusType.INVALID_PEER_ID:
+ return INVALID_PEER_ID;
+ case android.hardware.wifi.V1_0.NanStatusType.INVALID_NDP_ID:
+ return INVALID_NDP_ID;
+ case android.hardware.wifi.V1_0.NanStatusType.NAN_NOT_ALLOWED:
+ return NAN_NOT_ALLOWED;
+ case android.hardware.wifi.V1_0.NanStatusType.NO_OTA_ACK:
+ return NO_OTA_ACK;
+ case android.hardware.wifi.V1_0.NanStatusType.ALREADY_ENABLED:
+ return ALREADY_ENABLED;
+ case android.hardware.wifi.V1_0.NanStatusType.FOLLOWUP_TX_QUEUE_FULL:
+ return FOLLOWUP_TX_QUEUE_FULL;
+ case android.hardware.wifi.V1_0.NanStatusType.UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
+ return UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
+ default:
+ Log.e(TAG, "Unknown NanStatusType received from HIDL: " + code);
+ return -1;
+ }
+ }
+
+ /**
+ * Convert NanStatusCode from AIDL to framework.
+ */
+ public static int fromAidl(int code) {
+ switch (code) {
+ case android.hardware.wifi.NanStatusCode.SUCCESS:
+ return SUCCESS;
+ case android.hardware.wifi.NanStatusCode.INTERNAL_FAILURE:
+ return INTERNAL_FAILURE;
+ case android.hardware.wifi.NanStatusCode.PROTOCOL_FAILURE:
+ return PROTOCOL_FAILURE;
+ case android.hardware.wifi.NanStatusCode.INVALID_SESSION_ID:
+ return INVALID_SESSION_ID;
+ case android.hardware.wifi.NanStatusCode.NO_RESOURCES_AVAILABLE:
+ return NO_RESOURCES_AVAILABLE;
+ case android.hardware.wifi.NanStatusCode.INVALID_ARGS:
+ return INVALID_ARGS;
+ case android.hardware.wifi.NanStatusCode.INVALID_PEER_ID:
+ return INVALID_PEER_ID;
+ case android.hardware.wifi.NanStatusCode.INVALID_NDP_ID:
+ return INVALID_NDP_ID;
+ case android.hardware.wifi.NanStatusCode.NAN_NOT_ALLOWED:
+ return NAN_NOT_ALLOWED;
+ case android.hardware.wifi.NanStatusCode.NO_OTA_ACK:
+ return NO_OTA_ACK;
+ case android.hardware.wifi.NanStatusCode.ALREADY_ENABLED:
+ return ALREADY_ENABLED;
+ case android.hardware.wifi.NanStatusCode.FOLLOWUP_TX_QUEUE_FULL:
+ return FOLLOWUP_TX_QUEUE_FULL;
+ case android.hardware.wifi.NanStatusCode.UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
+ return UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
+ default:
+ Log.e(TAG, "Unknown NanStatusType received from AIDL: " + code);
+ return -1;
+ }
+ }
+ }
+
+ /**
+ * Configuration parameters used in the call to enableAndConfigure.
+ */
+ public static class PowerParameters {
+ public int discoveryWindow24Ghz;
+ public int discoveryWindow5Ghz;
+ public int discoveryWindow6Ghz;
+ public int discoveryBeaconIntervalMs;
+ public int numberOfSpatialStreamsInDiscovery;
+ public boolean enableDiscoveryWindowEarlyTermination;
+ }
+
+ public WifiNanIface(@NonNull android.hardware.wifi.V1_0.IWifiNanIface nanIface) {
+ Log.i(TAG, "Creating WifiNanIface using the HIDL implementation");
+ mWifiNanIface = createWifiNanIfaceHidlImplMockable(nanIface);
+ }
+
+ public WifiNanIface(@NonNull android.hardware.wifi.IWifiNanIface nanIface) {
+ mWifiNanIface = createWifiNanIfaceAidlImplMockable(nanIface);
+ }
+
+ protected WifiNanIfaceHidlImpl createWifiNanIfaceHidlImplMockable(
+ android.hardware.wifi.V1_0.IWifiNanIface nanIface) {
+ return new WifiNanIfaceHidlImpl(nanIface);
+ }
+
+ protected WifiNanIfaceAidlImpl createWifiNanIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiNanIface nanIface) {
+ return new WifiNanIfaceAidlImpl(nanIface);
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiNanIface == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiNanIface is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+
+ /**
+ * Enable verbose logging.
+ */
+ public void enableVerboseLogging(boolean verbose) {
+ if (mWifiNanIface != null) {
+ mWifiNanIface.enableVerboseLogging(verbose);
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#getNanIface()}
+ *
+ * TODO: Remove this API. Will only be used temporarily until HalDeviceManager is refactored.
+ */
+ public android.hardware.wifi.V1_0.IWifiNanIface getNanIface() {
+ return validateAndCall("getNanIface", null,
+ () -> mWifiNanIface.getNanIface());
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#registerFrameworkCallback(Callback)}
+ */
+ public boolean registerFrameworkCallback(Callback cb) {
+ return validateAndCall("registerFrameworkCallback", false,
+ () -> mWifiNanIface.registerFrameworkCallback(cb));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#getName()}
+ */
+ @Override
+ @Nullable
+ public String getName() {
+ return validateAndCall("getName", null,
+ () -> mWifiNanIface.getName());
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#getCapabilities(short)}
+ */
+ public boolean getCapabilities(short transactionId) {
+ return validateAndCall("getCapabilities", false,
+ () -> mWifiNanIface.getCapabilities(transactionId));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#enableAndConfigure(short, ConfigRequest, boolean,
+ * boolean, boolean, boolean, int, int, PowerParameters)}
+ */
+ public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest,
+ boolean notifyIdentityChange, boolean initialConfiguration, boolean rangingEnabled,
+ boolean isInstantCommunicationEnabled, int instantModeChannel,
+ int macAddressRandomizationIntervalSec, PowerParameters powerParameters) {
+ return validateAndCall("enableAndConfigure", false,
+ () -> mWifiNanIface.enableAndConfigure(transactionId, configRequest,
+ notifyIdentityChange, initialConfiguration, rangingEnabled,
+ isInstantCommunicationEnabled, instantModeChannel,
+ macAddressRandomizationIntervalSec, powerParameters));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#disable(short)}
+ */
+ public boolean disable(short transactionId) {
+ return validateAndCall("disable", false,
+ () -> mWifiNanIface.disable(transactionId));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#publish(short, byte, PublishConfig)}
+ */
+ public boolean publish(short transactionId, byte publishId, PublishConfig publishConfig) {
+ return validateAndCall("publish", false,
+ () -> mWifiNanIface.publish(transactionId, publishId, publishConfig));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#subscribe(short, byte, SubscribeConfig)}
+ */
+ public boolean subscribe(short transactionId, byte subscribeId,
+ SubscribeConfig subscribeConfig) {
+ return validateAndCall("subscribe", false,
+ () -> mWifiNanIface.subscribe(transactionId, subscribeId, subscribeConfig));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#sendMessage(short, byte, int, MacAddress, byte[])}
+ */
+ public boolean sendMessage(short transactionId, byte pubSubId, int requestorInstanceId,
+ MacAddress dest, byte[] message) {
+ return validateAndCall("sendMessage", false,
+ () -> mWifiNanIface.sendMessage(transactionId, pubSubId, requestorInstanceId,
+ dest, message));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#stopPublish(short, byte)}
+ */
+ public boolean stopPublish(short transactionId, byte pubSubId) {
+ return validateAndCall("stopPublish", false,
+ () -> mWifiNanIface.stopPublish(transactionId, pubSubId));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#stopSubscribe(short, byte)}
+ */
+ public boolean stopSubscribe(short transactionId, byte pubSubId) {
+ return validateAndCall("stopSubscribe", false,
+ () -> mWifiNanIface.stopSubscribe(transactionId, pubSubId));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#createAwareNetworkInterface(short, String)}
+ */
+ public boolean createAwareNetworkInterface(short transactionId, String interfaceName) {
+ return validateAndCall("createAwareNetworkInterface", false,
+ () -> mWifiNanIface.createAwareNetworkInterface(transactionId, interfaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#deleteAwareNetworkInterface(short, String)}
+ */
+ public boolean deleteAwareNetworkInterface(short transactionId, String interfaceName) {
+ return validateAndCall("deleteAwareNetworkInterface", false,
+ () -> mWifiNanIface.deleteAwareNetworkInterface(transactionId, interfaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#initiateDataPath(short, int, int, int, MacAddress,
+ * String, boolean, byte[], Capabilities,
+ * WifiAwareDataPathSecurityConfig)}
+ */
+ public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
+ int channel, MacAddress peer, String interfaceName,
+ boolean isOutOfBand, byte[] appInfo, Capabilities capabilities,
+ WifiAwareDataPathSecurityConfig securityConfig) {
+ return validateAndCall("initiateDataPath", false,
+ () -> mWifiNanIface.initiateDataPath(transactionId, peerId, channelRequestType,
+ channel, peer, interfaceName, isOutOfBand, appInfo, capabilities,
+ securityConfig));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#respondToDataPathRequest(short, boolean, int, String,
+ * byte[], boolean, Capabilities, WifiAwareDataPathSecurityConfig)}
+ */
+ public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
+ String interfaceName, byte[] appInfo,
+ boolean isOutOfBand, Capabilities capabilities,
+ WifiAwareDataPathSecurityConfig securityConfig) {
+ return validateAndCall("respondToDataPathRequest", false,
+ () -> mWifiNanIface.respondToDataPathRequest(transactionId, accept, ndpId,
+ interfaceName, appInfo, isOutOfBand, capabilities, securityConfig));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#endDataPath(short, int)}
+ */
+ public boolean endDataPath(short transactionId, int ndpId) {
+ return validateAndCall("endDataPath", false,
+ () -> mWifiNanIface.endDataPath(transactionId, ndpId));
+ }
+
+ /**
+ * Framework callback object. Will get called when the equivalent events are received
+ * from the HAL.
+ */
+ public interface Callback {
+ /**
+ * Invoked in response to a capability request.
+ * @param id ID corresponding to the original request.
+ * @param capabilities Capability data.
+ */
+ void notifyCapabilitiesResponse(short id, Capabilities capabilities);
+
+ /**
+ * Invoked in response to an enable request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void notifyEnableResponse(short id, int status);
+
+ /**
+ * Invoked in response to a config request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void notifyConfigResponse(short id, int status);
+
+ /**
+ * Invoked in response to a disable request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void notifyDisableResponse(short id, int status);
+
+ /**
+ * Invoked to notify the status of the start publish request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ * @param publishId
+ */
+ void notifyStartPublishResponse(short id, int status, byte publishId);
+
+ /**
+ * Invoked to notify the status of the start subscribe request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ * @param subscribeId ID of the new subscribe session (if successfully created).
+ */
+ void notifyStartSubscribeResponse(short id, int status, byte subscribeId);
+
+ /**
+ * Invoked in response to a transmit followup request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void notifyTransmitFollowupResponse(short id, int status);
+
+ /**
+ * Invoked in response to a create data interface request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void notifyCreateDataInterfaceResponse(short id, int status);
+
+ /**
+ * Invoked in response to a delete data interface request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void notifyDeleteDataInterfaceResponse(short id, int status);
+
+ /**
+ * Invoked in response to a delete data interface request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ * @param ndpInstanceId
+ */
+ void notifyInitiateDataPathResponse(short id, int status, int ndpInstanceId);
+
+ /**
+ * Invoked in response to a respond to data path indication request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void notifyRespondToDataPathIndicationResponse(short id, int status);
+
+ /**
+ * Invoked in response to a terminate data path request.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void notifyTerminateDataPathResponse(short id, int status);
+
+ /**
+ * Indicates that a cluster event has been received.
+ * @param eventType Type of the cluster event (see {@link NanClusterEventType}).
+ * @param addr MAC Address associated with the corresponding event.
+ */
+ void eventClusterEvent(int eventType, byte[] addr);
+
+ /**
+ * Indicates that a NAN has been disabled.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void eventDisabled(int status);
+
+ /**
+ * Indicates that an active publish session has terminated.
+ * @param sessionId Discovery session ID of the terminated session.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void eventPublishTerminated(byte sessionId, int status);
+
+ /**
+ * Indicates that an active subscribe session has terminated.
+ * @param sessionId Discovery session ID of the terminated session.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void eventSubscribeTerminated(byte sessionId, int status);
+
+ /**
+ * Indicates that a match has occurred - i.e. a service has been discovered.
+ * @param discoverySessionId Publish or subscribe discovery session ID of an existing
+ * discovery session.
+ * @param peerId Unique ID of the peer. Can be used subsequently in sendMessage()
+ * or to set up a data-path.
+ * @param addr NAN Discovery (management) MAC address of the peer.
+ * @param serviceSpecificInfo The arbitrary information contained in the
+ * |NanDiscoveryCommonConfig.serviceSpecificInfo| of
+ * the peer's discovery session configuration.
+ * @param matchFilter The match filter from the discovery packet (publish or subscribe)
+ * which caused service discovery. Matches the
+ * |NanDiscoveryCommonConfig.txMatchFilter| of the peer's unsolicited
+ * publish message or of the local device's Active subscribe message.
+ * @param rangingIndicationType The ranging event(s) which triggered the ranging. Ex. can
+ * indicate that continuous ranging was requested, or else that
+ * an ingress event occurred. See {@link NanRangingIndication}.
+ * @param rangingMeasurementInMm If ranging was required and executed, contains the
+ * distance to the peer in mm.
+ * @param scid Security Context Identifier identifies the Security Context.
+ * For NAN Shared Key Cipher Suite, this field contains the 16 octet PMKID
+ * 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.
+ */
+ void eventMatch(byte discoverySessionId, int peerId, byte[] addr,
+ byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndicationType,
+ int rangingMeasurementInMm, byte[] scid, int peerCipherType);
+
+ /**
+ * Indicates that a previously discovered match (service) has expired.
+ * @param discoverySessionId Discovery session ID of the expired match.
+ * @param peerId Peer ID of the expired match.
+ */
+ void eventMatchExpired(byte discoverySessionId, int peerId);
+
+ /**
+ * Indicates that a followup message has been received from a peer.
+ * @param discoverySessionId Discovery session (publish or subscribe) ID of a previously
+ * created discovery session.
+ * @param peerId Unique ID of the peer.
+ * @param addr NAN Discovery (management) MAC address of the peer.
+ * @param serviceSpecificInfo Received message from the peer. There is no semantic
+ * meaning to these bytes. They are passed-through from sender
+ * to receiver as-is with no parsing.
+ */
+ void eventFollowupReceived(byte discoverySessionId, int peerId, byte[] addr,
+ byte[] serviceSpecificInfo);
+
+ /**
+ * Provides status of a completed followup message transmit operation.
+ * @param id ID corresponding to the original request.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ */
+ void eventTransmitFollowup(short id, int status);
+
+ /**
+ * Indicates that a data-path (NDP) setup has been requested by an initiator peer
+ * (received by the intended responder).
+ * @param discoverySessionId ID of an active publish or subscribe discovery session.
+ * @param peerDiscMacAddr MAC address of the Initiator peer. This is the MAC address of
+ * the peer's management/discovery NAN interface.
+ * @param ndpInstanceId ID of the data-path. Used to identify the data-path in further
+ * negotiation/APIs.
+ * @param appInfo Arbitrary information communicated from the peer as part of the
+ * data-path setup process. There is no semantic meaning to these bytes.
+ * They are passed from sender to receiver as-is with no parsing.
+ */
+ void eventDataPathRequest(byte discoverySessionId, byte[] peerDiscMacAddr,
+ int ndpInstanceId, byte[] appInfo);
+
+ /**
+ * Indicates that a data-path (NDP) setup has been completed. Received by both the
+ * Initiator and Responder.
+ * @param status Status the operation (see {@link NanStatusCode}).
+ * @param ndpInstanceId ID of the data-path.
+ * @param dataPathSetupSuccess Indicates whether the data-path setup succeeded (true)
+ * or failed (false).
+ * @param peerNdiMacAddr MAC address of the peer's data-interface (not its
+ * management/discovery interface).
+ * @param appInfo Arbitrary information communicated from the peer as part of the
+ * data-path setup process. There is no semantic meaning to these bytes.
+ * They are passed from sender to receiver as-is with no parsing.
+ * @param channelInfos
+ */
+ void eventDataPathConfirm(int status, int ndpInstanceId, boolean dataPathSetupSuccess,
+ byte[] peerNdiMacAddr, byte[] appInfo, List<WifiAwareChannelInfo> channelInfos);
+
+ /**
+ * Indicates that a data-path (NDP) schedule has been updated (ex. channels
+ * have been changed).
+ * @param peerDiscoveryAddress Discovery address (NMI) of the peer to which the NDP
+ * is connected.
+ * @param ndpInstanceIds List of NDPs to which this update applies.
+ * @param channelInfo Updated channel(s) information.
+ */
+ void eventDataPathScheduleUpdate(byte[] peerDiscoveryAddress,
+ ArrayList<Integer> ndpInstanceIds, List<WifiAwareChannelInfo> channelInfo);
+
+ /**
+ * Indicates that a list of data-paths (NDP) have been terminated. Received by both the
+ * Initiator and Responder.
+ * @param ndpInstanceId Data-path ID of the terminated data-path.
+ */
+ void eventDataPathTerminated(int ndpInstanceId);
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java
new file mode 100644
index 0000000000..656dfd3685
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java
@@ -0,0 +1,843 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.hardware.wifi.NanBandIndex;
+import android.hardware.wifi.NanBandSpecificConfig;
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanConfigRequest;
+import android.hardware.wifi.NanConfigRequestSupplemental;
+import android.hardware.wifi.NanDataPathSecurityConfig;
+import android.hardware.wifi.NanDataPathSecurityType;
+import android.hardware.wifi.NanDebugConfig;
+import android.hardware.wifi.NanDiscoveryCommonConfig;
+import android.hardware.wifi.NanEnableRequest;
+import android.hardware.wifi.NanInitiateDataPathRequest;
+import android.hardware.wifi.NanMatchAlg;
+import android.hardware.wifi.NanPublishRequest;
+import android.hardware.wifi.NanRangingIndication;
+import android.hardware.wifi.NanRespondToDataPathIndicationRequest;
+import android.hardware.wifi.NanSubscribeRequest;
+import android.hardware.wifi.NanTransmitFollowupRequest;
+import android.hardware.wifi.NanTxType;
+import android.net.MacAddress;
+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.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+import com.android.server.wifi.aware.Capabilities;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * AIDL implementation of the IWifiNanIface interface.
+ */
+public class WifiNanIfaceAidlImpl implements IWifiNanIface {
+ private static final String TAG = "WifiNanIfaceAidlImpl";
+ private android.hardware.wifi.IWifiNanIface mWifiNanIface;
+ private String mIfaceName;
+ private final Object mLock = new Object();
+ private WifiNanIfaceCallbackAidlImpl mHalCallback;
+ private WifiNanIface.Callback mFrameworkCallback;
+
+ public WifiNanIfaceAidlImpl(@NonNull android.hardware.wifi.IWifiNanIface nanIface) {
+ mWifiNanIface = nanIface;
+ mHalCallback = new WifiNanIfaceCallbackAidlImpl(this);
+ }
+
+ /**
+ * Enable verbose logging.
+ */
+ @Override
+ public void enableVerboseLogging(boolean verbose) {
+ synchronized (mLock) {
+ if (mHalCallback != null) {
+ mHalCallback.enableVerboseLogging(verbose);
+ }
+ }
+ }
+
+ protected WifiNanIface.Callback getFrameworkCallback() {
+ return mFrameworkCallback;
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#getNanIface()}
+ *
+ * TODO: Remove this API. Will only be used temporarily until HalDeviceManager is refactored.
+ */
+ @Override
+ public android.hardware.wifi.V1_0.IWifiNanIface getNanIface() {
+ return null;
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#registerFrameworkCallback(WifiNanIface.Callback)}
+ */
+ @Override
+ public boolean registerFrameworkCallback(WifiNanIface.Callback callback) {
+ final String methodStr = "registerFrameworkCallback";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ if (mFrameworkCallback != null) {
+ Log.e(TAG, "Framework callback is already registered");
+ return false;
+ } else if (callback == null) {
+ Log.e(TAG, "Cannot register a null framework callback");
+ return false;
+ }
+
+ try {
+ mWifiNanIface.registerEventCallback(mHalCallback);
+ mFrameworkCallback = callback;
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#getName()}
+ */
+ @Override
+ @Nullable
+ public String getName() {
+ final String methodStr = "getName";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ if (mIfaceName != null) return mIfaceName;
+ try {
+ String ifaceName = mWifiNanIface.getName();
+ mIfaceName = ifaceName;
+ return mIfaceName;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#getCapabilities(short)}
+ */
+ @Override
+ public boolean getCapabilities(short transactionId) {
+ final String methodStr = "getCapabilities";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiNanIface.getCapabilitiesRequest((char) transactionId);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#enableAndConfigure(short, ConfigRequest, boolean,
+ * boolean, boolean, boolean, int, int, WifiNanIface.PowerParameters)}
+ */
+ @Override
+ public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest,
+ boolean notifyIdentityChange, boolean initialConfiguration, boolean rangingEnabled,
+ boolean isInstantCommunicationEnabled, int instantModeChannel,
+ int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters) {
+ final String methodStr = "enableAndConfigure";
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ NanConfigRequestSupplemental supplemental = createNanConfigRequestSupplemental(
+ rangingEnabled, isInstantCommunicationEnabled, instantModeChannel);
+ if (initialConfiguration) {
+ NanEnableRequest req = createNanEnableRequest(
+ configRequest, notifyIdentityChange, supplemental,
+ macAddressRandomizationIntervalSec, powerParameters);
+ mWifiNanIface.enableRequest((char) transactionId, req, supplemental);
+ } else {
+ NanConfigRequest req = createNanConfigRequest(
+ configRequest, notifyIdentityChange, supplemental,
+ macAddressRandomizationIntervalSec, powerParameters);
+ mWifiNanIface.configRequest((char) transactionId, req, supplemental);
+ }
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#disable(short)}
+ */
+ @Override
+ public boolean disable(short transactionId) {
+ final String methodStr = "disable";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiNanIface.disableRequest((char) transactionId);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#publish(short, byte, PublishConfig)}
+ */
+ @Override
+ public boolean publish(short transactionId, byte publishId, PublishConfig publishConfig) {
+ final String methodStr = "publish";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ NanPublishRequest req = createNanPublishRequest(publishId, publishConfig);
+ mWifiNanIface.startPublishRequest((char) transactionId, req);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#subscribe(short, byte, SubscribeConfig)}
+ */
+ @Override
+ public boolean subscribe(short transactionId, byte subscribeId,
+ SubscribeConfig subscribeConfig) {
+ final String methodStr = "subscribe";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ NanSubscribeRequest req = createNanSubscribeRequest(subscribeId, subscribeConfig);
+ mWifiNanIface.startSubscribeRequest((char) transactionId, req);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#sendMessage(short, byte, int, MacAddress, byte[])}
+ */
+ @Override
+ public boolean sendMessage(short transactionId, byte pubSubId, int requesterInstanceId,
+ MacAddress dest, byte[] message) {
+ final String methodStr = "sendMessage";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ NanTransmitFollowupRequest req = createNanTransmitFollowupRequest(
+ pubSubId, requesterInstanceId, dest, message);
+ mWifiNanIface.transmitFollowupRequest((char) transactionId, req);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#stopPublish(short, byte)}
+ */
+ @Override
+ public boolean stopPublish(short transactionId, byte pubSubId) {
+ final String methodStr = "stopPublish";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiNanIface.stopPublishRequest((char) transactionId, pubSubId);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#stopSubscribe(short, byte)}
+ */
+ @Override
+ public boolean stopSubscribe(short transactionId, byte pubSubId) {
+ final String methodStr = "stopSubscribe";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiNanIface.stopSubscribeRequest((char) transactionId, pubSubId);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#createAwareNetworkInterface(short, String)}
+ */
+ @Override
+ public boolean createAwareNetworkInterface(short transactionId, String interfaceName) {
+ final String methodStr = "createAwareNetworkInterface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiNanIface.createDataInterfaceRequest((char) transactionId, interfaceName);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#deleteAwareNetworkInterface(short, String)}
+ */
+ @Override
+ public boolean deleteAwareNetworkInterface(short transactionId, String interfaceName) {
+ final String methodStr = "deleteAwareNetworkInterface";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiNanIface.deleteDataInterfaceRequest((char) transactionId, interfaceName);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#initiateDataPath(short, int, int, int, MacAddress,
+ * String, boolean, byte[], Capabilities,
+ * WifiAwareDataPathSecurityConfig)}
+ */
+ @Override
+ public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
+ int channel, MacAddress peer, String interfaceName,
+ boolean isOutOfBand, byte[] appInfo, Capabilities capabilities,
+ WifiAwareDataPathSecurityConfig securityConfig) {
+ final String methodStr = "initiateDataPath";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ NanInitiateDataPathRequest req = createNanInitiateDataPathRequest(
+ peerId, channelRequestType, channel, peer, interfaceName, isOutOfBand,
+ appInfo, securityConfig);
+ mWifiNanIface.initiateDataPathRequest((char) transactionId, req);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#respondToDataPathRequest(short, boolean, int, String,
+ * byte[], boolean, Capabilities, WifiAwareDataPathSecurityConfig)}
+ */
+ @Override
+ public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
+ String interfaceName, byte[] appInfo, boolean isOutOfBand, Capabilities capabilities,
+ WifiAwareDataPathSecurityConfig securityConfig) {
+ final String methodStr = "respondToDataPathRequest";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ NanRespondToDataPathIndicationRequest req =
+ createNanRespondToDataPathIndicationRequest(
+ accept, ndpId, interfaceName, appInfo, isOutOfBand,
+ securityConfig);
+ mWifiNanIface.respondToDataPathIndicationRequest((char) transactionId, req);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#endDataPath(short, int)}
+ */
+ @Override
+ public boolean endDataPath(short transactionId, int ndpId) {
+ final String methodStr = "endDataPath";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiNanIface.terminateDataPathRequest((char) transactionId, ndpId);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+
+ // Utilities
+
+ private static NanConfigRequestSupplemental createNanConfigRequestSupplemental(
+ boolean rangingEnabled, boolean isInstantCommunicationEnabled, int instantModeChannel) {
+ NanConfigRequestSupplemental out = new NanConfigRequestSupplemental();
+ out.discoveryBeaconIntervalMs = 0;
+ out.numberOfSpatialStreamsInDiscovery = 0;
+ out.enableDiscoveryWindowEarlyTermination = false;
+ out.enableRanging = rangingEnabled;
+ out.enableInstantCommunicationMode = isInstantCommunicationEnabled;
+ out.instantModeChannel = instantModeChannel;
+ return out;
+ }
+
+ private static NanBandSpecificConfig[] createNanBandSpecificConfigs(
+ ConfigRequest configRequest) {
+ NanBandSpecificConfig config24 = new NanBandSpecificConfig();
+ config24.rssiClose = 60;
+ config24.rssiMiddle = 70;
+ config24.rssiCloseProximity = 60;
+ config24.dwellTimeMs = 200;
+ config24.scanPeriodSec = 20;
+ if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]
+ == ConfigRequest.DW_INTERVAL_NOT_INIT) {
+ config24.validDiscoveryWindowIntervalVal = false;
+ } else {
+ config24.validDiscoveryWindowIntervalVal = true;
+ config24.discoveryWindowIntervalVal =
+ (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ];
+ }
+
+ NanBandSpecificConfig config5 = new NanBandSpecificConfig();
+ config5.rssiClose = 60;
+ config5.rssiMiddle = 75;
+ config5.rssiCloseProximity = 60;
+ config5.dwellTimeMs = 200;
+ config5.scanPeriodSec = 20;
+ if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]
+ == ConfigRequest.DW_INTERVAL_NOT_INIT) {
+ config5.validDiscoveryWindowIntervalVal = false;
+ } else {
+ config5.validDiscoveryWindowIntervalVal = true;
+ config5.discoveryWindowIntervalVal =
+ (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ];
+ }
+
+ NanBandSpecificConfig config6 = new NanBandSpecificConfig();
+ config6.rssiClose = 60;
+ config6.rssiMiddle = 75;
+ config6.rssiCloseProximity = 60;
+ config6.dwellTimeMs = 200;
+ config6.scanPeriodSec = 20;
+ if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ]
+ == ConfigRequest.DW_INTERVAL_NOT_INIT) {
+ config6.validDiscoveryWindowIntervalVal = false;
+ } else {
+ config6.validDiscoveryWindowIntervalVal = true;
+ config6.discoveryWindowIntervalVal =
+ (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ];
+ }
+
+ return new NanBandSpecificConfig[]{config24, config5, config6};
+ }
+
+ private static NanEnableRequest createNanEnableRequest(
+ ConfigRequest configRequest, boolean notifyIdentityChange,
+ NanConfigRequestSupplemental configSupplemental,
+ int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters) {
+ NanEnableRequest req = new NanEnableRequest();
+ NanBandSpecificConfig[] nanBandSpecificConfigs =
+ createNanBandSpecificConfigs(configRequest);
+
+ req.operateInBand = new boolean[3];
+ req.operateInBand[NanBandIndex.NAN_BAND_24GHZ] = true;
+ req.operateInBand[NanBandIndex.NAN_BAND_5GHZ] = configRequest.mSupport5gBand;
+ req.operateInBand[NanBandIndex.NAN_BAND_6GHZ] = configRequest.mSupport6gBand;
+ req.hopCountMax = 2;
+ req.configParams = new NanConfigRequest();
+ req.configParams.masterPref = (byte) configRequest.mMasterPreference;
+ req.configParams.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
+ req.configParams.disableStartedClusterIndication = !notifyIdentityChange;
+ req.configParams.disableJoinedClusterIndication = !notifyIdentityChange;
+ req.configParams.includePublishServiceIdsInBeacon = true;
+ req.configParams.numberOfPublishServiceIdsInBeacon = 0;
+ req.configParams.includeSubscribeServiceIdsInBeacon = true;
+ req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
+ req.configParams.rssiWindowSize = 8;
+ req.configParams.macAddressRandomizationIntervalSec = macAddressRandomizationIntervalSec;
+
+ req.configParams.bandSpecificConfig = new NanBandSpecificConfig[3];
+ req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] =
+ nanBandSpecificConfigs[0];
+ req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = nanBandSpecificConfigs[1];
+ req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_6GHZ] = nanBandSpecificConfigs[2];
+
+ req.debugConfigs = new NanDebugConfig();
+ req.debugConfigs.validClusterIdVals = true;
+ req.debugConfigs.clusterIdTopRangeVal = (char) configRequest.mClusterHigh;
+ req.debugConfigs.clusterIdBottomRangeVal = (char) configRequest.mClusterLow;
+ req.debugConfigs.validIntfAddrVal = false;
+ req.debugConfigs.validOuiVal = false;
+ req.debugConfigs.ouiVal = 0;
+ req.debugConfigs.validRandomFactorForceVal = false;
+ req.debugConfigs.randomFactorForceVal = 0;
+ req.debugConfigs.validHopCountForceVal = false;
+ req.debugConfigs.hopCountForceVal = 0;
+ req.debugConfigs.validDiscoveryChannelVal = false;
+ req.debugConfigs.discoveryChannelMhzVal = new int[3];
+ req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_24GHZ] = 0;
+ req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_5GHZ] = 0;
+ req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_6GHZ] = 0;
+ req.debugConfigs.validUseBeaconsInBandVal = false;
+ req.debugConfigs.useBeaconsInBandVal = new boolean[3];
+ req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
+ req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
+ req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_6GHZ] = true;
+ req.debugConfigs.validUseSdfInBandVal = false;
+ req.debugConfigs.useSdfInBandVal = new boolean[3];
+ req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
+ req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
+ req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_6GHZ] = true;
+ updateConfigForPowerSettings(req.configParams, configSupplemental, powerParameters);
+ return req;
+ }
+
+ private static NanConfigRequest createNanConfigRequest(
+ ConfigRequest configRequest, boolean notifyIdentityChange,
+ NanConfigRequestSupplemental configSupplemental,
+ int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters) {
+ NanConfigRequest req = new NanConfigRequest();
+ NanBandSpecificConfig[] nanBandSpecificConfigs =
+ createNanBandSpecificConfigs(configRequest);
+
+ req.masterPref = (byte) configRequest.mMasterPreference;
+ req.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
+ req.disableStartedClusterIndication = !notifyIdentityChange;
+ req.disableJoinedClusterIndication = !notifyIdentityChange;
+ req.includePublishServiceIdsInBeacon = true;
+ req.numberOfPublishServiceIdsInBeacon = 0;
+ req.includeSubscribeServiceIdsInBeacon = true;
+ req.numberOfSubscribeServiceIdsInBeacon = 0;
+ req.rssiWindowSize = 8;
+ req.macAddressRandomizationIntervalSec = macAddressRandomizationIntervalSec;
+
+ req.bandSpecificConfig = new NanBandSpecificConfig[3];
+ req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = nanBandSpecificConfigs[0];
+ req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = nanBandSpecificConfigs[1];
+ req.bandSpecificConfig[NanBandIndex.NAN_BAND_6GHZ] = nanBandSpecificConfigs[2];
+ updateConfigForPowerSettings(req, configSupplemental, powerParameters);
+ return req;
+ }
+
+ /**
+ * Update the NAN configuration to reflect the current power settings
+ */
+ private static void updateConfigForPowerSettings(NanConfigRequest req,
+ NanConfigRequestSupplemental configSupplemental,
+ WifiNanIface.PowerParameters powerParameters) {
+ updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ],
+ powerParameters.discoveryWindow5Ghz);
+ updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ],
+ powerParameters.discoveryWindow24Ghz);
+ updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_6GHZ],
+ powerParameters.discoveryWindow6Ghz);
+
+ configSupplemental.discoveryBeaconIntervalMs = powerParameters.discoveryBeaconIntervalMs;
+ configSupplemental.numberOfSpatialStreamsInDiscovery =
+ powerParameters.numberOfSpatialStreamsInDiscovery;
+ configSupplemental.enableDiscoveryWindowEarlyTermination =
+ powerParameters.enableDiscoveryWindowEarlyTermination;
+ }
+
+ private static void updateSingleConfigForPowerSettings(
+ NanBandSpecificConfig cfg, int override) {
+ if (override != -1) {
+ cfg.validDiscoveryWindowIntervalVal = true;
+ cfg.discoveryWindowIntervalVal = (byte) override;
+ }
+ }
+
+ private static NanPublishRequest createNanPublishRequest(
+ byte publishId, PublishConfig publishConfig) {
+ NanPublishRequest req = new NanPublishRequest();
+ req.baseConfigs = new NanDiscoveryCommonConfig();
+ req.baseConfigs.sessionId = publishId;
+ req.baseConfigs.ttlSec = (char) publishConfig.mTtlSec;
+ req.baseConfigs.discoveryWindowPeriod = 1;
+ req.baseConfigs.discoveryCount = 0;
+ req.baseConfigs.serviceName = publishConfig.mServiceName;
+ req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_NEVER;
+ req.baseConfigs.serviceSpecificInfo = publishConfig.mServiceSpecificInfo;
+ if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED) {
+ req.baseConfigs.txMatchFilter = publishConfig.mMatchFilter;
+ req.baseConfigs.rxMatchFilter = new byte[0];
+ } else {
+ req.baseConfigs.rxMatchFilter = publishConfig.mMatchFilter;
+ req.baseConfigs.txMatchFilter = new byte[0];
+ }
+ req.baseConfigs.useRssiThreshold = false;
+ req.baseConfigs.disableDiscoveryTerminationIndication =
+ !publishConfig.mEnableTerminateNotification;
+ req.baseConfigs.disableMatchExpirationIndication = true;
+ req.baseConfigs.disableFollowupReceivedIndication = false;
+
+ req.autoAcceptDataPathRequests = false;
+
+ req.baseConfigs.rangingRequired = publishConfig.mEnableRanging;
+
+ req.baseConfigs.securityConfig = new NanDataPathSecurityConfig();
+ req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+ WifiAwareDataPathSecurityConfig securityConfig = publishConfig.getSecurityConfig();
+ if (securityConfig != null) {
+ req.baseConfigs.securityConfig.cipherType = getHalCipherSuiteType(
+ securityConfig.getCipherSuite());
+ if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
+ req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.PMK;
+ req.baseConfigs.securityConfig.pmk = copyArray(securityConfig.getPmk());
+ }
+ if (securityConfig.getPskPassphrase() != null
+ && securityConfig.getPskPassphrase().length() != 0) {
+ req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
+ req.baseConfigs.securityConfig.passphrase =
+ securityConfig.getPskPassphrase().getBytes();
+ }
+ if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) {
+ req.baseConfigs.securityConfig.scid = copyArray(securityConfig.getPmkId());
+ }
+ }
+
+ req.publishType = publishConfig.mPublishType;
+ req.txType = NanTxType.BROADCAST;
+ return req;
+ }
+
+ private static NanSubscribeRequest createNanSubscribeRequest(
+ byte subscribeId, SubscribeConfig subscribeConfig) {
+ NanSubscribeRequest req = new NanSubscribeRequest();
+ req.baseConfigs = new NanDiscoveryCommonConfig();
+ req.baseConfigs.sessionId = subscribeId;
+ req.baseConfigs.ttlSec = (char) subscribeConfig.mTtlSec;
+ req.baseConfigs.discoveryWindowPeriod = 1;
+ req.baseConfigs.discoveryCount = 0;
+ req.baseConfigs.serviceName = subscribeConfig.mServiceName;
+ req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_ONCE;
+ req.baseConfigs.serviceSpecificInfo = subscribeConfig.mServiceSpecificInfo;
+ if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE) {
+ req.baseConfigs.txMatchFilter = subscribeConfig.mMatchFilter;
+ req.baseConfigs.rxMatchFilter = new byte[0];
+ } else {
+ req.baseConfigs.rxMatchFilter = subscribeConfig.mMatchFilter;
+ req.baseConfigs.txMatchFilter = new byte[0];
+ }
+ req.baseConfigs.useRssiThreshold = false;
+ req.baseConfigs.disableDiscoveryTerminationIndication =
+ !subscribeConfig.mEnableTerminateNotification;
+ req.baseConfigs.disableMatchExpirationIndication = false;
+ req.baseConfigs.disableFollowupReceivedIndication = false;
+
+ req.baseConfigs.rangingRequired =
+ subscribeConfig.mMinDistanceMmSet || subscribeConfig.mMaxDistanceMmSet;
+ req.baseConfigs.configRangingIndications = 0;
+ if (subscribeConfig.mMinDistanceMmSet) {
+ req.baseConfigs.distanceEgressCm = (char) Math.min(
+ subscribeConfig.mMinDistanceMm / 10, Short.MAX_VALUE);
+ req.baseConfigs.configRangingIndications |= NanRangingIndication.EGRESS_MET_MASK;
+ }
+ if (subscribeConfig.mMaxDistanceMmSet) {
+ req.baseConfigs.distanceIngressCm = (char) Math.min(
+ subscribeConfig.mMaxDistanceMm / 10, Short.MAX_VALUE);
+ req.baseConfigs.configRangingIndications |= NanRangingIndication.INGRESS_MET_MASK;
+ }
+
+ // TODO: configure security
+ req.baseConfigs.securityConfig = new NanDataPathSecurityConfig();
+ req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+
+ req.subscribeType = subscribeConfig.mSubscribeType;
+ return req;
+ }
+
+ private static NanTransmitFollowupRequest createNanTransmitFollowupRequest(
+ byte pubSubId, int requesterInstanceId, MacAddress dest, byte[] message) {
+ NanTransmitFollowupRequest req = new NanTransmitFollowupRequest();
+ req.discoverySessionId = pubSubId;
+ req.peerId = requesterInstanceId;
+ req.addr = dest.toByteArray();
+ req.isHighPriority = false;
+ req.shouldUseDiscoveryWindow = true;
+ req.serviceSpecificInfo = message;
+ req.disableFollowupResultIndication = false;
+ return req;
+ }
+
+ private static NanInitiateDataPathRequest createNanInitiateDataPathRequest(
+ int peerId, int channelRequestType, int channel, MacAddress peer, String interfaceName,
+ boolean isOutOfBand, byte[] appInfo, WifiAwareDataPathSecurityConfig securityConfig) {
+ NanInitiateDataPathRequest req = new NanInitiateDataPathRequest();
+ req.peerId = peerId;
+ req.peerDiscMacAddr = peer.toByteArray();
+ req.channelRequestType = WifiNanIface.NanDataPathChannelCfg.toAidl(channelRequestType);
+ req.channel = channel;
+ req.ifaceName = interfaceName;
+ req.securityConfig = new NanDataPathSecurityConfig();
+ req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+ if (securityConfig != null) {
+ req.securityConfig.cipherType = getHalCipherSuiteType(securityConfig.getCipherSuite());
+ if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
+ req.securityConfig.securityType = NanDataPathSecurityType.PMK;
+ req.securityConfig.pmk = copyArray(securityConfig.getPmk());
+ }
+ if (securityConfig.getPskPassphrase() != null
+ && securityConfig.getPskPassphrase().length() != 0) {
+ req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
+ req.securityConfig.passphrase = securityConfig.getPskPassphrase().getBytes();
+ }
+ if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) {
+ req.securityConfig.scid = copyArray(securityConfig.getPmkId());
+ }
+ }
+
+ if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
+ req.serviceNameOutOfBand = WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH
+ .getBytes(StandardCharsets.UTF_8);
+ }
+ req.appInfo = appInfo;
+ return req;
+ }
+
+ private static NanRespondToDataPathIndicationRequest
+ createNanRespondToDataPathIndicationRequest(boolean accept, int ndpId,
+ String interfaceName, byte[] appInfo, boolean isOutOfBand,
+ WifiAwareDataPathSecurityConfig securityConfig) {
+ NanRespondToDataPathIndicationRequest req = new NanRespondToDataPathIndicationRequest();
+ req.acceptRequest = accept;
+ req.ndpInstanceId = ndpId;
+ req.ifaceName = interfaceName;
+ req.securityConfig = new NanDataPathSecurityConfig();
+ req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+ if (securityConfig != null) {
+ req.securityConfig.cipherType = getHalCipherSuiteType(securityConfig.getCipherSuite());
+ if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
+ req.securityConfig.securityType = NanDataPathSecurityType.PMK;
+ req.securityConfig.pmk = copyArray(securityConfig.getPmk());
+ }
+ if (securityConfig.getPskPassphrase() != null
+ && securityConfig.getPskPassphrase().length() != 0) {
+ req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
+ req.securityConfig.passphrase = securityConfig.getPskPassphrase().getBytes();
+ }
+ if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) {
+ req.securityConfig.scid = copyArray(securityConfig.getPmkId());
+ }
+ }
+
+ if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
+ req.serviceNameOutOfBand = WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH
+ .getBytes(StandardCharsets.UTF_8);
+ }
+ req.appInfo = appInfo;
+ return req;
+ }
+
+ private static int getHalCipherSuiteType(int frameworkCipherSuites) {
+ switch (frameworkCipherSuites) {
+ case WIFI_AWARE_CIPHER_SUITE_NCS_SK_128:
+ return NanCipherSuiteType.SHARED_KEY_128_MASK;
+ case WIFI_AWARE_CIPHER_SUITE_NCS_SK_256:
+ return NanCipherSuiteType.SHARED_KEY_256_MASK;
+ case WIFI_AWARE_CIPHER_SUITE_NCS_PK_128:
+ return NanCipherSuiteType.PUBLIC_KEY_128_MASK;
+ case WIFI_AWARE_CIPHER_SUITE_NCS_PK_256:
+ return NanCipherSuiteType.PUBLIC_KEY_256_MASK;
+ }
+ return NanCipherSuiteType.NONE;
+ }
+
+ private static byte[] copyArray(byte[] source) {
+ return source != null ? source.clone() : new byte[0];
+ }
+
+ private boolean checkIfaceAndLogFailure(String methodStr) {
+ if (mWifiNanIface == null) {
+ Log.e(TAG, "Unable to call " + methodStr + " because iface is null.");
+ return false;
+ }
+ return true;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ mWifiNanIface = null;
+ mIfaceName = null;
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ }
+
+ private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with service-specific exception: " + e);
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java
new file mode 100644
index 0000000000..80cfe43ae6
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java
@@ -0,0 +1,514 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.hardware.wifi.IWifiNanIfaceEventCallback;
+import android.hardware.wifi.NanCapabilities;
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanClusterEventInd;
+import android.hardware.wifi.NanDataPathChannelInfo;
+import android.hardware.wifi.NanDataPathConfirmInd;
+import android.hardware.wifi.NanDataPathRequestInd;
+import android.hardware.wifi.NanDataPathScheduleUpdateInd;
+import android.hardware.wifi.NanFollowupReceivedInd;
+import android.hardware.wifi.NanMatchInd;
+import android.hardware.wifi.NanStatus;
+import android.hardware.wifi.NanStatusCode;
+import android.hardware.wifi.WifiChannelWidthInMhz;
+import android.net.MacAddress;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiAnnotations;
+import android.net.wifi.aware.Characteristics;
+import android.net.wifi.aware.WifiAwareChannelInfo;
+import android.net.wifi.util.HexEncoding;
+import android.util.Log;
+
+import com.android.server.wifi.aware.Capabilities;
+import com.android.server.wifi.hal.WifiNanIface.NanClusterEventType;
+import com.android.server.wifi.hal.WifiNanIface.NanRangingIndication;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Callback registered with the Vendor HAL service. On events, converts arguments
+ * to their framework equivalents and calls the registered framework callback.
+ */
+public class WifiNanIfaceCallbackAidlImpl extends IWifiNanIfaceEventCallback.Stub {
+ private static final String TAG = "WifiNanIfaceCallbackAidlImpl";
+
+ private boolean mVerboseLoggingEnabled;
+ private WifiNanIfaceAidlImpl mWifiNanIface;
+
+ public WifiNanIfaceCallbackAidlImpl(WifiNanIfaceAidlImpl wifiNanIface) {
+ mWifiNanIface = wifiNanIface;
+ }
+
+ /**
+ * Enable verbose logging.
+ */
+ public void enableVerboseLogging(boolean verbose) {
+ mVerboseLoggingEnabled = verbose;
+ }
+
+ @Override
+ public void notifyCapabilitiesResponse(char id, NanStatus status,
+ NanCapabilities capabilities) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyCapabilitiesResponse: id=" + id + ", status="
+ + statusString(status) + ", capabilities=" + capabilities);
+ }
+
+ if (status.status == NanStatusCode.SUCCESS) {
+ Capabilities frameworkCapabilities = toFrameworkCapability(capabilities);
+ mWifiNanIface.getFrameworkCallback().notifyCapabilitiesResponse(
+ (short) id, frameworkCapabilities);
+ } else {
+ Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " ("
+ + status.description + ")");
+ }
+ }
+
+ @Override
+ public void notifyEnableResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyEnableResponse: id=" + id + ", status=" + statusString(status));
+ }
+
+ if (status.status == NanStatusCode.ALREADY_ENABLED) {
+ Log.wtf(TAG, "notifyEnableResponse: id=" + id + ", already enabled!?");
+ }
+ mWifiNanIface.getFrameworkCallback().notifyEnableResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void notifyConfigResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyConfigResponse: id=" + id + ", status=" + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyConfigResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void notifyDisableResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyDisableResponse: id=" + id + ", status=" + statusString(status));
+ }
+
+ if (status.status != NanStatusCode.SUCCESS) {
+ Log.e(TAG, "notifyDisableResponse: failure - code=" + status.status + " ("
+ + status.description + ")");
+ }
+ mWifiNanIface.getFrameworkCallback().notifyDisableResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void notifyStartPublishResponse(char id, NanStatus status, byte publishId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyStartPublishResponse: id=" + id + ", status=" + statusString(status)
+ + ", publishId=" + publishId);
+ }
+ mWifiNanIface.getFrameworkCallback().notifyStartPublishResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status), publishId);
+ }
+
+ @Override
+ public void notifyStopPublishResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyStopPublishResponse: id=" + id + ", status=" + statusString(status));
+ }
+
+ if (status.status == NanStatusCode.SUCCESS) {
+ // NOP
+ } else {
+ Log.e(TAG, "notifyStopPublishResponse: failure - code=" + status.status + " ("
+ + status.description + ")");
+ }
+ }
+
+ @Override
+ public void notifyStartSubscribeResponse(char id, NanStatus status, byte subscribeId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyStartSubscribeResponse: id=" + id + ", status=" + statusString(status)
+ + ", subscribeId=" + subscribeId);
+ }
+ mWifiNanIface.getFrameworkCallback().notifyStartSubscribeResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status), subscribeId);
+ }
+
+ @Override
+ public void notifyStopSubscribeResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyStopSubscribeResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+
+ if (status.status == NanStatusCode.SUCCESS) {
+ // NOP
+ } else {
+ Log.e(TAG, "notifyStopSubscribeResponse: failure - code=" + status.status + " ("
+ + status.description + ")");
+ }
+ }
+
+ @Override
+ public void notifyTransmitFollowupResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyTransmitFollowupResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyTransmitFollowupResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void notifyCreateDataInterfaceResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyCreateDataInterfaceResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyCreateDataInterfaceResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void notifyDeleteDataInterfaceResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyDeleteDataInterfaceResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyDeleteDataInterfaceResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void notifyInitiateDataPathResponse(char id, NanStatus status,
+ int ndpInstanceId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyInitiateDataPathResponse: id=" + id + ", status="
+ + statusString(status) + ", ndpInstanceId=" + ndpInstanceId);
+ }
+ mWifiNanIface.getFrameworkCallback().notifyInitiateDataPathResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status), ndpInstanceId);
+ }
+
+ @Override
+ public void notifyRespondToDataPathIndicationResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyRespondToDataPathIndicationResponse: id=" + id
+ + ", status=" + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyRespondToDataPathIndicationResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void notifyTerminateDataPathResponse(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyTerminateDataPathResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyTerminateDataPathResponse(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void eventClusterEvent(NanClusterEventInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventClusterEvent: eventType=" + event.eventType + ", addr="
+ + String.valueOf(HexEncoding.encode(event.addr)));
+ }
+ mWifiNanIface.getFrameworkCallback().eventClusterEvent(
+ NanClusterEventType.fromAidl(event.eventType), event.addr);
+ }
+
+ @Override
+ public void eventDisabled(NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) Log.v(TAG, "eventDisabled: status=" + statusString(status));
+ mWifiNanIface.getFrameworkCallback().eventDisabled(
+ WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void eventPublishTerminated(byte sessionId, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventPublishTerminated: sessionId=" + sessionId + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().eventPublishTerminated(
+ sessionId, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void eventSubscribeTerminated(byte sessionId, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventSubscribeTerminated: sessionId=" + sessionId + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().eventSubscribeTerminated(
+ sessionId, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void eventMatch(NanMatchInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventMatch: discoverySessionId=" + event.discoverySessionId
+ + ", peerId=" + event.peerId
+ + ", addr=" + String.valueOf(HexEncoding.encode(event.addr))
+ + ", serviceSpecificInfo=" + Arrays.toString(event.serviceSpecificInfo)
+ + ", ssi.size()=" + (event.serviceSpecificInfo == null
+ ? 0 : event.serviceSpecificInfo.length)
+ + ", matchFilter=" + Arrays.toString(event.matchFilter)
+ + ", mf.size()=" + (event.matchFilter == null ? 0 : event.matchFilter.length)
+ + ", rangingIndicationType=" + event.rangingIndicationType
+ + ", rangingMeasurementInMm=" + event.rangingMeasurementInMm + ", "
+ + "scid=" + Arrays.toString(event.scid));
+ }
+ mWifiNanIface.getFrameworkCallback().eventMatch(event.discoverySessionId, event.peerId,
+ event.addr, event.serviceSpecificInfo, event.matchFilter,
+ NanRangingIndication.fromAidl(event.rangingIndicationType),
+ event.rangingMeasurementInMm, event.scid,
+ toPublicCipherSuites(event.peerCipherType));
+ }
+
+ @Override
+ public void eventMatchExpired(byte discoverySessionId, int peerId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventMatchExpired: discoverySessionId=" + discoverySessionId
+ + ", peerId=" + peerId);
+ }
+ mWifiNanIface.getFrameworkCallback().eventMatchExpired(discoverySessionId, peerId);
+ }
+
+ @Override
+ public void eventFollowupReceived(NanFollowupReceivedInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventFollowupReceived: discoverySessionId=" + event.discoverySessionId
+ + ", peerId=" + event.peerId + ", addr=" + String.valueOf(
+ HexEncoding.encode(event.addr)) + ", serviceSpecificInfo=" + Arrays.toString(
+ event.serviceSpecificInfo) + ", ssi.size()="
+ + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.length));
+ }
+ mWifiNanIface.getFrameworkCallback().eventFollowupReceived(
+ event.discoverySessionId, event.peerId, event.addr, event.serviceSpecificInfo);
+ }
+
+ @Override
+ public void eventTransmitFollowup(char id, NanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventTransmitFollowup: id=" + id + ", status=" + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().eventTransmitFollowup(
+ (short) id, WifiNanIface.NanStatusCode.fromAidl(status.status));
+ }
+
+ @Override
+ public void eventDataPathRequest(NanDataPathRequestInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId
+ + ", peerDiscMacAddr=" + String.valueOf(
+ HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId="
+ + event.ndpInstanceId + ", appInfo.size()=" + event.appInfo.length);
+ }
+ mWifiNanIface.getFrameworkCallback().eventDataPathRequest(event.discoverySessionId,
+ event.peerDiscMacAddr, event.ndpInstanceId, event.appInfo);
+ }
+
+ @Override
+ public void eventDataPathConfirm(NanDataPathConfirmInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId
+ + ", peerNdiMacAddr=" + String.valueOf(
+ HexEncoding.encode(event.peerNdiMacAddr)) + ", dataPathSetupSuccess="
+ + event.dataPathSetupSuccess + ", reason=" + event.status.status
+ + ", appInfo.size()=" + event.appInfo.length
+ + ", channelInfo" + Arrays.toString(event.channelInfo));
+ }
+ List<WifiAwareChannelInfo> wifiAwareChannelInfos = convertHalChannelInfo(event.channelInfo);
+ mWifiNanIface.getFrameworkCallback().eventDataPathConfirm(
+ WifiNanIface.NanStatusCode.fromAidl(event.status.status), event.ndpInstanceId,
+ event.dataPathSetupSuccess, event.peerNdiMacAddr, event.appInfo,
+ wifiAwareChannelInfos);
+ }
+
+ @Override
+ public void eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathScheduleUpdate: peerMac="
+ + MacAddress.fromBytes(event.peerDiscoveryAddress)
+ + ", ndpIds=" + Arrays.toString(event.ndpInstanceIds)
+ + ", channelInfo=" + Arrays.toString(event.channelInfo));
+ }
+ List<WifiAwareChannelInfo> wifiAwareChannelInfos = convertHalChannelInfo(event.channelInfo);
+ ArrayList<Integer> ndpInstanceIds = new ArrayList<>();
+ for (int i : event.ndpInstanceIds) {
+ ndpInstanceIds.add(i);
+ }
+ mWifiNanIface.getFrameworkCallback().eventDataPathScheduleUpdate(
+ event.peerDiscoveryAddress, ndpInstanceIds, wifiAwareChannelInfos);
+ }
+
+ @Override
+ public void eventDataPathTerminated(int ndpInstanceId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId);
+ }
+ mWifiNanIface.getFrameworkCallback().eventDataPathTerminated(ndpInstanceId);
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return IWifiNanIfaceEventCallback.HASH;
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return IWifiNanIfaceEventCallback.VERSION;
+ }
+
+ private Capabilities toFrameworkCapability(NanCapabilities capabilities) {
+ Capabilities frameworkCapabilities = new Capabilities();
+ frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters;
+ frameworkCapabilities.maxPublishes = capabilities.maxPublishes;
+ frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes;
+ frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen;
+ frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen;
+ frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen;
+ frameworkCapabilities.maxServiceSpecificInfoLen =
+ capabilities.maxServiceSpecificInfoLen;
+ frameworkCapabilities.maxExtendedServiceSpecificInfoLen =
+ capabilities.maxExtendedServiceSpecificInfoLen;
+ frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces;
+ frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions;
+ frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen;
+ frameworkCapabilities.maxQueuedTransmitMessages =
+ capabilities.maxQueuedTransmitFollowupMsgs;
+ frameworkCapabilities.maxSubscribeInterfaceAddresses =
+ capabilities.maxSubscribeInterfaceAddresses;
+ frameworkCapabilities.supportedCipherSuites = toPublicCipherSuites(
+ capabilities.supportedCipherSuites);
+ frameworkCapabilities.isInstantCommunicationModeSupported =
+ capabilities.instantCommunicationModeSupportFlag;
+ return frameworkCapabilities;
+ }
+
+ private int toPublicCipherSuites(int nativeCipherSuites) {
+ int publicCipherSuites = 0;
+
+ if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_128_MASK) != 0) {
+ publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
+ }
+ if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_256_MASK) != 0) {
+ publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
+ }
+ if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_128_MASK) != 0) {
+ publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128;
+ }
+ if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_256_MASK) != 0) {
+ publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256;
+ }
+
+ return publicCipherSuites;
+ }
+
+ private static String statusString(NanStatus status) {
+ if (status == null) {
+ return "status=null";
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(status.status).append(" (").append(status.description).append(")");
+ return sb.toString();
+ }
+
+ /**
+ * Convert HAL channelBandwidth to framework enum
+ */
+ private @WifiAnnotations.ChannelWidth 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
+ */
+ private List<WifiAwareChannelInfo> convertHalChannelInfo(
+ NanDataPathChannelInfo[] channelInfos) {
+ List<WifiAwareChannelInfo> wifiAwareChannelInfos = new ArrayList<>();
+ if (channelInfos == null) {
+ return null;
+ }
+ for (android.hardware.wifi.NanDataPathChannelInfo channelInfo : channelInfos) {
+ wifiAwareChannelInfos.add(new WifiAwareChannelInfo(channelInfo.channelFreq,
+ getChannelBandwidthFromHal(channelInfo.channelBandwidth),
+ channelInfo.numSpatialStreams));
+ }
+ return wifiAwareChannelInfos;
+ }
+
+ private boolean checkFrameworkCallback() {
+ if (mWifiNanIface == null) {
+ Log.e(TAG, "mWifiNanIface is null");
+ return false;
+ } else if (mWifiNanIface.getFrameworkCallback() == null) {
+ Log.e(TAG, "Framework callback is null");
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackHidlImpl.java
new file mode 100644
index 0000000000..721a340992
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackHidlImpl.java
@@ -0,0 +1,678 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.hardware.wifi.V1_0.NanClusterEventInd;
+import android.hardware.wifi.V1_0.NanDataPathConfirmInd;
+import android.hardware.wifi.V1_0.NanDataPathRequestInd;
+import android.hardware.wifi.V1_0.NanFollowupReceivedInd;
+import android.hardware.wifi.V1_0.NanMatchInd;
+import android.hardware.wifi.V1_0.NanStatusType;
+import android.hardware.wifi.V1_0.WifiNanStatus;
+import android.hardware.wifi.V1_2.NanDataPathScheduleUpdateInd;
+import android.hardware.wifi.V1_6.IWifiNanIfaceEventCallback;
+import android.hardware.wifi.V1_6.NanCipherSuiteType;
+import android.hardware.wifi.V1_6.WifiChannelWidthInMhz;
+import android.net.MacAddress;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiAnnotations;
+import android.net.wifi.aware.Characteristics;
+import android.net.wifi.aware.WifiAwareChannelInfo;
+import android.net.wifi.util.HexEncoding;
+import android.util.Log;
+
+import com.android.server.wifi.aware.Capabilities;
+import com.android.server.wifi.hal.WifiNanIface.NanClusterEventType;
+import com.android.server.wifi.hal.WifiNanIface.NanRangingIndication;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Callback registered with the Vendor HAL service. On events, converts arguments
+ * to their framework equivalents and calls the registered framework callback.
+ */
+public class WifiNanIfaceCallbackHidlImpl extends IWifiNanIfaceEventCallback.Stub {
+ private static final String TAG = "WifiNanIfaceCallbackHidlImpl";
+
+ private boolean mVerboseLoggingEnabled;
+ private WifiNanIfaceHidlImpl mWifiNanIface;
+
+ public WifiNanIfaceCallbackHidlImpl(WifiNanIfaceHidlImpl wifiNanIface) {
+ mWifiNanIface = wifiNanIface;
+ }
+
+ /**
+ * Enable verbose logging.
+ */
+ public void enableVerboseLogging(boolean verbose) {
+ mVerboseLoggingEnabled = verbose;
+ }
+
+ @Override
+ public void notifyCapabilitiesResponse(short id, WifiNanStatus status,
+ android.hardware.wifi.V1_0.NanCapabilities capabilities) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyCapabilitiesResponse: id=" + id + ", status=" + statusString(status)
+ + ", capabilities=" + capabilities);
+ }
+
+ if (status.status == NanStatusType.SUCCESS) {
+ Capabilities frameworkCapabilities = toFrameworkCapability10(capabilities);
+ mWifiNanIface.getFrameworkCallback().notifyCapabilitiesResponse(
+ id, frameworkCapabilities);
+ } else {
+ Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " ("
+ + status.description + ")");
+ }
+ }
+
+ @Override
+ public void notifyCapabilitiesResponse_1_5(short id, WifiNanStatus status,
+ android.hardware.wifi.V1_5.NanCapabilities capabilities) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyCapabilitiesResponse_1_5: id=" + id + ", status="
+ + statusString(status) + ", capabilities=" + capabilities);
+ }
+
+ if (status.status == NanStatusType.SUCCESS) {
+ Capabilities frameworkCapabilities = toFrameworkCapability10(capabilities.V1_0);
+ frameworkCapabilities.isInstantCommunicationModeSupported =
+ capabilities.instantCommunicationModeSupportFlag;
+ mWifiNanIface.getFrameworkCallback().notifyCapabilitiesResponse(
+ id, frameworkCapabilities);
+ } else {
+ Log.e(TAG, "notifyCapabilitiesResponse_1_5: error code=" + status.status + " ("
+ + status.description + ")");
+ }
+ }
+
+ @Override
+ public void notifyCapabilitiesResponse_1_6(short id, WifiNanStatus status,
+ android.hardware.wifi.V1_6.NanCapabilities capabilities) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyCapabilitiesResponse_1_6: id=" + id + ", status="
+ + statusString(status) + ", capabilities=" + capabilities);
+ }
+
+ if (status.status == NanStatusType.SUCCESS) {
+ Capabilities frameworkCapabilities = toFrameworkCapability1_6(capabilities);
+ mWifiNanIface.getFrameworkCallback().notifyCapabilitiesResponse(
+ id, frameworkCapabilities);
+ } else {
+ Log.e(TAG, "notifyCapabilitiesResponse_1_6: error code=" + status.status + " ("
+ + status.description + ")");
+ }
+ }
+
+ @Override
+ public void notifyEnableResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyEnableResponse: id=" + id + ", status=" + statusString(status));
+ }
+
+ if (status.status == NanStatusType.ALREADY_ENABLED) {
+ Log.wtf(TAG, "notifyEnableResponse: id=" + id + ", already enabled!?");
+ }
+ mWifiNanIface.getFrameworkCallback().notifyEnableResponse(
+ id, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void notifyConfigResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyConfigResponse: id=" + id + ", status=" + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyConfigResponse(
+ id, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void notifyDisableResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyDisableResponse: id=" + id + ", status=" + statusString(status));
+ }
+
+ if (status.status != NanStatusType.SUCCESS) {
+ Log.e(TAG, "notifyDisableResponse: failure - code=" + status.status + " ("
+ + status.description + ")");
+ }
+ mWifiNanIface.getFrameworkCallback().notifyDisableResponse(
+ id, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void notifyStartPublishResponse(short id, WifiNanStatus status, byte publishId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyStartPublishResponse: id=" + id + ", status=" + statusString(status)
+ + ", publishId=" + publishId);
+ }
+ mWifiNanIface.getFrameworkCallback().notifyStartPublishResponse(
+ id, NanStatusCode.fromHidl(status.status), publishId);
+ }
+
+ @Override
+ public void notifyStopPublishResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyStopPublishResponse: id=" + id + ", status=" + statusString(status));
+ }
+
+ if (status.status == NanStatusType.SUCCESS) {
+ // NOP
+ } else {
+ Log.e(TAG, "notifyStopPublishResponse: failure - code=" + status.status + " ("
+ + status.description + ")");
+ }
+ }
+
+ @Override
+ public void notifyStartSubscribeResponse(short id, WifiNanStatus status, byte subscribeId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyStartSubscribeResponse: id=" + id + ", status=" + statusString(status)
+ + ", subscribeId=" + subscribeId);
+ }
+ mWifiNanIface.getFrameworkCallback().notifyStartSubscribeResponse(
+ id, NanStatusCode.fromHidl(status.status), subscribeId);
+ }
+
+ @Override
+ public void notifyStopSubscribeResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyStopSubscribeResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+
+ if (status.status == NanStatusType.SUCCESS) {
+ // NOP
+ } else {
+ Log.e(TAG, "notifyStopSubscribeResponse: failure - code=" + status.status + " ("
+ + status.description + ")");
+ }
+ }
+
+ @Override
+ public void notifyTransmitFollowupResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyTransmitFollowupResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyTransmitFollowupResponse(
+ id, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void notifyCreateDataInterfaceResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyCreateDataInterfaceResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyCreateDataInterfaceResponse(
+ id, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void notifyDeleteDataInterfaceResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyDeleteDataInterfaceResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyDeleteDataInterfaceResponse(
+ id, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void notifyInitiateDataPathResponse(short id, WifiNanStatus status,
+ int ndpInstanceId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyInitiateDataPathResponse: id=" + id + ", status="
+ + statusString(status) + ", ndpInstanceId=" + ndpInstanceId);
+ }
+ mWifiNanIface.getFrameworkCallback().notifyInitiateDataPathResponse(
+ id, NanStatusCode.fromHidl(status.status), ndpInstanceId);
+ }
+
+ @Override
+ public void notifyRespondToDataPathIndicationResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyRespondToDataPathIndicationResponse: id=" + id
+ + ", status=" + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyRespondToDataPathIndicationResponse(
+ id, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void notifyTerminateDataPathResponse(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "notifyTerminateDataPathResponse: id=" + id + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().notifyTerminateDataPathResponse(
+ id, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void eventClusterEvent(NanClusterEventInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventClusterEvent: eventType=" + event.eventType + ", addr="
+ + String.valueOf(HexEncoding.encode(event.addr)));
+ }
+ mWifiNanIface.getFrameworkCallback().eventClusterEvent(
+ NanClusterEventType.fromHidl(event.eventType), event.addr);
+ }
+
+ @Override
+ public void eventDisabled(WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) Log.v(TAG, "eventDisabled: status=" + statusString(status));
+ mWifiNanIface.getFrameworkCallback().eventDisabled(
+ NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void eventPublishTerminated(byte sessionId, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventPublishTerminated: sessionId=" + sessionId + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().eventPublishTerminated(
+ sessionId, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void eventSubscribeTerminated(byte sessionId, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventSubscribeTerminated: sessionId=" + sessionId + ", status="
+ + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().eventSubscribeTerminated(
+ sessionId, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void eventMatch(NanMatchInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventMatch: discoverySessionId=" + event.discoverySessionId + ", peerId="
+ + event.peerId + ", addr=" + String.valueOf(HexEncoding.encode(event.addr))
+ + ", serviceSpecificInfo=" + Arrays.toString(
+ convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
+ + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size())
+ + ", matchFilter=" + Arrays.toString(
+ convertArrayListToNativeByteArray(event.matchFilter)) + ", mf.size()=" + (
+ event.matchFilter == null ? 0 : event.matchFilter.size())
+ + ", rangingIndicationType=" + event.rangingIndicationType
+ + ", rangingMeasurementInCm=" + event.rangingMeasurementInCm);
+ }
+ mWifiNanIface.getFrameworkCallback().eventMatch(event.discoverySessionId, event.peerId,
+ event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo),
+ convertArrayListToNativeByteArray(event.matchFilter),
+ NanRangingIndication.fromHidl(event.rangingIndicationType),
+ event.rangingMeasurementInCm * 10, new byte[0], 0);
+ }
+
+ @Override
+ public void eventMatch_1_6(android.hardware.wifi.V1_6.NanMatchInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventMatch_1_6: discoverySessionId=" + event.discoverySessionId
+ + ", peerId=" + event.peerId
+ + ", addr=" + String.valueOf(HexEncoding.encode(event.addr))
+ + ", serviceSpecificInfo=" + Arrays.toString(
+ convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
+ + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size())
+ + ", matchFilter=" + Arrays.toString(
+ convertArrayListToNativeByteArray(event.matchFilter)) + ", mf.size()=" + (
+ event.matchFilter == null ? 0 : event.matchFilter.size())
+ + ", rangingIndicationType=" + event.rangingIndicationType
+ + ", rangingMeasurementInCm=" + event.rangingMeasurementInMm + ", "
+ + "scid=" + Arrays.toString(convertArrayListToNativeByteArray(event.scid)));
+ }
+ mWifiNanIface.getFrameworkCallback().eventMatch(event.discoverySessionId, event.peerId,
+ event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo),
+ convertArrayListToNativeByteArray(event.matchFilter),
+ NanRangingIndication.fromHidl(event.rangingIndicationType),
+ event.rangingMeasurementInMm, convertArrayListToNativeByteArray(event.scid),
+ toPublicCipherSuites(event.peerCipherType));
+ }
+
+ @Override
+ public void eventMatchExpired(byte discoverySessionId, int peerId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventMatchExpired: discoverySessionId=" + discoverySessionId
+ + ", peerId=" + peerId);
+ }
+ mWifiNanIface.getFrameworkCallback().eventMatchExpired(discoverySessionId, peerId);
+ }
+
+ @Override
+ public void eventFollowupReceived(NanFollowupReceivedInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventFollowupReceived: discoverySessionId=" + event.discoverySessionId
+ + ", peerId=" + event.peerId + ", addr=" + String.valueOf(
+ HexEncoding.encode(event.addr)) + ", serviceSpecificInfo=" + Arrays.toString(
+ convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
+ + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size()));
+ }
+ mWifiNanIface.getFrameworkCallback().eventFollowupReceived(
+ event.discoverySessionId, event.peerId, event.addr,
+ convertArrayListToNativeByteArray(event.serviceSpecificInfo));
+ }
+
+ @Override
+ public void eventTransmitFollowup(short id, WifiNanStatus status) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventTransmitFollowup: id=" + id + ", status=" + statusString(status));
+ }
+ mWifiNanIface.getFrameworkCallback().eventTransmitFollowup(
+ id, NanStatusCode.fromHidl(status.status));
+ }
+
+ @Override
+ public void eventDataPathRequest(NanDataPathRequestInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId
+ + ", peerDiscMacAddr=" + String.valueOf(
+ HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId="
+ + event.ndpInstanceId + ", appInfo.size()=" + event.appInfo.size());
+ }
+ mWifiNanIface.getFrameworkCallback().eventDataPathRequest(event.discoverySessionId,
+ event.peerDiscMacAddr, event.ndpInstanceId,
+ convertArrayListToNativeByteArray(event.appInfo));
+ }
+
+ @Override
+ public void eventDataPathConfirm(NanDataPathConfirmInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "onDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId
+ + ", peerNdiMacAddr=" + String.valueOf(HexEncoding.encode(event.peerNdiMacAddr))
+ + ", dataPathSetupSuccess=" + event.dataPathSetupSuccess + ", reason="
+ + event.status.status + ", appInfo.size()=" + event.appInfo.size());
+ }
+ mWifiNanIface.getFrameworkCallback().eventDataPathConfirm(
+ NanStatusCode.fromHidl(event.status.status), event.ndpInstanceId,
+ event.dataPathSetupSuccess, event.peerNdiMacAddr,
+ convertArrayListToNativeByteArray(event.appInfo), null);
+ }
+
+ @Override
+ public void eventDataPathConfirm_1_2(android.hardware.wifi.V1_2.NanDataPathConfirmInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathConfirm_1_2: ndpInstanceId=" + event.V1_0.ndpInstanceId
+ + ", peerNdiMacAddr=" + String.valueOf(
+ HexEncoding.encode(event.V1_0.peerNdiMacAddr)) + ", dataPathSetupSuccess="
+ + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status
+ + ", appInfo.size()=" + event.V1_0.appInfo.size()
+ + ", channelInfo" + event.channelInfo);
+ }
+ List<WifiAwareChannelInfo> wifiAwareChannelInfos =
+ convertHalChannelInfo_1_2(event.channelInfo);
+ mWifiNanIface.getFrameworkCallback().eventDataPathConfirm(
+ NanStatusCode.fromHidl(event.V1_0.status.status), event.V1_0.ndpInstanceId,
+ event.V1_0.dataPathSetupSuccess, event.V1_0.peerNdiMacAddr,
+ convertArrayListToNativeByteArray(event.V1_0.appInfo), wifiAwareChannelInfos);
+ }
+
+ @Override
+ public void eventDataPathConfirm_1_6(android.hardware.wifi.V1_6.NanDataPathConfirmInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathConfirm_1_6: ndpInstanceId=" + event.V1_0.ndpInstanceId
+ + ", peerNdiMacAddr=" + String.valueOf(
+ HexEncoding.encode(event.V1_0.peerNdiMacAddr)) + ", dataPathSetupSuccess="
+ + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status
+ + ", appInfo.size()=" + event.V1_0.appInfo.size()
+ + ", channelInfo" + event.channelInfo);
+ }
+ List<WifiAwareChannelInfo> wifiAwareChannelInfos =
+ convertHalChannelInfo_1_6(event.channelInfo);
+ mWifiNanIface.getFrameworkCallback().eventDataPathConfirm(
+ NanStatusCode.fromHidl(event.V1_0.status.status), event.V1_0.ndpInstanceId,
+ event.V1_0.dataPathSetupSuccess, event.V1_0.peerNdiMacAddr,
+ convertArrayListToNativeByteArray(event.V1_0.appInfo), wifiAwareChannelInfos);
+ }
+
+ @Override
+ public void eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathScheduleUpdate: peerMac="
+ + MacAddress.fromBytes(event.peerDiscoveryAddress)
+ + ", ndpIds=" + event.ndpInstanceIds + ", channelInfo=" + event.channelInfo);
+ }
+ List<WifiAwareChannelInfo> wifiAwareChannelInfos =
+ convertHalChannelInfo_1_2(event.channelInfo);
+ mWifiNanIface.getFrameworkCallback().eventDataPathScheduleUpdate(
+ event.peerDiscoveryAddress, event.ndpInstanceIds, wifiAwareChannelInfos);
+ }
+
+ @Override
+ public void eventDataPathScheduleUpdate_1_6(
+ android.hardware.wifi.V1_6.NanDataPathScheduleUpdateInd event) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathScheduleUpdate_1_6: peerMac="
+ + MacAddress.fromBytes(event.peerDiscoveryAddress)
+ + ", ndpIds=" + event.ndpInstanceIds + ", channelInfo=" + event.channelInfo);
+ }
+ List<WifiAwareChannelInfo> wifiAwareChannelInfos =
+ convertHalChannelInfo_1_6(event.channelInfo);
+ mWifiNanIface.getFrameworkCallback().eventDataPathScheduleUpdate(
+ event.peerDiscoveryAddress, event.ndpInstanceIds, wifiAwareChannelInfos);
+ }
+
+ @Override
+ public void eventDataPathTerminated(int ndpInstanceId) {
+ if (!checkFrameworkCallback()) return;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId);
+ }
+ mWifiNanIface.getFrameworkCallback().eventDataPathTerminated(ndpInstanceId);
+ }
+
+ private Capabilities toFrameworkCapability10(
+ android.hardware.wifi.V1_0.NanCapabilities capabilities) {
+ Capabilities frameworkCapabilities = new Capabilities();
+ frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters;
+ frameworkCapabilities.maxPublishes = capabilities.maxPublishes;
+ frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes;
+ frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen;
+ frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen;
+ frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen;
+ frameworkCapabilities.maxServiceSpecificInfoLen =
+ capabilities.maxServiceSpecificInfoLen;
+ frameworkCapabilities.maxExtendedServiceSpecificInfoLen =
+ capabilities.maxExtendedServiceSpecificInfoLen;
+ frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces;
+ frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions;
+ frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen;
+ frameworkCapabilities.maxQueuedTransmitMessages =
+ capabilities.maxQueuedTransmitFollowupMsgs;
+ frameworkCapabilities.maxSubscribeInterfaceAddresses =
+ capabilities.maxSubscribeInterfaceAddresses;
+ frameworkCapabilities.supportedCipherSuites = toPublicCipherSuites(
+ capabilities.supportedCipherSuites);
+ frameworkCapabilities.isInstantCommunicationModeSupported = false;
+ return frameworkCapabilities;
+ }
+
+ private Capabilities toFrameworkCapability1_6(
+ android.hardware.wifi.V1_6.NanCapabilities capabilities) {
+ Capabilities frameworkCapabilities = new Capabilities();
+ frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters;
+ frameworkCapabilities.maxPublishes = capabilities.maxPublishes;
+ frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes;
+ frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen;
+ frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen;
+ frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen;
+ frameworkCapabilities.maxServiceSpecificInfoLen =
+ capabilities.maxServiceSpecificInfoLen;
+ frameworkCapabilities.maxExtendedServiceSpecificInfoLen =
+ capabilities.maxExtendedServiceSpecificInfoLen;
+ frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces;
+ frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions;
+ frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen;
+ frameworkCapabilities.maxQueuedTransmitMessages =
+ capabilities.maxQueuedTransmitFollowupMsgs;
+ frameworkCapabilities.maxSubscribeInterfaceAddresses =
+ capabilities.maxSubscribeInterfaceAddresses;
+ frameworkCapabilities.supportedCipherSuites = toPublicCipherSuites(
+ capabilities.supportedCipherSuites);
+ frameworkCapabilities.isInstantCommunicationModeSupported =
+ capabilities.instantCommunicationModeSupportFlag;
+ return frameworkCapabilities;
+ }
+
+ private int toPublicCipherSuites(int nativeCipherSuites) {
+ int publicCipherSuites = 0;
+
+ if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_128_MASK) != 0) {
+ publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
+ }
+ if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_256_MASK) != 0) {
+ publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
+ }
+ if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_128_MASK) != 0) {
+ publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128;
+ }
+ if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_256_MASK) != 0) {
+ publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256;
+ }
+
+ return publicCipherSuites;
+ }
+
+ /**
+ * Converts an ArrayList<Byte> to a byte[].
+ *
+ * @param from The input ArrayList<Byte></Byte> to convert from.
+ *
+ * @return A newly allocated byte[].
+ */
+ private byte[] convertArrayListToNativeByteArray(ArrayList<Byte> from) {
+ if (from == null) {
+ return null;
+ }
+
+ byte[] to = new byte[from.size()];
+ for (int i = 0; i < from.size(); ++i) {
+ to[i] = from.get(i);
+ }
+ return to;
+ }
+
+ private static String statusString(WifiNanStatus status) {
+ if (status == null) {
+ return "status=null";
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(status.status).append(" (").append(status.description).append(")");
+ return sb.toString();
+ }
+
+ /**
+ * Convert HAL channelBandwidth to framework enum
+ */
+ private @WifiAnnotations.ChannelWidth 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 V1_2 NanDataPathChannelInfo to WifiAwareChannelInfo
+ */
+ private List<WifiAwareChannelInfo> convertHalChannelInfo_1_2(
+ List<android.hardware.wifi.V1_2.NanDataPathChannelInfo> channelInfos) {
+ List<WifiAwareChannelInfo> wifiAwareChannelInfos = new ArrayList<>();
+ if (channelInfos == null) {
+ return null;
+ }
+ for (android.hardware.wifi.V1_2.NanDataPathChannelInfo channelInfo : channelInfos) {
+ wifiAwareChannelInfos.add(new WifiAwareChannelInfo(channelInfo.channelFreq,
+ getChannelBandwidthFromHal(channelInfo.channelBandwidth),
+ channelInfo.numSpatialStreams));
+ }
+ return wifiAwareChannelInfos;
+ }
+
+ /**
+ * Convert HAL V1_6 NanDataPathChannelInfo to WifiAwareChannelInfo
+ */
+ private List<WifiAwareChannelInfo> convertHalChannelInfo_1_6(
+ List<android.hardware.wifi.V1_6.NanDataPathChannelInfo> channelInfos) {
+ List<WifiAwareChannelInfo> wifiAwareChannelInfos = new ArrayList<>();
+ if (channelInfos == null) {
+ return null;
+ }
+ for (android.hardware.wifi.V1_6.NanDataPathChannelInfo channelInfo : channelInfos) {
+ wifiAwareChannelInfos.add(new WifiAwareChannelInfo(channelInfo.channelFreq,
+ getChannelBandwidthFromHal(channelInfo.channelBandwidth),
+ channelInfo.numSpatialStreams));
+ }
+ return wifiAwareChannelInfos;
+ }
+
+ private boolean checkFrameworkCallback() {
+ if (mWifiNanIface == null) {
+ Log.e(TAG, "mWifiNanIface is null");
+ return false;
+ } else if (mWifiNanIface.getFrameworkCallback() == null) {
+ Log.e(TAG, "Framework callback is null");
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceHidlImpl.java
new file mode 100644
index 0000000000..8869031a0c
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceHidlImpl.java
@@ -0,0 +1,1149 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
+
+import android.annotation.NonNull;
+import android.hardware.wifi.V1_0.NanBandIndex;
+import android.hardware.wifi.V1_0.NanBandSpecificConfig;
+import android.hardware.wifi.V1_0.NanConfigRequest;
+import android.hardware.wifi.V1_0.NanDataPathSecurityType;
+import android.hardware.wifi.V1_0.NanEnableRequest;
+import android.hardware.wifi.V1_0.NanInitiateDataPathRequest;
+import android.hardware.wifi.V1_0.NanMatchAlg;
+import android.hardware.wifi.V1_0.NanPublishRequest;
+import android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest;
+import android.hardware.wifi.V1_0.NanSubscribeRequest;
+import android.hardware.wifi.V1_0.NanTransmitFollowupRequest;
+import android.hardware.wifi.V1_0.NanTxType;
+import android.hardware.wifi.V1_0.WifiStatus;
+import android.hardware.wifi.V1_0.WifiStatusCode;
+import android.hardware.wifi.V1_6.NanCipherSuiteType;
+import android.net.MacAddress;
+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.RemoteException;
+import android.util.Log;
+
+import com.android.server.wifi.aware.Capabilities;
+import com.android.server.wifi.util.GeneralUtil.Mutable;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.function.Supplier;
+
+/**
+ * HIDL implementation of the IWifiNanIface interface.
+ */
+public class WifiNanIfaceHidlImpl implements IWifiNanIface {
+ private static final String TAG = "WifiNanIfaceHidlImpl";
+ private android.hardware.wifi.V1_0.IWifiNanIface mWifiNanIface;
+ private String mIfaceName;
+ private WifiNanIfaceCallbackHidlImpl mHalCallback;
+ private WifiNanIface.Callback mFrameworkCallback;
+
+ public WifiNanIfaceHidlImpl(@NonNull android.hardware.wifi.V1_0.IWifiNanIface nanIface) {
+ mWifiNanIface = nanIface;
+ mHalCallback = new WifiNanIfaceCallbackHidlImpl(this);
+ }
+
+ /**
+ * Enable verbose logging.
+ */
+ public void enableVerboseLogging(boolean verbose) {
+ if (mHalCallback != null) {
+ mHalCallback.enableVerboseLogging(verbose);
+ }
+ }
+
+ protected WifiNanIface.Callback getFrameworkCallback() {
+ return mFrameworkCallback;
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#getNanIface()}
+ *
+ * TODO: Remove this API. Will only be used temporarily until HalDeviceManager is refactored.
+ */
+ public android.hardware.wifi.V1_0.IWifiNanIface getNanIface() {
+ return mWifiNanIface;
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#registerFrameworkCallback(WifiNanIface.Callback)}
+ */
+ public boolean registerFrameworkCallback(WifiNanIface.Callback callback) {
+ final String methodStr = "registerFrameworkCallback";
+ return validateAndCall(methodStr, false,
+ () -> registerFrameworkCallbackInternal(methodStr, callback));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#getName()}
+ */
+ public String getName() {
+ final String methodStr = "getName";
+ return validateAndCall(methodStr, null,
+ () -> getNameInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#getCapabilities(short)}
+ */
+ public boolean getCapabilities(short transactionId) {
+ final String methodStr = "getCapabilities";
+ return validateAndCall(methodStr, false,
+ () -> getCapabilitiesInternal(methodStr, transactionId));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#enableAndConfigure(short, ConfigRequest, boolean,
+ * boolean, boolean, boolean, int, int, WifiNanIface.PowerParameters)}
+ */
+ public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest,
+ boolean notifyIdentityChange, boolean initialConfiguration, boolean rangingEnabled,
+ boolean isInstantCommunicationEnabled, int instantModeChannel,
+ int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters) {
+ final String methodStr = "enableAndConfigure";
+ return validateAndCall(methodStr, false,
+ () -> enableAndConfigureInternal(methodStr, transactionId, configRequest,
+ notifyIdentityChange, initialConfiguration, rangingEnabled,
+ isInstantCommunicationEnabled, instantModeChannel,
+ macAddressRandomizationIntervalSec, powerParameters));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#disable(short)}
+ */
+ public boolean disable(short transactionId) {
+ final String methodStr = "disable";
+ return validateAndCall(methodStr, false,
+ () -> disableInternal(methodStr, transactionId));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#publish(short, byte, PublishConfig)}
+ */
+ public boolean publish(short transactionId, byte publishId, PublishConfig publishConfig) {
+ final String methodStr = "publish";
+ return validateAndCall(methodStr, false,
+ () -> publishInternal(methodStr, transactionId, publishId, publishConfig));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#subscribe(short, byte, SubscribeConfig)}
+ */
+ public boolean subscribe(short transactionId, byte subscribeId,
+ SubscribeConfig subscribeConfig) {
+ final String methodStr = "subscribe";
+ return validateAndCall(methodStr, false,
+ () -> subscribeInternal(methodStr, transactionId, subscribeId, subscribeConfig));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#sendMessage(short, byte, int, MacAddress, byte[])}
+ */
+ public boolean sendMessage(short transactionId, byte pubSubId, int requestorInstanceId,
+ MacAddress dest, byte[] message) {
+ final String methodStr = "sendMessage";
+ return validateAndCall(methodStr, false,
+ () -> sendMessageInternal(methodStr, transactionId, pubSubId, requestorInstanceId,
+ dest, message));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#stopPublish(short, byte)}
+ */
+ public boolean stopPublish(short transactionId, byte pubSubId) {
+ final String methodStr = "stopPublish";
+ return validateAndCall(methodStr, false,
+ () -> stopPublishInternal(methodStr, transactionId, pubSubId));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#stopSubscribe(short, byte)}
+ */
+ public boolean stopSubscribe(short transactionId, byte pubSubId) {
+ final String methodStr = "stopSubscribe";
+ return validateAndCall(methodStr, false,
+ () -> stopSubscribeInternal(methodStr, transactionId, pubSubId));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#createAwareNetworkInterface(short, String)}
+ */
+ public boolean createAwareNetworkInterface(short transactionId, String interfaceName) {
+ final String methodStr = "createAwareNetworkInterface";
+ return validateAndCall(methodStr, false,
+ () -> createAwareNetworkInterfaceInternal(methodStr, transactionId, interfaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#deleteAwareNetworkInterface(short, String)}
+ */
+ public boolean deleteAwareNetworkInterface(short transactionId, String interfaceName) {
+ final String methodStr = "deleteAwareNetworkInterface";
+ return validateAndCall(methodStr, false,
+ () -> deleteAwareNetworkInterfaceInternal(methodStr, transactionId, interfaceName));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#initiateDataPath(short, int, int, int, MacAddress,
+ * String, boolean, byte[], Capabilities,
+ * WifiAwareDataPathSecurityConfig)}
+ */
+ public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
+ int channel, MacAddress peer, String interfaceName,
+ boolean isOutOfBand, byte[] appInfo, Capabilities capabilities,
+ WifiAwareDataPathSecurityConfig securityConfig) {
+ final String methodStr = "initiateDataPath";
+ return validateAndCall(methodStr, false,
+ () -> initiateDataPathInternal(methodStr, transactionId, peerId, channelRequestType,
+ channel, peer, interfaceName, isOutOfBand, appInfo, capabilities,
+ securityConfig));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#respondToDataPathRequest(short, boolean, int, String,
+ * byte[], boolean, Capabilities, WifiAwareDataPathSecurityConfig)}
+ */
+ public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
+ String interfaceName, byte[] appInfo, boolean isOutOfBand, Capabilities capabilities,
+ WifiAwareDataPathSecurityConfig securityConfig) {
+ final String methodStr = "respondToDataPathRequest";
+ return validateAndCall(methodStr, false,
+ () -> respondToDataPathRequestInternal(methodStr, transactionId, accept, ndpId,
+ interfaceName, appInfo, isOutOfBand, capabilities, securityConfig));
+ }
+
+ /**
+ * See comments for {@link IWifiNanIface#endDataPath(short, int)}
+ */
+ public boolean endDataPath(short transactionId, int ndpId) {
+ final String methodStr = "endDataPath";
+ return validateAndCall(methodStr, false,
+ () -> endDataPathInternal(methodStr, transactionId, ndpId));
+ }
+
+
+ // Internal Implementations
+
+ private boolean registerFrameworkCallbackInternal(String methodStr, WifiNanIface.Callback cb) {
+ if (mFrameworkCallback != null) {
+ Log.e(TAG, "Framework callback is already registered");
+ return false;
+ } else if (cb == null) {
+ Log.e(TAG, "Cannot register a null framework callback");
+ return false;
+ }
+
+ WifiStatus status;
+ try {
+ android.hardware.wifi.V1_2.IWifiNanIface iface12 = mockableCastTo_1_2();
+ android.hardware.wifi.V1_5.IWifiNanIface iface15 = mockableCastTo_1_5();
+ android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6();
+ if (iface16 != null) {
+ status = iface16.registerEventCallback_1_6(mHalCallback);
+ } else if (iface15 != null) {
+ status = iface15.registerEventCallback_1_5(mHalCallback);
+ } else if (iface12 != null) {
+ status = iface12.registerEventCallback_1_2(mHalCallback);
+ } else {
+ status = mWifiNanIface.registerEventCallback(mHalCallback);
+ }
+ if (!isOk(status, methodStr)) return false;
+ mFrameworkCallback = cb;
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private String getNameInternal(String methodStr) {
+ if (mIfaceName != null) return mIfaceName;
+ Mutable<String> nameResp = new Mutable<>();
+ try {
+ mWifiNanIface.getName((WifiStatus status, String name) -> {
+ if (isOk(status, methodStr)) {
+ nameResp.value = name;
+ mIfaceName = name;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return nameResp.value;
+ }
+
+ private boolean getCapabilitiesInternal(String methodStr, short transactionId) {
+ android.hardware.wifi.V1_5.IWifiNanIface iface15 = mockableCastTo_1_5();
+ try {
+ WifiStatus status;
+ if (iface15 == null) {
+ status = mWifiNanIface.getCapabilitiesRequest(transactionId);
+ } else {
+ status = iface15.getCapabilitiesRequest_1_5(transactionId);
+ }
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ boolean enableAndConfigureInternal(
+ String methodStr, short transactionId, ConfigRequest configRequest,
+ boolean notifyIdentityChange, boolean initialConfiguration, boolean rangingEnabled,
+ boolean isInstantCommunicationEnabled, int instantModeChannel,
+ int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters) {
+ android.hardware.wifi.V1_2.IWifiNanIface iface12 = mockableCastTo_1_2();
+ android.hardware.wifi.V1_4.IWifiNanIface iface14 = mockableCastTo_1_4();
+ android.hardware.wifi.V1_5.IWifiNanIface iface15 = mockableCastTo_1_5();
+ android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6();
+ android.hardware.wifi.V1_2.NanConfigRequestSupplemental configSupplemental12 =
+ new android.hardware.wifi.V1_2.NanConfigRequestSupplemental();
+ android.hardware.wifi.V1_5.NanConfigRequestSupplemental configSupplemental15 =
+ new android.hardware.wifi.V1_5.NanConfigRequestSupplemental();
+ android.hardware.wifi.V1_6.NanConfigRequestSupplemental configSupplemental16 =
+ new android.hardware.wifi.V1_6.NanConfigRequestSupplemental();
+ if (iface12 != null || iface14 != null) {
+ configSupplemental12.discoveryBeaconIntervalMs = 0;
+ configSupplemental12.numberOfSpatialStreamsInDiscovery = 0;
+ configSupplemental12.enableDiscoveryWindowEarlyTermination = false;
+ configSupplemental12.enableRanging = rangingEnabled;
+ }
+
+ if (iface15 != null) {
+ configSupplemental15.V1_2 = configSupplemental12;
+ configSupplemental15.enableInstantCommunicationMode = isInstantCommunicationEnabled;
+ }
+ if (iface16 != null) {
+ configSupplemental16.V1_5 = configSupplemental15;
+ configSupplemental16.instantModeChannel = instantModeChannel;
+ }
+
+ NanBandSpecificConfig config24 = new NanBandSpecificConfig();
+ config24.rssiClose = 60;
+ config24.rssiMiddle = 70;
+ config24.rssiCloseProximity = 60;
+ config24.dwellTimeMs = (byte) 200;
+ config24.scanPeriodSec = 20;
+ if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]
+ == ConfigRequest.DW_INTERVAL_NOT_INIT) {
+ config24.validDiscoveryWindowIntervalVal = false;
+ } else {
+ config24.validDiscoveryWindowIntervalVal = true;
+ config24.discoveryWindowIntervalVal =
+ (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
+ .NAN_BAND_24GHZ];
+ }
+
+ NanBandSpecificConfig config5 = new NanBandSpecificConfig();
+ config5.rssiClose = 60;
+ config5.rssiMiddle = 75;
+ config5.rssiCloseProximity = 60;
+ config5.dwellTimeMs = (byte) 200;
+ config5.scanPeriodSec = 20;
+ if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]
+ == ConfigRequest.DW_INTERVAL_NOT_INIT) {
+ config5.validDiscoveryWindowIntervalVal = false;
+ } else {
+ config5.validDiscoveryWindowIntervalVal = true;
+ config5.discoveryWindowIntervalVal =
+ (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
+ .NAN_BAND_5GHZ];
+ }
+
+ NanBandSpecificConfig config6 = new NanBandSpecificConfig();
+ config6.rssiClose = 60;
+ config6.rssiMiddle = 75;
+ config6.rssiCloseProximity = 60;
+ config6.dwellTimeMs = (byte) 200;
+ config6.scanPeriodSec = 20;
+ if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ]
+ == ConfigRequest.DW_INTERVAL_NOT_INIT) {
+ config6.validDiscoveryWindowIntervalVal = false;
+ } else {
+ config6.validDiscoveryWindowIntervalVal = true;
+ config6.discoveryWindowIntervalVal =
+ (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
+ .NAN_BAND_6GHZ];
+ }
+
+ try {
+ WifiStatus status;
+ if (initialConfiguration) {
+ if (iface14 != null || iface15 != null || iface16 != null) {
+ // translate framework to HIDL configuration (V_1.4)
+ android.hardware.wifi.V1_4.NanEnableRequest req =
+ new android.hardware.wifi.V1_4.NanEnableRequest();
+
+ req.operateInBand[NanBandIndex.NAN_BAND_24GHZ] = true;
+ req.operateInBand[NanBandIndex.NAN_BAND_5GHZ] = configRequest.mSupport5gBand;
+ req.operateInBand[android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] =
+ configRequest.mSupport6gBand;
+ req.hopCountMax = 2;
+ req.configParams.masterPref = (byte) configRequest.mMasterPreference;
+ req.configParams.disableDiscoveryAddressChangeIndication =
+ !notifyIdentityChange;
+ req.configParams.disableStartedClusterIndication = !notifyIdentityChange;
+ req.configParams.disableJoinedClusterIndication = !notifyIdentityChange;
+ req.configParams.includePublishServiceIdsInBeacon = true;
+ req.configParams.numberOfPublishServiceIdsInBeacon = 0;
+ req.configParams.includeSubscribeServiceIdsInBeacon = true;
+ req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
+ req.configParams.rssiWindowSize = 8;
+ req.configParams.macAddressRandomizationIntervalSec =
+ macAddressRandomizationIntervalSec;
+
+ req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
+ req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
+ req.configParams.bandSpecificConfig[
+ android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] = config6;
+
+ req.debugConfigs.validClusterIdVals = true;
+ req.debugConfigs.clusterIdTopRangeVal = (short) configRequest.mClusterHigh;
+ req.debugConfigs.clusterIdBottomRangeVal = (short) configRequest.mClusterLow;
+ req.debugConfigs.validIntfAddrVal = false;
+ req.debugConfigs.validOuiVal = false;
+ req.debugConfigs.ouiVal = 0;
+ req.debugConfigs.validRandomFactorForceVal = false;
+ req.debugConfigs.randomFactorForceVal = 0;
+ req.debugConfigs.validHopCountForceVal = false;
+ req.debugConfigs.hopCountForceVal = 0;
+ req.debugConfigs.validDiscoveryChannelVal = false;
+ req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_24GHZ] = 0;
+ req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_5GHZ] = 0;
+ req.debugConfigs.discoveryChannelMhzVal[
+ android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] = 0;
+ req.debugConfigs.validUseBeaconsInBandVal = false;
+ req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
+ req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
+ req.debugConfigs.useBeaconsInBandVal[
+ android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] = true;
+ req.debugConfigs.validUseSdfInBandVal = false;
+ req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
+ req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
+ req.debugConfigs.useSdfInBandVal[
+ android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] = true;
+ updateConfigForPowerSettings14(req.configParams, configSupplemental12,
+ powerParameters);
+
+ if (iface16 != null) {
+ status = iface16.enableRequest_1_6(transactionId, req,
+ configSupplemental16);
+ } else if (iface15 != null) {
+ status = iface15.enableRequest_1_5(transactionId, req,
+ configSupplemental15);
+ } else {
+ status = iface14.enableRequest_1_4(transactionId, req,
+ configSupplemental12);
+ }
+ } else {
+ // translate framework to HIDL configuration (before V_1.4)
+ NanEnableRequest req = new NanEnableRequest();
+
+ req.operateInBand[NanBandIndex.NAN_BAND_24GHZ] = true;
+ req.operateInBand[NanBandIndex.NAN_BAND_5GHZ] = configRequest.mSupport5gBand;
+ req.hopCountMax = 2;
+ req.configParams.masterPref = (byte) configRequest.mMasterPreference;
+ req.configParams.disableDiscoveryAddressChangeIndication =
+ !notifyIdentityChange;
+ req.configParams.disableStartedClusterIndication = !notifyIdentityChange;
+ req.configParams.disableJoinedClusterIndication = !notifyIdentityChange;
+ req.configParams.includePublishServiceIdsInBeacon = true;
+ req.configParams.numberOfPublishServiceIdsInBeacon = 0;
+ req.configParams.includeSubscribeServiceIdsInBeacon = true;
+ req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
+ req.configParams.rssiWindowSize = 8;
+ req.configParams.macAddressRandomizationIntervalSec =
+ macAddressRandomizationIntervalSec;
+
+ req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
+ req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
+
+ req.debugConfigs.validClusterIdVals = true;
+ req.debugConfigs.clusterIdTopRangeVal = (short) configRequest.mClusterHigh;
+ req.debugConfigs.clusterIdBottomRangeVal = (short) configRequest.mClusterLow;
+ req.debugConfigs.validIntfAddrVal = false;
+ req.debugConfigs.validOuiVal = false;
+ req.debugConfigs.ouiVal = 0;
+ req.debugConfigs.validRandomFactorForceVal = false;
+ req.debugConfigs.randomFactorForceVal = 0;
+ req.debugConfigs.validHopCountForceVal = false;
+ req.debugConfigs.hopCountForceVal = 0;
+ req.debugConfigs.validDiscoveryChannelVal = false;
+ req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_24GHZ] = 0;
+ req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_5GHZ] = 0;
+ req.debugConfigs.validUseBeaconsInBandVal = false;
+ req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
+ req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
+ req.debugConfigs.validUseSdfInBandVal = false;
+ req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
+ req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
+
+ updateConfigForPowerSettings(req.configParams, configSupplemental12,
+ powerParameters);
+
+ if (iface12 != null) {
+ status = iface12.enableRequest_1_2(transactionId, req,
+ configSupplemental12);
+ } else {
+ status = mWifiNanIface.enableRequest(transactionId, req);
+ }
+ }
+ } else {
+ if (iface14 != null || iface15 != null || iface16 != null) {
+ android.hardware.wifi.V1_4.NanConfigRequest req =
+ new android.hardware.wifi.V1_4.NanConfigRequest();
+ req.masterPref = (byte) configRequest.mMasterPreference;
+ req.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
+ req.disableStartedClusterIndication = !notifyIdentityChange;
+ req.disableJoinedClusterIndication = !notifyIdentityChange;
+ req.includePublishServiceIdsInBeacon = true;
+ req.numberOfPublishServiceIdsInBeacon = 0;
+ req.includeSubscribeServiceIdsInBeacon = true;
+ req.numberOfSubscribeServiceIdsInBeacon = 0;
+ req.rssiWindowSize = 8;
+ req.macAddressRandomizationIntervalSec =
+ macAddressRandomizationIntervalSec;
+
+ req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
+ req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
+ req.bandSpecificConfig[android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ] =
+ config6;
+
+ updateConfigForPowerSettings14(req, configSupplemental12,
+ powerParameters);
+ if (iface16 != null) {
+ status = iface16.configRequest_1_6(transactionId, req,
+ configSupplemental16);
+ } else if (iface15 != null) {
+ status = iface15.configRequest_1_5(transactionId, req,
+ configSupplemental15);
+ } else {
+ status = iface14.configRequest_1_4(transactionId, req,
+ configSupplemental12);
+ }
+ } else {
+ NanConfigRequest req = new NanConfigRequest();
+ req.masterPref = (byte) configRequest.mMasterPreference;
+ req.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
+ req.disableStartedClusterIndication = !notifyIdentityChange;
+ req.disableJoinedClusterIndication = !notifyIdentityChange;
+ req.includePublishServiceIdsInBeacon = true;
+ req.numberOfPublishServiceIdsInBeacon = 0;
+ req.includeSubscribeServiceIdsInBeacon = true;
+ req.numberOfSubscribeServiceIdsInBeacon = 0;
+ req.rssiWindowSize = 8;
+ req.macAddressRandomizationIntervalSec =
+ macAddressRandomizationIntervalSec;
+
+ req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
+ req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
+
+ updateConfigForPowerSettings(req, configSupplemental12, powerParameters);
+
+ if (iface12 != null) {
+ status = iface12.configRequest_1_2(transactionId, req,
+ configSupplemental12);
+ } else {
+ status = mWifiNanIface.configRequest(transactionId, req);
+ }
+ }
+ }
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean disableInternal(String methodStr, short transactionId) {
+ try {
+ WifiStatus status = mWifiNanIface.disableRequest(transactionId);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean publishInternal(String methodStr, short transactionId, byte publishId,
+ PublishConfig publishConfig) {
+ android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6();
+ if (iface16 == null) {
+ NanPublishRequest req = new NanPublishRequest();
+ req.baseConfigs.sessionId = publishId;
+ req.baseConfigs.ttlSec = (short) publishConfig.mTtlSec;
+ req.baseConfigs.discoveryWindowPeriod = 1;
+ req.baseConfigs.discoveryCount = 0;
+ convertNativeByteArrayToArrayList(publishConfig.mServiceName,
+ req.baseConfigs.serviceName);
+ req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_NEVER;
+ convertNativeByteArrayToArrayList(publishConfig.mServiceSpecificInfo,
+ req.baseConfigs.serviceSpecificInfo);
+ convertNativeByteArrayToArrayList(publishConfig.mMatchFilter,
+ publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
+ ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
+ req.baseConfigs.useRssiThreshold = false;
+ req.baseConfigs.disableDiscoveryTerminationIndication =
+ !publishConfig.mEnableTerminateNotification;
+ req.baseConfigs.disableMatchExpirationIndication = true;
+ req.baseConfigs.disableFollowupReceivedIndication = false;
+
+ req.autoAcceptDataPathRequests = false;
+
+ req.baseConfigs.rangingRequired = publishConfig.mEnableRanging;
+
+ req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+ WifiAwareDataPathSecurityConfig securityConfig = publishConfig.getSecurityConfig();
+ if (securityConfig != null) {
+ req.baseConfigs.securityConfig.cipherType = getHalCipherSuiteType(
+ securityConfig.getCipherSuite());
+ if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
+ req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.PMK;
+ copyArray(securityConfig.getPmk(), req.baseConfigs.securityConfig.pmk);
+ }
+ if (securityConfig.getPskPassphrase() != null
+ && securityConfig.getPskPassphrase().length() != 0) {
+ req.baseConfigs.securityConfig.securityType =
+ NanDataPathSecurityType.PASSPHRASE;
+ convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
+ req.baseConfigs.securityConfig.passphrase);
+ }
+ }
+
+ req.publishType = publishConfig.mPublishType;
+ req.txType = NanTxType.BROADCAST;
+
+ try {
+ WifiStatus status = mWifiNanIface.startPublishRequest(transactionId, req);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ } else {
+ android.hardware.wifi.V1_6.NanPublishRequest req =
+ new android.hardware.wifi.V1_6.NanPublishRequest();
+ req.baseConfigs.sessionId = publishId;
+ req.baseConfigs.ttlSec = (short) publishConfig.mTtlSec;
+ req.baseConfigs.discoveryWindowPeriod = 1;
+ req.baseConfigs.discoveryCount = 0;
+ convertNativeByteArrayToArrayList(publishConfig.mServiceName,
+ req.baseConfigs.serviceName);
+ req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_NEVER;
+ convertNativeByteArrayToArrayList(publishConfig.mServiceSpecificInfo,
+ req.baseConfigs.serviceSpecificInfo);
+ convertNativeByteArrayToArrayList(publishConfig.mMatchFilter,
+ publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
+ ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
+ req.baseConfigs.useRssiThreshold = false;
+ req.baseConfigs.disableDiscoveryTerminationIndication =
+ !publishConfig.mEnableTerminateNotification;
+ req.baseConfigs.disableMatchExpirationIndication = true;
+ req.baseConfigs.disableFollowupReceivedIndication = false;
+
+ req.autoAcceptDataPathRequests = false;
+
+ req.baseConfigs.rangingRequired = publishConfig.mEnableRanging;
+
+ req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+ WifiAwareDataPathSecurityConfig securityConfig = publishConfig.getSecurityConfig();
+ if (securityConfig != null) {
+ req.baseConfigs.securityConfig.cipherType = getHalCipherSuiteType(
+ securityConfig.getCipherSuite());
+ if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
+ req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.PMK;
+ copyArray(securityConfig.getPmk(), req.baseConfigs.securityConfig.pmk);
+ }
+ if (securityConfig.getPskPassphrase() != null
+ && securityConfig.getPskPassphrase().length() != 0) {
+ req.baseConfigs.securityConfig.securityType =
+ NanDataPathSecurityType.PASSPHRASE;
+ convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
+ req.baseConfigs.securityConfig.passphrase);
+ }
+ if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) {
+ copyArray(securityConfig.getPmkId(), req.baseConfigs.securityConfig.scid);
+ }
+ }
+
+ req.publishType = publishConfig.mPublishType;
+ req.txType = NanTxType.BROADCAST;
+
+ try {
+ WifiStatus status = iface16.startPublishRequest_1_6(transactionId, req);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+ }
+
+ private boolean subscribeInternal(String methodStr, short transactionId, byte subscribeId,
+ SubscribeConfig subscribeConfig) {
+ NanSubscribeRequest req = new NanSubscribeRequest();
+ req.baseConfigs.sessionId = subscribeId;
+ req.baseConfigs.ttlSec = (short) subscribeConfig.mTtlSec;
+ req.baseConfigs.discoveryWindowPeriod = 1;
+ req.baseConfigs.discoveryCount = 0;
+ convertNativeByteArrayToArrayList(subscribeConfig.mServiceName,
+ req.baseConfigs.serviceName);
+ req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_ONCE;
+ convertNativeByteArrayToArrayList(subscribeConfig.mServiceSpecificInfo,
+ req.baseConfigs.serviceSpecificInfo);
+ convertNativeByteArrayToArrayList(subscribeConfig.mMatchFilter,
+ subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
+ ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
+ req.baseConfigs.useRssiThreshold = false;
+ req.baseConfigs.disableDiscoveryTerminationIndication =
+ !subscribeConfig.mEnableTerminateNotification;
+ req.baseConfigs.disableMatchExpirationIndication = false;
+ req.baseConfigs.disableFollowupReceivedIndication = false;
+
+ req.baseConfigs.rangingRequired =
+ subscribeConfig.mMinDistanceMmSet || subscribeConfig.mMaxDistanceMmSet;
+ req.baseConfigs.configRangingIndications = 0;
+ if (subscribeConfig.mMinDistanceMmSet) {
+ req.baseConfigs.distanceEgressCm = (short) Math.min(
+ subscribeConfig.mMinDistanceMm / 10, Short.MAX_VALUE);
+ req.baseConfigs.configRangingIndications |=
+ android.hardware.wifi.V1_0.NanRangingIndication.EGRESS_MET_MASK;
+ }
+ if (subscribeConfig.mMaxDistanceMmSet) {
+ req.baseConfigs.distanceIngressCm = (short) Math.min(
+ subscribeConfig.mMaxDistanceMm / 10, Short.MAX_VALUE);
+ req.baseConfigs.configRangingIndications |=
+ android.hardware.wifi.V1_0.NanRangingIndication.INGRESS_MET_MASK;
+ }
+
+ // TODO: configure security
+ req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+
+ req.subscribeType = subscribeConfig.mSubscribeType;
+
+ try {
+ WifiStatus status = mWifiNanIface.startSubscribeRequest(transactionId, req);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean sendMessageInternal(String methodStr, short transactionId, byte pubSubId,
+ int requestorInstanceId, MacAddress dest, byte[] message) {
+ NanTransmitFollowupRequest req = new NanTransmitFollowupRequest();
+ req.discoverySessionId = pubSubId;
+ req.peerId = requestorInstanceId;
+ req.addr = dest.toByteArray();
+ req.isHighPriority = false;
+ req.shouldUseDiscoveryWindow = true;
+ convertNativeByteArrayToArrayList(message, req.serviceSpecificInfo);
+ req.disableFollowupResultIndication = false;
+
+ try {
+ WifiStatus status = mWifiNanIface.transmitFollowupRequest(transactionId, req);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean stopPublishInternal(String methodStr, short transactionId, byte pubSubId) {
+ try {
+ WifiStatus status = mWifiNanIface.stopPublishRequest(transactionId, pubSubId);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean stopSubscribeInternal(String methodStr, short transactionId, byte pubSubId) {
+ try {
+ WifiStatus status = mWifiNanIface.stopSubscribeRequest(transactionId, pubSubId);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean createAwareNetworkInterfaceInternal(String methodStr, short transactionId,
+ String interfaceName) {
+ try {
+ WifiStatus status =
+ mWifiNanIface.createDataInterfaceRequest(transactionId, interfaceName);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean deleteAwareNetworkInterfaceInternal(String methodStr, short transactionId,
+ String interfaceName) {
+ try {
+ WifiStatus status =
+ mWifiNanIface.deleteDataInterfaceRequest(transactionId, interfaceName);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean initiateDataPathInternal(String methodStr, short transactionId, int peerId,
+ int channelRequestType, int channel, MacAddress peer, String interfaceName,
+ boolean isOutOfBand, byte[] appInfo, Capabilities capabilities,
+ WifiAwareDataPathSecurityConfig securityConfig) {
+ if (capabilities == null) {
+ Log.e(TAG, "Null capabilities were received");
+ return false;
+ }
+
+ android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6();
+
+ if (iface16 == null) {
+ NanInitiateDataPathRequest req = new NanInitiateDataPathRequest();
+ req.peerId = peerId;
+ req.peerDiscMacAddr = peer.toByteArray();
+ req.channelRequestType = WifiNanIface.NanDataPathChannelCfg.toHidl(channelRequestType);
+ req.channel = channel;
+ req.ifaceName = interfaceName;
+ req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+ if (securityConfig != null) {
+ req.securityConfig.cipherType = getHalCipherSuiteType(
+ securityConfig.getCipherSuite());
+ if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
+
+ req.securityConfig.securityType = NanDataPathSecurityType.PMK;
+ copyArray(securityConfig.getPmk(), req.securityConfig.pmk);
+ }
+ if (securityConfig.getPskPassphrase() != null
+ && securityConfig.getPskPassphrase().length() != 0) {
+ req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
+ convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
+ req.securityConfig.passphrase);
+ }
+ }
+
+ if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
+ convertNativeByteArrayToArrayList(WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH
+ .getBytes(StandardCharsets.UTF_8), req.serviceNameOutOfBand);
+ }
+ convertNativeByteArrayToArrayList(appInfo, req.appInfo);
+
+ try {
+ WifiStatus status = mWifiNanIface.initiateDataPathRequest(transactionId, req);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ Log.e(TAG, "initiateDataPath: exception: " + e);
+ return false;
+ }
+ } else {
+ android.hardware.wifi.V1_6.NanInitiateDataPathRequest req =
+ new android.hardware.wifi.V1_6.NanInitiateDataPathRequest();
+ req.peerId = peerId;
+ req.peerDiscMacAddr = peer.toByteArray();
+ req.channelRequestType = WifiNanIface.NanDataPathChannelCfg.toHidl(channelRequestType);
+ req.channel = channel;
+ req.ifaceName = interfaceName;
+ req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+ if (securityConfig != null) {
+ req.securityConfig.cipherType = getHalCipherSuiteType(
+ securityConfig.getCipherSuite());
+ if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
+ req.securityConfig.securityType = NanDataPathSecurityType.PMK;
+ copyArray(securityConfig.getPmk(), req.securityConfig.pmk);
+ }
+ if (securityConfig.getPskPassphrase() != null
+ && securityConfig.getPskPassphrase().length() != 0) {
+ req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
+ convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
+ req.securityConfig.passphrase);
+ }
+ if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) {
+ copyArray(securityConfig.getPmkId(), req.securityConfig.scid);
+ }
+ }
+
+ if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
+ convertNativeByteArrayToArrayList(WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH
+ .getBytes(StandardCharsets.UTF_8), req.serviceNameOutOfBand);
+ }
+ convertNativeByteArrayToArrayList(appInfo, req.appInfo);
+
+ try {
+ WifiStatus status = iface16.initiateDataPathRequest_1_6(transactionId, req);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+ }
+
+ private boolean respondToDataPathRequestInternal(String methodStr, short transactionId,
+ boolean accept, int ndpId, String interfaceName, byte[] appInfo, boolean isOutOfBand,
+ Capabilities capabilities, WifiAwareDataPathSecurityConfig securityConfig) {
+ if (capabilities == null) {
+ Log.e(TAG, "Null capabilities were received");
+ return false;
+ }
+
+ android.hardware.wifi.V1_6.IWifiNanIface iface16 = mockableCastTo_1_6();
+
+ if (iface16 == null) {
+ NanRespondToDataPathIndicationRequest req = new NanRespondToDataPathIndicationRequest();
+ req.acceptRequest = accept;
+ req.ndpInstanceId = ndpId;
+ req.ifaceName = interfaceName;
+ req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+ if (securityConfig != null) {
+ req.securityConfig.cipherType = getHalCipherSuiteType(
+ securityConfig.getCipherSuite());
+ if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
+
+ req.securityConfig.securityType = NanDataPathSecurityType.PMK;
+ copyArray(securityConfig.getPmk(), req.securityConfig.pmk);
+ }
+ if (securityConfig.getPskPassphrase() != null
+ && securityConfig.getPskPassphrase().length() != 0) {
+ req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
+ convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
+ req.securityConfig.passphrase);
+ }
+ }
+
+ if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
+ convertNativeByteArrayToArrayList(WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH
+ .getBytes(StandardCharsets.UTF_8), req.serviceNameOutOfBand);
+ }
+ convertNativeByteArrayToArrayList(appInfo, req.appInfo);
+
+ try {
+ WifiStatus status = mWifiNanIface.respondToDataPathIndicationRequest(
+ transactionId, req);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ } else {
+ android.hardware.wifi.V1_6.NanRespondToDataPathIndicationRequest req =
+ new android.hardware.wifi.V1_6.NanRespondToDataPathIndicationRequest();
+ req.acceptRequest = accept;
+ req.ndpInstanceId = ndpId;
+ req.ifaceName = interfaceName;
+ req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
+ if (securityConfig != null) {
+ req.securityConfig.cipherType = getHalCipherSuiteType(
+ securityConfig.getCipherSuite());
+ if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
+
+ req.securityConfig.securityType = NanDataPathSecurityType.PMK;
+ copyArray(securityConfig.getPmk(), req.securityConfig.pmk);
+ }
+ if (securityConfig.getPskPassphrase() != null
+ && securityConfig.getPskPassphrase().length() != 0) {
+ req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
+ convertNativeByteArrayToArrayList(securityConfig.getPskPassphrase().getBytes(),
+ req.securityConfig.passphrase);
+ }
+ if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) {
+ copyArray(securityConfig.getPmkId(), req.securityConfig.scid);
+ }
+ }
+
+ if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) {
+ convertNativeByteArrayToArrayList(WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH
+ .getBytes(StandardCharsets.UTF_8), req.serviceNameOutOfBand);
+ }
+ convertNativeByteArrayToArrayList(appInfo, req.appInfo);
+
+ try {
+ WifiStatus status = iface16
+ .respondToDataPathIndicationRequest_1_6(transactionId, req);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+ }
+
+ private boolean endDataPathInternal(String methodStr, short transactionId, int ndpId) {
+ try {
+ WifiStatus status = mWifiNanIface.terminateDataPathRequest(transactionId, ndpId);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+
+ // Helper Functions
+
+ /**
+ * Update the NAN configuration to reflect the current power settings (before V1.4)
+ */
+ private void updateConfigForPowerSettings(NanConfigRequest req,
+ android.hardware.wifi.V1_2.NanConfigRequestSupplemental configSupplemental12,
+ WifiNanIface.PowerParameters powerParameters) {
+ updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ],
+ powerParameters.discoveryWindow5Ghz);
+ updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ],
+ powerParameters.discoveryWindow24Ghz);
+
+ configSupplemental12.discoveryBeaconIntervalMs = powerParameters.discoveryBeaconIntervalMs;
+ configSupplemental12.numberOfSpatialStreamsInDiscovery =
+ powerParameters.numberOfSpatialStreamsInDiscovery;
+ configSupplemental12.enableDiscoveryWindowEarlyTermination =
+ powerParameters.enableDiscoveryWindowEarlyTermination;
+ }
+
+ /**
+ * Update the NAN configuration to reflect the current power settings (V1.4)
+ */
+ private void updateConfigForPowerSettings14(android.hardware.wifi.V1_4.NanConfigRequest req,
+ android.hardware.wifi.V1_2.NanConfigRequestSupplemental configSupplemental12,
+ WifiNanIface.PowerParameters powerParameters) {
+ updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ],
+ powerParameters.discoveryWindow5Ghz);
+ updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ],
+ powerParameters.discoveryWindow24Ghz);
+ updateSingleConfigForPowerSettings(req.bandSpecificConfig[
+ android.hardware.wifi.V1_4.NanBandIndex.NAN_BAND_6GHZ],
+ powerParameters.discoveryWindow6Ghz);
+
+ configSupplemental12.discoveryBeaconIntervalMs = powerParameters.discoveryBeaconIntervalMs;
+ configSupplemental12.numberOfSpatialStreamsInDiscovery =
+ powerParameters.numberOfSpatialStreamsInDiscovery;
+ configSupplemental12.enableDiscoveryWindowEarlyTermination =
+ powerParameters.enableDiscoveryWindowEarlyTermination;
+ }
+
+ private void updateSingleConfigForPowerSettings(NanBandSpecificConfig cfg, int override) {
+ if (override != -1) {
+ cfg.validDiscoveryWindowIntervalVal = true;
+ cfg.discoveryWindowIntervalVal = (byte) override;
+ }
+ }
+
+ /**
+ * Returns the HAL cipher suite.
+ */
+ private int getHalCipherSuiteType(int frameworkCipherSuites) {
+ switch (frameworkCipherSuites) {
+ case WIFI_AWARE_CIPHER_SUITE_NCS_SK_128:
+ return NanCipherSuiteType.SHARED_KEY_128_MASK;
+ case WIFI_AWARE_CIPHER_SUITE_NCS_SK_256:
+ return NanCipherSuiteType.SHARED_KEY_256_MASK;
+ case WIFI_AWARE_CIPHER_SUITE_NCS_PK_128:
+ return NanCipherSuiteType.PUBLIC_KEY_128_MASK;
+ case WIFI_AWARE_CIPHER_SUITE_NCS_PK_256:
+ return NanCipherSuiteType.PUBLIC_KEY_256_MASK;
+ }
+ return NanCipherSuiteType.NONE;
+ }
+
+ /**
+ * Converts a byte[] to an ArrayList<Byte>. Fills in the entries of the 'to' array if
+ * provided (non-null), otherwise creates and returns a new ArrayList<>.
+ *
+ * @param from The input byte[] to convert from.
+ * @param to An optional ArrayList<> to fill in from 'from'.
+ *
+ * @return A newly allocated ArrayList<> if 'to' is null, otherwise null.
+ */
+ private ArrayList<Byte> convertNativeByteArrayToArrayList(byte[] from, ArrayList<Byte> to) {
+ if (from == null) {
+ from = new byte[0];
+ }
+
+ if (to == null) {
+ to = new ArrayList<>(from.length);
+ } else {
+ to.ensureCapacity(from.length);
+ }
+ for (int i = 0; i < from.length; ++i) {
+ to.add(from[i]);
+ }
+ return to;
+ }
+
+ private void copyArray(byte[] from, byte[] to) {
+ if (from == null || to == null || from.length != to.length) {
+ Log.e(TAG, "copyArray error: from=" + Arrays.toString(from) + ", to="
+ + Arrays.toString(to));
+ return;
+ }
+ for (int i = 0; i < from.length; ++i) {
+ to[i] = from[i];
+ }
+ }
+
+ protected android.hardware.wifi.V1_2.IWifiNanIface mockableCastTo_1_2() {
+ return android.hardware.wifi.V1_2.IWifiNanIface.castFrom(mWifiNanIface);
+ }
+
+ protected android.hardware.wifi.V1_4.IWifiNanIface mockableCastTo_1_4() {
+ return android.hardware.wifi.V1_4.IWifiNanIface.castFrom(mWifiNanIface);
+ }
+
+ protected android.hardware.wifi.V1_5.IWifiNanIface mockableCastTo_1_5() {
+ return android.hardware.wifi.V1_5.IWifiNanIface.castFrom(mWifiNanIface);
+ }
+
+ protected android.hardware.wifi.V1_6.IWifiNanIface mockableCastTo_1_6() {
+ return android.hardware.wifi.V1_6.IWifiNanIface.castFrom(mWifiNanIface);
+ }
+
+ private boolean isOk(WifiStatus status, String methodStr) {
+ if (status.code == WifiStatusCode.SUCCESS) return true;
+ Log.e(TAG, methodStr + " failed with status: " + status);
+ return false;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ mWifiNanIface = null;
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiNanIface == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiNanIface is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiP2pIface.java b/service/java/com/android/server/wifi/hal/WifiP2pIface.java
new file mode 100644
index 0000000000..26414283b1
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiP2pIface.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Log;
+
+/**
+ * Wrapper around a WifiP2pIface.
+ * May be initialized using a HIDL or AIDL WifiP2pIface.
+ */
+public class WifiP2pIface implements WifiHal.WifiInterface {
+ private static final String TAG = "WifiP2pIface";
+ private final IWifiP2pIface mWifiP2pIface;
+
+ public WifiP2pIface(@NonNull android.hardware.wifi.V1_0.IWifiP2pIface p2pIface) {
+ mWifiP2pIface = createWifiP2pIfaceHidlImplMockable(p2pIface);
+ }
+
+ public WifiP2pIface(@NonNull android.hardware.wifi.IWifiP2pIface p2pIface) {
+ mWifiP2pIface = createWifiP2pIfaceAidlImplMockable(p2pIface);
+ }
+
+ protected WifiP2pIfaceHidlImpl createWifiP2pIfaceHidlImplMockable(
+ android.hardware.wifi.V1_0.IWifiP2pIface p2pIface) {
+ return new WifiP2pIfaceHidlImpl(p2pIface);
+ }
+
+ protected WifiP2pIfaceAidlImpl createWifiP2pIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiP2pIface p2pIface) {
+ return new WifiP2pIfaceAidlImpl(p2pIface);
+ }
+
+ private void handleNullIface(String methodStr) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiP2pIface is null");
+ }
+
+ /**
+ * See comments for {@link IWifiP2pIface#getName()}
+ */
+ @Override
+ @Nullable
+ public String getName() {
+ final String methodStr = "getName";
+ if (mWifiP2pIface == null) {
+ handleNullIface(methodStr);
+ return null;
+ }
+ return mWifiP2pIface.getName();
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiP2pIfaceAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiP2pIfaceAidlImpl.java
new file mode 100644
index 0000000000..9ae33f6cc7
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiP2pIfaceAidlImpl.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+/**
+ * AIDL implementation of the IWifiP2pIface interface.
+ */
+public class WifiP2pIfaceAidlImpl implements IWifiP2pIface {
+ private static final String TAG = "WifiP2pIfaceAidlImpl";
+ private android.hardware.wifi.IWifiP2pIface mWifiP2pIface;
+ private final Object mLock = new Object();
+ private String mIfaceName;
+
+ public WifiP2pIfaceAidlImpl(@NonNull android.hardware.wifi.IWifiP2pIface p2pIface) {
+ mWifiP2pIface = p2pIface;
+ }
+
+ /**
+ * See comments for {@link com.android.server.wifi.hal.IWifiP2pIface#getName()}
+ */
+ @Override
+ @Nullable
+ public String getName() {
+ final String methodStr = "getName";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ if (mIfaceName != null) return mIfaceName;
+ try {
+ String ifaceName = mWifiP2pIface.getName();
+ mIfaceName = ifaceName;
+ return mIfaceName;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ private boolean checkIfaceAndLogFailure(String methodStr) {
+ if (mWifiP2pIface == null) {
+ Log.e(TAG, "Unable to call " + methodStr + " because iface is null.");
+ return false;
+ }
+ return true;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ mWifiP2pIface = null;
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ }
+
+ private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with service-specific exception: " + e);
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiP2pIfaceHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiP2pIfaceHidlImpl.java
new file mode 100644
index 0000000000..cb63e18940
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiP2pIfaceHidlImpl.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.hardware.wifi.V1_0.WifiStatus;
+import android.hardware.wifi.V1_0.WifiStatusCode;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.server.wifi.util.GeneralUtil.Mutable;
+
+/**
+ * HIDL implementation of the IWifiP2pIface interface.
+ */
+public class WifiP2pIfaceHidlImpl implements IWifiP2pIface {
+ private static final String TAG = "WifiP2pIfaceHidlImpl";
+ private android.hardware.wifi.V1_0.IWifiP2pIface mWifiP2pIface;
+ private String mIfaceName;
+
+ public WifiP2pIfaceHidlImpl(@NonNull android.hardware.wifi.V1_0.IWifiP2pIface p2pIface) {
+ mWifiP2pIface = p2pIface;
+ }
+
+ /**
+ * See comments for {@link com.android.server.wifi.hal.IWifiP2pIface#getName()}
+ */
+ public String getName() {
+ final String methodStr = "getName";
+ if (mWifiP2pIface == null) {
+ handleNullIface(methodStr);
+ return null;
+ }
+ if (mIfaceName != null) return mIfaceName;
+ Mutable<String> nameResp = new Mutable<>();
+ try {
+ mWifiP2pIface.getName((WifiStatus status, String name) -> {
+ if (isOk(status, methodStr)) {
+ nameResp.value = name;
+ mIfaceName = name;
+ }
+ });
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception in " + methodStr + ": " + e);
+ }
+ return nameResp.value;
+ }
+
+ private boolean isOk(WifiStatus status, String methodStr) {
+ if (status.code == WifiStatusCode.SUCCESS) return true;
+ Log.e(TAG, methodStr + " failed with status: " + status);
+ return false;
+ }
+
+ private void handleNullIface(String methodStr) {
+ Log.e(TAG, "Cannot call " + methodStr + " because mWifiP2pIface is null");
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiRttController.java b/service/java/com/android/server/wifi/hal/WifiRttController.java
new file mode 100644
index 0000000000..2a0f7a6281
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiRttController.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.net.wifi.rtt.RangingRequest;
+import android.net.wifi.rtt.RangingResult;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * Wrapper around a WifiRttController.
+ * May be initialized using a HIDL or AIDL WifiRttController.
+ */
+public class WifiRttController {
+ private static final String TAG = "WifiRttController";
+ protected static final int CONVERSION_US_TO_MS = 1_000;
+
+ private IWifiRttController mWifiRttController;
+
+ /** Unknown status */
+ public static final int FRAMEWORK_RTT_STATUS_UNKNOWN = -1;
+ /** Success */
+ public static final int FRAMEWORK_RTT_STATUS_SUCCESS = 0;
+ /** General failure status */
+ public static final int FRAMEWORK_RTT_STATUS_FAILURE = 1;
+ /** Target STA does not respond to request */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_NO_RSP = 2;
+ /** Request rejected. Applies to 2-sided RTT only */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_REJECTED = 3;
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4;
+ /** Timing measurement times out */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT = 5;
+ /** Target on different channel, cannot range */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6;
+ /** Ranging not supported */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY = 7;
+ /** Request aborted for unknown reason */
+ public static final int FRAMEWORK_RTT_STATUS_ABORTED = 8;
+ /** Invalid T1-T4 timestamp */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS = 9;
+ /** 11mc protocol failed */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL = 10;
+ /** Request could not be scheduled */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE = 11;
+ /** Responder cannot collaborate at time of request */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER = 12;
+ /** Bad request args */
+ public static final int FRAMEWORK_RTT_STATUS_INVALID_REQ = 13;
+ /** WiFi not enabled. */
+ public static final int FRAMEWORK_RTT_STATUS_NO_WIFI = 14;
+ /** Responder overrides param info, cannot range with new params */
+ public static final int FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15;
+
+ /** @hide */
+ @IntDef(prefix = "FRAMEWORK_RTT_STATUS_", value = {FRAMEWORK_RTT_STATUS_UNKNOWN,
+ FRAMEWORK_RTT_STATUS_SUCCESS, FRAMEWORK_RTT_STATUS_FAILURE,
+ FRAMEWORK_RTT_STATUS_FAIL_NO_RSP, FRAMEWORK_RTT_STATUS_FAIL_REJECTED,
+ FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET, FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT,
+ FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY,
+ FRAMEWORK_RTT_STATUS_ABORTED, FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS,
+ FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL, FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE,
+ FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER, FRAMEWORK_RTT_STATUS_INVALID_REQ,
+ FRAMEWORK_RTT_STATUS_NO_WIFI, FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FrameworkRttStatus {}
+
+ /**
+ * Framework representation of RTT capabilities.
+ */
+ public static class Capabilities {
+ // 1-sided rtt measurement is supported.
+ public boolean oneSidedRttSupported;
+ // Location configuration information supported.
+ public boolean lciSupported;
+ // Location civic records supported.
+ public boolean lcrSupported;
+ // Preamble supported, see bit mask definition above.
+ public int preambleSupported;
+ // RTT bandwidth supported.
+ public int bwSupported;
+ // Whether STA responder role is supported.
+ public boolean responderSupported;
+ // Draft 11mc version supported, including major and minor version. e.g., draft 4.3 is 43.
+ public byte mcVersion;
+ // Whether ftm rtt data collection is supported.
+ public boolean rttFtmSupported;
+
+ public Capabilities() {
+ }
+
+ public Capabilities(android.hardware.wifi.V1_0.RttCapabilities rttHalCapabilities) {
+ oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported;
+ lciSupported = rttHalCapabilities.lciSupported;
+ lcrSupported = rttHalCapabilities.lcrSupported;
+ responderSupported = rttHalCapabilities.responderSupported;
+ preambleSupported = rttHalCapabilities.preambleSupport;
+ mcVersion = rttHalCapabilities.mcVersion;
+ bwSupported = rttHalCapabilities.bwSupport;
+ rttFtmSupported = rttHalCapabilities.rttFtmSupported;
+ }
+
+ public Capabilities(android.hardware.wifi.V1_4.RttCapabilities rttHalCapabilities) {
+ oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported;
+ lciSupported = rttHalCapabilities.lciSupported;
+ lcrSupported = rttHalCapabilities.lcrSupported;
+ responderSupported = rttHalCapabilities.responderSupported;
+ preambleSupported = rttHalCapabilities.preambleSupport;
+ mcVersion = rttHalCapabilities.mcVersion;
+ bwSupported = rttHalCapabilities.bwSupport;
+ rttFtmSupported = rttHalCapabilities.rttFtmSupported;
+ }
+
+ public Capabilities(android.hardware.wifi.V1_6.RttCapabilities rttHalCapabilities) {
+ oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported;
+ lciSupported = rttHalCapabilities.lciSupported;
+ lcrSupported = rttHalCapabilities.lcrSupported;
+ responderSupported = rttHalCapabilities.responderSupported;
+ preambleSupported = rttHalCapabilities.preambleSupport;
+ mcVersion = rttHalCapabilities.mcVersion;
+ bwSupported = rttHalCapabilities.bwSupport;
+ rttFtmSupported = rttHalCapabilities.rttFtmSupported;
+ }
+
+ public Capabilities(android.hardware.wifi.RttCapabilities rttHalCapabilities) {
+ oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported;
+ lciSupported = rttHalCapabilities.lciSupported;
+ lcrSupported = rttHalCapabilities.lcrSupported;
+ responderSupported = rttHalCapabilities.responderSupported;
+ preambleSupported = rttHalCapabilities.preambleSupport;
+ mcVersion = rttHalCapabilities.mcVersion;
+ bwSupported = rttHalCapabilities.bwSupport;
+ rttFtmSupported = rttHalCapabilities.rttFtmSupported;
+ }
+ }
+
+ /**
+ * Callback to receive ranging results.
+ */
+ public interface RttControllerRangingResultsCallback {
+ /**
+ * Called when ranging results are received from the HAL.
+ *
+ * @param cmdId Command ID specified in the original request.
+ * @param rangingResults A list of range results.
+ */
+ void onRangingResults(int cmdId, List<RangingResult> rangingResults);
+ }
+
+ public WifiRttController(@NonNull android.hardware.wifi.V1_0.IWifiRttController rttController) {
+ mWifiRttController = createWifiRttControllerHidlImplMockable(rttController);
+ }
+
+ public WifiRttController(@NonNull android.hardware.wifi.IWifiRttController rttController) {
+ mWifiRttController = createWifiRttControllerAidlImplMockable(rttController);
+ }
+
+ protected WifiRttControllerHidlImpl createWifiRttControllerHidlImplMockable(
+ @NonNull android.hardware.wifi.V1_0.IWifiRttController rttController) {
+ return new WifiRttControllerHidlImpl(rttController);
+ }
+
+ protected WifiRttControllerAidlImpl createWifiRttControllerAidlImplMockable(
+ @NonNull android.hardware.wifi.IWifiRttController rttController) {
+ return new WifiRttControllerAidlImpl(rttController);
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiRttController == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiRttController is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#setup()}
+ */
+ public boolean setup() {
+ return validateAndCall("setup", false,
+ () -> mWifiRttController.setup());
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#enableVerboseLogging(boolean)}
+ */
+ public void enableVerboseLogging(boolean verbose) {
+ if (mWifiRttController != null) {
+ mWifiRttController.enableVerboseLogging(verbose);
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#registerRangingResultsCallback(
+ * RttControllerRangingResultsCallback)}
+ */
+ public void registerRangingResultsCallback(RttControllerRangingResultsCallback callback) {
+ if (mWifiRttController != null) {
+ mWifiRttController.registerRangingResultsCallback(callback);
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#validate()}
+ */
+ public boolean validate() {
+ return validateAndCall("validate", false,
+ () -> mWifiRttController.validate());
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#getRttCapabilities()}
+ */
+ @Nullable
+ public Capabilities getRttCapabilities() {
+ return validateAndCall("getRttCapabilities", null,
+ () -> mWifiRttController.getRttCapabilities());
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#rangeRequest(int, RangingRequest)}
+ */
+ public boolean rangeRequest(int cmdId, RangingRequest request) {
+ return validateAndCall("rangeRequest", false,
+ () -> mWifiRttController.rangeRequest(cmdId, request));
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#rangeCancel(int, List)}
+ */
+ public boolean rangeCancel(int cmdId, ArrayList<MacAddress> macAddresses) {
+ return validateAndCall("rangeCancel", false,
+ () -> mWifiRttController.rangeCancel(cmdId, macAddresses));
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#dump(PrintWriter)}
+ */
+ public void dump(PrintWriter pw) {
+ if (mWifiRttController != null) {
+ mWifiRttController.dump(pw);
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java
new file mode 100644
index 0000000000..8629b088d8
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java
@@ -0,0 +1,579 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.hardware.wifi.IWifiRttControllerEventCallback;
+import android.hardware.wifi.RttBw;
+import android.hardware.wifi.RttCapabilities;
+import android.hardware.wifi.RttConfig;
+import android.hardware.wifi.RttPeerType;
+import android.hardware.wifi.RttPreamble;
+import android.hardware.wifi.RttResult;
+import android.hardware.wifi.RttStatus;
+import android.hardware.wifi.RttType;
+import android.hardware.wifi.WifiChannelInfo;
+import android.hardware.wifi.WifiChannelWidthInMhz;
+import android.net.MacAddress;
+import android.net.wifi.rtt.RangingRequest;
+import android.net.wifi.rtt.RangingResult;
+import android.net.wifi.rtt.ResponderConfig;
+import android.net.wifi.rtt.ResponderLocation;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * AIDL implementation of the IWifiRttController interface.
+ */
+public class WifiRttControllerAidlImpl implements IWifiRttController {
+ private static final String TAG = "WifiRttControllerAidl";
+ private boolean mVerboseLoggingEnabled = false;
+
+ private android.hardware.wifi.IWifiRttController mWifiRttController;
+ private WifiRttController.Capabilities mRttCapabilities;
+ private WifiRttControllerEventCallback mHalCallback;
+ private Set<WifiRttController.RttControllerRangingResultsCallback> mRangingResultsCallbacks =
+ new HashSet<>();
+ private final Object mLock = new Object();
+
+ public WifiRttControllerAidlImpl(
+ @NonNull android.hardware.wifi.IWifiRttController rttController) {
+ mWifiRttController = rttController;
+ mHalCallback = new WifiRttControllerEventCallback();
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#setup()}
+ */
+ @Override
+ public boolean setup() {
+ final String methodStr = "setup";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ try {
+ mWifiRttController.registerEventCallback(mHalCallback);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ updateRttCapabilities();
+ return true;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#enableVerboseLogging(boolean)}
+ */
+ @Override
+ public void enableVerboseLogging(boolean verbose) {
+ synchronized (mLock) {
+ mVerboseLoggingEnabled = verbose;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#registerRangingResultsCallback(
+ * WifiRttController.RttControllerRangingResultsCallback)}
+ */
+ @Override
+ public void registerRangingResultsCallback(
+ WifiRttController.RttControllerRangingResultsCallback callback) {
+ synchronized (mLock) {
+ if (!mRangingResultsCallbacks.add(callback)) {
+ Log.e(TAG, "Ranging results callback was already registered");
+ }
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#validate()}
+ */
+ @Override
+ public boolean validate() {
+ final String methodStr = "validate";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ try {
+ // Just check that we can call this method successfully.
+ mWifiRttController.getBoundIface();
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#getRttCapabilities()}
+ */
+ @Override
+ @Nullable
+ public WifiRttController.Capabilities getRttCapabilities() {
+ synchronized (mLock) {
+ return mRttCapabilities;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#rangeRequest(int, RangingRequest)}
+ */
+ @Override
+ public boolean rangeRequest(int cmdId, RangingRequest request) {
+ final String methodStr = "rangeRequest";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "rangeRequest: cmdId=" + cmdId + ", # of requests="
+ + request.mRttPeers.size() + ", request=" + request);
+ }
+
+ updateRttCapabilities();
+ try {
+ RttConfig[] rttConfigs =
+ convertRangingRequestToRttConfigs(request, mRttCapabilities);
+ if (rttConfigs == null) {
+ Log.e(TAG, methodStr + " received invalid request parameters");
+ return false;
+ } else if (rttConfigs.length == 0) {
+ Log.e(TAG, methodStr + " invalidated all requests");
+ dispatchOnRangingResults(cmdId, new ArrayList<>());
+ return true;
+ }
+ mWifiRttController.rangeRequest(cmdId, rttConfigs);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#rangeCancel(int, List)}
+ */
+ @Override
+ public boolean rangeCancel(int cmdId, List<MacAddress> macAddresses) {
+ final String methodStr = "rangeCancel";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ try {
+ android.hardware.wifi.MacAddress[] halAddresses =
+ new android.hardware.wifi.MacAddress[macAddresses.size()];
+ for (int i = 0; i < macAddresses.size(); i++) {
+ android.hardware.wifi.MacAddress halAddress =
+ new android.hardware.wifi.MacAddress();
+ halAddress.data = macAddresses.get(i).toByteArray();
+ halAddresses[i] = halAddress;
+ }
+ mWifiRttController.rangeCancel(cmdId, halAddresses);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#dump(PrintWriter)}
+ */
+ @Override
+ public void dump(PrintWriter pw) {
+ pw.println("WifiRttController:");
+ pw.println(" mIWifiRttController: " + mWifiRttController);
+ pw.println(" mRttCapabilities: " + mRttCapabilities);
+ }
+
+ /**
+ * Callback for HAL events on the WifiRttController
+ */
+ private class WifiRttControllerEventCallback extends IWifiRttControllerEventCallback.Stub {
+ @Override
+ public void onResults(int cmdId, RttResult[] halResults) {
+ if (mVerboseLoggingEnabled) {
+ int numResults = halResults != null ? halResults.length : -1;
+ Log.v(TAG, "onResults: cmdId=" + cmdId + ", # of results=" + numResults);
+ }
+ if (halResults == null) {
+ halResults = new RttResult[0];
+ }
+ ArrayList<RangingResult> rangingResults = halToFrameworkRangingResults(halResults);
+ dispatchOnRangingResults(cmdId, rangingResults);
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return IWifiRttControllerEventCallback.HASH;
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return IWifiRttControllerEventCallback.VERSION;
+ }
+ }
+
+
+ // Utilities
+
+ private ArrayList<RangingResult> halToFrameworkRangingResults(RttResult[] halResults) {
+ ArrayList<RangingResult> rangingResults = new ArrayList();
+ for (RttResult rttResult : halResults) {
+ if (rttResult == null) continue;
+ byte[] lci = rttResult.lci.data;
+ byte[] lcr = rttResult.lcr.data;
+ ResponderLocation responderLocation;
+ try {
+ responderLocation = new ResponderLocation(lci, lcr);
+ if (!responderLocation.isValid()) {
+ responderLocation = null;
+ }
+ } catch (Exception e) {
+ responderLocation = null;
+ Log.e(TAG, "ResponderLocation: lci/lcr parser failed exception -- " + e);
+ }
+ if (rttResult.successNumber <= 1 && rttResult.distanceSdInMm != 0) {
+ if (mVerboseLoggingEnabled) {
+ Log.w(TAG, "postProcessResults: non-zero distance stdev with 0||1 num "
+ + "samples!? result=" + rttResult);
+ }
+ 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));
+ }
+ return rangingResults;
+ }
+
+ private static @WifiRttController.FrameworkRttStatus int halToFrameworkRttStatus(
+ int halStatus) {
+ switch (halStatus) {
+ case RttStatus.SUCCESS:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS;
+ case RttStatus.FAILURE:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAILURE;
+ case RttStatus.FAIL_NO_RSP:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NO_RSP;
+ case RttStatus.FAIL_REJECTED:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_REJECTED;
+ case RttStatus.FAIL_NOT_SCHEDULED_YET:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
+ case RttStatus.FAIL_TM_TIMEOUT:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT;
+ case RttStatus.FAIL_AP_ON_DIFF_CHANNEL:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
+ case RttStatus.FAIL_NO_CAPABILITY:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY;
+ case RttStatus.ABORTED:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_ABORTED;
+ case RttStatus.FAIL_INVALID_TS:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS;
+ case RttStatus.FAIL_PROTOCOL:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL;
+ case RttStatus.FAIL_SCHEDULE:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE;
+ case RttStatus.FAIL_BUSY_TRY_LATER:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER;
+ case RttStatus.INVALID_REQ:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_INVALID_REQ;
+ case RttStatus.NO_WIFI:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_NO_WIFI;
+ case RttStatus.FAIL_FTM_PARAM_OVERRIDE:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
+ default:
+ Log.e(TAG, "Unrecognized RttStatus: " + halStatus);
+ return WifiRttController.FRAMEWORK_RTT_STATUS_UNKNOWN;
+ }
+ }
+
+ private void updateRttCapabilities() {
+ final String methodStr = "updateRttCapabilities";
+ if (mRttCapabilities != null) return;
+ if (mVerboseLoggingEnabled) Log.v(TAG, "updateRttCapabilities");
+
+ try {
+ RttCapabilities halCapabilities = mWifiRttController.getCapabilities();
+ mRttCapabilities = new WifiRttController.Capabilities(halCapabilities);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+
+ if (mRttCapabilities != null && !mRttCapabilities.rttFtmSupported) {
+ Log.wtf(TAG, "Firmware indicates RTT is not supported - but device supports RTT - "
+ + "ignored!?");
+ }
+ }
+
+ private static RttConfig[] convertRangingRequestToRttConfigs(RangingRequest request,
+ WifiRttController.Capabilities cap) {
+ ArrayList<RttConfig> rttConfigs = new ArrayList<>();
+
+ // Skip any configurations which have an error (just print out a message).
+ // The caller will only get results for valid configurations.
+ for (ResponderConfig responder: request.mRttPeers) {
+ RttConfig config = new RttConfig();
+ config.addr = responder.macAddress.toByteArray();
+
+ 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;
+ }
+
+ config.peer = frameworkToHalRttPeerType(responder.responderType);
+ config.channel = new WifiChannelInfo();
+ config.channel.width = frameworkToHalChannelWidth(
+ responder.channelWidth);
+ config.channel.centerFreq = responder.frequency;
+ config.channel.centerFreq0 = responder.centerFreq0;
+ config.channel.centerFreq1 = responder.centerFreq1;
+ config.bw = frameworkToHalChannelBandwidth(responder.channelWidth);
+ config.preamble = frameworkToHalResponderPreamble(responder.preamble);
+ validateBwAndPreambleCombination(config.bw, config.preamble);
+
+ if (config.peer == RttPeerType.NAN_TYPE) {
+ config.mustRequestLci = false;
+ config.mustRequestLcr = false;
+ config.burstPeriod = 0;
+ config.numBurst = 0;
+ config.numFramesPerBurst = request.mRttBurstSize;
+ config.numRetriesPerRttFrame = 0; // irrelevant for 2-sided RTT
+ config.numRetriesPerFtmr = 3;
+ config.burstDuration = 9;
+ } else { // AP + all non-NAN requests
+ config.mustRequestLci = true;
+ config.mustRequestLcr = true;
+ config.burstPeriod = 0;
+ config.numBurst = 0;
+ config.numFramesPerBurst = request.mRttBurstSize;
+ config.numRetriesPerRttFrame = (config.type == RttType.TWO_SIDED ? 0 : 3);
+ config.numRetriesPerFtmr = 3;
+ config.burstDuration = 9;
+
+ 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);
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Invalid configuration: " + e.getMessage());
+ continue;
+ }
+
+ rttConfigs.add(config);
+ }
+
+ RttConfig[] configArray = new RttConfig[rttConfigs.size()];
+ for (int i = 0; i < rttConfigs.size(); i++) {
+ configArray[i] = rttConfigs.get(i);
+ }
+ return configArray;
+ }
+
+ private static void validateBwAndPreambleCombination(int bw, int preamble) {
+ if (bw <= RttBw.BW_20MHZ) {
+ return;
+ }
+ if (bw == RttBw.BW_40MHZ && preamble >= RttPreamble.HT) {
+ return;
+ }
+ if (bw == RttBw.BW_320MHZ && preamble == RttPreamble.EHT) {
+ return;
+ }
+ if (bw >= RttBw.BW_80MHZ && bw < RttBw.BW_320MHZ && preamble >= RttPreamble.VHT) {
+ return;
+ }
+ throw new IllegalArgumentException(
+ "bw and preamble combination is invalid, bw: " + bw + " preamble: " + preamble);
+ }
+
+ private static int frameworkToHalRttPeerType(int responderType)
+ throws IllegalArgumentException {
+ switch (responderType) {
+ case ResponderConfig.RESPONDER_AP:
+ return RttPeerType.AP;
+ case ResponderConfig.RESPONDER_STA:
+ return RttPeerType.STA;
+ case ResponderConfig.RESPONDER_P2P_GO:
+ return RttPeerType.P2P_GO;
+ case ResponderConfig.RESPONDER_P2P_CLIENT:
+ return RttPeerType.P2P_CLIENT;
+ case ResponderConfig.RESPONDER_AWARE:
+ return RttPeerType.NAN_TYPE;
+ default:
+ throw new IllegalArgumentException(
+ "frameworkToHalRttPeerType: bad " + responderType);
+ }
+ }
+
+ private static int frameworkToHalChannelWidth(int responderChannelWidth)
+ throws IllegalArgumentException {
+ switch (responderChannelWidth) {
+ case ResponderConfig.CHANNEL_WIDTH_20MHZ:
+ return WifiChannelWidthInMhz.WIDTH_20;
+ case ResponderConfig.CHANNEL_WIDTH_40MHZ:
+ return WifiChannelWidthInMhz.WIDTH_40;
+ case ResponderConfig.CHANNEL_WIDTH_80MHZ:
+ return WifiChannelWidthInMhz.WIDTH_80;
+ case ResponderConfig.CHANNEL_WIDTH_160MHZ:
+ return WifiChannelWidthInMhz.WIDTH_160;
+ case ResponderConfig.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
+ return WifiChannelWidthInMhz.WIDTH_80P80;
+ case ResponderConfig.CHANNEL_WIDTH_320MHZ:
+ return WifiChannelWidthInMhz.WIDTH_320;
+ default:
+ throw new IllegalArgumentException(
+ "frameworkToHalChannelWidth: bad " + responderChannelWidth);
+ }
+ }
+
+ private static int frameworkToHalChannelBandwidth(int responderChannelWidth)
+ throws IllegalArgumentException {
+ switch (responderChannelWidth) {
+ case ResponderConfig.CHANNEL_WIDTH_20MHZ:
+ return RttBw.BW_20MHZ;
+ case ResponderConfig.CHANNEL_WIDTH_40MHZ:
+ return RttBw.BW_40MHZ;
+ case ResponderConfig.CHANNEL_WIDTH_80MHZ:
+ return RttBw.BW_80MHZ;
+ case ResponderConfig.CHANNEL_WIDTH_160MHZ:
+ case ResponderConfig.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
+ return RttBw.BW_160MHZ;
+ case ResponderConfig.CHANNEL_WIDTH_320MHZ:
+ return RttBw.BW_320MHZ;
+ default:
+ throw new IllegalArgumentException(
+ "halRttChannelBandwidthFromHalBandwidth: bad " + responderChannelWidth);
+ }
+ }
+
+ private static int frameworkToHalResponderPreamble(int responderPreamble)
+ throws IllegalArgumentException {
+ switch (responderPreamble) {
+ case ResponderConfig.PREAMBLE_LEGACY:
+ return RttPreamble.LEGACY;
+ case ResponderConfig.PREAMBLE_HT:
+ return RttPreamble.HT;
+ case ResponderConfig.PREAMBLE_VHT:
+ return RttPreamble.VHT;
+ case ResponderConfig.PREAMBLE_HE:
+ return RttPreamble.HE;
+ default:
+ throw new IllegalArgumentException(
+ "frameworkToHalResponderPreamble: bad " + responderPreamble);
+ }
+ }
+
+ /**
+ * Check whether the selected RTT channel bandwidth is supported by the device.
+ * If supported, return the requested bandwidth.
+ * If not supported, return the next lower bandwidth which is supported.
+ * If none, throw an IllegalArgumentException.
+ *
+ * Note: the halRttChannelBandwidth is a single bit flag from the HAL RttBw type.
+ */
+ private static int halRttChannelBandwidthCapabilityLimiter(int halRttChannelBandwidth,
+ WifiRttController.Capabilities cap) throws IllegalArgumentException {
+ int requestedBandwidth = halRttChannelBandwidth;
+ while ((halRttChannelBandwidth != 0) && ((halRttChannelBandwidth & cap.bwSupported) == 0)) {
+ halRttChannelBandwidth >>= 1;
+ }
+
+ if (halRttChannelBandwidth != 0) {
+ return halRttChannelBandwidth;
+ }
+
+ throw new IllegalArgumentException(
+ "RTT BW=" + requestedBandwidth + ", not supported by device capabilities=" + cap
+ + " - and no supported alternative");
+ }
+
+ /**
+ * Check whether the selected RTT preamble is supported by the device.
+ * If supported, return the requested preamble.
+ * If not supported, return the next "lower" preamble which is supported.
+ * If none, throw an IllegalArgumentException.
+ *
+ * Note: the halRttPreamble is a single bit flag from the HAL RttPreamble type.
+ */
+ private static int halRttPreambleCapabilityLimiter(int halRttPreamble,
+ WifiRttController.Capabilities cap) throws IllegalArgumentException {
+ int requestedPreamble = halRttPreamble;
+ while ((halRttPreamble != 0) && ((halRttPreamble & cap.preambleSupported) == 0)) {
+ halRttPreamble >>= 1;
+ }
+
+ if (halRttPreamble != 0) {
+ return halRttPreamble;
+ }
+
+ throw new IllegalArgumentException(
+ "RTT Preamble=" + requestedPreamble + ", not supported by device capabilities="
+ + cap + " - and no supported alternative");
+ }
+
+ private void dispatchOnRangingResults(int cmdId, List<RangingResult> rangingResults) {
+ for (WifiRttController.RttControllerRangingResultsCallback
+ callback : mRangingResultsCallbacks) {
+ callback.onRangingResults(cmdId, rangingResults);
+ }
+ }
+
+ private boolean checkIfaceAndLogFailure(String methodStr) {
+ if (mWifiRttController == null) {
+ Log.e(TAG, "Unable to call " + methodStr + " because iface is null.");
+ return false;
+ }
+ return true;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ mWifiRttController = null;
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ }
+
+ private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with service-specific exception: " + e);
+ }
+}
diff --git a/service/java/com/android/server/wifi/rtt/RttNative.java b/service/java/com/android/server/wifi/hal/WifiRttControllerHidlImpl.java
index a4fd9e7516..6ef2eaabff 100644
--- a/service/java/com/android/server/wifi/rtt/RttNative.java
+++ b/service/java/com/android/server/wifi/hal/WifiRttControllerHidlImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,13 +14,11 @@
* limitations under the License.
*/
-package com.android.server.wifi.rtt;
+package com.android.server.wifi.hal;
-import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.wifi.V1_0.IWifiRttController;
import android.hardware.wifi.V1_0.IWifiRttControllerEventCallback;
-import android.hardware.wifi.V1_0.RttCapabilities;
import android.hardware.wifi.V1_0.RttConfig;
import android.hardware.wifi.V1_0.RttPeerType;
import android.hardware.wifi.V1_0.RttResult;
@@ -36,425 +34,560 @@ import android.net.wifi.rtt.RangingRequest;
import android.net.wifi.rtt.RangingResult;
import android.net.wifi.rtt.ResponderConfig;
import android.net.wifi.rtt.ResponderLocation;
-import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
-import com.android.server.wifi.HalDeviceManager;
+import com.android.server.wifi.util.GeneralUtil.Mutable;
import com.android.server.wifi.util.NativeUtil;
-import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
+import java.util.Set;
+import java.util.function.Supplier;
/**
- * TBD
+ * HIDL implementation of the IWifiRttController interface.
*/
-public class RttNative {
- private static final String TAG = "RttNative";
- private static final boolean VDBG = false; // STOPSHIP if true
+public class WifiRttControllerHidlImpl implements IWifiRttController {
+ private static final String TAG = "WifiRttControllerHidl";
private boolean mVerboseLoggingEnabled = false;
- /** Unknown status */
- public static final int FRAMEWORK_RTT_STATUS_UNKNOWN = -1;
- /** Success */
- public static final int FRAMEWORK_RTT_STATUS_SUCCESS = 0;
- /** General failure status */
- public static final int FRAMEWORK_RTT_STATUS_FAILURE = 1;
- /** Target STA does not respond to request */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_NO_RSP = 2;
- /** Request rejected. Applies to 2-sided RTT only */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_REJECTED = 3;
- public static final int FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4;
- /** Timing measurement times out */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT = 5;
- /** Target on different channel, cannot range */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6;
- /** Ranging not supported */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY = 7;
- /** Request aborted for unknown reason */
- public static final int FRAMEWORK_RTT_STATUS_ABORTED = 8;
- /** Invalid T1-T4 timestamp */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS = 9;
- /** 11mc protocol failed */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL = 10;
- /** Request could not be scheduled */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE = 11;
- /** Responder cannot collaborate at time of request */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER = 12;
- /** Bad request args */
- public static final int FRAMEWORK_RTT_STATUS_INVALID_REQ = 13;
- /** WiFi not enabled. */
- public static final int FRAMEWORK_RTT_STATUS_NO_WIFI = 14;
- /** Responder overrides param info, cannot range with new params */
- public static final int FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15;
-
- /** @hide */
- @IntDef(prefix = "FRAMEWORK_RTT_STATUS_", value = {FRAMEWORK_RTT_STATUS_UNKNOWN,
- FRAMEWORK_RTT_STATUS_SUCCESS, FRAMEWORK_RTT_STATUS_FAILURE,
- FRAMEWORK_RTT_STATUS_FAIL_NO_RSP, FRAMEWORK_RTT_STATUS_FAIL_REJECTED,
- FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET, FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT,
- FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY,
- FRAMEWORK_RTT_STATUS_ABORTED, FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS,
- FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL, FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE,
- FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER, FRAMEWORK_RTT_STATUS_INVALID_REQ,
- FRAMEWORK_RTT_STATUS_NO_WIFI, FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE})
- @Retention(RetentionPolicy.SOURCE)
- public @interface FrameworkRttStatus {}
-
-
- private final RttServiceImpl mRttService;
- private final HalDeviceManager mHalDeviceManager;
-
- private Object mLock = new Object();
-
- private volatile IWifiRttController mIWifiRttController;
- private volatile Capabilities mRttCapabilities;
+ private android.hardware.wifi.V1_0.IWifiRttController mWifiRttController;
+ private android.hardware.wifi.V1_4.IWifiRttController mWifiRttController14;
+ private android.hardware.wifi.V1_6.IWifiRttController mWifiRttController16;
private final WifiRttControllerEventCallback mWifiRttControllerEventCallback;
- private volatile android.hardware.wifi.V1_4.IWifiRttController mIWifiRttController14;
- private volatile android.hardware.wifi.V1_6.IWifiRttController mIWifiRttController16;
private final WifiRttControllerEventCallback14 mWifiRttControllerEventCallback14;
private final WifiRttControllerEventCallback16 mWifiRttControllerEventCallback16;
- private static final int CONVERSION_US_TO_MS = 1_000;
-
- private final HalDeviceManager.InterfaceRttControllerLifecycleCallback mRttLifecycleCb =
- new HalDeviceManager.InterfaceRttControllerLifecycleCallback() {
- @Override
- public void onNewRttController(IWifiRttController controller) {
- if (mVerboseLoggingEnabled) {
- Log.d(TAG,
- "onNewRttController: controller=" + controller);
- }
- boolean changed = mIWifiRttController == null;
- synchronized (mLock) {
- mIWifiRttController = controller;
- mIWifiRttController14 = getWifiRttControllerV1_4();
- mIWifiRttController16 = getWifiRttControllerV1_6();
- try {
- if (mIWifiRttController16 != null) {
- mIWifiRttController16.registerEventCallback_1_6(
- mWifiRttControllerEventCallback16);
- } else if (mIWifiRttController14 != null) {
- mIWifiRttController14.registerEventCallback_1_4(
- mWifiRttControllerEventCallback14);
- } else {
- mIWifiRttController.registerEventCallback(
- mWifiRttControllerEventCallback);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "onNewRttController: exception registering callback: " + e);
- if (mIWifiRttController != null) {
- mIWifiRttController = null;
- mIWifiRttController14 = null;
- mIWifiRttController16 = null;
- mRttService.disable();
- }
- return;
- }
- if (changed) {
- mRttService.enableIfPossible();
- }
- updateRttCapabilities();
- }
- }
-
- @Override
- public void onRttControllerDestroyed() {
- if (mVerboseLoggingEnabled) Log.d(TAG, "onRttControllerDestroyed");
- synchronized (mLock) {
- mIWifiRttController = null;
- mIWifiRttController14 = null;
- mIWifiRttController16 = null;
- mRttCapabilities = null;
- mRttService.disable();
- }
- }
- };
-
- public RttNative(RttServiceImpl rttService, HalDeviceManager halDeviceManager) {
- mRttService = rttService;
- mHalDeviceManager = halDeviceManager;
+ private WifiRttController.Capabilities mRttCapabilities;
+ private Set<WifiRttController.RttControllerRangingResultsCallback> mRangingResultsCallbacks =
+ new HashSet<>();
+
+ public WifiRttControllerHidlImpl(
+ @NonNull android.hardware.wifi.V1_0.IWifiRttController rttController) {
+ mWifiRttController = rttController;
+ mWifiRttController14 =
+ android.hardware.wifi.V1_4.IWifiRttController.castFrom(mWifiRttController);
+ mWifiRttController16 =
+ android.hardware.wifi.V1_6.IWifiRttController.castFrom(mWifiRttController);
mWifiRttControllerEventCallback = new WifiRttControllerEventCallback();
mWifiRttControllerEventCallback14 = new WifiRttControllerEventCallback14();
mWifiRttControllerEventCallback16 = new WifiRttControllerEventCallback16();
}
/**
- * Initialize the object - registering with the HAL device manager.
+ * See comments for {@link IWifiRttController#setup()}
*/
- public void start(Handler handler) {
- synchronized (mLock) {
- mHalDeviceManager.initialize();
- mHalDeviceManager.registerStatusListener(() -> {
- if (VDBG) Log.d(TAG, "hdm.onStatusChanged");
- if (mHalDeviceManager.isStarted()) {
- mHalDeviceManager.registerRttControllerLifecycleCallback(mRttLifecycleCb,
- handler);
- }
- }, handler);
- if (mHalDeviceManager.isStarted()) {
- mHalDeviceManager.registerRttControllerLifecycleCallback(mRttLifecycleCb, handler);
- }
- }
+ public boolean setup() {
+ final String methodStr = "setup";
+ return validateAndCall(methodStr, false,
+ () -> setupInternal(methodStr));
}
/**
- * Enable/Disable verbose logging.
- *
+ * See comments for {@link IWifiRttController#enableVerboseLogging(boolean)}
*/
- public void enableVerboseLogging(boolean verboseEnabled) {
- mVerboseLoggingEnabled = verboseEnabled;
+ public void enableVerboseLogging(boolean verbose) {
+ mVerboseLoggingEnabled = verbose;
}
/**
- * Returns true if Wi-Fi is ready for RTT requests, false otherwise.
+ * See comments for {@link IWifiRttController#registerRangingResultsCallback(
+ * WifiRttController.RttControllerRangingResultsCallback)}
*/
- public boolean isReady() {
- return mIWifiRttController != null;
+ public void registerRangingResultsCallback(
+ WifiRttController.RttControllerRangingResultsCallback callback) {
+ if (!mRangingResultsCallbacks.add(callback)) {
+ Log.e(TAG, "Ranging results callback was already registered");
+ }
}
/**
- * Returns the RTT capabilities. Will only be null when disabled (e.g. no STA interface
- * available - not necessarily up).
+ * See comments for {@link IWifiRttController#validate()}
*/
- public @Nullable Capabilities getRttCapabilities() {
+ public boolean validate() {
+ final String methodStr = "validate";
+ return validateAndCall(methodStr, false,
+ () -> validateInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#getRttCapabilities()}
+ */
+ @Nullable
+ public WifiRttController.Capabilities getRttCapabilities() {
return mRttCapabilities;
}
/**
- * Updates the RTT capabilities.
+ * See comments for {@link IWifiRttController#rangeRequest(int, RangingRequest)}
*/
- void updateRttCapabilities() {
- if (mIWifiRttController == null) {
- Log.e(TAG, "updateRttCapabilities: but a RTT controller is NULL!?");
- return;
- }
- if (mRttCapabilities != null) {
- return;
- }
- if (mVerboseLoggingEnabled) Log.v(TAG, "updateRttCapabilities");
+ public boolean rangeRequest(int cmdId, RangingRequest request) {
+ final String methodStr = "rangeRequest";
+ return validateAndCall(methodStr, false,
+ () -> rangeRequestInternal(methodStr, cmdId, request));
+ }
- synchronized (mLock) {
- try {
- if (mIWifiRttController16 != null) {
- mIWifiRttController16.getCapabilities_1_6(
- (status, capabilities16) -> {
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "updateRttCapabilities:"
- + " error requesting capabilities "
- + "-- code=" + status.code);
- return;
- }
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "updateRttCapabilities: RTT capabilities="
- + capabilities16);
- }
- mRttCapabilities = new Capabilities(capabilities16);
- });
- } else if (mIWifiRttController14 != null) {
- mIWifiRttController14.getCapabilities_1_4(
- (status, capabilities14) -> {
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "updateRttCapabilities:"
- + " error requesting capabilities "
- + "-- code=" + status.code);
- return;
- }
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "updateRttCapabilities: RTT capabilities="
- + capabilities14);
- }
- mRttCapabilities = new Capabilities(capabilities14);
- });
- } else {
- mIWifiRttController.getCapabilities(
- (status, capabilities) -> {
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "updateRttCapabilities:"
- + " error requesting capabilities "
- + "-- code=" + status.code);
- return;
- }
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "updateRttCapabilities: RTT capabilities="
- + capabilities);
- }
- mRttCapabilities = new Capabilities(capabilities);
- });
- }
- } catch (RemoteException e) {
- Log.e(TAG, "updateRttCapabilities: exception requesting capabilities: " + e);
- }
+ /**
+ * See comments for {@link IWifiRttController#rangeCancel(int, List)}
+ */
+ public boolean rangeCancel(int cmdId, List<MacAddress> macAddresses) {
+ final String methodStr = "rangeCancel";
+ return validateAndCall(methodStr, false,
+ () -> rangeCancelInternal(methodStr, cmdId, macAddresses));
+ }
+
+ /**
+ * See comments for {@link IWifiRttController#dump(PrintWriter)}
+ */
+ public void dump(PrintWriter pw) {
+ pw.println("WifiRttController:");
+ pw.println(" mIWifiRttController: " + mWifiRttController);
+ pw.println(" mRttCapabilities: " + mRttCapabilities);
+ }
+
+
+ // Internal Implementations
- if (mRttCapabilities != null && !mRttCapabilities.rttFtmSupported) {
- Log.wtf(TAG, "Firmware indicates RTT is not supported - but device supports RTT - "
- + "ignored!?");
+ private boolean setupInternal(String methodStr) {
+ try {
+ if (mWifiRttController16 != null) {
+ mWifiRttController16.registerEventCallback_1_6(mWifiRttControllerEventCallback16);
+ } else if (mWifiRttController14 != null) {
+ mWifiRttController14.registerEventCallback_1_4(mWifiRttControllerEventCallback14);
+ } else {
+ mWifiRttController.registerEventCallback(mWifiRttControllerEventCallback);
}
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
}
+ updateRttCapabilities();
+ return true;
}
- /**
- * Issue a range request to the HAL.
- *
- * @param cmdId Command ID for the request. Will be used in the corresponding
- * {@link WifiRttControllerEventCallback#onResults(int, ArrayList)}.
- * @param request Range request.
- * @param isCalledFromPrivilegedContext Indicates whether privileged APIs are permitted,
- * initially: support for one-sided RTT.
- *
- * @return Success status: true for success, false for failure.
- */
- public boolean rangeRequest(int cmdId, RangingRequest request,
- boolean isCalledFromPrivilegedContext) {
+ private boolean validateInternal(String methodStr) {
+ Mutable<Boolean> isRttControllerValid = new Mutable<>(false);
+ try {
+ mWifiRttController.getBoundIface(
+ (status, iface) -> {
+ if (isOk(status, methodStr)) {
+ isRttControllerValid.value = true;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return isRttControllerValid.value;
+ }
+
+ private boolean rangeRequestInternal(String methodStr, int cmdId, RangingRequest request) {
if (mVerboseLoggingEnabled) {
- Log.v(TAG,
- "rangeRequest: cmdId=" + cmdId + ", # of requests=" + request.mRttPeers.size());
+ Log.v(TAG, "rangeRequest: cmdId=" + cmdId + ", # of requests="
+ + request.mRttPeers.size() + ", request=" + request);
}
- if (VDBG) Log.v(TAG, "rangeRequest: request=" + request);
- synchronized (mLock) {
- if (!isReady()) {
- Log.e(TAG, "rangeRequest: RttController is null");
- return false;
- }
- updateRttCapabilities();
- if (mIWifiRttController16 != null) {
- return sendRangeRequest16(cmdId, request, isCalledFromPrivilegedContext);
- } else if (mIWifiRttController14 != null) {
- return sendRangeRequest14(cmdId, request, isCalledFromPrivilegedContext);
- } else {
- return sendRangeRequest(cmdId, request, isCalledFromPrivilegedContext);
- }
+ updateRttCapabilities();
+ if (mWifiRttController16 != null) {
+ return sendRangeRequest16(cmdId, request);
+ } else if (mWifiRttController14 != null) {
+ return sendRangeRequest14(cmdId, request);
+ } else {
+ return sendRangeRequest(cmdId, request);
}
}
- private boolean sendRangeRequest(int cmdId, RangingRequest request,
- boolean isCalledFromPrivilegedContext) {
- ArrayList<RttConfig> rttConfig = convertRangingRequestToRttConfigs(request,
- isCalledFromPrivilegedContext, mRttCapabilities);
+ private boolean sendRangeRequest(int cmdId, RangingRequest request) {
+ final String methodStr = "sendRangeRequest";
+ ArrayList<RttConfig> rttConfig =
+ convertRangingRequestToRttConfigs(request, mRttCapabilities);
if (rttConfig == null) {
Log.e(TAG, "sendRangeRequest: invalid request parameters");
return false;
}
if (rttConfig.size() == 0) {
Log.e(TAG, "sendRangeRequest: all requests invalidated");
- mRttService.onRangingResults(cmdId, new ArrayList<>());
+ dispatchOnRangingResults(cmdId, new ArrayList<>());
return true;
}
try {
- WifiStatus status = mIWifiRttController.rangeRequest(cmdId, rttConfig);
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "sendRangeRequest: cannot issue range request -- code=" + status.code);
- return false;
- }
+ WifiStatus status = mWifiRttController.rangeRequest(cmdId, rttConfig);
+ return isOk(status, methodStr);
} catch (RemoteException e) {
- Log.e(TAG, "sendRangeRequest: exception issuing range request: " + e);
+ handleRemoteException(e, methodStr);
return false;
}
-
- return true;
}
- private boolean sendRangeRequest14(int cmdId, RangingRequest request,
- boolean isCalledFromPrivilegedContext) {
+ private boolean sendRangeRequest14(int cmdId, RangingRequest request) {
+ final String methodStr = "sendRangeRequest14";
ArrayList<android.hardware.wifi.V1_4.RttConfig> rttConfig =
- convertRangingRequestToRttConfigs14(request,
- isCalledFromPrivilegedContext, mRttCapabilities);
+ convertRangingRequestToRttConfigs14(request, mRttCapabilities);
if (rttConfig == null) {
Log.e(TAG, "sendRangeRequest14: invalid request parameters");
return false;
}
if (rttConfig.size() == 0) {
Log.e(TAG, "sendRangeRequest14: all requests invalidated");
- mRttService.onRangingResults(cmdId, new ArrayList<>());
+ dispatchOnRangingResults(cmdId, new ArrayList<>());
return true;
}
try {
- WifiStatus status = mIWifiRttController14.rangeRequest_1_4(cmdId, rttConfig);
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "sendRangeRequest14: cannot issue range request -- code="
- + status.code);
- return false;
- }
+ WifiStatus status = mWifiRttController14.rangeRequest_1_4(cmdId, rttConfig);
+ return isOk(status, methodStr);
} catch (RemoteException e) {
- Log.e(TAG, "sendRangeRequest14: exception issuing range request: " + e);
+ handleRemoteException(e, methodStr);
return false;
}
-
- return true;
}
- private boolean sendRangeRequest16(int cmdId, RangingRequest request,
- boolean isCalledFromPrivilegedContext) {
+ private boolean sendRangeRequest16(int cmdId, RangingRequest request) {
+ final String methodStr = "sendRangeRequest16";
ArrayList<android.hardware.wifi.V1_6.RttConfig> rttConfig =
- convertRangingRequestToRttConfigs16(request,
- isCalledFromPrivilegedContext, mRttCapabilities);
+ convertRangingRequestToRttConfigs16(request, mRttCapabilities);
if (rttConfig == null) {
Log.e(TAG, "sendRangeRequest16: invalid request parameters");
return false;
}
if (rttConfig.size() == 0) {
Log.e(TAG, "sendRangeRequest16: all requests invalidated");
- mRttService.onRangingResults(cmdId, new ArrayList<>());
+ dispatchOnRangingResults(cmdId, new ArrayList<>());
return true;
}
try {
- WifiStatus status = mIWifiRttController16.rangeRequest_1_6(cmdId, rttConfig);
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "sendRangeRequest16: cannot issue range request -- code="
- + status.code);
- return false;
+ WifiStatus status = mWifiRttController16.rangeRequest_1_6(cmdId, rttConfig);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ boolean rangeCancelInternal(String methodStr, int cmdId, List<MacAddress> macAddresses) {
+ if (mVerboseLoggingEnabled) Log.v(TAG, "rangeCancel: cmdId=" + cmdId);
+ try {
+ ArrayList<byte[]> macBytes = new ArrayList<>();
+ for (MacAddress mac : macAddresses) {
+ macBytes.add(mac.toByteArray());
}
+ WifiStatus status = mWifiRttController.rangeCancel(cmdId, macBytes);
+ return isOk(status, methodStr);
} catch (RemoteException e) {
- Log.e(TAG, "sendRangeRequest16: exception issuing range request: " + e);
+ handleRemoteException(e, methodStr);
return false;
}
+ }
- return true;
+ /**
+ * Callback for HAL events on 1.0 WifiRttController
+ */
+ private class WifiRttControllerEventCallback extends IWifiRttControllerEventCallback.Stub {
+ /**
+ * Callback from the HAL with range results.
+ *
+ * @param cmdId Command ID specified in the original request.
+ * @param halResults A list of range results.
+ */
+ @Override
+ public void onResults(int cmdId, ArrayList<RttResult> halResults) {
+ if (mVerboseLoggingEnabled) {
+ int numResults = halResults != null ? halResults.size() : -1;
+ Log.v(TAG, "onResults: cmdId=" + cmdId + ", # of results=" + numResults);
+ }
+ if (halResults == null) {
+ halResults = new ArrayList<>();
+ }
+ halResults.removeIf(Objects::isNull);
+ ArrayList<RangingResult> rangingResults = convertHalResultsRangingResults(halResults);
+ dispatchOnRangingResults(cmdId, rangingResults);
+ }
}
/**
- * Cancel an outstanding ranging request: no guarantees of execution - we will ignore any
- * results which are returned for the canceled request.
- *
- * @param cmdId The cmdId issued with the original rangeRequest command.
- * @param macAddresses A list of MAC addresses for which to cancel the operation.
- * @return Success status: true for success, false for failure.
+ * Callback for HAL events on 1.4 WifiRttController
*/
- public boolean rangeCancel(int cmdId, ArrayList<byte[]> macAddresses) {
- if (mVerboseLoggingEnabled) Log.v(TAG, "rangeCancel: cmdId=" + cmdId);
- synchronized (mLock) {
- if (!isReady()) {
- Log.e(TAG, "rangeCancel: RttController is null");
- return false;
+ private class WifiRttControllerEventCallback14 extends
+ android.hardware.wifi.V1_4.IWifiRttControllerEventCallback.Stub {
+ @Override
+ public void onResults(int cmdId, ArrayList<RttResult> halResults) {
+ // This callback is not supported on this version of the interface.
+ return;
+ }
+
+ @Override
+ public void onResults_1_4(int cmdId,
+ ArrayList<android.hardware.wifi.V1_4.RttResult> halResults) {
+ if (mVerboseLoggingEnabled) {
+ int numResults = halResults != null ? halResults.size() : -1;
+ Log.v(TAG, "onResults_1_4: cmdId=" + cmdId + ", # of results=" + numResults);
+ }
+ if (halResults == null) {
+ halResults = new ArrayList<>();
}
+ halResults.removeIf(Objects::isNull);
+ ArrayList<RangingResult> rangingResults = convertHalResultsRangingResults14(halResults);
+ dispatchOnRangingResults(cmdId, rangingResults);
+ }
+ }
+ /**
+ * Callback for HAL events on 1.6 WifiRttController
+ */
+ private class WifiRttControllerEventCallback16 extends
+ android.hardware.wifi.V1_6.IWifiRttControllerEventCallback.Stub {
+ @Override
+ public void onResults(int cmdId, ArrayList<RttResult> halResults) {
+ // This callback is not supported on this version of the interface.
+ return;
+ }
+
+ @Override
+ public void onResults_1_4(int cmdId,
+ ArrayList<android.hardware.wifi.V1_4.RttResult> halResults) {
+ // This callback is not supported on this version of the interface.
+ return;
+ }
+
+ @Override
+ public void onResults_1_6(int cmdId,
+ ArrayList<android.hardware.wifi.V1_6.RttResult> halResults) {
+ if (mVerboseLoggingEnabled) {
+ int numResults = halResults != null ? halResults.size() : -1;
+ Log.v(TAG, "onResults_1_6: cmdId=" + cmdId + ", # of results=" + numResults);
+ }
+ if (halResults == null) {
+ halResults = new ArrayList<>();
+ }
+ halResults.removeIf(Objects::isNull);
+ ArrayList<RangingResult> rangingResults = convertHalResultsRangingResults16(halResults);
+ dispatchOnRangingResults(cmdId, rangingResults);
+ }
+ }
+
+
+ // Helper Functions
+
+ private ArrayList<RangingResult> convertHalResultsRangingResults(
+ ArrayList<RttResult> halResults) {
+ ArrayList<RangingResult> rangingResults = new ArrayList<>();
+ for (RttResult rttResult : halResults) {
+ byte[] lci = NativeUtil.byteArrayFromArrayList(rttResult.lci.data);
+ byte[] lcr = NativeUtil.byteArrayFromArrayList(rttResult.lcr.data);
+ ResponderLocation responderLocation;
try {
- WifiStatus status = mIWifiRttController.rangeCancel(cmdId, macAddresses);
- if (status.code != WifiStatusCode.SUCCESS) {
- Log.e(TAG, "rangeCancel: cannot issue range cancel -- code=" + status.code);
- return false;
+ responderLocation = new ResponderLocation(lci, lcr);
+ if (!responderLocation.isValid()) {
+ responderLocation = null;
}
- } catch (RemoteException e) {
- Log.e(TAG, "rangeCancel: exception issuing range cancel: " + e);
- return false;
+ } catch (Exception e) {
+ responderLocation = null;
+ Log.e(TAG,
+ "ResponderLocation: lci/lcr parser failed exception -- " + e);
}
+ if (rttResult.successNumber <= 1 && rttResult.distanceSdInMm != 0) {
+ if (mVerboseLoggingEnabled) {
+ Log.w(TAG, "postProcessResults: non-zero distance stdev with 0||1 num "
+ + "samples!? result=" + rttResult);
+ }
+ 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));
+ }
+ return rangingResults;
+ }
- return true;
+ private ArrayList<RangingResult> convertHalResultsRangingResults14(
+ ArrayList<android.hardware.wifi.V1_4.RttResult> halResults) {
+ ArrayList<RangingResult> rangingResults = new ArrayList<>();
+ for (android.hardware.wifi.V1_4.RttResult rttResult : halResults) {
+ byte[] lci = NativeUtil.byteArrayFromArrayList(rttResult.lci.data);
+ byte[] lcr = NativeUtil.byteArrayFromArrayList(rttResult.lcr.data);
+ ResponderLocation responderLocation;
+ try {
+ responderLocation = new ResponderLocation(lci, lcr);
+ if (!responderLocation.isValid()) {
+ responderLocation = null;
+ }
+ } catch (Exception e) {
+ responderLocation = null;
+ Log.e(TAG,
+ "ResponderLocation: lci/lcr parser failed exception -- " + e);
+ }
+ if (rttResult.successNumber <= 1 && rttResult.distanceSdInMm != 0) {
+ if (mVerboseLoggingEnabled) {
+ Log.w(TAG, "postProcessResults: non-zero distance stdev with 0||1 num "
+ + "samples!? result=" + rttResult);
+ }
+ 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));
}
+ return rangingResults;
}
- private static ArrayList<RttConfig> convertRangingRequestToRttConfigs(RangingRequest request,
- boolean isCalledFromPrivilegedContext, Capabilities cap) {
+ private ArrayList<RangingResult> convertHalResultsRangingResults16(
+ ArrayList<android.hardware.wifi.V1_6.RttResult> halResults) {
+ ArrayList<RangingResult> rangingResults = new ArrayList<>();
+ for (android.hardware.wifi.V1_6.RttResult rttResult : halResults) {
+ byte[] lci = NativeUtil.byteArrayFromArrayList(rttResult.lci.data);
+ byte[] lcr = NativeUtil.byteArrayFromArrayList(rttResult.lcr.data);
+ ResponderLocation responderLocation;
+ try {
+ responderLocation = new ResponderLocation(lci, lcr);
+ if (!responderLocation.isValid()) {
+ responderLocation = null;
+ }
+ } catch (Exception e) {
+ responderLocation = null;
+ Log.e(TAG,
+ "ResponderLocation: lci/lcr parser failed exception -- " + e);
+ }
+ if (rttResult.successNumber <= 1 && rttResult.distanceSdInMm != 0) {
+ if (mVerboseLoggingEnabled) {
+ Log.w(TAG, "postProcessResults: non-zero distance stdev with 0||1 num "
+ + "samples!? result=" + rttResult);
+ }
+ 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));
+ }
+ return rangingResults;
+ }
+
+ private @WifiRttController.FrameworkRttStatus
+ int convertHalStatusToFrameworkStatus(int halStatus) {
+ switch (halStatus) {
+ case RttStatus.SUCCESS:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS;
+ case RttStatus.FAILURE:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAILURE;
+ case RttStatus.FAIL_NO_RSP:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NO_RSP;
+ case RttStatus.FAIL_REJECTED:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_REJECTED;
+ case RttStatus.FAIL_NOT_SCHEDULED_YET:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
+ case RttStatus.FAIL_TM_TIMEOUT:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT;
+ case RttStatus.FAIL_AP_ON_DIFF_CHANNEL:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
+ case RttStatus.FAIL_NO_CAPABILITY:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY;
+ case RttStatus.ABORTED:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_ABORTED;
+ case RttStatus.FAIL_INVALID_TS:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS;
+ case RttStatus.FAIL_PROTOCOL:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL;
+ case RttStatus.FAIL_SCHEDULE:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE;
+ case RttStatus.FAIL_BUSY_TRY_LATER:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER;
+ case RttStatus.INVALID_REQ:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_INVALID_REQ;
+ case RttStatus.NO_WIFI:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_NO_WIFI;
+ case RttStatus.FAIL_FTM_PARAM_OVERRIDE:
+ return WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
+ default:
+ Log.e(TAG, "Unrecognized RttStatus: " + halStatus);
+ return WifiRttController.FRAMEWORK_RTT_STATUS_UNKNOWN;
+ }
+ }
+
+ private void updateRttCapabilities() {
+ if (mRttCapabilities != null) return;
+ if (mVerboseLoggingEnabled) Log.v(TAG, "updateRttCapabilities");
+
+ try {
+ if (mWifiRttController16 != null) {
+ mWifiRttController16.getCapabilities_1_6(
+ (status, capabilities16) -> {
+ if (status.code != WifiStatusCode.SUCCESS) {
+ Log.e(TAG, "updateRttCapabilities:"
+ + " error requesting capabilities "
+ + "-- code=" + status.code);
+ return;
+ }
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "updateRttCapabilities: RTT capabilities="
+ + capabilities16);
+ }
+ mRttCapabilities = new WifiRttController.Capabilities(capabilities16);
+ });
+ } else if (mWifiRttController14 != null) {
+ mWifiRttController14.getCapabilities_1_4(
+ (status, capabilities14) -> {
+ if (status.code != WifiStatusCode.SUCCESS) {
+ Log.e(TAG, "updateRttCapabilities:"
+ + " error requesting capabilities "
+ + "-- code=" + status.code);
+ return;
+ }
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "updateRttCapabilities: RTT capabilities="
+ + capabilities14);
+ }
+ mRttCapabilities = new WifiRttController.Capabilities(capabilities14);
+ });
+ } else {
+ mWifiRttController.getCapabilities(
+ (status, capabilities) -> {
+ if (status.code != WifiStatusCode.SUCCESS) {
+ Log.e(TAG, "updateRttCapabilities:"
+ + " error requesting capabilities "
+ + "-- code=" + status.code);
+ return;
+ }
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "updateRttCapabilities: RTT capabilities="
+ + capabilities);
+ }
+ mRttCapabilities = new WifiRttController.Capabilities(capabilities);
+ });
+
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, "updateRttCapabilities");
+ }
+
+ if (mRttCapabilities != null && !mRttCapabilities.rttFtmSupported) {
+ Log.wtf(TAG, "Firmware indicates RTT is not supported - but device supports RTT - "
+ + "ignored!?");
+ }
+ }
+
+ private static ArrayList<RttConfig> convertRangingRequestToRttConfigs(
+ RangingRequest request, WifiRttController.Capabilities cap) {
ArrayList<RttConfig> rttConfigs = new ArrayList<>(request.mRttPeers.size());
- // Skipping any configurations which have an error (printing out a message).
+ // Skip any configurations which have an error (just print out a message).
// The caller will only get results for valid configurations.
for (ResponderConfig responder: request.mRttPeers) {
RttConfig config = new RttConfig();
@@ -534,18 +667,16 @@ public class RttNative {
}
private static ArrayList<android.hardware.wifi.V1_4.RttConfig>
- convertRangingRequestToRttConfigs14(
- RangingRequest request, boolean isCalledFromPrivilegedContext, Capabilities cap) {
+ convertRangingRequestToRttConfigs14(RangingRequest request,
+ WifiRttController.Capabilities cap) {
ArrayList<android.hardware.wifi.V1_4.RttConfig> rttConfigs =
new ArrayList<>(request.mRttPeers.size());
- // Skipping any configurations which have an error (printing out a message).
+ // Skip any configurations which have an error (just print out a message).
// The caller will only get results for valid configurations.
for (ResponderConfig responder: request.mRttPeers) {
-
android.hardware.wifi.V1_4.RttConfig config =
new android.hardware.wifi.V1_4.RttConfig();
-
System.arraycopy(responder.macAddress.toByteArray(), 0, config.addr, 0,
config.addr.length);
@@ -603,18 +734,16 @@ public class RttNative {
}
private static ArrayList<android.hardware.wifi.V1_6.RttConfig>
- convertRangingRequestToRttConfigs16(
- RangingRequest request, boolean isCalledFromPrivilegedContext, Capabilities cap) {
+ convertRangingRequestToRttConfigs16(RangingRequest request,
+ WifiRttController.Capabilities cap) {
ArrayList<android.hardware.wifi.V1_6.RttConfig> rttConfigs =
new ArrayList<>(request.mRttPeers.size());
- // Skipping any configurations which have an error (printing out a message).
+ // Skip any configurations which have an error (just print out a message).
// The caller will only get results for valid configurations.
for (ResponderConfig responder: request.mRttPeers) {
-
android.hardware.wifi.V1_6.RttConfig config =
new android.hardware.wifi.V1_6.RttConfig();
-
System.arraycopy(responder.macAddress.toByteArray(), 0, config.addr, 0,
config.addr.length);
@@ -763,15 +892,16 @@ public class RttNative {
}
/**
- * Check to see whether the selected RTT channel bandwidth is supported by the device.
- * If not supported: return the next lower bandwidth which is supported
- * If none: throw an IllegalArgumentException.
+ * Check whether the selected RTT channel bandwidth is supported by the device.
+ * If supported, return the requested bandwidth.
+ * If not supported, return the next lower bandwidth which is supported.
+ * If none, throw an IllegalArgumentException.
*
- * Note: the halRttChannelBandwidth is a single bit flag of the ones used in cap.bwSupport (HAL
- * specifications).
+ * Note: the halRttChannelBandwidth is a single bit flag from the HAL RttBw type.
*/
private static int halRttChannelBandwidthCapabilityLimiter(int halRttChannelBandwidth,
- Capabilities cap) {
+ WifiRttController.Capabilities cap) {
+ int requestedBandwidth = halRttChannelBandwidth;
while ((halRttChannelBandwidth != 0) && ((halRttChannelBandwidth & cap.bwSupported) == 0)) {
halRttChannelBandwidth >>= 1;
}
@@ -781,19 +911,21 @@ public class RttNative {
}
throw new IllegalArgumentException(
- "RTT BW=" + halRttChannelBandwidth + ", not supported by device capabilities=" + cap
+ "RTT BW=" + requestedBandwidth + ", not supported by device capabilities=" + cap
+ " - and no supported alternative");
}
/**
- * Check to see whether the selected RTT preamble is supported by the device.
- * If not supported: return the next "lower" preamble which is supported
- * If none: throw an IllegalArgumentException.
+ * Check whether the selected RTT preamble is supported by the device.
+ * If supported, return the requested preamble.
+ * If not supported, return the next "lower" preamble which is supported.
+ * If none, throw an IllegalArgumentException.
*
- * Note: the halRttPreamble is a single bit flag of the ones used in cap.preambleSupport (HAL
- * specifications).
+ * Note: the halRttPreamble is a single bit flag from the HAL RttPreamble type.
*/
- private static int halRttPreambleCapabilityLimiter(int halRttPreamble, Capabilities cap) {
+ private static int halRttPreambleCapabilityLimiter(int halRttPreamble,
+ WifiRttController.Capabilities cap) {
+ int requestedPreamble = halRttPreamble;
while ((halRttPreamble != 0) && ((halRttPreamble & cap.preambleSupported) == 0)) {
halRttPreamble >>= 1;
}
@@ -803,338 +935,33 @@ public class RttNative {
}
throw new IllegalArgumentException(
- "RTT Preamble=" + halRttPreamble + ", not supported by device capabilities=" + cap
- + " - and no supported alternative");
- }
-
- /**
- * Check if HAL Interface 1.4 is running
- *
- * @return 1.4 IWifiRttController object if the device is running the 1.4 hal service, null
- * otherwise
- */
- private android.hardware.wifi.V1_4.IWifiRttController getWifiRttControllerV1_4() {
- if (mIWifiRttController == null) {
- return null;
- }
- return android.hardware.wifi.V1_4.IWifiRttController.castFrom(mIWifiRttController);
- }
-
- /**
- * Check if HAL Interface 1.6 is running
- *
- * @return 1.6 IWifiRttController object if the device is running the 1.6 hal service, null
- * otherwise
- */
- private android.hardware.wifi.V1_6.IWifiRttController getWifiRttControllerV1_6() {
- if (mIWifiRttController == null) {
- return null;
- }
- return android.hardware.wifi.V1_6.IWifiRttController.castFrom(mIWifiRttController);
- }
-
- /**
- * Dump the internal state of the class.
- */
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("RttNative:");
- pw.println(" mHalDeviceManager: " + mHalDeviceManager);
- pw.println(" mIWifiRttController: " + mIWifiRttController);
- pw.println(" mRttCapabilities: " + mRttCapabilities);
- }
-
- /**
- * Callback for events on 1.0 WifiRttController
- */
- private class WifiRttControllerEventCallback extends IWifiRttControllerEventCallback.Stub {
- /**
- * Callback from HAL with range results.
- *
- * @param cmdId Command ID specified in the original request
- * {@link #rangeRequest(int, RangingRequest, boolean)}.
- * @param halResults A list of range results.
- */
- @Override
- public void onResults(int cmdId, ArrayList<RttResult> halResults) {
- // sanitize HAL results
- if (halResults == null) {
- halResults = new ArrayList<>();
- }
- halResults.removeIf(Objects::isNull);
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "onResults: cmdId=" + cmdId + ", # of results=" + halResults.size());
- }
- ArrayList<RangingResult> rangingResults = convertHalResultsRangingResults(halResults);
- mRttService.onRangingResults(cmdId, rangingResults);
- }
- }
-
- /**
- * Callback for events on 1.4 WifiRttController
- */
- private class WifiRttControllerEventCallback14 extends
- android.hardware.wifi.V1_4.IWifiRttControllerEventCallback.Stub {
- @Override
- public void onResults(int cmdId, ArrayList<RttResult> halResults) {
- // This callback is not supported on this version of the interface
- return;
- }
-
- @Override
- public void onResults_1_4(int cmdId,
- ArrayList<android.hardware.wifi.V1_4.RttResult> halResults) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG,
- "onResults_1_4: cmdId=" + cmdId + ", # of results=" + halResults.size());
- }
- // sanitize HAL results
- if (halResults == null) {
- halResults = new ArrayList<>();
- }
- halResults.removeIf(Objects::isNull);
- ArrayList<RangingResult> rangingResults = convertHalResultsRangingResults14(halResults);
- mRttService.onRangingResults(cmdId, rangingResults);
- }
- }
-
- /**
- * Callback for events on 1.6 WifiRttController
- */
- private class WifiRttControllerEventCallback16 extends
- android.hardware.wifi.V1_6.IWifiRttControllerEventCallback.Stub {
- @Override
- public void onResults(int cmdId, ArrayList<RttResult> halResults) {
- // This callback is not supported on this version of the interface
- return;
- }
-
- @Override
- public void onResults_1_4(int cmdId,
- ArrayList<android.hardware.wifi.V1_4.RttResult> halResults) {
- // This callback is not supported on this version of the interface
- return;
- }
-
- @Override
- public void onResults_1_6(int cmdId,
- ArrayList<android.hardware.wifi.V1_6.RttResult> halResults) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG,
- "onResults_1_6: cmdId=" + cmdId + ", # of results=" + halResults.size());
- }
- // sanitize HAL results
- if (halResults == null) {
- halResults = new ArrayList<>();
- }
- halResults.removeIf(Objects::isNull);
- ArrayList<RangingResult> rangingResults = convertHalResultsRangingResults16(halResults);
- mRttService.onRangingResults(cmdId, rangingResults);
- }
- }
-
- private ArrayList<RangingResult> convertHalResultsRangingResults(
- ArrayList<RttResult> halResults) {
- ArrayList<RangingResult> rangingResults = new ArrayList<>();
- for (RttResult rttResult : halResults) {
- byte[] lci = NativeUtil.byteArrayFromArrayList(rttResult.lci.data);
- byte[] lcr = NativeUtil.byteArrayFromArrayList(rttResult.lcr.data);
- ResponderLocation responderLocation;
- try {
- responderLocation = new ResponderLocation(lci, lcr);
- if (!responderLocation.isValid()) {
- responderLocation = null;
- }
- } catch (Exception e) {
- responderLocation = null;
- Log.e(TAG,
- "ResponderLocation: lci/lcr parser failed exception -- " + e);
- }
- if (rttResult.successNumber <= 1
- && rttResult.distanceSdInMm != 0) {
- if (mVerboseLoggingEnabled) {
- Log.w(TAG, "postProcessResults: non-zero distance stdev with 0||1 num "
- + "samples!? result=" + rttResult);
- }
- 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 / CONVERSION_US_TO_MS,
- rttResult.type == RttType.TWO_SIDED));
- }
- return rangingResults;
+ "RTT Preamble=" + requestedPreamble + ", not supported by device capabilities="
+ + cap + " - and no supported alternative");
}
- private ArrayList<RangingResult> convertHalResultsRangingResults14(
- ArrayList<android.hardware.wifi.V1_4.RttResult> halResults) {
- ArrayList<RangingResult> rangingResults = new ArrayList<>();
- for (android.hardware.wifi.V1_4.RttResult rttResult : halResults) {
- byte[] lci = NativeUtil.byteArrayFromArrayList(rttResult.lci.data);
- byte[] lcr = NativeUtil.byteArrayFromArrayList(rttResult.lcr.data);
- ResponderLocation responderLocation;
- try {
- responderLocation = new ResponderLocation(lci, lcr);
- if (!responderLocation.isValid()) {
- responderLocation = null;
- }
- } catch (Exception e) {
- responderLocation = null;
- Log.e(TAG,
- "ResponderLocation: lci/lcr parser failed exception -- " + e);
- }
- if (rttResult.successNumber <= 1
- && rttResult.distanceSdInMm != 0) {
- if (mVerboseLoggingEnabled) {
- Log.w(TAG, "postProcessResults: non-zero distance stdev with 0||1 num "
- + "samples!? result=" + rttResult);
- }
- 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 / CONVERSION_US_TO_MS,
- rttResult.type == RttType.TWO_SIDED));
+ private void dispatchOnRangingResults(int cmdId, List<RangingResult> rangingResults) {
+ for (WifiRttController.RttControllerRangingResultsCallback
+ callback : mRangingResultsCallbacks) {
+ callback.onRangingResults(cmdId, rangingResults);
}
- return rangingResults;
}
- private ArrayList<RangingResult> convertHalResultsRangingResults16(
- ArrayList<android.hardware.wifi.V1_6.RttResult> halResults) {
- ArrayList<RangingResult> rangingResults = new ArrayList<>();
- for (android.hardware.wifi.V1_6.RttResult rttResult : halResults) {
- byte[] lci = NativeUtil.byteArrayFromArrayList(rttResult.lci.data);
- byte[] lcr = NativeUtil.byteArrayFromArrayList(rttResult.lcr.data);
- ResponderLocation responderLocation;
- try {
- responderLocation = new ResponderLocation(lci, lcr);
- if (!responderLocation.isValid()) {
- responderLocation = null;
- }
- } catch (Exception e) {
- responderLocation = null;
- Log.e(TAG,
- "ResponderLocation: lci/lcr parser failed exception -- " + e);
- }
- if (rttResult.successNumber <= 1
- && rttResult.distanceSdInMm != 0) {
- if (mVerboseLoggingEnabled) {
- Log.w(TAG, "postProcessResults: non-zero distance stdev with 0||1 num "
- + "samples!? result=" + rttResult);
- }
- 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 / CONVERSION_US_TO_MS,
- rttResult.type == RttType.TWO_SIDED));
- }
- return rangingResults;
+ private boolean isOk(WifiStatus status, String methodStr) {
+ if (status.code == WifiStatusCode.SUCCESS) return true;
+ Log.e(TAG, methodStr + " failed with status: " + status);
+ return false;
}
- private @FrameworkRttStatus int convertHalStatusToFrameworkStatus(int halStatus) {
- switch (halStatus) {
- case RttStatus.SUCCESS:
- return FRAMEWORK_RTT_STATUS_SUCCESS;
- case RttStatus.FAILURE:
- return FRAMEWORK_RTT_STATUS_FAILURE;
- case RttStatus.FAIL_NO_RSP:
- return FRAMEWORK_RTT_STATUS_FAIL_NO_RSP;
- case RttStatus.FAIL_REJECTED:
- return FRAMEWORK_RTT_STATUS_FAIL_REJECTED;
- case RttStatus.FAIL_NOT_SCHEDULED_YET:
- return FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
- case RttStatus.FAIL_TM_TIMEOUT:
- return FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT;
- case RttStatus.FAIL_AP_ON_DIFF_CHANNEL:
- return FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
- case RttStatus.FAIL_NO_CAPABILITY:
- return FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY;
- case RttStatus.ABORTED:
- return FRAMEWORK_RTT_STATUS_ABORTED;
- case RttStatus.FAIL_INVALID_TS:
- return FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS;
- case RttStatus.FAIL_PROTOCOL:
- return FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL;
- case RttStatus.FAIL_SCHEDULE:
- return FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE;
- case RttStatus.FAIL_BUSY_TRY_LATER:
- return FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER;
- case RttStatus.INVALID_REQ:
- return FRAMEWORK_RTT_STATUS_INVALID_REQ;
- case RttStatus.NO_WIFI:
- return FRAMEWORK_RTT_STATUS_NO_WIFI;
- case RttStatus.FAIL_FTM_PARAM_OVERRIDE:
- return FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
- default:
- Log.e(TAG, "Unrecognized RttStatus: " + halStatus);
- return FRAMEWORK_RTT_STATUS_UNKNOWN;
- }
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ mWifiRttController = null;
}
- /**
- * Rtt capabilities inside framework
- */
- public class Capabilities {
- //1-sided rtt measurement is supported
- public boolean oneSidedRttSupported;
- //location configuration information supported
- public boolean lciSupported;
- //location civic records supported
- public boolean lcrSupported;
- //preamble supported, see bit mask definition above
- public int preambleSupported;
- //RTT bandwidth supported
- public int bwSupported;
- // Whether STA responder role is supported.
- public boolean responderSupported;
- //Draft 11mc version supported, including major and minor version. e.g, draft 4.3 is 43.
- public byte mcVersion;
- //if ftm rtt data collection is supported.
- public boolean rttFtmSupported;
-
- public Capabilities(RttCapabilities rttHalCapabilities) {
- oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported;
- lciSupported = rttHalCapabilities.lciSupported;
- lcrSupported = rttHalCapabilities.lcrSupported;
- responderSupported = rttHalCapabilities.responderSupported;
- preambleSupported = rttHalCapabilities.preambleSupport;
- mcVersion = rttHalCapabilities.mcVersion;
- bwSupported = rttHalCapabilities.bwSupport;
- rttFtmSupported = rttHalCapabilities.rttFtmSupported;
- }
-
- public Capabilities(android.hardware.wifi.V1_4.RttCapabilities rttHalCapabilities) {
- oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported;
- lciSupported = rttHalCapabilities.lciSupported;
- lcrSupported = rttHalCapabilities.lcrSupported;
- responderSupported = rttHalCapabilities.responderSupported;
- preambleSupported = rttHalCapabilities.preambleSupport;
- mcVersion = rttHalCapabilities.mcVersion;
- bwSupported = rttHalCapabilities.bwSupport;
- rttFtmSupported = rttHalCapabilities.rttFtmSupported;
- }
-
- public Capabilities(android.hardware.wifi.V1_6.RttCapabilities rttHalCapabilities) {
- oneSidedRttSupported = rttHalCapabilities.rttOneSidedSupported;
- lciSupported = rttHalCapabilities.lciSupported;
- lcrSupported = rttHalCapabilities.lcrSupported;
- responderSupported = rttHalCapabilities.responderSupported;
- preambleSupported = rttHalCapabilities.preambleSupport;
- mcVersion = rttHalCapabilities.mcVersion;
- bwSupported = rttHalCapabilities.bwSupport;
- rttFtmSupported = rttHalCapabilities.rttFtmSupported;
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiRttController == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiRttController is null");
+ return defaultVal;
}
+ return supplier.get();
}
}
diff --git a/service/java/com/android/server/wifi/hal/WifiStaIface.java b/service/java/com/android/server/wifi/hal/WifiStaIface.java
new file mode 100644
index 0000000000..1a04c2ff3e
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiStaIface.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.net.MacAddress;
+import android.net.apf.ApfCapabilities;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiScanner;
+import android.util.Log;
+
+import com.android.server.wifi.SsidTranslator;
+import com.android.server.wifi.WifiLinkLayerStats;
+import com.android.server.wifi.WifiNative;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * Wrapper around a WifiStaIface.
+ * May be initialized using a HIDL or AIDL WifiStaIface.
+ */
+public class WifiStaIface implements WifiHal.WifiInterface {
+ private static final String TAG = "WifiStaIface";
+ private final IWifiStaIface mWifiStaIface;
+
+ public static final int SET_ROAMING_STATE_FAILURE_CODE =
+ WifiNative.SET_FIRMWARE_ROAMING_FAILURE;
+
+ /**
+ * Parameters for a background scan request.
+ */
+ public static class StaBackgroundScanParameters {
+ public int basePeriodInMs;
+ public int maxApPerScan;
+ public int reportThresholdPercent;
+ public int reportThresholdNumScans;
+ public List<WifiNative.BucketSettings> buckets;
+
+ public StaBackgroundScanParameters(int inBasePeriodInMs, int inMaxApPerScan,
+ int inReportThresholdPercent, int inReportThresholdNumScans,
+ List<WifiNative.BucketSettings> inBuckets) {
+ basePeriodInMs = inBasePeriodInMs;
+ maxApPerScan = inMaxApPerScan;
+ reportThresholdPercent = inReportThresholdPercent;
+ reportThresholdNumScans = inReportThresholdNumScans;
+ buckets = inBuckets;
+ }
+ }
+
+ /**
+ * Framework callback object. Will get called when the equivalent events are received
+ * from the HAL.
+ */
+ public interface Callback {
+ /**
+ * Called for each received beacon/probe response for a scan with the
+ * |REPORT_EVENTS_FULL_RESULTS| flag set in
+ * |StaBackgroundScanBucketParameters.eventReportScheme|.
+ *
+ * @param cmdId Command ID corresponding to the request.
+ * @param bucketsScanned Bitset where each bit indicates if the bucket with
+ * that index (starting at 0) was scanned.
+ * @param result Full scan result for an AP.
+ */
+ void onBackgroundFullScanResult(int cmdId, int bucketsScanned, ScanResult result);
+
+ /**
+ * Callback indicating that an ongoing background scan request has failed.
+ * The background scan needs to be restarted to continue scanning.
+ *
+ * @param cmdId Command ID corresponding to the request.
+ */
+ void onBackgroundScanFailure(int cmdId);
+
+ /**
+ * Called when the |StaBackgroundScanBucketParameters.eventReportScheme| flags
+ * for at least one bucket that was just scanned was |REPORT_EVENTS_EACH_SCAN|,
+ * or one of the configured thresholds was breached.
+ *
+ * @param cmdId Command ID corresponding to the request.
+ * @param scanDatas List of scan results for all APs seen since the last callback.
+ */
+ void onBackgroundScanResults(int cmdId, WifiScanner.ScanData[] scanDatas);
+
+ /**
+ * Called when the RSSI of the currently connected access point goes beyond the
+ * thresholds set via
+ * {@link IWifiStaIface#startRssiMonitoring(int, int, int)}
+ *
+ * @param cmdId Command ID corresponding to the request.
+ * @param currBssid BSSID of the currently connected access point.
+ * @param currRssi RSSI of the currently connected access point.
+ */
+ void onRssiThresholdBreached(int cmdId, byte[] currBssid, int currRssi);
+ }
+
+ public WifiStaIface(@NonNull android.hardware.wifi.V1_0.IWifiStaIface staIface,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ mWifiStaIface = createWifiStaIfaceHidlImplMockable(staIface, context, ssidTranslator);
+ }
+
+ public WifiStaIface(@NonNull android.hardware.wifi.IWifiStaIface staIface,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ mWifiStaIface = createWifiStaIfaceAidlImplMockable(staIface, context, ssidTranslator);
+ }
+
+ protected WifiStaIfaceHidlImpl createWifiStaIfaceHidlImplMockable(
+ android.hardware.wifi.V1_0.IWifiStaIface staIface, @NonNull Context context,
+ @NonNull SsidTranslator ssidTranslator) {
+ return new WifiStaIfaceHidlImpl(staIface, context, ssidTranslator);
+ }
+
+ protected WifiStaIfaceAidlImpl createWifiStaIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiStaIface staIface, @NonNull Context context,
+ @NonNull SsidTranslator ssidTranslator) {
+ return new WifiStaIfaceAidlImpl(staIface, context, ssidTranslator);
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiStaIface == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiStaIface is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#registerFrameworkCallback(Callback)}
+ */
+ public boolean registerFrameworkCallback(Callback callback) {
+ return validateAndCall("registerFrameworkCallback", false,
+ () -> mWifiStaIface.registerFrameworkCallback(callback));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getName()}
+ */
+ @Override
+ @Nullable
+ public String getName() {
+ return validateAndCall("getName", null,
+ () -> mWifiStaIface.getName());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#configureRoaming(List, List)}
+ */
+ public boolean configureRoaming(List<MacAddress> bssidBlocklist,
+ List<byte[]> ssidAllowlist) {
+ return validateAndCall("configureRoaming", false,
+ () -> mWifiStaIface.configureRoaming(bssidBlocklist, ssidAllowlist));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#enableLinkLayerStatsCollection(boolean)}
+ */
+ public boolean enableLinkLayerStatsCollection(boolean debug) {
+ return validateAndCall("enableLinkLayerStatsCollection", false,
+ () -> mWifiStaIface.enableLinkLayerStatsCollection(debug));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#enableNdOffload(boolean)}
+ */
+ public boolean enableNdOffload(boolean enable) {
+ return validateAndCall("enableNdOffload", false,
+ () -> mWifiStaIface.enableNdOffload(enable));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getApfPacketFilterCapabilities()}
+ */
+ public ApfCapabilities getApfPacketFilterCapabilities() {
+ return validateAndCall("getApfPacketFilterCapabilities", new ApfCapabilities(0, 0, 0),
+ () -> mWifiStaIface.getApfPacketFilterCapabilities());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getBackgroundScanCapabilities()}
+ */
+ @Nullable
+ public WifiNative.ScanCapabilities getBackgroundScanCapabilities() {
+ return validateAndCall("getBackgroundScanCapabilities", null,
+ () -> mWifiStaIface.getBackgroundScanCapabilities());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getCapabilities()}
+ */
+ public long getCapabilities() {
+ return validateAndCall("getCapabilities", 0L,
+ () -> mWifiStaIface.getCapabilities());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getDebugRxPacketFates()}
+ */
+ public List<WifiNative.RxFateReport> getDebugRxPacketFates() {
+ return validateAndCall("getDebugRxPacketFates", new ArrayList<>(),
+ () -> mWifiStaIface.getDebugRxPacketFates());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getDebugTxPacketFates()}
+ */
+ public List<WifiNative.TxFateReport> getDebugTxPacketFates() {
+ return validateAndCall("getDebugTxPacketFates", new ArrayList<>(),
+ () -> mWifiStaIface.getDebugTxPacketFates());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getFactoryMacAddress()}
+ */
+ @Nullable
+ public MacAddress getFactoryMacAddress() {
+ return validateAndCall("getFactoryMacAddress", null,
+ () -> mWifiStaIface.getFactoryMacAddress());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getLinkLayerStats()}
+ */
+ @Nullable
+ public WifiLinkLayerStats getLinkLayerStats() {
+ return validateAndCall("getLinkLayerStats", null,
+ () -> mWifiStaIface.getLinkLayerStats());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getRoamingCapabilities()}
+ */
+ @Nullable
+ public WifiNative.RoamingCapabilities getRoamingCapabilities() {
+ return validateAndCall("getRoamingCapabilities", null,
+ () -> mWifiStaIface.getRoamingCapabilities());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#installApfPacketFilter(byte[])}
+ */
+ public boolean installApfPacketFilter(byte[] program) {
+ return validateAndCall("installApfPacketFilter", false,
+ () -> mWifiStaIface.installApfPacketFilter(program));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#readApfPacketFilterData()}
+ */
+ @Nullable
+ public byte[] readApfPacketFilterData() {
+ return validateAndCall("readApfPacketFilterData", null,
+ () -> mWifiStaIface.readApfPacketFilterData());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#setMacAddress(MacAddress)}
+ */
+ public boolean setMacAddress(MacAddress mac) {
+ return validateAndCall("setMacAddress", false,
+ () -> mWifiStaIface.setMacAddress(mac));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#setRoamingState(int)}
+ */
+ public @WifiNative.RoamingEnableStatus int setRoamingState(
+ @WifiNative.RoamingEnableState int state) {
+ return validateAndCall("setRoamingState", SET_ROAMING_STATE_FAILURE_CODE,
+ () -> mWifiStaIface.setRoamingState(state));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#setScanMode(boolean)}
+ */
+ public boolean setScanMode(boolean enable) {
+ return validateAndCall("setScanMode", false,
+ () -> mWifiStaIface.setScanMode(enable));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#startBackgroundScan(int, StaBackgroundScanParameters)}
+ */
+ public boolean startBackgroundScan(int cmdId, StaBackgroundScanParameters params) {
+ return validateAndCall("startBackgroundScan", false,
+ () -> mWifiStaIface.startBackgroundScan(cmdId, params));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#startDebugPacketFateMonitoring()}
+ */
+ public boolean startDebugPacketFateMonitoring() {
+ return validateAndCall("startDebugPacketFateMonitoring", false,
+ () -> mWifiStaIface.startDebugPacketFateMonitoring());
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#startRssiMonitoring(int, int, int)}
+ */
+ public boolean startRssiMonitoring(int cmdId, int maxRssi, int minRssi) {
+ return validateAndCall("startRssiMonitoring", false,
+ () -> mWifiStaIface.startRssiMonitoring(cmdId, maxRssi, minRssi));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#startSendingKeepAlivePackets(int, byte[], int,
+ * MacAddress, MacAddress, int)}
+ */
+ public boolean startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType,
+ MacAddress srcAddress, MacAddress dstAddress, int periodInMs) {
+ return validateAndCall("startSendingKeepAlivePackets", false,
+ () -> mWifiStaIface.startSendingKeepAlivePackets(cmdId, ipPacketData, etherType,
+ srcAddress, dstAddress, periodInMs));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#stopBackgroundScan(int)}
+ */
+ public boolean stopBackgroundScan(int cmdId) {
+ return validateAndCall("stopBackgroundScan", false,
+ () -> mWifiStaIface.stopBackgroundScan(cmdId));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#stopRssiMonitoring(int)}
+ */
+ public boolean stopRssiMonitoring(int cmdId) {
+ return validateAndCall("stopRssiMonitoring", false,
+ () -> mWifiStaIface.stopRssiMonitoring(cmdId));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#stopSendingKeepAlivePackets(int)}
+ */
+ public boolean stopSendingKeepAlivePackets(int cmdId) {
+ return validateAndCall("stopSendingKeepAlivePackets", false,
+ () -> mWifiStaIface.stopSendingKeepAlivePackets(cmdId));
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java
new file mode 100644
index 0000000000..90e9f797f2
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java
@@ -0,0 +1,1203 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.wifi.IWifiStaIfaceEventCallback;
+import android.hardware.wifi.Ssid;
+import android.hardware.wifi.StaApfPacketFilterCapabilities;
+import android.hardware.wifi.StaBackgroundScanBucketEventReportSchemeMask;
+import android.hardware.wifi.StaBackgroundScanBucketParameters;
+import android.hardware.wifi.StaBackgroundScanCapabilities;
+import android.hardware.wifi.StaBackgroundScanParameters;
+import android.hardware.wifi.StaLinkLayerIfaceStats;
+import android.hardware.wifi.StaLinkLayerRadioStats;
+import android.hardware.wifi.StaLinkLayerStats;
+import android.hardware.wifi.StaPeerInfo;
+import android.hardware.wifi.StaRateStat;
+import android.hardware.wifi.StaRoamingCapabilities;
+import android.hardware.wifi.StaRoamingConfig;
+import android.hardware.wifi.StaRoamingState;
+import android.hardware.wifi.StaScanData;
+import android.hardware.wifi.StaScanDataFlagMask;
+import android.hardware.wifi.StaScanResult;
+import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiChannelStats;
+import android.hardware.wifi.WifiDebugPacketFateFrameType;
+import android.hardware.wifi.WifiDebugRxPacketFate;
+import android.hardware.wifi.WifiDebugRxPacketFateReport;
+import android.hardware.wifi.WifiDebugTxPacketFate;
+import android.hardware.wifi.WifiDebugTxPacketFateReport;
+import android.hardware.wifi.WifiStatusCode;
+import android.net.MacAddress;
+import android.net.apf.ApfCapabilities;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiScanner;
+import android.net.wifi.WifiSsid;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.SsidTranslator;
+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.NativeUtil;
+import com.android.wifi.resources.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * AIDL implementation of the IWifiStaIface interface.
+ */
+public class WifiStaIfaceAidlImpl implements IWifiStaIface {
+ private static final String TAG = "WifiStaIfaceAidlImpl";
+ private android.hardware.wifi.IWifiStaIface mWifiStaIface;
+ private IWifiStaIfaceEventCallback mHalCallback;
+ private WifiStaIface.Callback mFrameworkCallback;
+ private final Object mLock = new Object();
+ private String mIfaceName;
+ private Context mContext;
+ private SsidTranslator mSsidTranslator;
+
+ public WifiStaIfaceAidlImpl(@NonNull android.hardware.wifi.IWifiStaIface staIface,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ mWifiStaIface = staIface;
+ mContext = context;
+ mSsidTranslator = ssidTranslator;
+ mHalCallback = new StaIfaceEventCallback();
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#registerFrameworkCallback(WifiStaIface.Callback)}
+ */
+ @Override
+ public boolean registerFrameworkCallback(WifiStaIface.Callback callback) {
+ final String methodStr = "registerFrameworkCallback";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ if (mFrameworkCallback != null) {
+ Log.e(TAG, "Framework callback is already registered");
+ return false;
+ } else if (callback == null) {
+ Log.e(TAG, "Cannot register a null callback");
+ return false;
+ }
+
+ try {
+ mWifiStaIface.registerEventCallback(mHalCallback);
+ mFrameworkCallback = callback;
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getName()}
+ */
+ @Override
+ @Nullable
+ public String getName() {
+ final String methodStr = "getName";
+ synchronized (mLock) {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ if (mIfaceName != null) return mIfaceName;
+ try {
+ String ifaceName = mWifiStaIface.getName();
+ mIfaceName = ifaceName;
+ return mIfaceName;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#configureRoaming(List, List)}
+ */
+ @Override
+ public boolean configureRoaming(List<MacAddress> bssidBlocklist,
+ List<byte[]> ssidAllowlist) {
+ final String methodStr = "configureRoaming";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ StaRoamingConfig config =
+ frameworkToHalStaRoamingConfig(bssidBlocklist, ssidAllowlist);
+ mWifiStaIface.configureRoaming(config);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#enableLinkLayerStatsCollection(boolean)}
+ */
+ @Override
+ public boolean enableLinkLayerStatsCollection(boolean debug) {
+ final String methodStr = "enableLinkLayerStatsCollection";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.enableLinkLayerStatsCollection(debug);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#enableNdOffload(boolean)}
+ */
+ @Override
+ public boolean enableNdOffload(boolean enable) {
+ final String methodStr = "enableNdOffload";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.enableNdOffload(enable);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getApfPacketFilterCapabilities()}
+ */
+ @Override
+ public ApfCapabilities getApfPacketFilterCapabilities() {
+ final String methodStr = "getApfPacketFilterCapabilities";
+ final ApfCapabilities defaultVal = new ApfCapabilities(0, 0, 0);
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return defaultVal;
+ StaApfPacketFilterCapabilities halCaps =
+ mWifiStaIface.getApfPacketFilterCapabilities();
+ return new ApfCapabilities(
+ halCaps.version, // apfVersionSupported
+ halCaps.maxLength, // maximumApfProgramSize
+ android.system.OsConstants.ARPHRD_ETHER); // apfPacketFormat
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return defaultVal;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getBackgroundScanCapabilities()}
+ */
+ @Override
+ @Nullable
+ public WifiNative.ScanCapabilities getBackgroundScanCapabilities() {
+ final String methodStr = "getBackgroundScanCapabilities";
+ synchronized (mLock) {
+ try {
+ StaBackgroundScanCapabilities halCaps =
+ mWifiStaIface.getBackgroundScanCapabilities();
+ WifiNative.ScanCapabilities frameworkCaps = new WifiNative.ScanCapabilities();
+ frameworkCaps.max_scan_cache_size = halCaps.maxCacheSize;
+ frameworkCaps.max_ap_cache_per_scan = halCaps.maxApCachePerScan;
+ frameworkCaps.max_scan_buckets = halCaps.maxBuckets;
+ frameworkCaps.max_rssi_sample_size = 0;
+ frameworkCaps.max_scan_reporting_threshold = halCaps.maxReportingThreshold;
+ return frameworkCaps;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getCapabilities()}
+ */
+ @Override
+ public long getCapabilities() {
+ final String methodStr = "getCapabilities";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return 0L;
+ long halCaps = mWifiStaIface.getCapabilities();
+ return halToFrameworkStaIfaceCapability(halCaps);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return 0L;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getDebugRxPacketFates()}
+ */
+ @Override
+ public List<WifiNative.RxFateReport> getDebugRxPacketFates() {
+ final String methodStr = "getDebugRxPacketFates";
+ List<WifiNative.RxFateReport> fateReports = new ArrayList<>();
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return fateReports;
+ WifiDebugRxPacketFateReport[] halReports = mWifiStaIface.getDebugRxPacketFates();
+ for (WifiDebugRxPacketFateReport report : halReports) {
+ if (fateReports.size() >= WifiLoggerHal.MAX_FATE_LOG_LEN) break;
+ byte code = halToFrameworkRxPktFate(report.fate);
+ long us = report.frameInfo.driverTimestampUsec;
+ byte type = halToFrameworkPktFateFrameType(report.frameInfo.frameType);
+ byte[] frame = report.frameInfo.frameContent;
+ fateReports.add(new WifiNative.RxFateReport(code, us, type, frame));
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ handleIllegalArgumentException(e, methodStr);
+ return new ArrayList<>();
+ }
+ return fateReports;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getDebugTxPacketFates()}
+ */
+ @Override
+ public List<WifiNative.TxFateReport> getDebugTxPacketFates() {
+ final String methodStr = "getDebugTxPacketFates";
+ List<WifiNative.TxFateReport> fateReports = new ArrayList<>();
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return fateReports;
+ WifiDebugTxPacketFateReport[] halReports = mWifiStaIface.getDebugTxPacketFates();
+ for (WifiDebugTxPacketFateReport report : halReports) {
+ if (fateReports.size() >= WifiLoggerHal.MAX_FATE_LOG_LEN) break;
+ byte code = halToFrameworkTxPktFate(report.fate);
+ long us = report.frameInfo.driverTimestampUsec;
+ byte type = halToFrameworkPktFateFrameType(report.frameInfo.frameType);
+ byte[] frame = report.frameInfo.frameContent;
+ fateReports.add(new WifiNative.TxFateReport(code, us, type, frame));
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ handleIllegalArgumentException(e, methodStr);
+ return new ArrayList<>();
+ }
+ return fateReports;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getFactoryMacAddress()}
+ */
+ @Override
+ @Nullable
+ public MacAddress getFactoryMacAddress() {
+ final String methodStr = "getFactoryMacAddress";
+ byte[] macBytes;
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ macBytes = mWifiStaIface.getFactoryMacAddress();
+ return MacAddress.fromBytes(macBytes);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Invalid MAC address received: " + e);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getLinkLayerStats()}
+ */
+ @Override
+ @Nullable
+ public WifiLinkLayerStats getLinkLayerStats() {
+ final String methodStr = "getLinkLayerStats";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ StaLinkLayerStats halStats = mWifiStaIface.getLinkLayerStats();
+ return halToFrameworkLinkLayerStats(halStats);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getRoamingCapabilities()}
+ */
+ @Override
+ @Nullable
+ public WifiNative.RoamingCapabilities getRoamingCapabilities() {
+ final String methodStr = "getRoamingCapabilities";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ StaRoamingCapabilities halCaps = mWifiStaIface.getRoamingCapabilities();
+ WifiNative.RoamingCapabilities out = new WifiNative.RoamingCapabilities();
+ out.maxBlocklistSize = halCaps.maxBlocklistSize;
+ out.maxAllowlistSize = halCaps.maxAllowlistSize;
+ return out;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#installApfPacketFilter(byte[])}
+ */
+ @Override
+ public boolean installApfPacketFilter(byte[] program) {
+ final String methodStr = "installApfPacketFilter";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.installApfPacketFilter(program);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#readApfPacketFilterData()}
+ */
+ @Override
+ @Nullable
+ public byte[] readApfPacketFilterData() {
+ final String methodStr = "readApfPacketFilterData";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return null;
+ return mWifiStaIface.readApfPacketFilterData();
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#setMacAddress(MacAddress)}
+ */
+ @Override
+ public boolean setMacAddress(MacAddress mac) {
+ final String methodStr = "setMacAddress";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.setMacAddress(mac.toByteArray());
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#setRoamingState(int)}
+ */
+ @Override public @WifiNative.RoamingEnableStatus int setRoamingState(
+ @WifiNative.RoamingEnableState int state) {
+ final String methodStr = "setRoamingState";
+ final int errorCode = WifiStaIface.SET_ROAMING_STATE_FAILURE_CODE;
+ final byte halState = frameworkToHalStaRoamingState(state);
+ if (halState == -1) return errorCode;
+
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return errorCode;
+ mWifiStaIface.setRoamingState(halState);
+ return WifiNative.SET_FIRMWARE_ROAMING_SUCCESS;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == WifiStatusCode.ERROR_BUSY) {
+ return WifiNative.SET_FIRMWARE_ROAMING_BUSY;
+ }
+ handleServiceSpecificException(e, methodStr);
+ }
+ return errorCode;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#setScanMode(boolean)}
+ */
+ @Override
+ public boolean setScanMode(boolean enable) {
+ final String methodStr = "setScanMode";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.setScanMode(enable);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for
+ * {@link IWifiStaIface#startBackgroundScan(int, WifiStaIface.StaBackgroundScanParameters)}
+ */
+ @Override
+ public boolean startBackgroundScan(int cmdId, WifiStaIface.StaBackgroundScanParameters params) {
+ final String methodStr = "startBackgroundScan";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ StaBackgroundScanParameters halParams = frameworkToHalBackgroundScanParams(params);
+ mWifiStaIface.startBackgroundScan(cmdId, halParams);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ } catch (IllegalArgumentException e) {
+ handleIllegalArgumentException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#startDebugPacketFateMonitoring()}
+ */
+ @Override
+ public boolean startDebugPacketFateMonitoring() {
+ final String methodStr = "startDebugPacketFateMonitoring";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.startDebugPacketFateMonitoring();
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for
+ * {@link IWifiStaIface#startRssiMonitoring(int, int, int)}
+ */
+ @Override
+ public boolean startRssiMonitoring(int cmdId, int maxRssi, int minRssi) {
+ final String methodStr = "startRssiMonitoring";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.startRssiMonitoring(cmdId, maxRssi, minRssi);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#startSendingKeepAlivePackets(int, byte[], int,
+ * MacAddress, MacAddress, int)}
+ */
+ @Override
+ public boolean startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType,
+ MacAddress srcAddress, MacAddress dstAddress, int periodInMs) {
+ final String methodStr = "startSendingKeepAlivePackets";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.startSendingKeepAlivePackets(cmdId, ipPacketData, (char) etherType,
+ srcAddress.toByteArray(), dstAddress.toByteArray(), periodInMs);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#stopBackgroundScan(int)}
+ */
+ @Override
+ public boolean stopBackgroundScan(int cmdId) {
+ final String methodStr = "stopBackgroundScan";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.stopBackgroundScan(cmdId);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#stopRssiMonitoring(int)}
+ */
+ @Override
+ public boolean stopRssiMonitoring(int cmdId) {
+ final String methodStr = "stopRssiMonitoring";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.stopRssiMonitoring(cmdId);
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodStr);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#stopSendingKeepAlivePackets(int)}
+ */
+ @Override
+ public boolean stopSendingKeepAlivePackets(int cmdId) {
+ final String methodStr = "stopSendingKeepAlivePackets";
+ synchronized (mLock) {
+ try {
+ if (!checkIfaceAndLogFailure(methodStr)) return false;
+ mWifiStaIface.stopSendingKeepAlivePackets(cmdId);
+ 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) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onBackgroundScanFailure(cmdId);
+ }
+
+ @Override
+ public void onBackgroundFullScanResult(int cmdId, int bucketsScanned,
+ StaScanResult result) {
+ if (mFrameworkCallback == null) return;
+ ScanResult frameworkScanResult = halToFrameworkScanResult(result);
+ if (frameworkScanResult == null) {
+ Log.e(TAG, "Unable to convert scan result from HAL to framework");
+ return;
+ }
+ mFrameworkCallback.onBackgroundFullScanResult(cmdId, bucketsScanned,
+ frameworkScanResult);
+ }
+
+ @Override
+ public void onBackgroundScanResults(int cmdId, StaScanData[] scanDatas) {
+ if (mFrameworkCallback == null) return;
+ WifiScanner.ScanData[] frameworkScanDatas = halToFrameworkScanDatas(cmdId, scanDatas);
+ mFrameworkCallback.onBackgroundScanResults(cmdId, frameworkScanDatas);
+ }
+
+ @Override
+ public void onRssiThresholdBreached(int cmdId, byte[/* 6 */] currBssid, int currRssi) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onRssiThresholdBreached(cmdId, currBssid, currRssi);
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return IWifiStaIfaceEventCallback.HASH;
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return IWifiStaIfaceEventCallback.VERSION;
+ }
+ }
+
+
+ // Utilities
+
+ // Only sets the fields of ScanResult used by Gscan clients.
+ private ScanResult halToFrameworkScanResult(StaScanResult 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.rssi;
+ frameworkScanResult.frequency = scanResult.frequency;
+ frameworkScanResult.timestamp = scanResult.timeStampInUs;
+ return frameworkScanResult;
+ }
+
+ private ScanResult[] aidlToFrameworkScanResults(StaScanResult[] scanResults) {
+ if (scanResults == null || scanResults.length == 0) return new ScanResult[0];
+ ScanResult[] frameworkScanResults = new ScanResult[scanResults.length];
+ int i = 0;
+ for (StaScanResult scanResult : scanResults) {
+ ScanResult frameworkScanResult = halToFrameworkScanResult(scanResult);
+ if (frameworkScanResult == null) {
+ Log.e(TAG, "halToFrameworkScanResults: unable to convert hidl to framework "
+ + "scan result!");
+ continue;
+ }
+ frameworkScanResults[i++] = frameworkScanResult;
+ }
+ return frameworkScanResults;
+ }
+
+ private static int halToFrameworkScanDataFlags(int flag) {
+ if (flag == StaScanDataFlagMask.INTERRUPTED) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ private WifiScanner.ScanData[] halToFrameworkScanDatas(int cmdId, StaScanData[] scanDatas) {
+ if (scanDatas == null || scanDatas.length == 0) return new WifiScanner.ScanData[0];
+ WifiScanner.ScanData[] frameworkScanDatas = new WifiScanner.ScanData[scanDatas.length];
+ int i = 0;
+ for (StaScanData scanData : scanDatas) {
+ int flags = halToFrameworkScanDataFlags(scanData.flags);
+ ScanResult[] frameworkScanResults = aidlToFrameworkScanResults(scanData.results);
+ frameworkScanDatas[i++] =
+ new WifiScanner.ScanData(cmdId, flags, scanData.bucketsScanned,
+ WifiScanner.WIFI_BAND_UNSPECIFIED, frameworkScanResults);
+ }
+ return frameworkScanDatas;
+ }
+
+ private static StaRoamingConfig frameworkToHalStaRoamingConfig(List<MacAddress> bssidBlocklist,
+ List<byte[]> ssidAllowlist) {
+ StaRoamingConfig config = new StaRoamingConfig();
+ config.bssidBlocklist = new android.hardware.wifi.MacAddress[bssidBlocklist.size()];
+ config.ssidAllowlist = new Ssid[ssidAllowlist.size()];
+ for (int i = 0; i < bssidBlocklist.size(); i++) {
+ android.hardware.wifi.MacAddress mac = new android.hardware.wifi.MacAddress();
+ mac.data = bssidBlocklist.get(i).toByteArray();
+ config.bssidBlocklist[i] = mac;
+ }
+ for (int i = 0; i < ssidAllowlist.size(); i++) {
+ Ssid ssid = new Ssid();
+ ssid.data = ssidAllowlist.get(i);
+ config.ssidAllowlist[i] = ssid;
+ }
+ return config;
+ }
+
+ private static byte halToFrameworkPktFateFrameType(int type) throws IllegalArgumentException {
+ switch (type) {
+ case WifiDebugPacketFateFrameType.UNKNOWN:
+ return WifiLoggerHal.FRAME_TYPE_UNKNOWN;
+ case WifiDebugPacketFateFrameType.ETHERNET_II:
+ return WifiLoggerHal.FRAME_TYPE_ETHERNET_II;
+ case WifiDebugPacketFateFrameType.MGMT_80211:
+ return WifiLoggerHal.FRAME_TYPE_80211_MGMT;
+ default:
+ throw new IllegalArgumentException("bad " + type);
+ }
+ }
+
+ private static byte halToFrameworkRxPktFate(int type) throws IllegalArgumentException {
+ switch (type) {
+ case WifiDebugRxPacketFate.SUCCESS:
+ return WifiLoggerHal.RX_PKT_FATE_SUCCESS;
+ case WifiDebugRxPacketFate.FW_QUEUED:
+ return WifiLoggerHal.RX_PKT_FATE_FW_QUEUED;
+ case WifiDebugRxPacketFate.FW_DROP_FILTER:
+ return WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER;
+ case WifiDebugRxPacketFate.FW_DROP_INVALID:
+ return WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID;
+ case WifiDebugRxPacketFate.FW_DROP_NOBUFS:
+ return WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS;
+ case WifiDebugRxPacketFate.FW_DROP_OTHER:
+ return WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER;
+ case WifiDebugRxPacketFate.DRV_QUEUED:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED;
+ case WifiDebugRxPacketFate.DRV_DROP_FILTER:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER;
+ case WifiDebugRxPacketFate.DRV_DROP_INVALID:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID;
+ case WifiDebugRxPacketFate.DRV_DROP_NOBUFS:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS;
+ case WifiDebugRxPacketFate.DRV_DROP_OTHER:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER;
+ default:
+ throw new IllegalArgumentException("bad " + type);
+ }
+ }
+
+ private static byte halToFrameworkTxPktFate(int type) throws IllegalArgumentException {
+ switch (type) {
+ case WifiDebugTxPacketFate.ACKED:
+ return WifiLoggerHal.TX_PKT_FATE_ACKED;
+ case WifiDebugTxPacketFate.SENT:
+ return WifiLoggerHal.TX_PKT_FATE_SENT;
+ case WifiDebugTxPacketFate.FW_QUEUED:
+ return WifiLoggerHal.TX_PKT_FATE_FW_QUEUED;
+ case WifiDebugTxPacketFate.FW_DROP_INVALID:
+ return WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID;
+ case WifiDebugTxPacketFate.FW_DROP_NOBUFS:
+ return WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS;
+ case WifiDebugTxPacketFate.FW_DROP_OTHER:
+ return WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER;
+ case WifiDebugTxPacketFate.DRV_QUEUED:
+ return WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED;
+ case WifiDebugTxPacketFate.DRV_DROP_INVALID:
+ return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID;
+ case WifiDebugTxPacketFate.DRV_DROP_NOBUFS:
+ return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS;
+ case WifiDebugTxPacketFate.DRV_DROP_OTHER:
+ return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER;
+ default:
+ throw new IllegalArgumentException("bad " + type);
+ }
+ }
+
+ private static boolean hasCapability(long capabilities, long desiredCapability) {
+ return (capabilities & desiredCapability) != 0;
+ }
+
+ @VisibleForTesting
+ protected static long halToFrameworkStaIfaceCapability(long caps) {
+ long features = 0;
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.HOTSPOT)) {
+ features |= WifiManager.WIFI_FEATURE_PASSPOINT;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN)) {
+ features |= WifiManager.WIFI_FEATURE_SCANNER;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.PNO)) {
+ features |= WifiManager.WIFI_FEATURE_PNO;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.TDLS)) {
+ features |= WifiManager.WIFI_FEATURE_TDLS;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.TDLS_OFFCHANNEL)) {
+ features |= WifiManager.WIFI_FEATURE_TDLS_OFFCHANNEL;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS)) {
+ features |= WifiManager.WIFI_FEATURE_LINK_LAYER_STATS;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.RSSI_MONITOR)) {
+ features |= WifiManager.WIFI_FEATURE_RSSI_MONITOR;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.KEEP_ALIVE)) {
+ features |= WifiManager.WIFI_FEATURE_MKEEP_ALIVE;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.ND_OFFLOAD)) {
+ features |= WifiManager.WIFI_FEATURE_CONFIG_NDO;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.CONTROL_ROAMING)) {
+ features |= WifiManager.WIFI_FEATURE_CONTROL_ROAMING;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.PROBE_IE_ALLOWLIST)) {
+ features |= WifiManager.WIFI_FEATURE_IE_WHITELIST;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask.SCAN_RAND)) {
+ features |= WifiManager.WIFI_FEATURE_SCAN_RAND;
+ }
+ return features;
+ }
+
+ @VisibleForTesting
+ WifiLinkLayerStats halToFrameworkLinkLayerStats(StaLinkLayerStats stats) {
+ if (stats == null) return null;
+ WifiLinkLayerStats out = new WifiLinkLayerStats();
+ setIfaceStats(out, stats.iface);
+ setRadioStats(out, stats.radios);
+ out.timeStampInMs = stats.timeStampInMs;
+ out.version = WifiLinkLayerStats.V1_5; // only used in unit tests, keep latest HIDL
+ return out;
+ }
+
+ private static void setIfaceStats(WifiLinkLayerStats stats, StaLinkLayerIfaceStats iface) {
+ if (iface == null) return;
+ stats.beacon_rx = iface.beaconRx;
+ stats.rssi_mgmt = iface.avgRssiMgmt;
+ // Statistics are broken out by Wireless Multimedia Extensions categories
+ // WME Best Effort Access Category
+ stats.rxmpdu_be = iface.wmeBePktStats.rxMpdu;
+ stats.txmpdu_be = iface.wmeBePktStats.txMpdu;
+ stats.lostmpdu_be = iface.wmeBePktStats.lostMpdu;
+ stats.retries_be = iface.wmeBePktStats.retries;
+ // WME Background Access Category
+ stats.rxmpdu_bk = iface.wmeBkPktStats.rxMpdu;
+ stats.txmpdu_bk = iface.wmeBkPktStats.txMpdu;
+ stats.lostmpdu_bk = iface.wmeBkPktStats.lostMpdu;
+ stats.retries_bk = iface.wmeBkPktStats.retries;
+ // WME Video Access Category
+ stats.rxmpdu_vi = iface.wmeViPktStats.rxMpdu;
+ stats.txmpdu_vi = iface.wmeViPktStats.txMpdu;
+ stats.lostmpdu_vi = iface.wmeViPktStats.lostMpdu;
+ stats.retries_vi = iface.wmeViPktStats.retries;
+ // WME Voice Access Category
+ stats.rxmpdu_vo = iface.wmeVoPktStats.rxMpdu;
+ stats.txmpdu_vo = iface.wmeVoPktStats.txMpdu;
+ stats.lostmpdu_vo = iface.wmeVoPktStats.lostMpdu;
+ stats.retries_vo = iface.wmeVoPktStats.retries;
+ stats.timeSliceDutyCycleInPercent = iface.timeSliceDutyCycleInPercent;
+ // WME Best Effort Access Category
+ stats.contentionTimeMinBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesBe = iface.wmeBeContentionTimeStats.contentionNumSamples;
+ // WME Background Access Category
+ stats.contentionTimeMinBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesBk = iface.wmeBkContentionTimeStats.contentionNumSamples;
+ // WME Video Access Category
+ stats.contentionTimeMinViInUsec = iface.wmeViContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxViInUsec = iface.wmeViContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgViInUsec = iface.wmeViContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesVi = iface.wmeViContentionTimeStats.contentionNumSamples;
+ // WME Voice Access Category
+ stats.contentionTimeMinVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesVo = iface.wmeVoContentionTimeStats.contentionNumSamples;
+ // Peer information statistics
+ stats.peerInfo = new WifiLinkLayerStats.PeerInfo[iface.peers.length];
+ for (int i = 0; i < stats.peerInfo.length; i++) {
+ WifiLinkLayerStats.PeerInfo peer = new WifiLinkLayerStats.PeerInfo();
+ StaPeerInfo staPeerInfo = iface.peers[i];
+ peer.staCount = (short) staPeerInfo.staCount;
+ peer.chanUtil = (short) staPeerInfo.chanUtil;
+ WifiLinkLayerStats.RateStat[] rateStats =
+ new WifiLinkLayerStats.RateStat[staPeerInfo.rateStats.length];
+ for (int j = 0; j < staPeerInfo.rateStats.length; j++) {
+ rateStats[j] = new WifiLinkLayerStats.RateStat();
+ StaRateStat staRateStat = staPeerInfo.rateStats[j];
+ rateStats[j].preamble = staRateStat.rateInfo.preamble;
+ rateStats[j].nss = staRateStat.rateInfo.nss;
+ rateStats[j].bw = staRateStat.rateInfo.bw;
+ rateStats[j].rateMcsIdx = staRateStat.rateInfo.rateMcsIdx;
+ rateStats[j].bitRateInKbps = staRateStat.rateInfo.bitRateInKbps;
+ rateStats[j].txMpdu = staRateStat.txMpdu;
+ rateStats[j].rxMpdu = staRateStat.rxMpdu;
+ rateStats[j].mpduLost = staRateStat.mpduLost;
+ rateStats[j].retries = staRateStat.retries;
+ }
+ peer.rateStats = rateStats;
+ stats.peerInfo[i] = peer;
+ }
+ }
+
+ private void setRadioStats(WifiLinkLayerStats stats, StaLinkLayerRadioStats[] radios) {
+ if (radios == null) return;
+ int radioIndex = 0;
+ stats.radioStats = new WifiLinkLayerStats.RadioStat[radios.length];
+ for (StaLinkLayerRadioStats radioStats : radios) {
+ WifiLinkLayerStats.RadioStat radio = new WifiLinkLayerStats.RadioStat();
+ setFrameworkPerRadioStatsFromAidl(radio, radioStats);
+ stats.radioStats[radioIndex] = radio;
+ aggregateFrameworkRadioStatsFromAidl(radioIndex, stats, radioStats);
+ radioIndex++;
+ }
+ }
+
+ private static void setFrameworkPerRadioStatsFromAidl(WifiLinkLayerStats.RadioStat radio,
+ StaLinkLayerRadioStats aidlRadioStats) {
+ radio.radio_id = aidlRadioStats.radioId;
+ radio.on_time = aidlRadioStats.onTimeInMs;
+ radio.tx_time = aidlRadioStats.txTimeInMs;
+ radio.rx_time = aidlRadioStats.rxTimeInMs;
+ radio.on_time_scan = aidlRadioStats.onTimeInMsForScan;
+ radio.on_time_nan_scan = aidlRadioStats.onTimeInMsForNanScan;
+ radio.on_time_background_scan = aidlRadioStats.onTimeInMsForBgScan;
+ radio.on_time_roam_scan = aidlRadioStats.onTimeInMsForRoamScan;
+ radio.on_time_pno_scan = aidlRadioStats.onTimeInMsForPnoScan;
+ radio.on_time_hs20_scan = aidlRadioStats.onTimeInMsForHs20Scan;
+ /* Copy list of channel stats */
+ for (WifiChannelStats channelStats : aidlRadioStats.channelStats) {
+ WifiLinkLayerStats.ChannelStats channelStatsEntry =
+ new WifiLinkLayerStats.ChannelStats();
+ channelStatsEntry.frequency = channelStats.channel.centerFreq;
+ channelStatsEntry.radioOnTimeMs = channelStats.onTimeInMs;
+ channelStatsEntry.ccaBusyTimeMs = channelStats.ccaBusyTimeInMs;
+ radio.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
+ }
+ }
+
+ private void aggregateFrameworkRadioStatsFromAidl(int radioIndex,
+ WifiLinkLayerStats stats, StaLinkLayerRadioStats aidlRadioStats) {
+ if (!mContext.getResources()
+ .getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled)
+ && radioIndex > 0) {
+ return;
+ }
+ // Aggregate the radio stats from all the radios
+ stats.on_time += aidlRadioStats.onTimeInMs;
+ stats.tx_time += aidlRadioStats.txTimeInMs;
+ // Aggregate tx_time_per_level based on the assumption that the length of
+ // txTimeInMsPerLevel is the same across all radios. So txTimeInMsPerLevel on other
+ // radios at array indices greater than the length of first radio will be dropped.
+ if (stats.tx_time_per_level == null) {
+ stats.tx_time_per_level = new int[aidlRadioStats.txTimeInMsPerLevel.length];
+ }
+ for (int i = 0; i < aidlRadioStats.txTimeInMsPerLevel.length
+ && i < stats.tx_time_per_level.length; i++) {
+ stats.tx_time_per_level[i] += aidlRadioStats.txTimeInMsPerLevel[i];
+ }
+ stats.rx_time += aidlRadioStats.rxTimeInMs;
+ stats.on_time_scan += aidlRadioStats.onTimeInMsForScan;
+ stats.on_time_nan_scan += aidlRadioStats.onTimeInMsForNanScan;
+ stats.on_time_background_scan += aidlRadioStats.onTimeInMsForBgScan;
+ stats.on_time_roam_scan += aidlRadioStats.onTimeInMsForRoamScan;
+ stats.on_time_pno_scan += aidlRadioStats.onTimeInMsForPnoScan;
+ stats.on_time_hs20_scan += aidlRadioStats.onTimeInMsForHs20Scan;
+ /* Copy list of channel stats */
+ for (WifiChannelStats channelStats : aidlRadioStats.channelStats) {
+ WifiLinkLayerStats.ChannelStats channelStatsEntry =
+ stats.channelStatsMap.get(channelStats.channel.centerFreq);
+ if (channelStatsEntry == null) {
+ channelStatsEntry = new WifiLinkLayerStats.ChannelStats();
+ channelStatsEntry.frequency = channelStats.channel.centerFreq;
+ stats.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
+ }
+ channelStatsEntry.radioOnTimeMs += channelStats.onTimeInMs;
+ channelStatsEntry.ccaBusyTimeMs += channelStats.ccaBusyTimeInMs;
+ }
+ stats.numRadios++;
+ }
+
+ private static byte frameworkToHalStaRoamingState(@WifiNative.RoamingEnableState int state) {
+ switch (state) {
+ case WifiNative.DISABLE_FIRMWARE_ROAMING:
+ return StaRoamingState.DISABLED;
+ case WifiNative.ENABLE_FIRMWARE_ROAMING:
+ return StaRoamingState.ENABLED;
+ default:
+ Log.e(TAG, "Invalid firmware roaming state enum: " + state);
+ return -1;
+ }
+ }
+
+ private static StaBackgroundScanParameters frameworkToHalBackgroundScanParams(
+ WifiStaIface.StaBackgroundScanParameters frameworkParams)
+ throws IllegalArgumentException {
+ StaBackgroundScanParameters halParams = new StaBackgroundScanParameters();
+ halParams.basePeriodInMs = frameworkParams.basePeriodInMs;
+ halParams.maxApPerScan = frameworkParams.maxApPerScan;
+ halParams.reportThresholdPercent = frameworkParams.reportThresholdPercent;
+ halParams.reportThresholdNumScans = frameworkParams.reportThresholdNumScans;
+ int numBuckets = frameworkParams.buckets != null ? frameworkParams.buckets.size() : 0;
+ halParams.buckets = new android.hardware.wifi.StaBackgroundScanBucketParameters[numBuckets];
+ if (frameworkParams.buckets != null) {
+ for (int i = 0; i < numBuckets; i++) {
+ halParams.buckets[i] = frameworkToHalBucketParams(frameworkParams.buckets.get(i));
+ }
+ }
+ return halParams;
+ }
+
+ private static StaBackgroundScanBucketParameters frameworkToHalBucketParams(
+ WifiNative.BucketSettings frameworkBucket) throws IllegalArgumentException {
+ StaBackgroundScanBucketParameters halBucket = new StaBackgroundScanBucketParameters();
+ halBucket.bucketIdx = frameworkBucket.bucket;
+ halBucket.band = frameworkToHalWifiBand(frameworkBucket.band);
+ int numChannels = frameworkBucket.channels != null ? frameworkBucket.channels.length : 0;
+ halBucket.frequencies = new int[numChannels];
+ if (frameworkBucket.channels != null) {
+ for (int i = 0; i < frameworkBucket.channels.length; i++) {
+ halBucket.frequencies[i] = frameworkBucket.channels[i].frequency;
+ }
+ }
+ halBucket.periodInMs = frameworkBucket.period_ms;
+ halBucket.eventReportScheme = frameworkToHalReportSchemeMask(frameworkBucket.report_events);
+ halBucket.exponentialMaxPeriodInMs = frameworkBucket.max_period_ms;
+ // Although HAL API allows configurable base value for the truncated
+ // exponential back off scan. Native API and above support only
+ // truncated binary exponential back off scan.
+ // Hard code value of base to 2 here.
+ halBucket.exponentialBase = 2;
+ halBucket.exponentialStepCount = frameworkBucket.step_count;
+ return halBucket;
+ }
+
+ private static int frameworkToHalWifiBand(int frameworkBand) throws IllegalArgumentException {
+ switch (frameworkBand) {
+ case WifiScanner.WIFI_BAND_UNSPECIFIED:
+ return WifiBand.BAND_UNSPECIFIED;
+ case WifiScanner.WIFI_BAND_24_GHZ:
+ return WifiBand.BAND_24GHZ;
+ case WifiScanner.WIFI_BAND_5_GHZ:
+ return WifiBand.BAND_5GHZ;
+ case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY:
+ return WifiBand.BAND_5GHZ_DFS;
+ case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS:
+ return WifiBand.BAND_5GHZ_WITH_DFS;
+ case WifiScanner.WIFI_BAND_BOTH:
+ return WifiBand.BAND_24GHZ_5GHZ;
+ case WifiScanner.WIFI_BAND_BOTH_WITH_DFS:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS;
+ case WifiScanner.WIFI_BAND_6_GHZ:
+ return WifiBand.BAND_6GHZ;
+ case WifiScanner.WIFI_BAND_24_5_6_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_6GHZ;
+ case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ;
+ case WifiScanner.WIFI_BAND_60_GHZ:
+ return WifiBand.BAND_60GHZ;
+ case WifiScanner.WIFI_BAND_24_5_6_60_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_6GHZ_60GHZ;
+ case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ;
+ case WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS:
+ default:
+ throw new IllegalArgumentException("bad band " + frameworkBand);
+ }
+ }
+
+ private static int frameworkToHalReportSchemeMask(int reportUnderscoreEvents)
+ throws IllegalArgumentException {
+ int ans = 0;
+ BitMask in = new BitMask(reportUnderscoreEvents);
+ if (in.testAndClear(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN)) {
+ ans |= StaBackgroundScanBucketEventReportSchemeMask.EACH_SCAN;
+ }
+ if (in.testAndClear(WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)) {
+ ans |= StaBackgroundScanBucketEventReportSchemeMask.FULL_RESULTS;
+ }
+ if (in.testAndClear(WifiScanner.REPORT_EVENT_NO_BATCH)) {
+ ans |= StaBackgroundScanBucketEventReportSchemeMask.NO_BATCH;
+ }
+ if (in.value != 0) throw new IllegalArgumentException("bad " + reportUnderscoreEvents);
+ return ans;
+ }
+
+ private boolean checkIfaceAndLogFailure(String methodStr) {
+ if (mWifiStaIface == null) {
+ Log.e(TAG, "Unable to call " + methodStr + " because iface is null.");
+ return false;
+ }
+ return true;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ mWifiStaIface = null;
+ mIfaceName = null;
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ }
+
+ private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with service-specific exception: " + e);
+ }
+
+ private void handleIllegalArgumentException(IllegalArgumentException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with illegal argument exception: " + e);
+ }
+}
diff --git a/service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java
new file mode 100644
index 0000000000..dc7f34ef12
--- /dev/null
+++ b/service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java
@@ -0,0 +1,1543 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.wifi.V1_0.IWifiStaIfaceEventCallback;
+import android.hardware.wifi.V1_0.StaBackgroundScanBucketEventReportSchemeMask;
+import android.hardware.wifi.V1_0.StaBackgroundScanBucketParameters;
+import android.hardware.wifi.V1_0.StaBackgroundScanParameters;
+import android.hardware.wifi.V1_0.StaLinkLayerIfaceStats;
+import android.hardware.wifi.V1_0.StaLinkLayerRadioStats;
+import android.hardware.wifi.V1_0.StaLinkLayerStats;
+import android.hardware.wifi.V1_0.StaRoamingConfig;
+import android.hardware.wifi.V1_0.StaRoamingState;
+import android.hardware.wifi.V1_0.StaScanData;
+import android.hardware.wifi.V1_0.StaScanDataFlagMask;
+import android.hardware.wifi.V1_0.StaScanResult;
+import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType;
+import android.hardware.wifi.V1_0.WifiDebugRxPacketFate;
+import android.hardware.wifi.V1_0.WifiDebugRxPacketFateReport;
+import android.hardware.wifi.V1_0.WifiDebugTxPacketFate;
+import android.hardware.wifi.V1_0.WifiDebugTxPacketFateReport;
+import android.hardware.wifi.V1_0.WifiStatus;
+import android.hardware.wifi.V1_0.WifiStatusCode;
+import android.hardware.wifi.V1_5.WifiBand;
+import android.net.MacAddress;
+import android.net.apf.ApfCapabilities;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiScanner;
+import android.net.wifi.WifiSsid;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.SsidTranslator;
+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.GeneralUtil;
+import com.android.server.wifi.util.NativeUtil;
+import com.android.wifi.resources.R;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+
+/**
+ * HIDL implementation of the IWifiStaIface interface.
+ */
+public class WifiStaIfaceHidlImpl implements IWifiStaIface {
+ private static final String TAG = "WifiStaIfaceHidlImpl";
+ private android.hardware.wifi.V1_0.IWifiStaIface mWifiStaIface;
+ private String mIfaceName;
+ private IWifiStaIfaceEventCallback mHalCallback;
+ private WifiStaIface.Callback mFrameworkCallback;
+ private Context mContext;
+ private SsidTranslator mSsidTranslator;
+
+ public WifiStaIfaceHidlImpl(@NonNull android.hardware.wifi.V1_0.IWifiStaIface staIface,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ mWifiStaIface = staIface;
+ mContext = context;
+ mSsidTranslator = ssidTranslator;
+ mHalCallback = new StaIfaceEventCallback();
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#registerFrameworkCallback(WifiStaIface.Callback)}
+ */
+ public boolean registerFrameworkCallback(WifiStaIface.Callback callback) {
+ final String methodStr = "registerFrameworkCallback";
+ return validateAndCall(methodStr, false,
+ () -> registerFrameworkCallbackInternal(methodStr, callback));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getName()}
+ */
+ @Nullable
+ public String getName() {
+ final String methodStr = "getName";
+ return validateAndCall(methodStr, null,
+ () -> getNameInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#configureRoaming(List, List)}
+ */
+ public boolean configureRoaming(List<MacAddress> bssidBlocklist,
+ List<byte[]> ssidAllowlist) {
+ final String methodStr = "configureRoaming";
+ return validateAndCall(methodStr, false,
+ () -> configureRoamingInternal(methodStr, bssidBlocklist, ssidAllowlist));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#enableLinkLayerStatsCollection(boolean)}
+ */
+ public boolean enableLinkLayerStatsCollection(boolean debug) {
+ final String methodStr = "enableLinkLayerStatsCollection";
+ return validateAndCall(methodStr, false,
+ () -> enableLinkLayerStatsCollectionInternal(methodStr, debug));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#enableNdOffload(boolean)}
+ */
+ public boolean enableNdOffload(boolean enable) {
+ final String methodStr = "enableNdOffload";
+ return validateAndCall(methodStr, false,
+ () -> enableNdOffloadInternal(methodStr, enable));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getApfPacketFilterCapabilities()}
+ */
+ public ApfCapabilities getApfPacketFilterCapabilities() {
+ final String methodStr = "getApfPacketFilterCapabilities";
+ return validateAndCall(methodStr, new ApfCapabilities(0, 0, 0),
+ () -> getApfPacketFilterCapabilitiesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getBackgroundScanCapabilities()}
+ */
+ @Nullable
+ public WifiNative.ScanCapabilities getBackgroundScanCapabilities() {
+ final String methodStr = "getBackgroundScanCapabilities";
+ return validateAndCall(methodStr, null,
+ () -> getBackgroundScanCapabilitiesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getCapabilities()}
+ */
+ public long getCapabilities() {
+ final String methodStr = "getCapabilities";
+ return validateAndCall(methodStr, 0L,
+ () -> getCapabilitiesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getDebugRxPacketFates()}
+ */
+ public List<WifiNative.RxFateReport> getDebugRxPacketFates() {
+ final String methodStr = "getDebugRxPacketFates";
+ return validateAndCall(methodStr, new ArrayList<>(),
+ () -> getDebugRxPacketFatesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getDebugTxPacketFates()}
+ */
+ public List<WifiNative.TxFateReport> getDebugTxPacketFates() {
+ final String methodStr = "getDebugTxPacketFates";
+ return validateAndCall(methodStr, new ArrayList<>(),
+ () -> getDebugTxPacketFatesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getFactoryMacAddress()}
+ */
+ @Nullable
+ public MacAddress getFactoryMacAddress() {
+ final String methodStr = "getFactoryMacAddress";
+ return validateAndCall(methodStr, null,
+ () -> getFactoryMacAddressInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getLinkLayerStats()}
+ */
+ @Nullable
+ public WifiLinkLayerStats getLinkLayerStats() {
+ final String methodStr = "getLinkLayerStats";
+ return validateAndCall(methodStr, null,
+ () -> getLinkLayerStatsInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#getRoamingCapabilities()}
+ */
+ @Nullable
+ public WifiNative.RoamingCapabilities getRoamingCapabilities() {
+ final String methodStr = "getRoamingCapabilities";
+ return validateAndCall(methodStr, null,
+ () -> getRoamingCapabilitiesInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#installApfPacketFilter(byte[])}
+ */
+ public boolean installApfPacketFilter(byte[] program) {
+ final String methodStr = "installApfPacketFilter";
+ return validateAndCall(methodStr, false,
+ () -> installApfPacketFilterInternal(methodStr, program));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#readApfPacketFilterData()}
+ */
+ @Nullable
+ public byte[] readApfPacketFilterData() {
+ final String methodStr = "readApfPacketFilterData";
+ return validateAndCall(methodStr, null,
+ () -> readApfPacketFilterDataInternal(methodStr));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#setMacAddress(MacAddress)}
+ */
+ public boolean setMacAddress(MacAddress mac) {
+ final String methodStr = "setMacAddress";
+ return validateAndCall(methodStr, false,
+ () -> setMacAddressInternal(methodStr, mac));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#setRoamingState(int)}
+ */
+ public @WifiNative.RoamingEnableStatus int setRoamingState(
+ @WifiNative.RoamingEnableState int state) {
+ final String methodStr = "setRoamingState";
+ return validateAndCall(methodStr, WifiNative.SET_FIRMWARE_ROAMING_FAILURE,
+ () -> setRoamingStateInternal(methodStr, state));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#setScanMode(boolean)}
+ */
+ public boolean setScanMode(boolean enable) {
+ final String methodStr = "setScanMode";
+ return validateAndCall(methodStr, false,
+ () -> setScanModeInternal(methodStr, enable));
+ }
+
+ /**
+ * See comments for
+ * {@link IWifiStaIface#startBackgroundScan(int, WifiStaIface.StaBackgroundScanParameters)}
+ */
+ public boolean startBackgroundScan(int cmdId, WifiStaIface.StaBackgroundScanParameters params) {
+ final String methodStr = "startBackgroundScan";
+ return validateAndCall(methodStr, false,
+ () -> startBackgroundScanInternal(methodStr, cmdId, params));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#startDebugPacketFateMonitoring()}
+ */
+ public boolean startDebugPacketFateMonitoring() {
+ final String methodStr = "startDebugPacketFateMonitoring";
+ return validateAndCall(methodStr, false,
+ () -> startDebugPacketFateMonitoringInternal(methodStr));
+ }
+
+ /**
+ * See comments for
+ * {@link IWifiStaIface#startRssiMonitoring(int, int, int)}
+ */
+ public boolean startRssiMonitoring(int cmdId, int maxRssi, int minRssi) {
+ final String methodStr = "startRssiMonitoring";
+ return validateAndCall(methodStr, false,
+ () -> startRssiMonitoringInternal(methodStr, cmdId, maxRssi, minRssi));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#startSendingKeepAlivePackets(int, byte[], int,
+ * MacAddress, MacAddress, int)}
+ */
+ public boolean startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType,
+ MacAddress srcAddress, MacAddress dstAddress, int periodInMs) {
+ final String methodStr = "startSendingKeepAlivePackets";
+ return validateAndCall(methodStr, false,
+ () -> startSendingKeepAlivePacketsInternal(methodStr, cmdId, ipPacketData,
+ etherType, srcAddress, dstAddress, periodInMs));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#stopBackgroundScan(int)}
+ */
+ public boolean stopBackgroundScan(int cmdId) {
+ final String methodStr = "stopBackgroundScan";
+ return validateAndCall(methodStr, false,
+ () -> stopBackgroundScanInternal(methodStr, cmdId));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#stopRssiMonitoring(int)}
+ */
+ public boolean stopRssiMonitoring(int cmdId) {
+ final String methodStr = "stopRssiMonitoring";
+ return validateAndCall(methodStr, false,
+ () -> stopRssiMonitoringInternal(methodStr, cmdId));
+ }
+
+ /**
+ * See comments for {@link IWifiStaIface#stopSendingKeepAlivePackets(int)}
+ */
+ public boolean stopSendingKeepAlivePackets(int cmdId) {
+ final String methodStr = "stopSendingKeepAlivePackets";
+ return validateAndCall(methodStr, false,
+ () -> stopSendingKeepAlivePacketsInternal(methodStr, cmdId));
+ }
+
+
+ // Internal Implementations
+
+ private boolean registerFrameworkCallbackInternal(String methodStr,
+ WifiStaIface.Callback callback) {
+ if (mFrameworkCallback != null) {
+ Log.e(TAG, "Framework callback is already registered");
+ return false;
+ } else if (callback == null) {
+ Log.e(TAG, "Cannot register a null callback");
+ return false;
+ }
+
+ try {
+ WifiStatus status = mWifiStaIface.registerEventCallback(mHalCallback);
+ if (!isOk(status, methodStr)) return false;
+ mFrameworkCallback = callback;
+ return true;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private String getNameInternal(String methodStr) {
+ if (mIfaceName != null) return mIfaceName;
+ GeneralUtil.Mutable<String> nameResp = new GeneralUtil.Mutable<>();
+ try {
+ mWifiStaIface.getName((WifiStatus status, String name) -> {
+ if (isOk(status, methodStr)) {
+ nameResp.value = name;
+ mIfaceName = name;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return nameResp.value;
+ }
+
+ private boolean configureRoamingInternal(String methodStr, List<MacAddress> bssidBlocklist,
+ List<byte[]> ssidAllowlist) {
+ StaRoamingConfig config = new StaRoamingConfig();
+ config.ssidWhitelist = new ArrayList<>(ssidAllowlist);
+ config.bssidBlacklist = new ArrayList<>();
+ for (MacAddress bssid : bssidBlocklist) {
+ config.bssidBlacklist.add(bssid.toByteArray());
+ }
+ try {
+ WifiStatus status = mWifiStaIface.configureRoaming(config);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean enableLinkLayerStatsCollectionInternal(String methodStr, boolean debug) {
+ try {
+ WifiStatus status = mWifiStaIface.enableLinkLayerStatsCollection(debug);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean enableNdOffloadInternal(String methodStr, boolean enable) {
+ try {
+ WifiStatus status = mWifiStaIface.enableNdOffload(enable);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private ApfCapabilities getApfPacketFilterCapabilitiesInternal(String methodStr) {
+ GeneralUtil.Mutable<ApfCapabilities> apfResp =
+ new GeneralUtil.Mutable<>(new ApfCapabilities(0, 0, 0));
+ try {
+ mWifiStaIface.getApfPacketFilterCapabilities((status, caps) -> {
+ if (isOk(status, methodStr)) {
+ apfResp.value = new ApfCapabilities(
+ /* apfVersionSupported */ caps.version,
+ /* maximumApfProgramSize */ caps.maxLength,
+ /* apfPacketFormat */ android.system.OsConstants.ARPHRD_ETHER);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return apfResp.value;
+ }
+
+ private WifiNative.ScanCapabilities getBackgroundScanCapabilitiesInternal(String methodStr) {
+ GeneralUtil.Mutable<WifiNative.ScanCapabilities> scanResp = new GeneralUtil.Mutable<>();
+ try {
+ mWifiStaIface.getBackgroundScanCapabilities((status, caps) -> {
+ if (isOk(status, methodStr)) {
+ WifiNative.ScanCapabilities out = new WifiNative.ScanCapabilities();
+ out.max_scan_cache_size = caps.maxCacheSize;
+ out.max_ap_cache_per_scan = caps.maxApCachePerScan;
+ out.max_scan_buckets = caps.maxBuckets;
+ out.max_rssi_sample_size = 0;
+ out.max_scan_reporting_threshold = caps.maxReportingThreshold;
+ scanResp.value = out;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return scanResp.value;
+ }
+
+ private long getCapabilitiesInternal(String methodStr) {
+ GeneralUtil.Mutable<Long> capsResp = new GeneralUtil.Mutable<>(0L);
+ try {
+ mWifiStaIface.getCapabilities((status, caps) -> {
+ if (isOk(status, methodStr)) {
+ capsResp.value = halToFrameworkStaIfaceCapability(caps);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return capsResp.value;
+ }
+
+ private List<WifiNative.RxFateReport> getDebugRxPacketFatesInternal(String methodStr) {
+ try {
+ List<WifiNative.RxFateReport> reportBufs = new ArrayList<>();
+ mWifiStaIface.getDebugRxPacketFates((status, fates) -> {
+ if (!isOk(status, methodStr)) return;
+ for (WifiDebugRxPacketFateReport fate : fates) {
+ if (reportBufs.size() >= WifiLoggerHal.MAX_FATE_LOG_LEN) break;
+ byte code = halToFrameworkRxPktFate(fate.fate);
+ long us = fate.frameInfo.driverTimestampUsec;
+ byte type = halToFrameworkPktFateFrameType(fate.frameInfo.frameType);
+ byte[] frame = NativeUtil.byteArrayFromArrayList(
+ fate.frameInfo.frameContent);
+ reportBufs.add(new WifiNative.RxFateReport(code, us, type, frame));
+ }
+ });
+ return reportBufs;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return new ArrayList<>();
+ }
+ }
+
+ private List<WifiNative.TxFateReport> getDebugTxPacketFatesInternal(String methodStr) {
+ try {
+ List<WifiNative.TxFateReport> reportBufs = new ArrayList<>();
+ mWifiStaIface.getDebugTxPacketFates((status, fates) -> {
+ if (!isOk(status, methodStr)) return;
+ for (WifiDebugTxPacketFateReport fate : fates) {
+ if (reportBufs.size() >= WifiLoggerHal.MAX_FATE_LOG_LEN) break;
+ byte code = halToFrameworkTxPktFate(fate.fate);
+ long us = fate.frameInfo.driverTimestampUsec;
+ byte type = halToFrameworkPktFateFrameType(fate.frameInfo.frameType);
+ byte[] frame = NativeUtil.byteArrayFromArrayList(
+ fate.frameInfo.frameContent);
+ reportBufs.add(new WifiNative.TxFateReport(code, us, type, frame));
+ }
+ });
+ return reportBufs;
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return new ArrayList<>();
+ }
+ }
+
+ private MacAddress getFactoryMacAddressInternal(String methodStr) {
+ GeneralUtil.Mutable<MacAddress> macResp = new GeneralUtil.Mutable<>();
+ try {
+ android.hardware.wifi.V1_3.IWifiStaIface sta13 = getWifiStaIfaceV1_3Mockable();
+ if (sta13 == null) return null;
+ sta13.getFactoryMacAddress((status, macBytes) -> {
+ if (isOk(status, methodStr)) {
+ macResp.value = MacAddress.fromBytes(macBytes);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return macResp.value;
+ }
+
+ private WifiLinkLayerStats getLinkLayerStatsInternal(String methodStr) {
+ if (getWifiStaIfaceV1_6Mockable() != null) {
+ return getLinkLayerStatsV1_6Internal(methodStr);
+ } else if (getWifiStaIfaceV1_5Mockable() != null) {
+ return getLinkLayerStatsV1_5Internal(methodStr);
+ } else if (getWifiStaIfaceV1_3Mockable() != null) {
+ return getLinkLayerStatsV1_3Internal(methodStr);
+ } else {
+ return getLinkLayerStatsV1_0Internal(methodStr);
+ }
+ }
+
+ private WifiLinkLayerStats getLinkLayerStatsV1_0Internal(String methodStr) {
+ final String methodStrV1_0 = methodStr + "V1_0";
+ GeneralUtil.Mutable<StaLinkLayerStats> statsResp = new GeneralUtil.Mutable<>();
+ try {
+ mWifiStaIface.getLinkLayerStats((status, stats) -> {
+ if (isOk(status, methodStrV1_0)) {
+ statsResp.value = stats;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStrV1_0);
+ return null;
+ }
+ return frameworkFromHalLinkLayerStats(statsResp.value);
+ }
+
+ private WifiLinkLayerStats getLinkLayerStatsV1_3Internal(String methodStr) {
+ final String methodStrV1_3 = methodStr + "V1_3";
+ GeneralUtil.Mutable<android.hardware.wifi.V1_3.StaLinkLayerStats> statsResp =
+ new GeneralUtil.Mutable<>();
+ try {
+ android.hardware.wifi.V1_3.IWifiStaIface iface13 = getWifiStaIfaceV1_3Mockable();
+ if (iface13 == null) return null;
+ iface13.getLinkLayerStats_1_3((status, stats) -> {
+ if (isOk(status, methodStrV1_3)) {
+ statsResp.value = stats;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStrV1_3);
+ return null;
+ }
+ return frameworkFromHalLinkLayerStats_1_3(statsResp.value);
+ }
+
+ private WifiLinkLayerStats getLinkLayerStatsV1_5Internal(String methodStr) {
+ final String methodStrV1_5 = methodStr + "V1_5";
+ GeneralUtil.Mutable<android.hardware.wifi.V1_5.StaLinkLayerStats> statsResp =
+ new GeneralUtil.Mutable<>();
+ try {
+ android.hardware.wifi.V1_5.IWifiStaIface iface15 = getWifiStaIfaceV1_5Mockable();
+ if (iface15 == null) return null;
+ iface15.getLinkLayerStats_1_5((status, stats) -> {
+ if (isOk(status, methodStrV1_5)) {
+ statsResp.value = stats;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStrV1_5);
+ return null;
+ }
+ return frameworkFromHalLinkLayerStats_1_5(statsResp.value);
+ }
+
+ private WifiLinkLayerStats getLinkLayerStatsV1_6Internal(String methodStr) {
+ final String methodStrV1_6 = methodStr + "V1_6";
+ GeneralUtil.Mutable<android.hardware.wifi.V1_6.StaLinkLayerStats> statsResp =
+ new GeneralUtil.Mutable<>();
+ try {
+ android.hardware.wifi.V1_6.IWifiStaIface iface16 = getWifiStaIfaceV1_6Mockable();
+ if (iface16 == null) return null;
+ iface16.getLinkLayerStats_1_6((status, stats) -> {
+ if (isOk(status, methodStrV1_6)) {
+ statsResp.value = stats;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStrV1_6);
+ return null;
+ }
+ return frameworkFromHalLinkLayerStats_1_6(statsResp.value);
+ }
+
+ private WifiNative.RoamingCapabilities getRoamingCapabilitiesInternal(String methodStr) {
+ GeneralUtil.Mutable<WifiNative.RoamingCapabilities> capsResp = new GeneralUtil.Mutable<>();
+ try {
+ mWifiStaIface.getRoamingCapabilities((status, caps) -> {
+ if (isOk(status, methodStr)) {
+ WifiNative.RoamingCapabilities out = new WifiNative.RoamingCapabilities();
+ out.maxBlocklistSize = caps.maxBlacklistSize;
+ out.maxAllowlistSize = caps.maxWhitelistSize;
+ capsResp.value = out;
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return capsResp.value;
+ }
+
+ private boolean installApfPacketFilterInternal(String methodStr, byte[] program) {
+ try {
+ int cmdId = 0; // We only aspire to support one program at a time.
+ ArrayList<Byte> filter = NativeUtil.byteArrayToArrayList(program);
+ WifiStatus status = mWifiStaIface.installApfPacketFilter(cmdId, filter);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private byte[] readApfPacketFilterDataInternal(String methodStr) {
+ GeneralUtil.Mutable<byte[]> dataResp = new GeneralUtil.Mutable<>();
+ try {
+ android.hardware.wifi.V1_2.IWifiStaIface iface12 = getWifiStaIfaceV1_2Mockable();
+ if (iface12 == null) return null;
+ iface12.readApfPacketFilterData((status, data) -> {
+ if (isOk(status, methodStr)) {
+ dataResp.value = NativeUtil.byteArrayFromArrayList(data);
+ }
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ return dataResp.value;
+ }
+
+ private boolean setMacAddressInternal(String methodStr, MacAddress mac) {
+ try {
+ android.hardware.wifi.V1_2.IWifiStaIface iface12 = getWifiStaIfaceV1_2Mockable();
+ if (iface12 == null) return false;
+ byte[] macBytes = mac.toByteArray();
+ WifiStatus status = iface12.setMacAddress(macBytes);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private @WifiNative.RoamingEnableStatus int setRoamingStateInternal(String methodStr,
+ @WifiNative.RoamingEnableState int state) {
+ byte halState = frameworkToHalStaRoamingState(state);
+ if (halState == -1) {
+ return WifiStaIface.SET_ROAMING_STATE_FAILURE_CODE;
+ }
+
+ try {
+ WifiStatus status = mWifiStaIface.setRoamingState(halState);
+ if (isOk(status, methodStr)) {
+ return WifiNative.SET_FIRMWARE_ROAMING_SUCCESS;
+ } else if (status.code == WifiStatusCode.ERROR_BUSY) {
+ return WifiNative.SET_FIRMWARE_ROAMING_BUSY;
+ } else {
+ return WifiStaIface.SET_ROAMING_STATE_FAILURE_CODE;
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return WifiStaIface.SET_ROAMING_STATE_FAILURE_CODE;
+ }
+ }
+
+ private boolean setScanModeInternal(String methodStr, boolean enable) {
+ try {
+ android.hardware.wifi.V1_5.IWifiStaIface iface15 = getWifiStaIfaceV1_5Mockable();
+ if (iface15 == null) return false;
+ WifiStatus status = iface15.setScanMode(enable);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean startBackgroundScanInternal(String methodStr, int cmdId,
+ WifiStaIface.StaBackgroundScanParameters params) {
+ try {
+ StaBackgroundScanParameters halParams = frameworkToHalBackgroundScanParams(params);
+ WifiStatus status = mWifiStaIface.startBackgroundScan(cmdId, halParams);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean startDebugPacketFateMonitoringInternal(String methodStr) {
+ try {
+ WifiStatus status = mWifiStaIface.startDebugPacketFateMonitoring();
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean startRssiMonitoringInternal(String methodStr, int cmdId, int maxRssi,
+ int minRssi) {
+ try {
+ WifiStatus status = mWifiStaIface.startRssiMonitoring(cmdId, maxRssi, minRssi);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean startSendingKeepAlivePacketsInternal(String methodStr, int cmdId,
+ byte[] ipPacketData, int etherType, MacAddress srcAddress, MacAddress dstAddress,
+ int periodInMs) {
+ try {
+ ArrayList<Byte> data = NativeUtil.byteArrayToArrayList(ipPacketData);
+ byte[] srcMac = srcAddress.toByteArray();
+ byte[] dstMac = dstAddress.toByteArray();
+ WifiStatus status = mWifiStaIface.startSendingKeepAlivePackets(
+ cmdId, data, (short) etherType, srcMac, dstMac, periodInMs);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean stopBackgroundScanInternal(String methodStr, int cmdId) {
+ try {
+ WifiStatus status = mWifiStaIface.stopBackgroundScan(cmdId);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean stopRssiMonitoringInternal(String methodStr, int cmdId) {
+ try {
+ WifiStatus status = mWifiStaIface.stopRssiMonitoring(cmdId);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+ private boolean stopSendingKeepAlivePacketsInternal(String methodStr, int cmdId) {
+ try {
+ WifiStatus status = mWifiStaIface.stopSendingKeepAlivePackets(cmdId);
+ return isOk(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+
+
+ // Helper Functions
+
+ private static byte frameworkToHalStaRoamingState(@WifiNative.RoamingEnableState int state) {
+ switch (state) {
+ case WifiNative.DISABLE_FIRMWARE_ROAMING:
+ return StaRoamingState.DISABLED;
+ case WifiNative.ENABLE_FIRMWARE_ROAMING:
+ return StaRoamingState.ENABLED;
+ default:
+ Log.e(TAG, "Invalid firmware roaming state enum: " + state);
+ return -1;
+ }
+ }
+
+ private static byte halToFrameworkPktFateFrameType(int type) {
+ switch (type) {
+ case WifiDebugPacketFateFrameType.UNKNOWN:
+ return WifiLoggerHal.FRAME_TYPE_UNKNOWN;
+ case WifiDebugPacketFateFrameType.ETHERNET_II:
+ return WifiLoggerHal.FRAME_TYPE_ETHERNET_II;
+ case WifiDebugPacketFateFrameType.MGMT_80211:
+ return WifiLoggerHal.FRAME_TYPE_80211_MGMT;
+ default:
+ throw new IllegalArgumentException("bad " + type);
+ }
+ }
+
+ private static byte halToFrameworkRxPktFate(int type) {
+ switch (type) {
+ case WifiDebugRxPacketFate.SUCCESS:
+ return WifiLoggerHal.RX_PKT_FATE_SUCCESS;
+ case WifiDebugRxPacketFate.FW_QUEUED:
+ return WifiLoggerHal.RX_PKT_FATE_FW_QUEUED;
+ case WifiDebugRxPacketFate.FW_DROP_FILTER:
+ return WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER;
+ case WifiDebugRxPacketFate.FW_DROP_INVALID:
+ return WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID;
+ case WifiDebugRxPacketFate.FW_DROP_NOBUFS:
+ return WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS;
+ case WifiDebugRxPacketFate.FW_DROP_OTHER:
+ return WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER;
+ case WifiDebugRxPacketFate.DRV_QUEUED:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED;
+ case WifiDebugRxPacketFate.DRV_DROP_FILTER:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER;
+ case WifiDebugRxPacketFate.DRV_DROP_INVALID:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID;
+ case WifiDebugRxPacketFate.DRV_DROP_NOBUFS:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS;
+ case WifiDebugRxPacketFate.DRV_DROP_OTHER:
+ return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER;
+ default:
+ throw new IllegalArgumentException("bad " + type);
+ }
+ }
+
+ private static byte halToFrameworkTxPktFate(int type) {
+ switch (type) {
+ case WifiDebugTxPacketFate.ACKED:
+ return WifiLoggerHal.TX_PKT_FATE_ACKED;
+ case WifiDebugTxPacketFate.SENT:
+ return WifiLoggerHal.TX_PKT_FATE_SENT;
+ case WifiDebugTxPacketFate.FW_QUEUED:
+ return WifiLoggerHal.TX_PKT_FATE_FW_QUEUED;
+ case WifiDebugTxPacketFate.FW_DROP_INVALID:
+ return WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID;
+ case WifiDebugTxPacketFate.FW_DROP_NOBUFS:
+ return WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS;
+ case WifiDebugTxPacketFate.FW_DROP_OTHER:
+ return WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER;
+ case WifiDebugTxPacketFate.DRV_QUEUED:
+ return WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED;
+ case WifiDebugTxPacketFate.DRV_DROP_INVALID:
+ return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID;
+ case WifiDebugTxPacketFate.DRV_DROP_NOBUFS:
+ return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS;
+ case WifiDebugTxPacketFate.DRV_DROP_OTHER:
+ return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER;
+ default:
+ throw new IllegalArgumentException("bad " + type);
+ }
+ }
+
+ private static boolean hasCapability(long capabilities, long desiredCapability) {
+ return (capabilities & desiredCapability) != 0;
+ }
+
+ @VisibleForTesting
+ long halToFrameworkStaIfaceCapability(int caps) {
+ long features = 0;
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.HOTSPOT)) {
+ features |= WifiManager.WIFI_FEATURE_PASSPOINT;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN)) {
+ features |= WifiManager.WIFI_FEATURE_SCANNER;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.PNO)) {
+ features |= WifiManager.WIFI_FEATURE_PNO;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.TDLS)) {
+ features |= WifiManager.WIFI_FEATURE_TDLS;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.TDLS_OFFCHANNEL)) {
+ features |= WifiManager.WIFI_FEATURE_TDLS_OFFCHANNEL;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS)) {
+ features |= WifiManager.WIFI_FEATURE_LINK_LAYER_STATS;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.RSSI_MONITOR)) {
+ features |= WifiManager.WIFI_FEATURE_RSSI_MONITOR;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.KEEP_ALIVE)) {
+ features |= WifiManager.WIFI_FEATURE_MKEEP_ALIVE;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.ND_OFFLOAD)) {
+ features |= WifiManager.WIFI_FEATURE_CONFIG_NDO;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.CONTROL_ROAMING)) {
+ features |= WifiManager.WIFI_FEATURE_CONTROL_ROAMING;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask
+ .PROBE_IE_WHITELIST)) {
+ features |= WifiManager.WIFI_FEATURE_IE_WHITELIST;
+ }
+ if (hasCapability(caps,
+ android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.SCAN_RAND)) {
+ features |= WifiManager.WIFI_FEATURE_SCAN_RAND;
+ }
+ return features;
+ }
+
+ @VisibleForTesting
+ WifiLinkLayerStats frameworkFromHalLinkLayerStats(StaLinkLayerStats stats) {
+ if (stats == null) return null;
+ WifiLinkLayerStats out = new WifiLinkLayerStats();
+ setIfaceStats(out, stats.iface);
+ setRadioStats(out, stats.radios);
+ out.timeStampInMs = stats.timeStampInMs;
+ out.version = WifiLinkLayerStats.V1_0;
+ return out;
+ }
+
+ /**
+ * Makes the framework version of link layer stats from the hal version.
+ */
+ @VisibleForTesting
+ WifiLinkLayerStats frameworkFromHalLinkLayerStats_1_3(
+ android.hardware.wifi.V1_3.StaLinkLayerStats stats) {
+ if (stats == null) return null;
+ WifiLinkLayerStats out = new WifiLinkLayerStats();
+ setIfaceStats(out, stats.iface);
+ setRadioStats_1_3(out, stats.radios);
+ out.timeStampInMs = stats.timeStampInMs;
+ out.version = WifiLinkLayerStats.V1_3;
+ return out;
+ }
+
+ /**
+ * Makes the framework version of link layer stats from the hal version.
+ */
+ @VisibleForTesting
+ WifiLinkLayerStats frameworkFromHalLinkLayerStats_1_5(
+ android.hardware.wifi.V1_5.StaLinkLayerStats stats) {
+ if (stats == null) return null;
+ WifiLinkLayerStats out = new WifiLinkLayerStats();
+ setIfaceStats_1_5(out, stats.iface);
+ setRadioStats_1_5(out, stats.radios);
+ out.timeStampInMs = stats.timeStampInMs;
+ out.version = WifiLinkLayerStats.V1_5;
+ return out;
+ }
+
+ /**
+ * Makes the framework version of link layer stats from the hal version.
+ */
+ @VisibleForTesting
+ WifiLinkLayerStats frameworkFromHalLinkLayerStats_1_6(
+ android.hardware.wifi.V1_6.StaLinkLayerStats stats) {
+ if (stats == null) return null;
+ WifiLinkLayerStats out = new WifiLinkLayerStats();
+ setIfaceStats_1_6(out, stats.iface);
+ setRadioStats_1_6(out, stats.radios);
+ out.timeStampInMs = stats.timeStampInMs;
+ out.version = WifiLinkLayerStats.V1_5;
+ return out;
+ }
+
+ private static void setIfaceStats(WifiLinkLayerStats stats, StaLinkLayerIfaceStats iface) {
+ if (iface == null) return;
+ stats.beacon_rx = iface.beaconRx;
+ stats.rssi_mgmt = iface.avgRssiMgmt;
+ // Statistics are broken out by Wireless Multimedia Extensions categories
+ // WME Best Effort Access Category
+ stats.rxmpdu_be = iface.wmeBePktStats.rxMpdu;
+ stats.txmpdu_be = iface.wmeBePktStats.txMpdu;
+ stats.lostmpdu_be = iface.wmeBePktStats.lostMpdu;
+ stats.retries_be = iface.wmeBePktStats.retries;
+ // WME Background Access Category
+ stats.rxmpdu_bk = iface.wmeBkPktStats.rxMpdu;
+ stats.txmpdu_bk = iface.wmeBkPktStats.txMpdu;
+ stats.lostmpdu_bk = iface.wmeBkPktStats.lostMpdu;
+ stats.retries_bk = iface.wmeBkPktStats.retries;
+ // WME Video Access Category
+ stats.rxmpdu_vi = iface.wmeViPktStats.rxMpdu;
+ stats.txmpdu_vi = iface.wmeViPktStats.txMpdu;
+ stats.lostmpdu_vi = iface.wmeViPktStats.lostMpdu;
+ stats.retries_vi = iface.wmeViPktStats.retries;
+ // WME Voice Access Category
+ stats.rxmpdu_vo = iface.wmeVoPktStats.rxMpdu;
+ stats.txmpdu_vo = iface.wmeVoPktStats.txMpdu;
+ stats.lostmpdu_vo = iface.wmeVoPktStats.lostMpdu;
+ stats.retries_vo = iface.wmeVoPktStats.retries;
+ }
+
+ private static void setIfaceStats_1_5(WifiLinkLayerStats stats,
+ android.hardware.wifi.V1_5.StaLinkLayerIfaceStats iface) {
+ if (iface == null) return;
+ setIfaceStats(stats, iface.V1_0);
+ stats.timeSliceDutyCycleInPercent = iface.timeSliceDutyCycleInPercent;
+ // WME Best Effort Access Category
+ stats.contentionTimeMinBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesBe = iface.wmeBeContentionTimeStats.contentionNumSamples;
+ // WME Background Access Category
+ stats.contentionTimeMinBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesBk = iface.wmeBkContentionTimeStats.contentionNumSamples;
+ // WME Video Access Category
+ stats.contentionTimeMinViInUsec = iface.wmeViContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxViInUsec = iface.wmeViContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgViInUsec = iface.wmeViContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesVi = iface.wmeViContentionTimeStats.contentionNumSamples;
+ // WME Voice Access Category
+ stats.contentionTimeMinVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesVo = iface.wmeVoContentionTimeStats.contentionNumSamples;
+ // Peer information statistics
+ stats.peerInfo = new WifiLinkLayerStats.PeerInfo[iface.peers.size()];
+ for (int i = 0; i < stats.peerInfo.length; i++) {
+ WifiLinkLayerStats.PeerInfo peer = new WifiLinkLayerStats.PeerInfo();
+ android.hardware.wifi.V1_5.StaPeerInfo staPeerInfo = iface.peers.get(i);
+ peer.staCount = staPeerInfo.staCount;
+ peer.chanUtil = staPeerInfo.chanUtil;
+ WifiLinkLayerStats.RateStat[] rateStats =
+ new WifiLinkLayerStats.RateStat[staPeerInfo.rateStats.size()];
+ for (int j = 0; j < staPeerInfo.rateStats.size(); j++) {
+ rateStats[j] = new WifiLinkLayerStats.RateStat();
+ android.hardware.wifi.V1_5.StaRateStat staRateStat = staPeerInfo.rateStats.get(j);
+ rateStats[j].preamble = staRateStat.rateInfo.preamble;
+ rateStats[j].nss = staRateStat.rateInfo.nss;
+ rateStats[j].bw = staRateStat.rateInfo.bw;
+ rateStats[j].rateMcsIdx = staRateStat.rateInfo.rateMcsIdx;
+ rateStats[j].bitRateInKbps = staRateStat.rateInfo.bitRateInKbps;
+ rateStats[j].txMpdu = staRateStat.txMpdu;
+ rateStats[j].rxMpdu = staRateStat.rxMpdu;
+ rateStats[j].mpduLost = staRateStat.mpduLost;
+ rateStats[j].retries = staRateStat.retries;
+ }
+ peer.rateStats = rateStats;
+ stats.peerInfo[i] = peer;
+ }
+ }
+
+ private static void setIfaceStats_1_6(WifiLinkLayerStats stats,
+ android.hardware.wifi.V1_6.StaLinkLayerIfaceStats iface) {
+ if (iface == null) return;
+ setIfaceStats(stats, iface.V1_0);
+ stats.timeSliceDutyCycleInPercent = iface.timeSliceDutyCycleInPercent;
+ // WME Best Effort Access Category
+ stats.contentionTimeMinBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgBeInUsec = iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesBe = iface.wmeBeContentionTimeStats.contentionNumSamples;
+ // WME Background Access Category
+ stats.contentionTimeMinBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgBkInUsec = iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesBk = iface.wmeBkContentionTimeStats.contentionNumSamples;
+ // WME Video Access Category
+ stats.contentionTimeMinViInUsec = iface.wmeViContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxViInUsec = iface.wmeViContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgViInUsec = iface.wmeViContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesVi = iface.wmeViContentionTimeStats.contentionNumSamples;
+ // WME Voice Access Category
+ stats.contentionTimeMinVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMinInUsec;
+ stats.contentionTimeMaxVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec;
+ stats.contentionTimeAvgVoInUsec = iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec;
+ stats.contentionNumSamplesVo = iface.wmeVoContentionTimeStats.contentionNumSamples;
+ // Peer information statistics
+ stats.peerInfo = new WifiLinkLayerStats.PeerInfo[iface.peers.size()];
+ for (int i = 0; i < stats.peerInfo.length; i++) {
+ WifiLinkLayerStats.PeerInfo peer = new WifiLinkLayerStats.PeerInfo();
+ android.hardware.wifi.V1_6.StaPeerInfo staPeerInfo = iface.peers.get(i);
+ peer.staCount = staPeerInfo.staCount;
+ peer.chanUtil = staPeerInfo.chanUtil;
+ WifiLinkLayerStats.RateStat[] rateStats =
+ new WifiLinkLayerStats.RateStat[staPeerInfo.rateStats.size()];
+ for (int j = 0; j < staPeerInfo.rateStats.size(); j++) {
+ rateStats[j] = new WifiLinkLayerStats.RateStat();
+ android.hardware.wifi.V1_6.StaRateStat staRateStat = staPeerInfo.rateStats.get(j);
+ rateStats[j].preamble = staRateStat.rateInfo.preamble;
+ rateStats[j].nss = staRateStat.rateInfo.nss;
+ rateStats[j].bw = staRateStat.rateInfo.bw;
+ rateStats[j].rateMcsIdx = staRateStat.rateInfo.rateMcsIdx;
+ rateStats[j].bitRateInKbps = staRateStat.rateInfo.bitRateInKbps;
+ rateStats[j].txMpdu = staRateStat.txMpdu;
+ rateStats[j].rxMpdu = staRateStat.rxMpdu;
+ rateStats[j].mpduLost = staRateStat.mpduLost;
+ rateStats[j].retries = staRateStat.retries;
+ }
+ peer.rateStats = rateStats;
+ stats.peerInfo[i] = peer;
+ }
+ }
+
+ private static void setRadioStats(WifiLinkLayerStats stats,
+ List<StaLinkLayerRadioStats> radios) {
+ if (radios == null) return;
+ // Do not coalesce this info for multi radio devices with older HALs.
+ if (radios.size() > 0) {
+ StaLinkLayerRadioStats radioStats = radios.get(0);
+ stats.on_time = radioStats.onTimeInMs;
+ stats.tx_time = radioStats.txTimeInMs;
+ stats.tx_time_per_level = new int[radioStats.txTimeInMsPerLevel.size()];
+ for (int i = 0; i < stats.tx_time_per_level.length; i++) {
+ stats.tx_time_per_level[i] = radioStats.txTimeInMsPerLevel.get(i);
+ }
+ stats.rx_time = radioStats.rxTimeInMs;
+ stats.on_time_scan = radioStats.onTimeInMsForScan;
+ stats.numRadios = 1;
+ }
+ }
+
+ private void setRadioStats_1_3(WifiLinkLayerStats stats,
+ List<android.hardware.wifi.V1_3.StaLinkLayerRadioStats> radios) {
+ if (radios == null) return;
+ int radioIndex = 0;
+ for (android.hardware.wifi.V1_3.StaLinkLayerRadioStats radioStats : radios) {
+ aggregateFrameworkRadioStatsFromHidl_1_3(radioIndex, stats, radioStats);
+ radioIndex++;
+ }
+ }
+
+ private void setRadioStats_1_5(WifiLinkLayerStats stats,
+ List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios) {
+ if (radios == null) return;
+ int radioIndex = 0;
+ stats.radioStats = new WifiLinkLayerStats.RadioStat[radios.size()];
+ for (android.hardware.wifi.V1_5.StaLinkLayerRadioStats radioStats : radios) {
+ WifiLinkLayerStats.RadioStat radio = new WifiLinkLayerStats.RadioStat();
+ setFrameworkPerRadioStatsFromHidl_1_3(radioStats.radioId, radio, radioStats.V1_3);
+ stats.radioStats[radioIndex] = radio;
+ aggregateFrameworkRadioStatsFromHidl_1_3(radioIndex, stats, radioStats.V1_3);
+ radioIndex++;
+ }
+ }
+
+ private void setRadioStats_1_6(WifiLinkLayerStats stats,
+ List<android.hardware.wifi.V1_6.StaLinkLayerRadioStats> radios) {
+ if (radios == null) return;
+ int radioIndex = 0;
+ stats.radioStats = new WifiLinkLayerStats.RadioStat[radios.size()];
+ for (android.hardware.wifi.V1_6.StaLinkLayerRadioStats radioStats : radios) {
+ WifiLinkLayerStats.RadioStat radio = new WifiLinkLayerStats.RadioStat();
+ setFrameworkPerRadioStatsFromHidl_1_6(radio, radioStats);
+ stats.radioStats[radioIndex] = radio;
+ aggregateFrameworkRadioStatsFromHidl_1_6(radioIndex, stats, radioStats);
+ radioIndex++;
+ }
+ }
+
+ /**
+ * Set individual radio stats from the hal radio stats for V1_3
+ */
+ private void setFrameworkPerRadioStatsFromHidl_1_3(int radioId,
+ WifiLinkLayerStats.RadioStat radio,
+ android.hardware.wifi.V1_3.StaLinkLayerRadioStats hidlRadioStats) {
+ radio.radio_id = radioId;
+ radio.on_time = hidlRadioStats.V1_0.onTimeInMs;
+ radio.tx_time = hidlRadioStats.V1_0.txTimeInMs;
+ radio.rx_time = hidlRadioStats.V1_0.rxTimeInMs;
+ radio.on_time_scan = hidlRadioStats.V1_0.onTimeInMsForScan;
+ radio.on_time_nan_scan = hidlRadioStats.onTimeInMsForNanScan;
+ radio.on_time_background_scan = hidlRadioStats.onTimeInMsForBgScan;
+ radio.on_time_roam_scan = hidlRadioStats.onTimeInMsForRoamScan;
+ radio.on_time_pno_scan = hidlRadioStats.onTimeInMsForPnoScan;
+ radio.on_time_hs20_scan = hidlRadioStats.onTimeInMsForHs20Scan;
+ /* Copy list of channel stats */
+ for (android.hardware.wifi.V1_3.WifiChannelStats channelStats
+ : hidlRadioStats.channelStats) {
+ WifiLinkLayerStats.ChannelStats channelStatsEntry =
+ new WifiLinkLayerStats.ChannelStats();
+ channelStatsEntry.frequency = channelStats.channel.centerFreq;
+ channelStatsEntry.radioOnTimeMs = channelStats.onTimeInMs;
+ channelStatsEntry.ccaBusyTimeMs = channelStats.ccaBusyTimeInMs;
+ radio.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
+ }
+ }
+
+ /**
+ * Set individual radio stats from the hal radio stats for V1_6
+ */
+ private void setFrameworkPerRadioStatsFromHidl_1_6(WifiLinkLayerStats.RadioStat radio,
+ android.hardware.wifi.V1_6.StaLinkLayerRadioStats hidlRadioStats) {
+ radio.radio_id = hidlRadioStats.radioId;
+ radio.on_time = hidlRadioStats.V1_0.onTimeInMs;
+ radio.tx_time = hidlRadioStats.V1_0.txTimeInMs;
+ radio.rx_time = hidlRadioStats.V1_0.rxTimeInMs;
+ radio.on_time_scan = hidlRadioStats.V1_0.onTimeInMsForScan;
+ radio.on_time_nan_scan = hidlRadioStats.onTimeInMsForNanScan;
+ radio.on_time_background_scan = hidlRadioStats.onTimeInMsForBgScan;
+ radio.on_time_roam_scan = hidlRadioStats.onTimeInMsForRoamScan;
+ radio.on_time_pno_scan = hidlRadioStats.onTimeInMsForPnoScan;
+ radio.on_time_hs20_scan = hidlRadioStats.onTimeInMsForHs20Scan;
+ /* Copy list of channel stats */
+ for (android.hardware.wifi.V1_6.WifiChannelStats channelStats
+ : hidlRadioStats.channelStats) {
+ WifiLinkLayerStats.ChannelStats channelStatsEntry =
+ new WifiLinkLayerStats.ChannelStats();
+ channelStatsEntry.frequency = channelStats.channel.centerFreq;
+ channelStatsEntry.radioOnTimeMs = channelStats.onTimeInMs;
+ channelStatsEntry.ccaBusyTimeMs = channelStats.ccaBusyTimeInMs;
+ radio.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
+ }
+ }
+
+ /**
+ * If config_wifiLinkLayerAllRadiosStatsAggregationEnabled is set to true, aggregate
+ * the radio stats from all the radios else process the stats from Radio 0 only.
+ * This method is for V1_3
+ */
+ private void aggregateFrameworkRadioStatsFromHidl_1_3(int radioIndex,
+ WifiLinkLayerStats stats,
+ android.hardware.wifi.V1_3.StaLinkLayerRadioStats hidlRadioStats) {
+ if (!mContext.getResources()
+ .getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled)
+ && radioIndex > 0) {
+ return;
+ }
+ // Aggregate the radio stats from all the radios
+ stats.on_time += hidlRadioStats.V1_0.onTimeInMs;
+ stats.tx_time += hidlRadioStats.V1_0.txTimeInMs;
+ // Aggregate tx_time_per_level based on the assumption that the length of
+ // txTimeInMsPerLevel is the same across all radios. So txTimeInMsPerLevel on other
+ // radios at array indices greater than the length of first radio will be dropped.
+ if (stats.tx_time_per_level == null) {
+ stats.tx_time_per_level = new int[hidlRadioStats.V1_0.txTimeInMsPerLevel.size()];
+ }
+ for (int i = 0; i < hidlRadioStats.V1_0.txTimeInMsPerLevel.size()
+ && i < stats.tx_time_per_level.length; i++) {
+ stats.tx_time_per_level[i] += hidlRadioStats.V1_0.txTimeInMsPerLevel.get(i);
+ }
+ stats.rx_time += hidlRadioStats.V1_0.rxTimeInMs;
+ stats.on_time_scan += hidlRadioStats.V1_0.onTimeInMsForScan;
+ stats.on_time_nan_scan += hidlRadioStats.onTimeInMsForNanScan;
+ stats.on_time_background_scan += hidlRadioStats.onTimeInMsForBgScan;
+ stats.on_time_roam_scan += hidlRadioStats.onTimeInMsForRoamScan;
+ stats.on_time_pno_scan += hidlRadioStats.onTimeInMsForPnoScan;
+ stats.on_time_hs20_scan += hidlRadioStats.onTimeInMsForHs20Scan;
+ /* Copy list of channel stats */
+ for (android.hardware.wifi.V1_3.WifiChannelStats channelStats
+ : hidlRadioStats.channelStats) {
+ WifiLinkLayerStats.ChannelStats channelStatsEntry =
+ stats.channelStatsMap.get(channelStats.channel.centerFreq);
+ if (channelStatsEntry == null) {
+ channelStatsEntry = new WifiLinkLayerStats.ChannelStats();
+ channelStatsEntry.frequency = channelStats.channel.centerFreq;
+ stats.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
+ }
+ channelStatsEntry.radioOnTimeMs += channelStats.onTimeInMs;
+ channelStatsEntry.ccaBusyTimeMs += channelStats.ccaBusyTimeInMs;
+ }
+ stats.numRadios++;
+ }
+
+ /**
+ * If config_wifiLinkLayerAllRadiosStatsAggregationEnabled is set to true, aggregate
+ * the radio stats from all the radios else process the stats from Radio 0 only.
+ * This method is for V1_6
+ */
+ private void aggregateFrameworkRadioStatsFromHidl_1_6(int radioIndex,
+ WifiLinkLayerStats stats,
+ android.hardware.wifi.V1_6.StaLinkLayerRadioStats hidlRadioStats) {
+ if (!mContext.getResources()
+ .getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled)
+ && radioIndex > 0) {
+ return;
+ }
+ // Aggregate the radio stats from all the radios
+ stats.on_time += hidlRadioStats.V1_0.onTimeInMs;
+ stats.tx_time += hidlRadioStats.V1_0.txTimeInMs;
+ // Aggregate tx_time_per_level based on the assumption that the length of
+ // txTimeInMsPerLevel is the same across all radios. So txTimeInMsPerLevel on other
+ // radios at array indices greater than the length of first radio will be dropped.
+ if (stats.tx_time_per_level == null) {
+ stats.tx_time_per_level = new int[hidlRadioStats.V1_0.txTimeInMsPerLevel.size()];
+ }
+ for (int i = 0; i < hidlRadioStats.V1_0.txTimeInMsPerLevel.size()
+ && i < stats.tx_time_per_level.length; i++) {
+ stats.tx_time_per_level[i] += hidlRadioStats.V1_0.txTimeInMsPerLevel.get(i);
+ }
+ stats.rx_time += hidlRadioStats.V1_0.rxTimeInMs;
+ stats.on_time_scan += hidlRadioStats.V1_0.onTimeInMsForScan;
+ stats.on_time_nan_scan += hidlRadioStats.onTimeInMsForNanScan;
+ stats.on_time_background_scan += hidlRadioStats.onTimeInMsForBgScan;
+ stats.on_time_roam_scan += hidlRadioStats.onTimeInMsForRoamScan;
+ stats.on_time_pno_scan += hidlRadioStats.onTimeInMsForPnoScan;
+ stats.on_time_hs20_scan += hidlRadioStats.onTimeInMsForHs20Scan;
+ /* Copy list of channel stats */
+ for (android.hardware.wifi.V1_6.WifiChannelStats channelStats
+ : hidlRadioStats.channelStats) {
+ WifiLinkLayerStats.ChannelStats channelStatsEntry =
+ stats.channelStatsMap.get(channelStats.channel.centerFreq);
+ if (channelStatsEntry == null) {
+ channelStatsEntry = new WifiLinkLayerStats.ChannelStats();
+ channelStatsEntry.frequency = channelStats.channel.centerFreq;
+ stats.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry);
+ }
+ channelStatsEntry.radioOnTimeMs += channelStats.onTimeInMs;
+ channelStatsEntry.ccaBusyTimeMs += channelStats.ccaBusyTimeInMs;
+ }
+ stats.numRadios++;
+ }
+
+ private static StaBackgroundScanParameters frameworkToHalBackgroundScanParams(
+ WifiStaIface.StaBackgroundScanParameters frameworkParams) {
+ StaBackgroundScanParameters halParams = new StaBackgroundScanParameters();
+ halParams.basePeriodInMs = frameworkParams.basePeriodInMs;
+ halParams.maxApPerScan = frameworkParams.maxApPerScan;
+ halParams.reportThresholdPercent = frameworkParams.reportThresholdPercent;
+ halParams.reportThresholdNumScans = frameworkParams.reportThresholdNumScans;
+ if (frameworkParams.buckets != null) {
+ for (WifiNative.BucketSettings bucket : frameworkParams.buckets) {
+ halParams.buckets.add(frameworkToHalBucketParams(bucket));
+ }
+ }
+ return halParams;
+ }
+
+ private static StaBackgroundScanBucketParameters frameworkToHalBucketParams(
+ WifiNative.BucketSettings frameworkBucket) {
+ StaBackgroundScanBucketParameters halBucket = new StaBackgroundScanBucketParameters();
+ halBucket.bucketIdx = frameworkBucket.bucket;
+ halBucket.band = frameworkToHalWifiBand(frameworkBucket.band);
+ if (frameworkBucket.channels != null) {
+ for (WifiNative.ChannelSettings cs : frameworkBucket.channels) {
+ halBucket.frequencies.add(cs.frequency);
+ }
+ }
+ halBucket.periodInMs = frameworkBucket.period_ms;
+ halBucket.eventReportScheme = frameworkToHalReportSchemeMask(frameworkBucket.report_events);
+ halBucket.exponentialMaxPeriodInMs = frameworkBucket.max_period_ms;
+ // Although HAL API allows configurable base value for the truncated
+ // exponential back off scan. Native API and above support only
+ // truncated binary exponential back off scan.
+ // Hard code value of base to 2 here.
+ halBucket.exponentialBase = 2;
+ halBucket.exponentialStepCount = frameworkBucket.step_count;
+ return halBucket;
+ }
+
+ /**
+ * Convert WifiBand from framework to HAL.
+ *
+ * Note: This method is only used by background scan which does not
+ * support 6GHz, hence band combinations including 6GHz are considered invalid
+ *
+ * @param frameworkBand one of WifiScanner.WIFI_BAND_*
+ * @return A WifiBand value
+ * @throws IllegalArgumentException if frameworkBand is not recognized
+ */
+ private static int frameworkToHalWifiBand(int frameworkBand) {
+ switch (frameworkBand) {
+ case WifiScanner.WIFI_BAND_UNSPECIFIED:
+ return WifiBand.BAND_UNSPECIFIED;
+ case WifiScanner.WIFI_BAND_24_GHZ:
+ return WifiBand.BAND_24GHZ;
+ case WifiScanner.WIFI_BAND_5_GHZ:
+ return WifiBand.BAND_5GHZ;
+ case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY:
+ return WifiBand.BAND_5GHZ_DFS;
+ case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS:
+ return WifiBand.BAND_5GHZ_WITH_DFS;
+ case WifiScanner.WIFI_BAND_BOTH:
+ return WifiBand.BAND_24GHZ_5GHZ;
+ case WifiScanner.WIFI_BAND_BOTH_WITH_DFS:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS;
+ case WifiScanner.WIFI_BAND_6_GHZ:
+ return WifiBand.BAND_6GHZ;
+ case WifiScanner.WIFI_BAND_24_5_6_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_6GHZ;
+ case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ;
+ case WifiScanner.WIFI_BAND_60_GHZ:
+ return WifiBand.BAND_60GHZ;
+ case WifiScanner.WIFI_BAND_24_5_6_60_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_6GHZ_60GHZ;
+ case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ:
+ return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ;
+ case WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS:
+ default:
+ throw new IllegalArgumentException("bad band " + frameworkBand);
+ }
+ }
+
+ /**
+ * Convert the report scheme mask from framework to hal.
+ *
+ * @param reportUnderscoreEvents is logical OR of WifiScanner.REPORT_EVENT_* values
+ * @return Corresponding StaBackgroundScanBucketEventReportSchemeMask value
+ * @throws IllegalArgumentException if a mask bit is not recognized
+ */
+ private static int frameworkToHalReportSchemeMask(int reportUnderscoreEvents) {
+ int ans = 0;
+ BitMask in = new BitMask(reportUnderscoreEvents);
+ if (in.testAndClear(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN)) {
+ ans |= StaBackgroundScanBucketEventReportSchemeMask.EACH_SCAN;
+ }
+ if (in.testAndClear(WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)) {
+ ans |= StaBackgroundScanBucketEventReportSchemeMask.FULL_RESULTS;
+ }
+ if (in.testAndClear(WifiScanner.REPORT_EVENT_NO_BATCH)) {
+ ans |= StaBackgroundScanBucketEventReportSchemeMask.NO_BATCH;
+ }
+ if (in.value != 0) throw new IllegalArgumentException("bad " + reportUnderscoreEvents);
+ return ans;
+ }
+
+ // Only sets the fields of ScanResult used by Gscan clients.
+ private ScanResult hidlToFrameworkScanResult(StaScanResult scanResult) {
+ if (scanResult == null) return null;
+ WifiSsid originalSsid = WifiSsid.fromBytes(
+ NativeUtil.byteArrayFromArrayList(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.rssi;
+ frameworkScanResult.frequency = scanResult.frequency;
+ frameworkScanResult.timestamp = scanResult.timeStampInUs;
+ return frameworkScanResult;
+ }
+
+ private ScanResult[] hidlToFrameworkScanResults(ArrayList<StaScanResult> scanResults) {
+ if (scanResults == null || scanResults.isEmpty()) return new ScanResult[0];
+ ScanResult[] frameworkScanResults = new ScanResult[scanResults.size()];
+ int i = 0;
+ for (StaScanResult scanResult : scanResults) {
+ ScanResult frameworkScanResult = hidlToFrameworkScanResult(scanResult);
+ if (frameworkScanResult == null) {
+ Log.e(TAG, "hidlToFrameworkScanResults: unable to convert hidl to framework "
+ + "scan result!");
+ continue;
+ }
+ frameworkScanResults[i++] = frameworkScanResult;
+ }
+ return frameworkScanResults;
+ }
+
+ private static int hidlToFrameworkScanDataFlags(int flag) {
+ if (flag == StaScanDataFlagMask.INTERRUPTED) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ private WifiScanner.ScanData[] hidlToFrameworkScanDatas(
+ int cmdId, ArrayList<StaScanData> scanDatas) {
+ if (scanDatas == null || scanDatas.isEmpty()) return new WifiScanner.ScanData[0];
+ WifiScanner.ScanData[] frameworkScanDatas = new WifiScanner.ScanData[scanDatas.size()];
+ int i = 0;
+ for (StaScanData scanData : scanDatas) {
+ int flags = hidlToFrameworkScanDataFlags(scanData.flags);
+ ScanResult[] frameworkScanResults = hidlToFrameworkScanResults(scanData.results);
+ frameworkScanDatas[i++] =
+ new WifiScanner.ScanData(cmdId, flags, scanData.bucketsScanned,
+ WifiScanner.WIFI_BAND_UNSPECIFIED, frameworkScanResults);
+ }
+ return frameworkScanDatas;
+ }
+
+ protected android.hardware.wifi.V1_2.IWifiStaIface getWifiStaIfaceV1_2Mockable() {
+ return android.hardware.wifi.V1_2.IWifiStaIface.castFrom(mWifiStaIface);
+ }
+
+ protected android.hardware.wifi.V1_3.IWifiStaIface getWifiStaIfaceV1_3Mockable() {
+ return android.hardware.wifi.V1_3.IWifiStaIface.castFrom(mWifiStaIface);
+ }
+
+ protected android.hardware.wifi.V1_5.IWifiStaIface getWifiStaIfaceV1_5Mockable() {
+ return android.hardware.wifi.V1_5.IWifiStaIface.castFrom(mWifiStaIface);
+ }
+
+ protected android.hardware.wifi.V1_6.IWifiStaIface getWifiStaIfaceV1_6Mockable() {
+ return android.hardware.wifi.V1_6.IWifiStaIface.castFrom(mWifiStaIface);
+ }
+
+ private boolean isOk(WifiStatus status, String methodStr) {
+ if (status.code == WifiStatusCode.SUCCESS) return true;
+ Log.e(TAG, methodStr + " failed with status: " + status);
+ return false;
+ }
+
+ private void handleRemoteException(RemoteException e, String methodStr) {
+ Log.e(TAG, methodStr + " failed with remote exception: " + e);
+ mWifiStaIface = null;
+ }
+
+ private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
+ if (mWifiStaIface == null) {
+ Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiStaIface is null");
+ return defaultVal;
+ }
+ return supplier.get();
+ }
+
+
+ // HAL Callback
+ private class StaIfaceEventCallback extends IWifiStaIfaceEventCallback.Stub {
+ @Override
+ public void onBackgroundScanFailure(int cmdId) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onBackgroundScanFailure(cmdId);
+ }
+
+ @Override
+ public void onBackgroundFullScanResult(int cmdId, int bucketsScanned,
+ StaScanResult result) {
+ if (mFrameworkCallback == null) return;
+ ScanResult frameworkScanResult = hidlToFrameworkScanResult(result);
+ if (frameworkScanResult == null) {
+ Log.e(TAG, "Unable to convert scan result from HAL to framework");
+ return;
+ }
+ mFrameworkCallback.onBackgroundFullScanResult(cmdId, bucketsScanned,
+ frameworkScanResult);
+ }
+
+ @Override
+ public void onBackgroundScanResults(int cmdId, ArrayList<StaScanData> scanDatas) {
+ if (mFrameworkCallback == null) return;
+ WifiScanner.ScanData[] frameworkScanDatas = hidlToFrameworkScanDatas(cmdId, scanDatas);
+ mFrameworkCallback.onBackgroundScanResults(cmdId, frameworkScanDatas);
+ }
+
+ @Override
+ public void onRssiThresholdBreached(int cmdId, byte[/* 6 */] currBssid, int currRssi) {
+ if (mFrameworkCallback == null) return;
+ mFrameworkCallback.onRssiThresholdBreached(cmdId, currBssid, currRssi);
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/hotspot2/LegacyPasspointConfig.java b/service/java/com/android/server/wifi/hotspot2/LegacyPasspointConfig.java
index 5f455f5174..8022ffb415 100644
--- a/service/java/com/android/server/wifi/hotspot2/LegacyPasspointConfig.java
+++ b/service/java/com/android/server/wifi/hotspot2/LegacyPasspointConfig.java
@@ -56,6 +56,7 @@ public class LegacyPasspointConfig {
@Override
public int hashCode() {
- return Objects.hash(mFqdn, mFriendlyName, mRoamingConsortiumOis, mRealm, mImsi);
+ return Objects.hash(mFqdn, mFriendlyName, Arrays.hashCode(mRoamingConsortiumOis), mRealm,
+ mImsi);
}
}
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
index 2853390ee3..b75fb06a7b 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
@@ -35,7 +35,6 @@ 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.os.Handler;
import android.os.Looper;
import android.os.Process;
import android.text.TextUtils;
@@ -47,6 +46,7 @@ import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.Clock;
import com.android.server.wifi.MacAddressUtil;
import com.android.server.wifi.NetworkUpdateResult;
+import com.android.server.wifi.RunnerHandler;
import com.android.server.wifi.WifiCarrierInfoManager;
import com.android.server.wifi.WifiConfigManager;
import com.android.server.wifi.WifiConfigStore;
@@ -119,7 +119,7 @@ public class PasspointManager {
private final PasspointEventHandler mPasspointEventHandler;
private final WifiInjector mWifiInjector;
- private final Handler mHandler;
+ private final RunnerHandler mHandler;
private final WifiKeyStore mKeyStore;
private final PasspointObjectFactory mObjectFactory;
@@ -356,7 +356,7 @@ public class PasspointManager {
mAppOps.stopWatchingMode(appOpsChangedListener);
}
- public PasspointManager(Context context, WifiInjector wifiInjector, Handler handler,
+ public PasspointManager(Context context, WifiInjector wifiInjector, RunnerHandler handler,
WifiNative wifiNative, WifiKeyStore keyStore, Clock clock,
PasspointObjectFactory objectFactory, WifiConfigManager wifiConfigManager,
WifiConfigStore wifiConfigStore,
@@ -388,7 +388,7 @@ public class PasspointManager {
sPasspointManager = this;
mMacAddressUtil = macAddressUtil;
mClock = clock;
- mHandler.postAtFrontOfQueue(() ->
+ mHandler.postToFront(() ->
mWifiConfigManager.addOnNetworkUpdateListener(
new PasspointManager.OnNetworkUpdateListener()));
mWifiPermissionsUtil = wifiPermissionsUtil;
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
index 28ab21da65..51832ea35c 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
@@ -576,6 +576,7 @@ public class PasspointProvider {
WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
enterpriseConfig.setRealm(mConfig.getCredential().getRealm());
enterpriseConfig.setDomainSuffixMatch(mConfig.getHomeSp().getFqdn());
+ enterpriseConfig.setMinimumTlsVersion(mConfig.getCredential().getMinimumTlsVersion());
if (mConfig.getCredential().getUserCredential() != null) {
buildEnterpriseConfigForUserCredential(enterpriseConfig,
mConfig.getCredential().getUserCredential());
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointXmlUtils.java b/service/java/com/android/server/wifi/hotspot2/PasspointXmlUtils.java
index df3107fdba..df6d8c2231 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointXmlUtils.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointXmlUtils.java
@@ -125,6 +125,7 @@ public class PasspointXmlUtils {
private static final String XML_TAG_IS_OEM_PRIVATE = "IsOemPrivate";
private static final String XML_TAG_DECORATED_IDENTITY_PREFIX = "DecoratedIdentityPrefix";
private static final String XML_TAG_SUBSCRIPTION_GROUP = "SubscriptionGroup";
+ private static final String XML_TAG_MINIMUM_TLS_VERSION = "MinimumTlsVersion";
/**
* Serialize a {@link PasspointConfiguration} to the output stream as a XML block.
@@ -343,6 +344,8 @@ public class PasspointXmlUtils {
XmlUtil.writeNextValue(out, XML_TAG_REALM, credential.getRealm());
XmlUtil.writeNextValue(out, XML_TAG_CHECK_AAA_SERVER_CERT_STATUS,
credential.getCheckAaaServerCertStatus());
+ XmlUtil.writeNextValue(out, XML_TAG_MINIMUM_TLS_VERSION,
+ credential.getMinimumTlsVersion());
serializeUserCredential(out, credential.getUserCredential());
serializeCertCredential(out, credential.getCertCredential());
serializeSimCredential(out, credential.getSimCredential());
@@ -629,6 +632,9 @@ public class PasspointXmlUtils {
case XML_TAG_CHECK_AAA_SERVER_CERT_STATUS:
credential.setCheckAaaServerCertStatus((boolean) value);
break;
+ case XML_TAG_MINIMUM_TLS_VERSION:
+ credential.setMinimumTlsVersion((int) value);
+ break;
default:
Log.w(TAG, "Unknown value under Credential: "
+ name[0]);
diff --git a/service/java/com/android/server/wifi/mockwifi/MockWifiNl80211Manager.java b/service/java/com/android/server/wifi/mockwifi/MockWifiNl80211Manager.java
new file mode 100644
index 0000000000..4e135fc7a0
--- /dev/null
+++ b/service/java/com/android/server/wifi/mockwifi/MockWifiNl80211Manager.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 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.mockwifi;
+
+import android.content.Context;
+import android.net.wifi.nl80211.WifiNl80211Manager;
+import android.os.IBinder;
+
+/**
+ * Mocked WifiNl80211Manager
+ */
+public class MockWifiNl80211Manager {
+ private static final String TAG = "MockWifiNl80211Manager";
+
+ private Context mContext;
+ private WifiNl80211Manager mMockWifiNl80211Manager;
+
+ public MockWifiNl80211Manager(IBinder wificondBinder, Context context) {
+ mContext = context;
+ mMockWifiNl80211Manager = new WifiNl80211Manager(mContext, wificondBinder);
+ }
+
+ public WifiNl80211Manager getWifiNl80211Manager() {
+ return mMockWifiNl80211Manager;
+ }
+}
diff --git a/service/java/com/android/server/wifi/mockwifi/MockWifiServiceUtil.java b/service/java/com/android/server/wifi/mockwifi/MockWifiServiceUtil.java
new file mode 100644
index 0000000000..dbce1ef611
--- /dev/null
+++ b/service/java/com/android/server/wifi/mockwifi/MockWifiServiceUtil.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2022 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.mockwifi;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.util.Log;
+
+/** This class provides wrapper APIs for binding interfaces to mock service. */
+public class MockWifiServiceUtil {
+ private static final String TAG = "MockWifiModemUtil";
+ private static final String BIND_NL80211 = "android.wifi.mockwifimodem.nl80211";
+ private static final int MOCK_NL80211_SERVICE = 0;
+
+ public static final int MIN_SERVICE_IDX = MOCK_NL80211_SERVICE;
+ public static final int NUM_SERVICES = 1;
+ public static final int BINDER_RETRY_MILLIS = 3 * 100;
+ public static final int BINDER_MAX_RETRY = 3;
+
+ private Context mContext;
+ private String mServiceName;
+ private String mPackageName;
+ private MockWifiNl80211Manager mMockWifiNl80211Manager;
+ private IBinder mMockNl80211Binder;
+ private ServiceConnection mMockNl80211ServiceConnection;
+
+ public MockWifiServiceUtil(Context context, String serviceName) {
+ mContext = context;
+ String[] componentInfo = serviceName.split("/", 2);
+ mPackageName = componentInfo[0];
+ mServiceName = componentInfo[1];
+ }
+
+ private class MockModemConnection implements ServiceConnection {
+ private int mService;
+
+ MockModemConnection(int module) {
+ mService = module;
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder binder) {
+ Log.d(TAG, "Wifi mock Service " + getModuleName(mService) + " - onServiceConnected");
+ if (mService == MOCK_NL80211_SERVICE) {
+ mMockNl80211Binder = binder;
+ mMockWifiNl80211Manager = new MockWifiNl80211Manager(mMockNl80211Binder, mContext);
+ }
+
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.d(TAG, "Wifi mock Service " + getModuleName(mService)
+ + " - onServiceDisconnected");
+ if (mService == MOCK_NL80211_SERVICE) {
+ mMockNl80211Binder = null;
+ mMockWifiNl80211Manager = null;
+ }
+ }
+ }
+
+ private boolean bindModuleToMockModemService(
+ String actionName, ServiceConnection serviceConnection) {
+ boolean status = false;
+
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(mPackageName, mServiceName));
+ intent.setAction(actionName);
+
+ status = mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
+ return status;
+ }
+
+ /** waitForBinder */
+ public IBinder getServiceBinder(int service) {
+ switch (service) {
+ case MOCK_NL80211_SERVICE:
+ return mMockNl80211Binder;
+ default:
+ return null;
+ }
+ }
+
+ /** Binding interfaces with mock modem service */
+ public void bindAllMockModemService() {
+ for (int service = MIN_SERVICE_IDX; service < NUM_SERVICES; service++) {
+ bindToMockModemService(service);
+ }
+ }
+
+ /** bindToMockModemService */
+ public void bindToMockModemService(int service) {
+ // Based on {@code service} to get each mocked HAL binder
+ if (service == MOCK_NL80211_SERVICE) {
+ mMockNl80211ServiceConnection = new MockModemConnection(MOCK_NL80211_SERVICE);
+
+ boolean status =
+ bindModuleToMockModemService(BIND_NL80211, mMockNl80211ServiceConnection);
+ if (!status) {
+ Log.d(TAG, getModuleName(service) + " bind fail");
+ mMockNl80211ServiceConnection = null;
+ }
+ }
+ }
+
+ public String getServiceName() {
+ return mServiceName;
+ }
+
+ private ServiceConnection getServiceConnection(int service) {
+ switch (service) {
+ case MOCK_NL80211_SERVICE:
+ return mMockNl80211ServiceConnection;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Returns name of the provided service.
+ */
+ public String getModuleName(int service) {
+ switch (service) {
+ case MOCK_NL80211_SERVICE:
+ return "nl80211";
+ default:
+ return "none";
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java
index 8aa77baa85..2a62b6c12b 100644
--- a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java
+++ b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackAidlImpl.java
@@ -18,6 +18,7 @@ package com.android.server.wifi.p2p;
import android.annotation.NonNull;
import android.hardware.wifi.supplicant.ISupplicantP2pIfaceCallback;
+import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
import android.hardware.wifi.supplicant.P2pStatusCode;
import android.hardware.wifi.supplicant.WpsConfigMethods;
@@ -253,6 +254,27 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
public void onGroupStarted(String groupIfName, boolean isGroupOwner, byte[] ssid,
int frequency, byte[] psk, String passphrase, byte[] goDeviceAddress,
boolean isPersistent) {
+ onGroupStarted(groupIfName, isGroupOwner, ssid, frequency, psk, passphrase, goDeviceAddress,
+ isPersistent, /* goInterfaceAddress */ null);
+ }
+
+ /**
+ * Used to indicate the start of a P2P group, with some parameters describing the group.
+ *
+ * @param groupStartedEventParams Parameters describing the P2P group.
+ */
+ @Override
+ public void onGroupStartedWithParams(P2pGroupStartedEventParams groupStartedEventParams) {
+ onGroupStarted(groupStartedEventParams.groupInterfaceName,
+ groupStartedEventParams.isGroupOwner, groupStartedEventParams.ssid,
+ groupStartedEventParams.frequencyMHz, groupStartedEventParams.psk,
+ groupStartedEventParams.passphrase, groupStartedEventParams.goDeviceAddress,
+ groupStartedEventParams.isPersistent, groupStartedEventParams.goInterfaceAddress);
+ }
+
+ private void onGroupStarted(String groupIfName, boolean isGroupOwner, byte[] ssid,
+ int frequency, byte[] psk, String passphrase, byte[] goDeviceAddress,
+ boolean isPersistent, byte[] goInterfaceAddress) {
if (groupIfName == null) {
Log.e(TAG, "Missing group interface name.");
return;
@@ -291,6 +313,8 @@ public class SupplicantP2pIfaceCallbackAidlImpl extends ISupplicantP2pIfaceCallb
return;
}
+ group.interfaceAddress = goInterfaceAddress;
+
group.setOwner(owner);
mMonitor.broadcastP2pGroupStarted(mInterface, group);
}
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 e29205e0f9..bacb5c7cba 100644
--- a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlV1_4Impl.java
+++ b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlV1_4Impl.java
@@ -24,6 +24,7 @@ import android.util.Log;
import com.android.server.wifi.util.NativeUtil;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* Class used for processing all P2P callbacks.
@@ -320,7 +321,7 @@ public class SupplicantP2pIfaceCallbackHidlV1_4Impl
}
logd("R2 Device discovered on " + mInterface + ": "
- + device + " R2 Info:" + wfdR2DeviceInfo);
+ + device + " R2 Info:" + Arrays.toString(wfdR2DeviceInfo));
mMonitor.broadcastP2pDeviceFound(mInterface, device);
}
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
index 970c31e44c..44462d26f0 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
@@ -18,7 +18,6 @@ package com.android.server.wifi.p2p;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.wifi.V1_0.IWifiP2pIface;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.ScanResult;
import android.net.wifi.nl80211.WifiNl80211Manager;
@@ -57,7 +56,7 @@ public class WifiP2pNative {
private final HalDeviceManager mHalDeviceManager;
private final PropertyService mPropertyService;
private final WifiVendorHal mWifiVendorHal;
- private IWifiP2pIface mIWifiP2pIface;
+ private String mP2pIfaceName;
private InterfaceDestroyedListenerInternal mInterfaceDestroyedListener;
// Cache the features and return it when P2P interface is not up.
private long mSupportedFeatures = -1L;
@@ -79,7 +78,7 @@ public class WifiP2pNative {
if (!TextUtils.isEmpty(ifaceName)) {
mSupplicantP2pIfaceHal.teardownIface(ifaceName);
}
- mIWifiP2pIface = null;
+ mP2pIfaceName = null;
mValid = false;
}
@@ -163,6 +162,7 @@ public class WifiP2pNative {
private static final String P2P_IFACE_NAME = "p2p0";
private static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface";
+
/**
* Helper function to handle creation of P2P iface.
* For devices which do not the support the HAL, this will bypass HalDeviceManager &
@@ -170,19 +170,13 @@ public class WifiP2pNative {
*/
private String createP2pIface(Handler handler, WorkSource requestorWs) {
if (mHalDeviceManager.isSupported()) {
- mIWifiP2pIface = mHalDeviceManager
- .createP2pIface(mInterfaceDestroyedListener, handler, requestorWs);
- if (mIWifiP2pIface == null) {
+ mP2pIfaceName = mHalDeviceManager.createP2pIface(
+ mInterfaceDestroyedListener, handler, requestorWs);
+ if (mP2pIfaceName == null) {
Log.e(TAG, "Failed to create P2p iface in HalDeviceManager");
return null;
}
- String ifaceName = HalDeviceManager.getName(mIWifiP2pIface);
- if (TextUtils.isEmpty(ifaceName)) {
- Log.e(TAG, "Failed to get p2p iface name");
- teardownInterface();
- return null;
- }
- return ifaceName;
+ return mP2pIfaceName;
} else {
Log.i(TAG, "Vendor Hal is not supported, ignoring createP2pIface.");
return mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME);
@@ -200,7 +194,7 @@ public class WifiP2pNative {
@Nullable HalDeviceManager.InterfaceDestroyedListener destroyedListener,
@NonNull Handler handler, @NonNull WorkSource requestorWs) {
Log.d(TAG, "Setup P2P interface");
- if (mIWifiP2pIface == null) {
+ if (mP2pIfaceName == null) {
mInterfaceDestroyedListener = (null == destroyedListener)
? null
: new InterfaceDestroyedListenerInternal(destroyedListener);
@@ -226,9 +220,9 @@ public class WifiP2pNative {
Log.i(TAG, "P2P interface setup completed");
return ifaceName;
} else {
- Log.i(TAG, "P2P interface is already existed");
+ Log.i(TAG, "P2P interface already exists");
return mHalDeviceManager.isSupported()
- ? HalDeviceManager.getName(mIWifiP2pIface)
+ ? mP2pIfaceName
: mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME);
}
}
@@ -239,11 +233,10 @@ public class WifiP2pNative {
public void teardownInterface() {
Log.d(TAG, "Teardown P2P interface");
if (mHalDeviceManager.isSupported()) {
- if (mIWifiP2pIface != null) {
- String ifaceName = HalDeviceManager.getName(mIWifiP2pIface);
- mHalDeviceManager.removeIface(mIWifiP2pIface);
+ if (mP2pIfaceName != null) {
+ mHalDeviceManager.removeP2pIface(mP2pIfaceName);
if (null != mInterfaceDestroyedListener) {
- mInterfaceDestroyedListener.teardownAndInvalidate(ifaceName);
+ mInterfaceDestroyedListener.teardownAndInvalidate(mP2pIfaceName);
}
Log.i(TAG, "P2P interface teardown completed");
}
@@ -261,8 +254,8 @@ public class WifiP2pNative {
*/
public boolean replaceRequestorWs(WorkSource requestorWs) {
if (mHalDeviceManager.isSupported()) {
- if (mIWifiP2pIface == null) return false;
- return mHalDeviceManager.replaceRequestorWs(mIWifiP2pIface, requestorWs);
+ if (mP2pIfaceName == null) return false;
+ return mHalDeviceManager.replaceRequestorWsForP2pIface(mP2pIfaceName, requestorWs);
} else {
Log.i(TAG, "HAL is not supported. Ignore replace requestorWs");
return true;
@@ -289,7 +282,7 @@ public class WifiP2pNative {
return 0L;
}
teardownInterface();
- mIWifiP2pIface = null;
+ mP2pIfaceName = null;
return mSupportedFeatures;
}
@@ -929,7 +922,7 @@ public class WifiP2pNative {
* Set vendor-specific information elements to the native service.
*
* @param vendorElements the vendor opaque data.
- * @return true, if opeartion was successful.
+ * @return true, if operation was successful.
*/
public boolean setVendorElements(Set<ScanResult.InformationElement> vendorElements) {
return mSupplicantP2pIfaceHal.setVendorElements(vendorElements);
@@ -945,8 +938,8 @@ public class WifiP2pNative {
/** Indicate whether or not 5GHz/6GHz DBS is supported. */
public boolean is5g6gDbsSupported() {
- if (null == mIWifiP2pIface) return false;
+ if (mP2pIfaceName == null) return false;
if (!mHalDeviceManager.isSupported()) return false;
- return mHalDeviceManager.is5g6gDbsSupported(mIWifiP2pIface);
+ 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 6109660bbe..6f3edc0c35 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -16,6 +16,9 @@
package com.android.server.wifi.p2p;
+import static android.net.wifi.p2p.WifiP2pConfig.GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP;
+import static android.net.wifi.p2p.WifiP2pConfig.GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL;
+
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_DEVICE_NAME;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_PENDING_FACTORY_RESET;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_VERBOSE_LOGGING_ENABLED;
@@ -120,6 +123,7 @@ import com.android.server.wifi.p2p.ExternalApproverManager.ApproverEntry;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.proto.nano.WifiMetricsProto.GroupEvent;
import com.android.server.wifi.proto.nano.WifiMetricsProto.P2pConnectionEvent;
+import com.android.server.wifi.util.LastCallerInfoManager;
import com.android.server.wifi.util.NetdWrapper;
import com.android.server.wifi.util.StringUtil;
import com.android.server.wifi.util.WaitingState;
@@ -130,9 +134,11 @@ import com.android.wifi.resources.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.net.Inet4Address;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
+import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
@@ -168,7 +174,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
+ " Idle Shutdown Message Timeout";
private boolean mVerboseLoggingEnabled = false;
private boolean mVerboseHalLoggingEnabled = false;
- private static final String NETWORKTYPE = "WIFI_P2P";
+ private static final String NETWORK_TYPE = "WIFI_P2P";
@VisibleForTesting
static final String DEFAULT_DEVICE_NAME_PREFIX = "Android_";
// The maxinum length of the device name is 32 bytes, see
@@ -194,29 +200,29 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// Otherwise it will cause interface down before function timeout.
static final long P2P_INTERFACE_IDLE_SHUTDOWN_TIMEOUT_MS = 150_000;
- private Context mContext;
+ private final Context mContext;
NetdWrapper mNetdWrapper;
private IIpClient mIpClient;
private int mIpClientStartIndex = 0;
private DhcpResultsParcelable mDhcpResultsParcelable;
- private P2pStateMachine mP2pStateMachine;
- private AsyncChannel mReplyChannel = new AsyncChannel();
+ private final P2pStateMachine mP2pStateMachine;
+ private final AsyncChannel mReplyChannel = new AsyncChannel();
private AsyncChannel mWifiChannel;
- private LocationManager mLocationManager;
- private WifiInjector mWifiInjector;
- private WifiPermissionsUtil mWifiPermissionsUtil;
- private FrameworkFacade mFrameworkFacade;
- private WifiSettingsConfigStore mSettingsConfigStore;
- private WifiP2pMetrics mWifiP2pMetrics;
+ private final WifiInjector mWifiInjector;
+ private final WifiPermissionsUtil mWifiPermissionsUtil;
+ private final FrameworkFacade mFrameworkFacade;
+ private final WifiSettingsConfigStore mSettingsConfigStore;
+ private final WifiP2pMetrics mWifiP2pMetrics;
private final BuildProperties mBuildProperties;
// This will only be null if SdkLevel is not at least S
- @Nullable private CoexManager mCoexManager;
- private WifiGlobals mWifiGlobals;
- private UserManager mUserManager;
- private InterfaceConflictManager mInterfaceConflictManager;
- private WifiP2pNative mWifiNative;
+ @Nullable private final CoexManager mCoexManager;
+ private final WifiGlobals mWifiGlobals;
+ private final UserManager mUserManager;
+ private final InterfaceConflictManager mInterfaceConflictManager;
+ private final WifiP2pNative mWifiNative;
+ private final LastCallerInfoManager mLastCallerInfoManager;
private static final Boolean JOIN_GROUP = true;
private static final Boolean FORM_GROUP = false;
@@ -319,7 +325,6 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private static final int P2P_CONNECT_TRIGGER_INVITATION_REQ = 2;
private static final int P2P_CONNECT_TRIGGER_OTHER = 3;
-
private final boolean mP2pSupported;
private final WifiP2pDevice mThisDevice = new WifiP2pDevice();
@@ -366,23 +371,23 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private String mServiceDiscReqId;
// clients(application) information list
- private HashMap<Messenger, ClientInfo> mClientInfoList = new HashMap<Messenger, ClientInfo>();
+ private final HashMap<Messenger, ClientInfo> mClientInfoList = new HashMap<>();
// clients(application) channel list
- private Map<IBinder, Messenger> mClientChannelList = new HashMap<IBinder, Messenger>();
+ private final Map<IBinder, Messenger> mClientChannelList = new HashMap<>();
// clients(application) approver manager
- private ExternalApproverManager mExternalApproverManager = new ExternalApproverManager();
+ private final ExternalApproverManager mExternalApproverManager = new ExternalApproverManager();
// client(application) attribution source list
private Map<IBinder, AttributionSource> mClientAttributionSource = new HashMap<>();
// client(application) vendor-specific information element list
- private Map<String, HashSet<ScanResult.InformationElement>> mVendorElements =
+ private final Map<String, HashSet<ScanResult.InformationElement>> mVendorElements =
new HashMap<>();
// peer authorizing timestamp which is indexed by the peer MAC address.
- private Map<String, Long> mPeerAuthorizingTimestamp = new HashMap<>();
+ private final Map<String, Long> mPeerAuthorizingTimestamp = new HashMap<>();
// The empty device address set by wpa_supplicant.
private static final String EMPTY_DEVICE_ADDRESS = "00:00:00:00:00:00";
@@ -520,7 +525,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
*/
private class ClientHandler extends Handler {
- ClientHandler(String tag, android.os.Looper looper) {
+ ClientHandler(String tag, Looper looper) {
super(looper);
}
@@ -573,18 +578,18 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
}
}
- private ClientHandler mClientHandler;
+ private final ClientHandler mClientHandler;
private NetworkInfo makeNetworkInfo() {
final NetworkInfo info = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P,
- 0, NETWORKTYPE, "");
+ 0, NETWORK_TYPE, "");
if (mDetailedState != NetworkInfo.DetailedState.IDLE) {
info.setDetailedState(mDetailedState, null, null);
}
return info;
}
- private class DeathHandlerData {
+ private static class DeathHandlerData {
DeathHandlerData(int uid, DeathRecipient dr, Messenger m, WorkSource ws, int displayId) {
mUid = uid;
mDeathRecipient = dr;
@@ -605,11 +610,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
final WorkSource mWorkSource;
final int mDisplayId;
}
- private Object mLock = new Object();
+ private final Object mLock = new Object();
private final Map<IBinder, DeathHandlerData> mDeathDataByBinder = new ConcurrentHashMap<>();
private final Map<Integer, WorkSource> mActiveClients = new ConcurrentHashMap<>();
- private Clock mClock;
+ private final Clock mClock;
public WifiP2pServiceImpl(Context context, WifiInjector wifiInjector) {
mContext = context;
@@ -633,6 +638,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
HandlerThread wifiP2pThread = mWifiInjector.getWifiP2pServiceHandlerThread();
mClientHandler = new ClientHandler(TAG, wifiP2pThread.getLooper());
mWifiNative = mWifiInjector.getWifiP2pNative();
+ mLastCallerInfoManager = mWifiInjector.getLastCallerInfoManager();
mP2pStateMachine = new P2pStateMachine(TAG, wifiP2pThread.getLooper(), mP2pSupported);
mP2pStateMachine.setDbg(false); // can enable for very verbose logs
mP2pStateMachine.start();
@@ -706,20 +712,24 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mDhcpResultsParcelable = null;
}
- private void startIpClient(String ifname, Handler smHandler) {
+ private void startIpClient(String ifname, Handler smHandler,
+ int groupClientIpProvisioningMode) {
stopIpClient();
mIpClientStartIndex++;
IpClientUtil.makeIpClient(mContext, ifname, new IpClientCallbacksImpl(
- mIpClientStartIndex, smHandler));
+ mIpClientStartIndex, smHandler, groupClientIpProvisioningMode));
}
private class IpClientCallbacksImpl extends IpClientCallbacks {
private final int mStartIndex;
private final Handler mHandler;
+ private final int mGroupClientIpProvisioningMode;
- private IpClientCallbacksImpl(int startIndex, Handler handler) {
+ private IpClientCallbacksImpl(int startIndex, Handler handler,
+ int groupClientIpProvisioningMode) {
mStartIndex = startIndex;
mHandler = handler;
+ mGroupClientIpProvisioningMode = groupClientIpProvisioningMode;
}
@Override
@@ -731,12 +741,25 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
mIpClient = ipClient;
- final ProvisioningConfiguration config =
- new ProvisioningConfiguration.Builder()
+ ProvisioningConfiguration config;
+ switch (mGroupClientIpProvisioningMode) {
+ case GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL:
+ config = new ProvisioningConfiguration.Builder()
+ .withoutIPv4()
+ .withIpv6LinkLocalOnly()
+ .withRandomMacAddress()
+ .build();
+ break;
+ case GROUP_CLIENT_IP_PROVISIONING_MODE_IPV4_DHCP:
+ default:
+ // DHCP IPV4 by default.
+ config = new ProvisioningConfiguration.Builder()
.withoutIpReachabilityMonitor()
.withPreDhcpAction(30 * 1000)
.withProvisioningTimeoutMs(36 * 1000)
.build();
+ }
+
try {
mIpClient.startProvisioning(config.toStableParcelable());
} catch (RemoteException e) {
@@ -759,7 +782,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
@Override
public void onProvisioningSuccess(LinkProperties newLp) {
- mP2pStateMachine.sendMessage(IPC_PROVISIONING_SUCCESS);
+ mP2pStateMachine.sendMessage(IPC_PROVISIONING_SUCCESS, newLp);
}
@Override
public void onProvisioningFailure(LinkProperties newLp) {
@@ -998,34 +1021,38 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
*/
private class P2pStateMachine extends StateMachine {
- private DefaultState mDefaultState = new DefaultState();
- private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
- private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
- private P2pDisabledContainerState mP2pDisabledContainerState =
+ private final DefaultState mDefaultState = new DefaultState();
+ private final P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
+ private final P2pDisablingState mP2pDisablingState = new P2pDisablingState();
+ private final P2pDisabledContainerState mP2pDisabledContainerState =
new P2pDisabledContainerState();
- private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
- private WaitingState mWaitingState = new WaitingState(this);
- private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
+ private final P2pDisabledState mP2pDisabledState = new P2pDisabledState();
+ private final WaitingState mWaitingState = new WaitingState(this);
+ private final P2pEnabledState mP2pEnabledState = new P2pEnabledState();
// Inactive is when p2p is enabled with no connectivity
- private InactiveState mInactiveState = new InactiveState();
- private GroupCreatingState mGroupCreatingState = new GroupCreatingState();
- private UserAuthorizingInviteRequestState mUserAuthorizingInviteRequestState =
+ private final InactiveState mInactiveState = new InactiveState();
+ private final GroupCreatingState mGroupCreatingState = new GroupCreatingState();
+ private final UserAuthorizingInviteRequestState mUserAuthorizingInviteRequestState =
new UserAuthorizingInviteRequestState();
- private UserAuthorizingNegotiationRequestState mUserAuthorizingNegotiationRequestState =
+ private final UserAuthorizingNegotiationRequestState
+ mUserAuthorizingNegotiationRequestState =
new UserAuthorizingNegotiationRequestState();
- private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
- private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
- private FrequencyConflictState mFrequencyConflictState = new FrequencyConflictState();
-
- private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
- private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
- private OngoingGroupRemovalState mOngoingGroupRemovalState = new OngoingGroupRemovalState();
-
- private WifiP2pMonitor mWifiMonitor = mWifiInjector.getWifiP2pMonitor();
+ private final ProvisionDiscoveryState mProvisionDiscoveryState =
+ new ProvisionDiscoveryState();
+ private final GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
+ private final FrequencyConflictState mFrequencyConflictState = new FrequencyConflictState();
+
+ private final GroupCreatedState mGroupCreatedState = new GroupCreatedState();
+ private final UserAuthorizingJoinState mUserAuthorizingJoinState =
+ new UserAuthorizingJoinState();
+ private final OngoingGroupRemovalState mOngoingGroupRemovalState =
+ new OngoingGroupRemovalState();
+
+ private final WifiP2pMonitor mWifiMonitor = mWifiInjector.getWifiP2pMonitor();
private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
private String mInterfaceName;
- private List<CoexUnsafeChannel> mCoexUnsafeChannels = new ArrayList<>();
+ private final List<CoexUnsafeChannel> mCoexUnsafeChannels = new ArrayList<>();
private int mUserListenChannel = 0;
private int mUserOperatingChannel = 0;
@@ -1147,12 +1174,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
(key, newValue) -> enableVerboseLogging(newValue),
getHandler());
if (SdkLevel.isAtLeastS()) {
- mCoexManager.registerCoexListener(new CoexManager.CoexListener() {
- @Override
- public void onCoexUnsafeChannelsChanged() {
- checkCoexUnsafeChannels();
- }
- });
+ mCoexManager.registerCoexListener(this::checkCoexUnsafeChannels);
}
if (SdkLevel.isAtLeastT()) {
mContext.registerReceiver(
@@ -1610,7 +1632,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
ac.connect(mContext, getHandler(), message.replyTo);
break;
case BLOCK_DISCOVERY:
- mDiscoveryBlocked = (message.arg1 == ENABLED ? true : false);
+ mDiscoveryBlocked = (message.arg1 == ENABLED);
// always reset this - we went to a state that doesn't support discovery so
// it would have stopped regardless
mDiscoveryPostponed = false;
@@ -2463,7 +2485,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
}
case BLOCK_DISCOVERY:
- boolean blocked = (message.arg1 == ENABLED ? true : false);
+ boolean blocked = (message.arg1 == ENABLED);
if (mDiscoveryBlocked == blocked) break;
mDiscoveryBlocked = blocked;
if (blocked && mDiscoveryStarted) {
@@ -2520,6 +2542,14 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
WifiP2pManager.BUSY);
break;
}
+ int apiType = WifiManager.API_P2P_DISCOVER_PEERS;
+ if (scanType == WifiP2pManager.WIFI_P2P_SCAN_SOCIAL) {
+ 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;
+ }
+ mLastCallerInfoManager.put(apiType, Process.myTid(), uid, 0, packageName,
+ true);
// do not send service discovery request while normal find operation.
clearSupplicantServiceRequest();
Log.e(TAG, "-------discover_peers before p2pFind");
@@ -2538,6 +2568,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
sendP2pDiscoveryChangedBroadcast(false);
break;
case WifiP2pManager.STOP_DISCOVERY:
+ mLastCallerInfoManager.put(WifiManager.API_P2P_STOP_PEER_DISCOVERY,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
if (mWifiNative.p2pStopFind()) {
replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
} else {
@@ -2621,7 +2654,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
int uid = message.sendingUid;
Bundle extras = (Bundle) message.obj;
- boolean hasPermission = false;
+ boolean hasPermission;
if (isPlatformOrTargetSdkLessThanT(packageName, uid)) {
hasPermission = mWifiPermissionsUtil.checkCanAccessWifiDirect(
packageName,
@@ -2637,7 +2670,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
}
if (mVerboseLoggingEnabled) logd(getName() + " add service");
- WifiP2pServiceInfo servInfo = (WifiP2pServiceInfo)
+ WifiP2pServiceInfo servInfo =
extras.getParcelable(WifiP2pManager.EXTRA_PARAM_KEY_SERVICE_INFO);
if (addLocalService(message.replyTo, servInfo)) {
replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_SUCCEEDED);
@@ -2719,7 +2752,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
int uid = message.sendingUid;
Bundle extras = (Bundle) message.obj;
- boolean hasPermission = false;
+ boolean hasPermission;
if (isPlatformOrTargetSdkLessThanT(packageName, uid)) {
hasPermission = mWifiPermissionsUtil.checkCanAccessWifiDirect(
packageName,
@@ -2733,6 +2766,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
break;
}
+ mLastCallerInfoManager.put(WifiManager.API_P2P_START_LISTENING,
+ Process.myTid(), uid, 0, packageName, true);
if (mVerboseLoggingEnabled) logd(getName() + " start listen mode");
mWifiNative.p2pStopFind();
if (mWifiNative.p2pExtListen(true,
@@ -2746,6 +2781,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
break;
case WifiP2pManager.STOP_LISTEN:
+ mLastCallerInfoManager.put(WifiManager.API_P2P_STOP_LISTENING,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
if (mVerboseLoggingEnabled) logd(getName() + " stop listen mode");
if (mWifiNative.p2pExtListen(false, 0, 0)) {
replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
@@ -2768,6 +2806,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
Log.e(TAG, "Illegal arguments(s)");
break;
}
+ mLastCallerInfoManager.put(WifiManager.API_P2P_SET_CHANNELS,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
Bundle p2pChannels = (Bundle) message.obj;
mUserListenChannel = p2pChannels.getInt("lc", 0);
mUserOperatingChannel = p2pChannels.getInt("oc", 0);
@@ -2861,6 +2902,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// remain at this state.
break;
}
+ mLastCallerInfoManager.put(WifiManager.API_P2P_CONNECT,
+ Process.myTid(), uid, 0, packageName, true);
if (mVerboseLoggingEnabled) logd(getName() + " sending connect");
WifiP2pConfig config = (WifiP2pConfig)
extras.getParcelable(WifiP2pManager.EXTRA_PARAM_KEY_CONFIG);
@@ -2911,6 +2954,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
}
case WifiP2pManager.STOP_DISCOVERY:
+ mLastCallerInfoManager.put(WifiManager.API_P2P_STOP_PEER_DISCOVERY,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
if (mWifiNative.p2pStopFind()) {
// When discovery stops in inactive state, flush to clear
// state peer data
@@ -3027,7 +3073,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
int uid = message.sendingUid;
Bundle extras = (Bundle) message.obj;
- boolean hasPermission = false;
+ boolean hasPermission;
if (isPlatformOrTargetSdkLessThanT(packageName, uid)) {
hasPermission = mWifiPermissionsUtil.checkCanAccessWifiDirect(
packageName,
@@ -3045,8 +3091,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
mAutonomousGroup = true;
int netId = message.arg1;
- config = (WifiP2pConfig)
- extras.getParcelable(WifiP2pManager.EXTRA_PARAM_KEY_CONFIG);
+ config = extras.getParcelable(WifiP2pManager.EXTRA_PARAM_KEY_CONFIG);
+ mLastCallerInfoManager.put(config == null
+ ? WifiManager.API_P2P_CREATE_GROUP
+ : WifiManager.API_P2P_CREATE_GROUP_P2P_CONFIG,
+ Process.myTid(), uid, 0, packageName, true);
boolean ret = false;
if (config != null) {
if (isConfigValidAsGroup(config)) {
@@ -3054,8 +3103,6 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
P2pConnectionEvent.CONNECTION_FAST,
config, GroupEvent.GROUP_OWNER, uid);
ret = mWifiNative.p2pGroupAdd(config, false);
- } else {
- ret = false;
}
} else if (netId == WifiP2pGroup.NETWORK_ID_PERSISTENT) {
// check if the go persistent group is present.
@@ -3118,7 +3165,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
int uid = message.sendingUid;
Bundle extras = (Bundle) message.obj;
- boolean hasPermission = false;
+ boolean hasPermission;
if (isPlatformOrTargetSdkLessThanT(packageName, uid)) {
hasPermission = mWifiPermissionsUtil.checkCanAccessWifiDirect(
packageName,
@@ -3132,6 +3179,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
break;
}
+ mLastCallerInfoManager.put(WifiManager.API_P2P_START_LISTENING,
+ Process.myTid(), uid, 0, packageName, true);
if (mVerboseLoggingEnabled) logd(getName() + " start listen mode");
mWifiNative.p2pStopFind();
if (mWifiNative.p2pExtListen(true,
@@ -3145,6 +3194,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
break;
case WifiP2pManager.STOP_LISTEN:
+ mLastCallerInfoManager.put(WifiManager.API_P2P_STOP_LISTENING,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
if (mVerboseLoggingEnabled) logd(getName() + " stop listen mode");
if (mWifiNative.p2pExtListen(false, 0, 0)) {
replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
@@ -3167,6 +3219,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
Log.e(TAG, "Illegal arguments(s)");
break;
}
+ mLastCallerInfoManager.put(WifiManager.API_P2P_SET_CHANNELS,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
Bundle p2pChannels = (Bundle) message.obj;
mUserListenChannel = p2pChannels.getInt("lc", 0);
mUserOperatingChannel = p2pChannels.getInt("oc", 0);
@@ -3282,6 +3337,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// discovery or for a pending user action, but at the framework
// level, we always treat cancel as succeeded and enter
// an inactive state
+ mLastCallerInfoManager.put(WifiManager.API_P2P_CANCEL_CONNECT,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
mWifiNative.p2pCancelConnect();
mWifiP2pMetrics.endConnectionEvent(
P2pConnectionEvent.CLF_CANCEL);
@@ -3321,7 +3379,6 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
@Override
public boolean processMessage(Message message) {
if (mVerboseLoggingEnabled) logd(getName() + message.toString());
- boolean ret = HANDLED;
switch (message.what) {
case PEER_CONNECTION_USER_ACCEPT:
mWifiNative.p2pStopFind();
@@ -3385,7 +3442,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
default:
return NOT_HANDLED;
}
- return ret;
+ return HANDLED;
}
@Override
@@ -3412,7 +3469,6 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
@Override
public boolean processMessage(Message message) {
if (mVerboseLoggingEnabled) logd(getName() + message.toString());
- boolean ret = HANDLED;
switch (message.what) {
case PEER_CONNECTION_USER_ACCEPT:
mWifiNative.p2pStopFind();
@@ -3451,7 +3507,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
default:
return NOT_HANDLED;
}
- return ret;
+ return HANDLED;
}
@Override
@@ -3635,7 +3691,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
- startIpClient(mGroup.getInterface(), getHandler());
+ startIpClient(mGroup.getInterface(), getHandler(),
+ mSavedPeerConfig.getGroupClientIpProvisioningMode());
WifiP2pDevice groupOwner = mGroup.getOwner();
WifiP2pDevice peer = mPeers.get(groupOwner.deviceAddress);
if (peer != null) {
@@ -3936,8 +3993,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
@Override
public boolean processMessage(Message message) {
if (mVerboseLoggingEnabled) logd(getName() + message.toString());
- WifiP2pDevice device = null;
- String deviceAddress = null;
+ WifiP2pDevice device;
+ String deviceAddress;
switch (message.what) {
case WifiP2pMonitor.AP_STA_CONNECTED_EVENT:
if (message.obj == null) {
@@ -4038,12 +4095,46 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
sendP2pConnectionChangedBroadcast();
break;
case IPC_PROVISIONING_SUCCESS:
+ if (mSavedPeerConfig.getGroupClientIpProvisioningMode()
+ != GROUP_CLIENT_IP_PROVISIONING_MODE_IPV6_LINK_LOCAL) {
+ break;
+ }
+
+ LinkProperties linkProperties = (LinkProperties) message.obj;
+ if (mVerboseLoggingEnabled) {
+ logd("IP provisioning result " + linkProperties);
+ }
+ try {
+ mNetdWrapper.addInterfaceToLocalNetwork(
+ mGroup.getInterface(),
+ linkProperties.getRoutes());
+ } catch (Exception e) {
+ loge("Failed to add iface to local network " + e);
+ mWifiNative.p2pGroupRemove(mGroup.getInterface());
+ }
+
+ byte[] goInterfaceMacAddress = mGroup.interfaceAddress;
+ byte[] goIpv6Address = MacAddress.fromBytes(goInterfaceMacAddress)
+ .getLinkLocalIpv6FromEui48Mac().getAddress();
+ try {
+ InetAddress goIp = Inet6Address.getByAddress(null, goIpv6Address,
+ NetworkInterface.getByName(mGroup.getInterface()));
+ setWifiP2pInfoOnGroupFormationWithInetAddress(goIp);
+ sendP2pConnectionChangedBroadcast();
+ } catch (UnknownHostException | SocketException e) {
+ loge("Unable to retrieve link-local IPv6 address of group owner "
+ + e);
+ mWifiNative.p2pGroupRemove(mGroup.getInterface());
+ }
break;
case IPC_PROVISIONING_FAILURE:
loge("IP provisioning failed");
mWifiNative.p2pGroupRemove(mGroup.getInterface());
break;
case WifiP2pManager.REMOVE_GROUP:
+ mLastCallerInfoManager.put(WifiManager.API_P2P_REMOVE_GROUP,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
if (mVerboseLoggingEnabled) logd(getName() + " remove group");
if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
transitionTo(mOngoingGroupRemovalState);
@@ -4141,6 +4232,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// remain at this state.
break;
}
+ mLastCallerInfoManager.put(WifiManager.API_P2P_CONNECT,
+ Process.myTid(), uid, 0, packageName, true);
WifiP2pConfig config = (WifiP2pConfig)
extras.getParcelable(WifiP2pManager.EXTRA_PARAM_KEY_CONFIG);
if (isConfigInvalid(config)) {
@@ -4226,6 +4319,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
loge("Duplicate group creation event notice, ignore");
break;
case WifiP2pManager.CANCEL_CONNECT:
+ mLastCallerInfoManager.put(WifiManager.API_P2P_CANCEL_CONNECT,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
mWifiNative.p2pCancelConnect();
mWifiP2pMetrics.endConnectionEvent(
P2pConnectionEvent.CLF_CANCEL);
@@ -4964,8 +5060,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private boolean isConfigInvalid(WifiP2pConfig config) {
if (config == null) return true;
if (TextUtils.isEmpty(config.deviceAddress)) return true;
- if (mPeers.get(config.deviceAddress) == null) return true;
- return false;
+ return mPeers.get(config.deviceAddress) == null;
}
/**
@@ -4980,9 +5075,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
byte[] ssidBytes = networkName.getBytes(StandardCharsets.UTF_8);
if (ssidBytes.length < MIN_NETWORK_NAME_BYTES) return false;
- if (ssidBytes.length > MAX_NETWORK_NAME_BYTES) return false;
-
- return true;
+ return ssidBytes.length <= MAX_NETWORK_NAME_BYTES;
}
/**
@@ -4995,12 +5088,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private boolean isConfigValidAsGroup(WifiP2pConfig config) {
if (config == null) return false;
if (TextUtils.isEmpty(config.deviceAddress)) return false;
- if (isValidNetworkName(config.networkName)
- && !TextUtils.isEmpty(config.passphrase)) {
- return true;
- }
-
- return false;
+ return isValidNetworkName(config.networkName)
+ && !TextUtils.isEmpty(config.passphrase);
}
private WifiP2pDevice fetchCurrentDeviceDetails(WifiP2pConfig config) {
@@ -5205,10 +5294,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
if (netId >= 0) {
// Skip WPS and start 4way handshake immediately.
- if (!mWifiNative.p2pGroupAdd(netId)) {
- return false;
- }
- return true;
+ return mWifiNative.p2pGroupAdd(netId);
}
}
@@ -5361,9 +5447,13 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
InetAddress serverInetAddress = serverAddress == null
? null
: InetAddresses.parseNumericAddress(serverAddress);
+ setWifiP2pInfoOnGroupFormationWithInetAddress(serverInetAddress);
+ }
+
+ private void setWifiP2pInfoOnGroupFormationWithInetAddress(InetAddress serverAddress) {
mWifiP2pInfo.groupFormed = true;
mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
- mWifiP2pInfo.groupOwnerAddress = serverInetAddress;
+ mWifiP2pInfo.groupOwnerAddress = serverAddress;
}
private void resetWifiP2pInfo() {
@@ -5377,7 +5467,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (d != null) {
return d.deviceName;
}
- //Treat the address as name if there is no match
+ // Treat the address as name if there is no match
return deviceAddress;
}
@@ -5449,7 +5539,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
decoder.flush(cb);
sb.append(new String(cb.array(), 0, cb.position()));
}
- Log.i(TAG, "P2P SSID postfix: " + sb.toString()
+ Log.i(TAG, "P2P SSID postfix: " + sb
+ " len=" + sb.toString().length()
+ " bytes=" + sb.toString().getBytes(charset).length);
return sb.toString();
@@ -5486,7 +5576,6 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private boolean setWfdInfo(WifiP2pWfdInfo wfdInfo) {
final boolean enabled = wfdInfo.isEnabled();
- boolean success;
if (!mWifiNative.setWfdEnable(enabled)) {
loge("Failed to set wfd enable: " + enabled);
return false;
@@ -5718,7 +5807,6 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
clearSupplicantServiceRequest();
StringBuffer sb = new StringBuffer();
for (ClientInfo c: mClientInfoList.values()) {
- int key;
WifiP2pServiceRequest req;
for (int i = 0; i < c.mReqList.size(); i++) {
req = c.mReqList.valueAt(i);
@@ -5732,10 +5820,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
mServiceDiscReqId = mWifiNative.p2pServDiscReq("00:00:00:00:00:00", sb.toString());
- if (mServiceDiscReqId == null) {
- return false;
- }
- return true;
+ return mServiceDiscReqId != null;
}
/**
@@ -6064,8 +6149,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return false;
}
- mVendorElements.put(packageName,
- new HashSet<ScanResult.InformationElement>(vendorElements));
+ mVendorElements.put(packageName, new HashSet<>(vendorElements));
Set<ScanResult.InformationElement> aggregatedVendorElements = new HashSet<>();
mVendorElements.forEach((k, v) -> aggregatedVendorElements.addAll(v));
@@ -6414,27 +6498,24 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
* Information about a particular client and we track the service discovery requests
* and the local services registered by the client.
*/
- private class ClientInfo {
+ private static class ClientInfo {
// A reference to WifiP2pManager.Channel handler.
// The response of this request is notified to WifiP2pManager.Channel handler
- private Messenger mMessenger;
+ private final Messenger mMessenger;
private String mPackageName;
- private @Nullable String mFeatureId;
-
+ @Nullable private String mFeatureId;
// A service discovery request list.
- private SparseArray<WifiP2pServiceRequest> mReqList;
+ private final SparseArray<WifiP2pServiceRequest> mReqList = new SparseArray<>();
// A local service information list.
- private List<WifiP2pServiceInfo> mServList;
+ private final List<WifiP2pServiceInfo> mServList = new ArrayList<>();
private ClientInfo(Messenger m) {
mMessenger = m;
mPackageName = null;
mFeatureId = null;
- mReqList = new SparseArray();
- mServList = new ArrayList<WifiP2pServiceInfo>();
}
}
diff --git a/service/java/com/android/server/wifi/rtt/RttMetrics.java b/service/java/com/android/server/wifi/rtt/RttMetrics.java
index 0d68e898d9..1c00bdeaf0 100644
--- a/service/java/com/android/server/wifi/rtt/RttMetrics.java
+++ b/service/java/com/android/server/wifi/rtt/RttMetrics.java
@@ -31,6 +31,7 @@ import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.hal.WifiRttController;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.util.MetricsUtils;
@@ -419,37 +420,37 @@ public class RttMetrics {
*/
public static int convertRttStatusTypeToProtoEnum(int rttStatusType) {
switch (rttStatusType) {
- case RttNative.FRAMEWORK_RTT_STATUS_SUCCESS:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS:
return WifiMetricsProto.WifiRttLog.SUCCESS;
- case RttNative.FRAMEWORK_RTT_STATUS_FAILURE:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAILURE:
return WifiMetricsProto.WifiRttLog.FAILURE;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_NO_RSP:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NO_RSP:
return WifiMetricsProto.WifiRttLog.FAIL_NO_RSP;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_REJECTED:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_REJECTED:
return WifiMetricsProto.WifiRttLog.FAIL_REJECTED;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET:
return WifiMetricsProto.WifiRttLog.FAIL_NOT_SCHEDULED_YET;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT:
return WifiMetricsProto.WifiRttLog.FAIL_TM_TIMEOUT;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL:
return WifiMetricsProto.WifiRttLog.FAIL_AP_ON_DIFF_CHANNEL;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY:
return WifiMetricsProto.WifiRttLog.FAIL_NO_CAPABILITY;
- case RttNative.FRAMEWORK_RTT_STATUS_ABORTED:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_ABORTED:
return WifiMetricsProto.WifiRttLog.ABORTED;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS:
return WifiMetricsProto.WifiRttLog.FAIL_INVALID_TS;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL:
return WifiMetricsProto.WifiRttLog.FAIL_PROTOCOL;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE:
return WifiMetricsProto.WifiRttLog.FAIL_SCHEDULE;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER:
return WifiMetricsProto.WifiRttLog.FAIL_BUSY_TRY_LATER;
- case RttNative.FRAMEWORK_RTT_STATUS_INVALID_REQ:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_INVALID_REQ:
return WifiMetricsProto.WifiRttLog.INVALID_REQ;
- case RttNative.FRAMEWORK_RTT_STATUS_NO_WIFI:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_NO_WIFI:
return WifiMetricsProto.WifiRttLog.NO_WIFI;
- case RttNative.FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE:
+ case WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE:
return WifiMetricsProto.WifiRttLog.FAIL_FTM_PARAM_OVERRIDE;
default:
Log.e(TAG, "Unrecognized RttStatus: " + rttStatusType);
diff --git a/service/java/com/android/server/wifi/rtt/RttService.java b/service/java/com/android/server/wifi/rtt/RttService.java
index 29b99a9195..fdfc55f901 100644
--- a/service/java/com/android/server/wifi/rtt/RttService.java
+++ b/service/java/com/android/server/wifi/rtt/RttService.java
@@ -23,7 +23,6 @@ import android.os.HandlerThread;
import android.util.Log;
import com.android.server.SystemService;
-import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -56,17 +55,14 @@ public class RttService extends SystemService {
return;
}
- HalDeviceManager halDeviceManager = wifiInjector.getHalDeviceManager();
HandlerThread handlerThread = wifiInjector.getRttHandlerThread();
WifiPermissionsUtil wifiPermissionsUtil = wifiInjector.getWifiPermissionsUtil();
RttMetrics rttMetrics = wifiInjector.getWifiMetrics().getRttMetrics();
-
WifiAwareManager awareManager = getContext().getSystemService(WifiAwareManager.class);
- RttNative rttNative = new RttNative(mImpl, halDeviceManager);
- mImpl.start(handlerThread.getLooper(), wifiInjector.getClock(), awareManager, rttNative,
- rttMetrics, wifiPermissionsUtil, wifiInjector.getSettingsConfigStore());
-
+ mImpl.start(handlerThread.getLooper(), wifiInjector.getClock(), awareManager,
+ rttMetrics, wifiPermissionsUtil, wifiInjector.getSettingsConfigStore(),
+ wifiInjector.getHalDeviceManager());
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mImpl.handleBootCompleted();
}
diff --git a/service/java/com/android/server/wifi/rtt/RttServiceImpl.java b/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
index d884f79701..9d7e979d34 100644
--- a/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
+++ b/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
@@ -17,6 +17,9 @@
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_ONE_SIDED_RTT;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_VERBOSE_LOGGING_ENABLED;
@@ -63,8 +66,10 @@ import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.BuildProperties;
import com.android.server.wifi.Clock;
import com.android.server.wifi.FrameworkFacade;
+import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.SystemBuildProperties;
import com.android.server.wifi.WifiSettingsConfigStore;
+import com.android.server.wifi.hal.WifiRttController;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.wifi.resources.R;
@@ -95,7 +100,8 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
private final RttShellCommand mShellCommand;
private Clock mClock;
private WifiAwareManager mAwareManager;
- private RttNative mRttNative;
+ private WifiRttController mWifiRttController;
+ private HalDeviceManager mHalDeviceManager;
private RttMetrics mRttMetrics;
private WifiPermissionsUtil mWifiPermissionsUtil;
private ActivityManager mActivityManager;
@@ -104,6 +110,7 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
private long mLastRequestTimestamp;
private final BuildProperties mBuildProperties;
private FrameworkFacade mFrameworkFacade;
+ private WifiRttController.Capabilities mCapabilities;
private RttServiceSynchronized mRttServiceSynchronized;
@@ -116,6 +123,41 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
// arbitrary, larger than anything reasonable
/* package */ static final int MAX_QUEUED_PER_UID = 20;
+
+ private final WifiRttController.RttControllerRangingResultsCallback mRangingResultsCallback =
+ new WifiRttController.RttControllerRangingResultsCallback() {
+ @Override
+ public void onRangingResults(int cmdId, List<RangingResult> rangingResults) {
+ if (mVerboseLoggingEnabled) Log.d(TAG, "onRangingResults: cmdId=" + cmdId);
+ mRttServiceSynchronized.mHandler.post(() -> {
+ mRttServiceSynchronized.onRangingResults(cmdId, rangingResults);
+ });
+ }
+ };
+
+ private final HalDeviceManager.InterfaceRttControllerLifecycleCallback mRttLifecycleCb =
+ new HalDeviceManager.InterfaceRttControllerLifecycleCallback() {
+ @Override
+ public void onNewRttController(WifiRttController controller) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "onNewRttController: controller=" + controller);
+ }
+ boolean changed = mWifiRttController == null;
+ mWifiRttController = controller;
+ mWifiRttController.registerRangingResultsCallback(mRangingResultsCallback);
+ if (changed) {
+ enableIfPossible();
+ }
+ }
+
+ @Override
+ public void onRttControllerDestroyed() {
+ if (mVerboseLoggingEnabled) Log.d(TAG, "onRttControllerDestroyed");
+ mWifiRttController = null;
+ disable();
+ }
+ };
+
public RttServiceImpl(Context context) {
mContext = context;
mBuildProperties = new SystemBuildProperties();
@@ -182,17 +224,18 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
return -1;
}
} else if ("get_capabilities".equals(cmd)) {
- RttNative.Capabilities cap =
- mRttNative.getRttCapabilities();
+ if (mCapabilities == null && mWifiRttController != null) {
+ mCapabilities = mWifiRttController.getRttCapabilities();
+ }
JSONObject j = new JSONObject();
- if (cap != null) {
+ if (mCapabilities != null) {
try {
- j.put("rttOneSidedSupported", cap.oneSidedRttSupported);
- j.put("rttFtmSupported", cap.rttFtmSupported);
- j.put("lciSupported", cap.lciSupported);
- j.put("lcrSupported", cap.lcrSupported);
- j.put("responderSupported", cap.responderSupported);
- j.put("mcVersion", cap.mcVersion);
+ j.put("rttOneSidedSupported", mCapabilities.oneSidedRttSupported);
+ j.put("rttFtmSupported", mCapabilities.rttFtmSupported);
+ j.put("lciSupported", mCapabilities.lciSupported);
+ j.put("lcrSupported", mCapabilities.lcrSupported);
+ j.put("responderSupported", mCapabilities.responderSupported);
+ j.put("mcVersion", mCapabilities.mcVersion);
} catch (JSONException e) {
Log.e(TAG, "onCommand: get_capabilities e=" + e);
}
@@ -254,20 +297,20 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
* @param looper The looper on which to synchronize operations.
* @param clock A mockable clock.
* @param awareManager The Wi-Fi Aware service (binder) if supported on the system.
- * @param rttNative The Native interface to the HAL.
* @param rttMetrics The Wi-Fi RTT metrics object.
* @param wifiPermissionsUtil Utility for permission checks.
* @param settingsConfigStore Used for retrieving verbose logging level.
+ * @param halDeviceManager The HAL device manager object.
*/
public void start(Looper looper, Clock clock, WifiAwareManager awareManager,
- RttNative rttNative, RttMetrics rttMetrics, WifiPermissionsUtil wifiPermissionsUtil,
- WifiSettingsConfigStore settingsConfigStore) {
+ RttMetrics rttMetrics, WifiPermissionsUtil wifiPermissionsUtil,
+ WifiSettingsConfigStore settingsConfigStore, HalDeviceManager halDeviceManager) {
mClock = clock;
mAwareManager = awareManager;
- mRttNative = rttNative;
+ mHalDeviceManager = halDeviceManager;
mRttMetrics = rttMetrics;
mWifiPermissionsUtil = wifiPermissionsUtil;
- mRttServiceSynchronized = new RttServiceSynchronized(looper, rttNative);
+ mRttServiceSynchronized = new RttServiceSynchronized(looper);
mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
mPowerManager = mContext.getSystemService(PowerManager.class);
@@ -316,7 +359,18 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
}
}, intentFilter);
- rttNative.start(mRttServiceSynchronized.mHandler);
+ mHalDeviceManager.initialize();
+ mHalDeviceManager.registerStatusListener(() -> {
+ if (VDBG) Log.d(TAG, "hdm.onStatusChanged");
+ if (mHalDeviceManager.isStarted()) {
+ mHalDeviceManager.registerRttControllerLifecycleCallback(mRttLifecycleCb,
+ mRttServiceSynchronized.mHandler);
+ }
+ }, mRttServiceSynchronized.mHandler);
+ if (mHalDeviceManager.isStarted()) {
+ mHalDeviceManager.registerRttControllerLifecycleCallback(
+ mRttLifecycleCb, mRttServiceSynchronized.mHandler);
+ }
});
}
@@ -324,8 +378,8 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
mVerboseHalLoggingEnabled = verboseEnabled || VDBG;
updateVerboseLoggingEnabled();
mRttMetrics.enableVerboseLogging(mVerboseLoggingEnabled);
- if (mRttNative != null) {
- mRttNative.enableVerboseLogging(mVerboseLoggingEnabled);
+ if (mWifiRttController != null) {
+ mWifiRttController.enableVerboseLogging(mVerboseLoggingEnabled);
}
}
@@ -399,13 +453,34 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
public boolean isAvailable() {
long ident = Binder.clearCallingIdentity();
try {
- return mRttNative != null && mRttNative.isReady() && !mPowerManager.isDeviceIdleMode()
+ return mWifiRttController != null && !mPowerManager.isDeviceIdleMode()
&& mWifiPermissionsUtil.isLocationModeEnabled();
} finally {
Binder.restoreCallingIdentity(ident);
}
}
+ @Override
+ public Bundle getRttCharacteristics() {
+ enforceAccessPermission();
+ if (mCapabilities == null && mWifiRttController != null) {
+ mCapabilities = mWifiRttController.getRttCapabilities();
+ }
+ return covertCapabilitiesToBundle(mCapabilities);
+ }
+
+ private Bundle covertCapabilitiesToBundle(WifiRttController.Capabilities capabilities) {
+ Bundle characteristics = new Bundle();
+ if (capabilities == null) {
+ return characteristics;
+ }
+ characteristics.putBoolean(CHARACTERISTICS_KEY_BOOLEAN_ONE_SIDED_RTT,
+ capabilities.oneSidedRttSupported);
+ characteristics.putBoolean(CHARACTERISTICS_KEY_BOOLEAN_LCI, capabilities.lciSupported);
+ characteristics.putBoolean(CHARACTERISTICS_KEY_BOOLEAN_LCR, capabilities.lcrSupported);
+ return characteristics;
+ }
+
/**
* Binder interface API to start a ranging operation. Called on binder thread, operations needs
* to be posted to handler thread.
@@ -534,17 +609,6 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
});
}
- /**
- * Called by HAL to report ranging results. Called on HAL thread - needs to post to local
- * thread.
- */
- public void onRangingResults(int cmdId, List<RangingResult> results) {
- if (VDBG) Log.v(TAG, "onRangingResults: cmdId=" + cmdId);
- mRttServiceSynchronized.mHandler.post(() -> {
- mRttServiceSynchronized.onRangingResults(cmdId, results);
- });
- }
-
private void enforceAccessPermission() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE, TAG);
}
@@ -580,6 +644,10 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
}
pw.println("Wi-Fi RTT Service");
mRttServiceSynchronized.dump(fd, pw, args);
+ pw.println(" mWifiRttController: " + mWifiRttController);
+ if (mWifiRttController != null) {
+ mWifiRttController.dump(pw);
+ }
}
/*
@@ -593,15 +661,12 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
private class RttServiceSynchronized {
public Handler mHandler;
- private RttNative mRttNative;
private int mNextCommandId = 1000;
private Map<Integer, RttRequesterInfo> mRttRequesterInfo = new HashMap<>();
private List<RttRequestInfo> mRttRequestQueue = new LinkedList<>();
private WakeupMessage mRangingTimeoutMessage = null;
- RttServiceSynchronized(Looper looper, RttNative rttNative) {
- mRttNative = rttNative;
-
+ RttServiceSynchronized(Looper looper) {
mHandler = new Handler(looper);
mRangingTimeoutMessage = new WakeupMessage(mContext, mHandler,
HAL_RANGING_TIMEOUT_TAG, () -> {
@@ -610,12 +675,16 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
}
private void cancelRanging(RttRequestInfo rri) {
- ArrayList<byte[]> macAddresses = new ArrayList<>();
+ ArrayList<MacAddress> macAddresses = new ArrayList<>();
for (ResponderConfig peer : rri.request.mRttPeers) {
- macAddresses.add(peer.macAddress.toByteArray());
+ macAddresses.add(peer.macAddress);
}
- mRttNative.rangeCancel(rri.cmdId, macAddresses);
+ if (mWifiRttController != null) {
+ mWifiRttController.rangeCancel(rri.cmdId, macAddresses);
+ } else {
+ Log.e(TAG, "Could not call cancelRanging, rttControllerHal is null");
+ }
}
private void cleanUpOnDisable() {
@@ -875,8 +944,8 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
nextRequest.cmdId = mNextCommandId++;
mLastRequestTimestamp = mClock.getWallClockMillis();
- if (mRttNative.rangeRequest(nextRequest.cmdId, nextRequest.request,
- nextRequest.isCalledFromPrivilegedContext)) {
+ if (mWifiRttController != null
+ && mWifiRttController.rangeRequest(nextRequest.cmdId, nextRequest.request)) {
long timeout = HAL_RANGING_TIMEOUT_MS;
for (ResponderConfig responderConfig : nextRequest.request.mRttPeers) {
if (responderConfig.responderType == ResponderConfig.RESPONDER_AWARE) {
@@ -887,6 +956,9 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
mRangingTimeoutMessage.schedule(mClock.getElapsedSinceBootMillis() + timeout);
} else {
Log.w(TAG, "RttServiceSynchronized.startRanging: native rangeRequest call failed");
+ if (mWifiRttController == null) {
+ Log.e(TAG, "mWifiRttController is null");
+ }
try {
mRttMetrics.recordOverallStatus(
WifiMetricsProto.WifiRttLog.OVERALL_HAL_FAILURE);
@@ -1188,8 +1260,8 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
for (ResponderConfig peer : request.mRttPeers) {
RangingResult resultForRequest = resultEntries.get(peer.macAddress);
- if (resultForRequest == null
- || resultForRequest.getStatus() != RttNative.FRAMEWORK_RTT_STATUS_SUCCESS) {
+ if (resultForRequest == null || resultForRequest.getStatus()
+ != WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "postProcessResults: missing=" + peer.macAddress);
}
@@ -1259,8 +1331,9 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
pw.println(" mRttRequesterInfo: " + mRttRequesterInfo);
pw.println(" mRttRequestQueue: " + mRttRequestQueue);
pw.println(" mRangingTimeoutMessage: " + mRangingTimeoutMessage);
+ pw.println(" mWifiRttController: " + mWifiRttController);
+ pw.println(" mHalDeviceManager: " + mHalDeviceManager);
mRttMetrics.dump(fd, pw, args);
- mRttNative.dump(fd, pw, args);
}
}
diff --git a/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java b/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java
new file mode 100644
index 0000000000..148f15ea6f
--- /dev/null
+++ b/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2022 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.scanner;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.wifi.IWifiScannerListener;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiScanner;
+import android.os.Handler;
+import android.os.Process;
+import android.os.WorkSource;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * WifiScanner manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class WifiScannerInternal {
+
+ /**
+ * Local scan listener
+ */
+ public static class ScanListener extends IWifiScannerListener.Stub {
+ private static final String TAG = "WifiScannerInternal";
+ private final WifiScanner.ScanListener mScanListener;
+ private final Handler mHandler;
+
+ /**
+ * Local scan listener constructor
+ * @param scanListener WifiScanner listener
+ * @param handler handler for the listener
+ */
+ public ScanListener(WifiScanner.ScanListener scanListener, Handler handler) {
+ mScanListener = scanListener;
+ mHandler = handler;
+ }
+
+ /**
+ * Get the WifiScanner listener
+ * @hide
+ */
+ @VisibleForTesting
+ public WifiScanner.ScanListener getWifiScannerListener() {
+ return mScanListener;
+ }
+
+ @Override
+ public void onSuccess() {
+ mHandler.post(() -> {
+ mScanListener.onSuccess();
+ });
+ }
+
+ @Override
+ public void onFailure(int reason, String description) {
+ mHandler.post(() -> {
+ mScanListener.onFailure(reason, description);
+ });
+ }
+
+ @Override
+ public void onResults(WifiScanner.ScanData[] scanDatas) {
+ mHandler.post(() -> {
+ mScanListener.onResults(scanDatas);
+ });
+ }
+
+ @Override
+ public void onFullResult(ScanResult fullScanResult) {
+ mHandler.post(() -> {
+ mScanListener.onFullResult(fullScanResult);
+ });
+ }
+
+ @Override
+ public void onSingleScanCompleted() {
+ // Internal scan listener doesn't need to handle this.
+ }
+
+ @Override
+ public void onPnoNetworkFound(ScanResult[] scanResult) {
+ if (!(mScanListener instanceof WifiScanner.PnoScanListener)) {
+ Log.wtf(TAG, "Listener is not a PnoScanListener!");
+ return;
+ }
+ WifiScanner.PnoScanListener pnoScanListener =
+ (WifiScanner.PnoScanListener) mScanListener;
+ mHandler.post(() -> {
+ pnoScanListener.onPnoNetworkFound(scanResult);
+ });
+ }
+ }
+
+ /**
+ * Enable/Disable wifi scanning.
+ *
+ * @param enable set true to enable scanning, false to disable all types of scanning.
+ */
+ public void setScanningEnabled(boolean enable) {
+ }
+
+ /**
+ * Register a listener that will receive results from all single scans.
+ * @param listener specifies the object to report events to.
+ */
+ public void registerScanListener(@NonNull ScanListener listener) {
+ }
+
+ /**
+ * Start a single scan.
+ * @param settings Wifi single scan setting
+ * @param listener listener to the scan
+ */
+ public void startScan(WifiScanner.ScanSettings settings, ScanListener listener) {
+ startScan(settings, listener, new WorkSource(Process.WIFI_UID));
+ }
+
+ /**
+ * Start a single scan.
+ * @param settings Wifi single scan setting
+ * @param listener listener to the scan
+ * @param workSource WorkSource to blame for power usage
+ */
+ public void startScan(WifiScanner.ScanSettings settings, ScanListener listener,
+ @Nullable WorkSource workSource) {
+ }
+
+ /**
+ * Stop a single scan.
+ * @param listener listener to the scan
+ */
+ public void stopScan(ScanListener listener) {
+ }
+
+ /**
+ * Start a PNO scan.
+ * @param scanSettings Wifi single scan setting
+ * @param pnoSettings Wifi pno scan setting
+ * @param listener listener to the scan
+ */
+ public void startPnoScan(WifiScanner.ScanSettings scanSettings,
+ WifiScanner.PnoSettings pnoSettings,
+ ScanListener listener) {
+ }
+
+ /**
+ * Stop a pno scan.
+ * @param listener listener to the scan
+ */
+ public void stopPnoScan(ScanListener listener) {
+ }
+
+ /**
+ * Get single scan results.
+ * @return the list of scan results
+ */
+ public List<ScanResult> getSingleScanResults() {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 2cab1fd067..7d0a679404 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -38,10 +38,12 @@ import android.net.wifi.WifiScanner.WifiBand;
import android.net.wifi.util.ScanResultUtil;
import android.os.BatteryStatsManager;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.os.WorkSource;
import android.util.ArrayMap;
@@ -58,6 +60,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.WifiInjector;
+import com.android.server.wifi.WifiLocalServices;
import com.android.server.wifi.WifiLog;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
@@ -114,17 +117,30 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
+ private boolean isPlatformOrTargetSdkLessThanU(String packageName, int uid) {
+ if (!SdkLevel.isAtLeastU()) {
+ return true;
+ }
+ return mWifiPermissionsUtil.isTargetSdkLessThan(packageName,
+ Build.VERSION_CODES.UPSIDE_DOWN_CAKE, uid);
+ }
+
@Override
public Bundle getAvailableChannels(@WifiBand int band, String packageName,
- @Nullable String attributionTag) {
+ @Nullable String attributionTag, Bundle extras) {
int uid = Binder.getCallingUid();
- long ident = Binder.clearCallingIdentity();
- try {
- enforcePermission(uid, packageName, attributionTag, false, false, false);
- } finally {
- Binder.restoreCallingIdentity(ident);
+ if (isPlatformOrTargetSdkLessThanU(packageName, uid)) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ enforcePermission(uid, packageName, attributionTag, false, false, false);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ } else {
+ mWifiPermissionsUtil.enforceNearbyDevicesPermission(
+ extras.getParcelable(WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE),
+ true, TAG + " getAvailableChannels");
}
-
ChannelSpec[][] channelSpecs = mWifiThreadRunner.call(() -> {
if (mChannelHelper == null) return new ChannelSpec[0][0];
mChannelHelper.updateChannels();
@@ -298,6 +314,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
localLog("stop background scan: " + client);
Message msg = Message.obtain();
msg.what = WifiScanner.CMD_STOP_BACKGROUND_SCAN;
+ msg.obj = new ScanParams(listener, null, null);
msg.sendingUid = uid;
mBackgroundScanStateMachine.sendMessage(msg);
}
@@ -359,6 +376,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
notifyFailure(listener, WifiScanner.REASON_NOT_AUTHORIZED, "Not authorized");
return;
}
+ mLastCallerInfoManager.put(WifiManager.API_WIFI_SCANNER_START_SCAN, Process.myTid(),
+ uid, Binder.getCallingPid(), packageName, true);
mWifiThreadRunner.post(() -> {
ExternalClientInfo client = (ExternalClientInfo) mClients.get(listener);
if (client == null) {
@@ -396,6 +415,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
localLog("stop scan: " + client);
Message msg = Message.obtain();
msg.what = WifiScanner.CMD_STOP_SINGLE_SCAN;
+ msg.obj = new ScanParams(listener, null, null);
msg.sendingUid = uid;
mSingleScanStateMachine.sendMessage(msg);
});
@@ -599,6 +619,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
public void startService() {
mWifiThreadRunner.post(() -> {
+ WifiLocalServices.addService(WifiScannerInternal.class, new LocalService());
mBackgroundScanStateMachine = new WifiBackgroundScanStateMachine(mLooper);
mSingleScanStateMachine = new WifiSingleScanStateMachine(mLooper);
mPnoScanStateMachine = new WifiPnoScanStateMachine(mLooper);
@@ -993,11 +1014,9 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
/**
* Helper method to handle the scan start message.
*/
- private void handleScanStartMessage(ClientInfo ci, Message msg) {
- ScanParams scanParams = (ScanParams) msg.obj;
- if (scanParams == null) {
- logCallback("singleScanInvalidRequest", ci, "null params");
- ci.replyFailed(WifiScanner.REASON_INVALID_REQUEST, "params null");
+ private void handleScanStartMessage(ClientInfo ci, ScanParams scanParams) {
+ if (ci == null) {
+ logCallback("singleScanInvalidRequest", ci, "null params");
return;
}
ScanSettings scanSettings = scanParams.settings;
@@ -1075,13 +1094,17 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
return HANDLED;
case WifiScanner.CMD_START_SINGLE_SCAN:
ScanParams scanParams = (ScanParams) msg.obj;
- ClientInfo ci = mClients.get(scanParams.listener);
- handleScanStartMessage(ci, msg);
+ if (scanParams != null) {
+ ClientInfo ci = mClients.get(scanParams.listener);
+ handleScanStartMessage(ci, scanParams);
+ }
return HANDLED;
case WifiScanner.CMD_STOP_SINGLE_SCAN:
scanParams = (ScanParams) msg.obj;
- ci = mClients.get(scanParams.listener);
- removeSingleScanRequests(ci);
+ if (scanParams != null) {
+ ClientInfo ci = mClients.get(scanParams.listener);
+ removeSingleScanRequests(ci);
+ }
return HANDLED;
case CMD_SCAN_RESULTS_AVAILABLE:
if (DBG) localLog("ignored scan results available event");
@@ -2515,10 +2538,11 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private void addSingleScanRequest(ScanSettings settings) {
if (DBG) localLog("Starting single scan");
if (mInternalClientInfo != null) {
- mSingleScanStateMachine.sendMessage(
- WifiScanner.CMD_START_SINGLE_SCAN,
- new ScanParams(mInternalClientInfo.mListener, settings,
- ClientModeImpl.WIFI_WORK_SOURCE));
+ Message msg = Message.obtain();
+ msg.what = WifiScanner.CMD_START_SINGLE_SCAN;
+ msg.obj = new ScanParams(mInternalClientInfo.mListener, settings,
+ ClientModeImpl.WIFI_WORK_SOURCE);
+ mSingleScanStateMachine.sendMessage(msg);
}
mWifiMetrics.getScanMetrics().setWorkSource(ClientModeImpl.WIFI_WORK_SOURCE);
}
@@ -2763,6 +2787,54 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
+ private class LocalService extends WifiScannerInternal {
+ @Override
+ public void setScanningEnabled(boolean enable) {
+ WifiScanningServiceImpl.this.setScanningEnabled(enable, Process.myTid(),
+ mContext.getOpPackageName());
+ }
+
+ @Override
+ public void registerScanListener(@NonNull WifiScannerInternal.ScanListener listener) {
+ WifiScanningServiceImpl.this.registerScanListener(listener,
+ mContext.getOpPackageName(), mContext.getAttributionTag());
+ }
+
+ @Override
+ public void startScan(WifiScanner.ScanSettings settings,
+ WifiScannerInternal.ScanListener listener,
+ @Nullable WorkSource workSource) {
+ WifiScanningServiceImpl.this.startScan(listener, settings, workSource,
+ workSource.getPackageName(0), mContext.getAttributionTag());
+ }
+
+ @Override
+ public void stopScan(WifiScannerInternal.ScanListener listener) {
+ WifiScanningServiceImpl.this.stopScan(listener,
+ mContext.getOpPackageName(), mContext.getAttributionTag());
+ }
+
+ @Override
+ public void startPnoScan(WifiScanner.ScanSettings scanSettings,
+ WifiScanner.PnoSettings pnoSettings,
+ WifiScannerInternal.ScanListener listener) {
+ WifiScanningServiceImpl.this.startPnoScan(listener,
+ scanSettings, pnoSettings, mContext.getOpPackageName(),
+ mContext.getAttributionTag());
+ }
+
+ @Override
+ public void stopPnoScan(WifiScannerInternal.ScanListener listener) {
+ WifiScanningServiceImpl.this.stopPnoScan(listener, mContext.getOpPackageName(),
+ mContext.getAttributionTag());
+ }
+
+ @Override
+ public List<ScanResult> getSingleScanResults() {
+ return mSingleScanStateMachine.filterCachedScanResultsByAge();
+ }
+ }
+
private static String toString(int uid, ScanSettings settings) {
StringBuilder sb = new StringBuilder();
sb.append("ScanSettings[uid=").append(uid);
diff --git a/service/java/com/android/server/wifi/util/HalAidlUtil.java b/service/java/com/android/server/wifi/util/HalAidlUtil.java
new file mode 100644
index 0000000000..6b822ca133
--- /dev/null
+++ b/service/java/com/android/server/wifi/util/HalAidlUtil.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 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.util;
+
+import android.hardware.wifi.supplicant.KeyMgmtMask;
+import android.net.wifi.WifiConfiguration;
+
+import java.util.BitSet;
+
+/**
+ * Provide utility functions for HAL AIDL implementation.
+ */
+public class HalAidlUtil {
+ private static int supplicantMaskValueToWifiConfigurationBitSet(int supplicantMask,
+ int supplicantValue, BitSet bitset, int bitSetPosition) {
+ bitset.set(bitSetPosition, (supplicantMask & supplicantValue) == supplicantValue);
+ int modifiedSupplicantMask = supplicantMask & ~supplicantValue;
+ return modifiedSupplicantMask;
+ }
+
+ /** Convert supplicant key management mask to framework key management mask. */
+ public static BitSet supplicantToWifiConfigurationKeyMgmtMask(int mask) {
+ BitSet bitset = new BitSet();
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.NONE, bitset,
+ WifiConfiguration.KeyMgmt.NONE);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.WPA_PSK, bitset,
+ WifiConfiguration.KeyMgmt.WPA_PSK);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.WPA_EAP, bitset,
+ WifiConfiguration.KeyMgmt.WPA_EAP);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.IEEE8021X, bitset,
+ WifiConfiguration.KeyMgmt.IEEE8021X);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.OSEN, bitset,
+ WifiConfiguration.KeyMgmt.OSEN);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.FT_PSK, bitset,
+ WifiConfiguration.KeyMgmt.FT_PSK);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.FT_EAP, bitset,
+ WifiConfiguration.KeyMgmt.FT_EAP);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.SAE,
+ bitset, WifiConfiguration.KeyMgmt.SAE);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.OWE,
+ bitset, WifiConfiguration.KeyMgmt.OWE);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.SUITE_B_192,
+ bitset, WifiConfiguration.KeyMgmt.SUITE_B_192);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.WPA_PSK_SHA256,
+ bitset, WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.WPA_EAP_SHA256,
+ bitset, WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.WAPI_PSK,
+ bitset, WifiConfiguration.KeyMgmt.WAPI_PSK);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.WAPI_CERT,
+ bitset, WifiConfiguration.KeyMgmt.WAPI_CERT);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.FILS_SHA256,
+ bitset, WifiConfiguration.KeyMgmt.FILS_SHA256);
+ mask = supplicantMaskValueToWifiConfigurationBitSet(
+ mask, KeyMgmtMask.FILS_SHA384,
+ bitset, WifiConfiguration.KeyMgmt.FILS_SHA384);
+ if (mask != 0) {
+ throw new IllegalArgumentException(
+ "invalid key mgmt mask from supplicant: " + mask);
+ }
+ return bitset;
+ }
+}
diff --git a/service/java/com/android/server/wifi/util/NativeUtil.java b/service/java/com/android/server/wifi/util/NativeUtil.java
index bcc426c48a..0d422d0b9a 100644
--- a/service/java/com/android/server/wifi/util/NativeUtil.java
+++ b/service/java/com/android/server/wifi/util/NativeUtil.java
@@ -16,10 +16,14 @@
package com.android.server.wifi.util;
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.net.wifi.WifiConfiguration;
import android.net.wifi.util.HexEncoding;
import android.text.TextUtils;
import com.android.server.wifi.ByteBufferReader;
+import com.android.server.wifi.WifiGlobals;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
@@ -31,6 +35,7 @@ import java.nio.charset.CharsetEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
/**
* Provide utility functions for native interfacing modules.
@@ -128,6 +133,23 @@ public class NativeUtil {
}
/**
+ * Converts a MAC address from the given string representation to android.net.MacAddress. A
+ * valid String representation for a MacAddress is a series of 6 values in the range [0,ff]
+ * printed in hexadecimal and joined by ':' characters.
+ *
+ * @param macAddress a String representation of a MAC address.
+ * @return the MacAddress corresponding to the given string representation or null.
+ */
+ public static MacAddress getMacAddressOrNull(@Nullable String macAddress) {
+ if (macAddress == null) return null;
+ try {
+ return MacAddress.fromString(macAddress);
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ /**
* Converts an array of 6 bytes to a HexEncoded String with format: "XX:XX:XX:XX:XX:XX", where X
* is any hexadecimal digit.
*
@@ -356,4 +378,71 @@ public class NativeUtil {
int z = ((a[6] & 0xFF) << 8) | (a[7] & 0xFF);
return String.format("%d-%s-%d", x, y, z);
}
+
+ /**
+ * Update PMF requirement if auto-upgrade offload is supported.
+ *
+ * If SAE auto-upgrade offload is supported and this config enables
+ * both PSK and SAE, do not set PMF requirement to
+ * mandatory to allow the device to roam between PSK and SAE BSSes.
+ * wpa_supplicant will set PMF requirement to optional by default.
+ */
+ public static boolean getOptimalPmfSettingForConfig(WifiConfiguration config,
+ boolean isPmfRequiredFromSelectedSecurityParams, WifiGlobals wifiGlobals) {
+ if (isPskSaeParamsMergeable(config, wifiGlobals)) {
+ return false;
+ }
+ return isPmfRequiredFromSelectedSecurityParams;
+ }
+
+ /**
+ * Update group ciphers if auto-upgrade offload is supported.
+ *
+ * If auto-upgrade offload is supported and this config enables both PSK and
+ * SAE, merge allowed group ciphers to allow native service to roam
+ * between two types.
+ */
+ public static BitSet getOptimalGroupCiphersForConfig(WifiConfiguration config,
+ BitSet ciphersFromSelectedParams, WifiGlobals wifiGlobals) {
+ BitSet ciphers = ciphersFromSelectedParams;
+ if (isPskSaeParamsMergeable(config, wifiGlobals)) {
+ ciphers = (BitSet) config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK)
+ .getAllowedGroupCiphers().clone();
+ ciphers.or((BitSet) config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE)
+ .getAllowedGroupCiphers().clone());
+ }
+ return ciphers;
+ }
+
+ /**
+ * Update pairwise ciphers if auto-upgrade offload is supported.
+ *
+ * If auto-upgrade offload is supported and this config enables both PSK and
+ * SAE, merge allowed pairwise ciphers to allow native service to roam
+ * between two types.
+ */
+ public static BitSet getOptimalPairwiseCiphersForConfig(WifiConfiguration config,
+ BitSet ciphersFromSelectedParams, WifiGlobals wifiGlobal) {
+ BitSet ciphers = ciphersFromSelectedParams;
+ if (isPskSaeParamsMergeable(config, wifiGlobal)) {
+ ciphers = (BitSet) config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK)
+ .getAllowedPairwiseCiphers().clone();
+ ciphers.or((BitSet) config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE)
+ .getAllowedPairwiseCiphers().clone());
+ }
+ return ciphers;
+ }
+
+ private static boolean isPskSaeParamsMergeable(
+ WifiConfiguration config, WifiGlobals wifiGlobals) {
+ if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)
+ && config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK).isEnabled()
+ && config.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)
+ && config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE).isEnabled()
+ && wifiGlobals.isWpa3SaeUpgradeOffloadEnabled()) {
+ return true;
+ }
+ return false;
+ }
+
}
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java b/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java
index a8d3e49a09..584cf66ed8 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java
@@ -37,23 +37,42 @@ public class WifiPermissionsWrapper {
/**
* Determine if a UID has a permission.
+ *
* @param permissionType permission string
* @param uid to get permission for
+ * @param pid to get permission for
* @return Permissions setting
*/
+ public int getUidPermission(String permissionType, int uid, int pid) {
+ return mContext.checkPermission(permissionType, pid, uid);
+ }
+
+ /**
+ * Wrapper around {@link #getUidPermission(String, int, int)}.
+ * TODO (b/231480106): Remove this wrapper and always pass the pid
+ */
public int getUidPermission(String permissionType, int uid) {
- // We don't care about pid, pass in -1
- return mContext.checkPermission(permissionType, -1, uid);
+ // We don't care about the pid, pass in -1
+ return getUidPermission(permissionType, uid, -1);
}
/**
* Determines if the caller has the override wifi config permission.
*
* @param uid to check the permission for
+ * @param pid to check the permission for
* @return int representation of success or denied
*/
- public int getOverrideWifiConfigPermission(int uid) {
- return getUidPermission(android.Manifest.permission.OVERRIDE_WIFI_CONFIG, uid);
+ public int getOverrideWifiConfigPermission(int uid, int pid) {
+ return getUidPermission(android.Manifest.permission.OVERRIDE_WIFI_CONFIG, uid, pid);
}
+ /**
+ * Wrapper around {@link #getOverrideWifiConfigPermission(int, int)}
+ * TODO (b/231480106): Remove this wrapper and always pass the pid
+ */
+ public int getOverrideWifiConfigPermission(int uid) {
+ // We don't care about the pid, pass in -1
+ return getOverrideWifiConfigPermission(uid, -1);
+ }
}
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
index 03632f6c7d..ee4f4bf830 100644
--- a/service/java/com/android/server/wifi/util/XmlUtil.java
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -1431,6 +1431,7 @@ public class XmlUtil {
public static final String XML_TAG_DECORATED_IDENTITY_PREFIX = "DecoratedIdentityPrefix";
public static final String XML_TAG_TRUST_ON_FIRST_USE = "TrustOnFirstUse";
public static final String XML_TAG_USER_APPROVE_NO_CA_CERT = "UserApproveNoCaCert";
+ public static final String XML_TAG_MINIMUM_TLS_VERSION = "MinimumTlsVersion";
/**
* Write password key to the XML stream.
@@ -1518,6 +1519,8 @@ public class XmlUtil {
enterpriseConfig.isTrustOnFirstUseEnabled());
XmlUtil.writeNextValue(out, XML_TAG_USER_APPROVE_NO_CA_CERT,
enterpriseConfig.isUserApproveNoCaCert());
+ XmlUtil.writeNextValue(out, XML_TAG_MINIMUM_TLS_VERSION,
+ enterpriseConfig.getMinimumTlsVersion());
}
/**
@@ -1640,6 +1643,9 @@ public class XmlUtil {
case XML_TAG_USER_APPROVE_NO_CA_CERT:
enterpriseConfig.setUserApproveNoCaCert((boolean) value);
break;
+ case XML_TAG_MINIMUM_TLS_VERSION:
+ enterpriseConfig.setMinimumTlsVersion((int) value);
+ break;
default:
Log.w(TAG, "Ignoring unknown value name found: " + valueName[0]);
break;
diff --git a/service/tests/OWNERS b/service/tests/OWNERS
deleted file mode 100644
index 4c05cfe0c3..0000000000
--- a/service/tests/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Add owners from connectivity for the time of the NetworkSelection
-# This also inherits OWNERS from the parent
-lorenzo@google.com
-jchalard@google.com
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 2cc22f638f..7ba5c836d6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
@@ -26,6 +26,7 @@ import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TR
import static com.android.server.wifi.ActiveModeManager.ROLE_SOFTAP_LOCAL_ONLY;
import static com.android.server.wifi.ActiveModeManager.ROLE_SOFTAP_TETHERED;
import static com.android.server.wifi.ActiveModeWarden.INTERNAL_REQUESTOR_WS;
+import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_STA_BANDS;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -63,6 +64,8 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.location.LocationManager;
+import android.net.MacAddress;
+import android.net.Network;
import android.net.wifi.ISubsystemRestartCallback;
import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.SoftApCapability;
@@ -72,6 +75,7 @@ import android.net.wifi.SoftApInfo;
import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiScanner;
import android.os.BatteryStatsManager;
import android.os.Build;
import android.os.IBinder;
@@ -81,6 +85,7 @@ import android.os.UserManager;
import android.os.WorkSource;
import android.os.test.TestLooper;
import android.telephony.TelephonyManager;
+import android.util.LocalLog;
import android.util.Log;
import androidx.test.filters.SmallTest;
@@ -141,6 +146,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
private static final WorkSource TEST_WORKSOURCE = new WorkSource(TEST_UID, TEST_PACKAGE);
private static final WorkSource SETTINGS_WORKSOURCE =
new WorkSource(Process.SYSTEM_UID, "system-service");
+ private static final int TEST_SUPPORTED_BANDS = 15;
TestLooper mLooper;
@Mock WifiInjector mWifiInjector;
@@ -169,6 +175,9 @@ public class ActiveModeWardenTest extends WifiBaseTest {
@Mock HalDeviceManager mHalDeviceManager;
@Mock UserManager mUserManager;
@Mock PackageManager mPackageManager;
+ @Mock Network mNetwork;
+ @Mock LocalLog mLocalLog;
+ @Mock WifiSettingsConfigStore mSettingsConfigStore;
Listener<ConcreteClientModeManager> mClientListener;
Listener<SoftApManager> mSoftApListener;
@@ -200,6 +209,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mWifiInjector.getSarManager()).thenReturn(mSarManager);
when(mWifiInjector.getHalDeviceManager()).thenReturn(mHalDeviceManager);
when(mWifiInjector.getUserManager()).thenReturn(mUserManager);
+ when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog);
when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
when(mContext.getResources()).thenReturn(mResources);
@@ -221,6 +231,10 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mFacade.getSettingsWorkSource(mContext)).thenReturn(SETTINGS_WORKSOURCE);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)).thenReturn(true);
+ when(mWifiInjector.getSettingsConfigStore()).thenReturn(mSettingsConfigStore);
+ when(mSettingsConfigStore.get(
+ eq(WIFI_NATIVE_SUPPORTED_STA_BANDS))).thenReturn(
+ TEST_SUPPORTED_BANDS);
doAnswer(new Answer<ClientModeManager>() {
public ClientModeManager answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
@@ -336,6 +350,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
mActiveModeWarden.wifiToggled(TEST_WORKSOURCE);
mLooper.dispatchAll();
when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
+ when(mClientModeManager.getCurrentNetwork()).thenReturn(mNetwork);
when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn(TEST_FEATURE_SET);
// ClientModeManager starts in SCAN_ONLY role.
mClientListener.onRoleChanged(mClientModeManager);
@@ -380,6 +395,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
mLooper.dispatchAll();
when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SCAN_ONLY);
when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
+ when(mClientModeManager.getCurrentNetwork()).thenReturn(null);
when(mWifiNative.getSupportedFeatureSet(null)).thenReturn(TEST_FEATURE_SET);
if (!isClientModeSwitch) {
mClientListener.onStarted(mClientModeManager);
@@ -4786,4 +4802,46 @@ public class ActiveModeWardenTest extends WifiBaseTest {
testGetSupportedFeaturesCaseForRtt(
featureLongBits | featureInfra | featureD2dRtt | featureD2apRtt, true));
}
+
+ @Test
+ public void testGetCurrentNetworkScanOnly() throws Exception {
+ enterScanOnlyModeActiveState();
+ assertNull(mActiveModeWarden.getCurrentNetwork());
+ }
+
+ @Test public void testGetCurrentNetworkClientMode() throws Exception {
+ mActiveModeWarden.setCurrentNetwork(mNetwork);
+ assertEquals(mNetwork, mActiveModeWarden.getCurrentNetwork());
+ }
+
+ /**
+ * Verifies that isClientModeManagerConnectedOrConnectingToBssid() checks for Affiliated link
+ * BSSID, if exists.
+ */
+ @Test
+ public void testClientModeManagerConnectedOrConnectingToBssid() {
+
+ WifiConfiguration config1 = new WifiConfiguration();
+ config1.SSID = TEST_SSID_1;
+ MacAddress bssid2 = MacAddress.fromString(TEST_BSSID_2);
+ when(mClientModeManager.getConnectedWifiConfiguration()).thenReturn(config1);
+ when(mClientModeManager.getConnectedBssid()).thenReturn(TEST_BSSID_1);
+ when(mClientModeManager.isAffiliatedLinkBssid(eq(bssid2))).thenReturn(true);
+
+ assertTrue(mActiveModeWarden.isClientModeManagerConnectedOrConnectingToBssid(
+ mClientModeManager, TEST_SSID_1, TEST_BSSID_2));
+ }
+
+ @Test
+ public void syncGetSupportedBands() throws Exception {
+ enterClientModeActiveState();
+ when(mWifiNative.getSupportedBandsForSta(anyString())).thenReturn(11);
+ mClientListener.onStarted(mClientModeManager);
+ mLooper.dispatchAll();
+ verify(mSettingsConfigStore).put(WIFI_NATIVE_SUPPORTED_STA_BANDS, 11);
+ assertTrue(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ));
+ assertTrue(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ));
+ assertFalse(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY));
+ assertTrue(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ));
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java b/service/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java
index 5541a7360a..1e83b4c9c8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java
@@ -220,7 +220,7 @@ public class CandidateScorerTest extends WifiBaseTest {
* Prefer current network when current network has low throughput and no internet (but expected)
*/
@Test
- public void testSwitchifCurrentNetworkHasNoInternetExceptedAndLowThroughput() throws Exception {
+ public void testSwitchifCurrentNetworkHasNoInternetExpectedAndLowThroughput() throws Exception {
if (mExpectedExpId != ThroughputScorer.THROUGHPUT_SCORER_DEFAULT_EXPID) return;
assertThat(evaluate(mCandidate1.setScanRssi(-57)
.setCurrentNetwork(true)
@@ -232,6 +232,36 @@ public class CandidateScorerTest extends WifiBaseTest {
}
/**
+ * Prefer to switch when current network has higher throughput but no internet access
+ */
+ @Test
+ public void testSwitchifCurrentNetworkNoInternetAndHighThroughput() throws Exception {
+ if (mExpectedExpId != ThroughputScorer.THROUGHPUT_SCORER_DEFAULT_EXPID) return;
+ assertThat(evaluate(mCandidate1.setScanRssi(-57)
+ .setCurrentNetwork(true)
+ .setPredictedThroughputMbps(560)
+ .setNoInternetAccess(true)
+ .setNoInternetAccessExpected(false)),
+ lessThan(evaluate(mCandidate2.setScanRssi(-57)
+ .setPredictedThroughputMbps(433))));
+ }
+
+ /**
+ * Prefer to switch when current network has lower RSSI but no internet access
+ */
+ @Test
+ public void testSwitchifCurrentNetworkNoInternetAndLowRssi() throws Exception {
+ if (mExpectedExpId != ThroughputScorer.THROUGHPUT_SCORER_DEFAULT_EXPID) return;
+ assertThat(evaluate(mCandidate1.setScanRssi(-57)
+ .setCurrentNetwork(true)
+ .setPredictedThroughputMbps(560)
+ .setNoInternetAccess(true)
+ .setNoInternetAccessExpected(false)),
+ lessThan(evaluate(mCandidate2.setScanRssi(-70)
+ .setPredictedThroughputMbps(560))));
+ }
+
+ /**
* Prefer to switch with a larger rssi difference.
*/
@Test
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 efa7011aa3..f5b31023c3 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -32,12 +32,14 @@ import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED
import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
+import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SCAN_ONLY;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LONG_LIVED;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT;
import static com.android.server.wifi.ClientModeImpl.ARP_TABLE_PATH;
import static com.android.server.wifi.ClientModeImpl.CMD_PRE_DHCP_ACTION;
import static com.android.server.wifi.ClientModeImpl.CMD_UNWANTED_NETWORK;
import static com.android.server.wifi.ClientModeImpl.WIFI_WORK_SOURCE;
+import static com.android.server.wifi.WifiSettingsConfigStore.SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STA_FACTORY_MAC_ADDRESS;
import static org.junit.Assert.assertArrayEquals;
@@ -74,6 +76,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -138,16 +141,17 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
-import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.Process;
+import android.os.UserHandle;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.util.ArraySet;
+import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
@@ -204,6 +208,7 @@ import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -268,7 +273,18 @@ public class ClientModeImplTest extends WifiBaseTest {
private static final String TEST_AP_MLD_MAC_ADDRESS_STR = "02:03:04:05:06:07";
private static final MacAddress TEST_AP_MLD_MAC_ADDRESS =
MacAddress.fromString(TEST_AP_MLD_MAC_ADDRESS_STR);
+
+ private static final String TEST_MLO_LINK_ADDR_STR = "02:03:04:05:06:0A";
+ private static final MacAddress TEST_MLO_LINK_ADDR =
+ MacAddress.fromString(TEST_MLO_LINK_ADDR_STR);
+
+
+ private static final String TEST_MLO_LINK_ADDR_1_STR = "02:03:04:05:06:0B";
+ private static final MacAddress TEST_MLO_LINK_ADDR_1 =
+ MacAddress.fromString(TEST_MLO_LINK_ADDR_1_STR);
+
private static final int TEST_MLO_LINK_ID = 1;
+ private static final int TEST_MLO_LINK_ID_1 = 2;
private long mBinderToken;
private MockitoSession mSession;
@@ -452,6 +468,7 @@ public class ClientModeImplTest extends WifiBaseTest {
static final WifiSsid TEST_WIFI_SSID1 = WifiSsid.fromUtf8Text(SSID_NO_QUOTE1);
static final String TEST_BSSID_STR = "01:02:03:04:05:06";
static final String TEST_BSSID_STR1 = "02:01:04:03:06:05";
+ static final String TEST_BSSID_STR2 = "02:01:04:03:06:04";
static final int sFreq = 2437;
static final int sFreq1 = 5240;
static final String WIFI_IFACE_NAME = "mockWlan";
@@ -544,6 +561,7 @@ public class ClientModeImplTest extends WifiBaseTest {
@Mock ScanResult mScanResult;
@Mock HandlerThread mWifiHandlerThread;
@Mock SsidTranslator mSsidTranslator;
+ @Mock LocalLog mLocalLog;
@Captor ArgumentCaptor<WifiConfigManager.OnNetworkUpdateListener> mConfigUpdateListenerCaptor;
@Captor ArgumentCaptor<WifiNetworkAgent.Callback> mWifiNetworkAgentCallbackCaptor;
@@ -552,6 +570,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiCarrierInfoManager.OnCarrierOffloadDisabledListener.class);
@Captor ArgumentCaptor<BroadcastReceiver> mScreenStateBroadcastReceiverCaptor;
@Captor ArgumentCaptor<ProvisioningConfigurationParcelable> mProvisioningConfigurationCaptor;
+ WifiInfo mPrimaryWifiInfo;
private void setUpWifiNative() throws Exception {
when(mWifiNative.getStaFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn(
@@ -620,6 +639,7 @@ public class ClientModeImplTest extends WifiBaseTest {
when(mUntrustedWifiNetworkFactory.hasConnectionRequests()).thenReturn(true);
when(mOemWifiNetworkFactory.hasConnectionRequests()).thenReturn(true);
when(mMultiInternetManager.hasPendingConnectionRequests()).thenReturn(true);
+ when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog);
mFrameworkFacade = getFrameworkFacade();
mContext = getContext();
@@ -682,7 +702,13 @@ public class ClientModeImplTest extends WifiBaseTest {
}
});
when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
-
+ // Update the WifiInfo in WifiActiveModeWarden
+ doAnswer(inv -> {
+ if (mCmi != null) {
+ mPrimaryWifiInfo = mCmi.getConnectionInfo();
+ }
+ return null;
+ }).when(mActiveModeWarden).updateCurrentConnectionInfo();
initializeCmi();
// Retrieve factory MAC address on first bootup.
verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME);
@@ -718,41 +744,12 @@ public class ClientModeImplTest extends WifiBaseTest {
}).when(mBroadcastQueue).queueOrSendBroadcast(any(), any());
}
- private void registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger,
- Handler wrappedHandler) {
- final AsyncChannel channel = new AsyncChannel();
- Handler handler = new Handler(mLooper.getLooper()) {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- consumer.accept(channel);
- } else {
- Log.d(TAG, "Failed to connect Command channel " + this);
- }
- break;
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- Log.d(TAG, "Command channel disconnected " + this);
- break;
- case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
- Log.d(TAG, "Command channel fully connected " + this);
- break;
- default:
- if (wrappedHandler != null) {
- wrappedHandler.handleMessage(msg);
- }
- break;
- }
- }
- };
-
- channel.connect(mContext, handler, messenger);
- mLooper.dispatchAll();
- }
-
- private void registerAsyncChannel(Consumer<AsyncChannel> consumer, Messenger messenger) {
- registerAsyncChannel(consumer, messenger, null /* wrappedHandler */);
+ private void validateConnectionInfo() {
+ // The WifiInfo#equals returns false for pre-S, don't enforce the check.
+ if (!SdkLevel.isAtLeastS()) return;
+ if (mClientModeManager.getRole() == ROLE_CLIENT_PRIMARY) {
+ assertEquals(mCmi.getConnectionInfo(), mPrimaryWifiInfo);
+ }
}
private void initializeCmi() throws Exception {
@@ -774,7 +771,6 @@ public class ClientModeImplTest extends WifiBaseTest {
WIFI_IFACE_NAME, mClientModeManager, mCmiMonitor,
mBroadcastQueue, mWifiNetworkSelector, mTelephonyManager, mWifiInjector,
mSettingsConfigStore, false, mWifiNotificationManager);
-
mCmi.mInsecureEapNetworkHandler = mInsecureEapNetworkHandler;
mWifiCoreThread = getCmiHandlerThread(mCmi);
@@ -794,6 +790,7 @@ public class ClientModeImplTest extends WifiBaseTest {
verify(mWifiLastResortWatchdog, atLeastOnce()).clearAllFailureCounts();
assertEquals("DisconnectedState", getCurrentState().getName());
+ validateConnectionInfo();
verify(mContext, atLeastOnce()).registerReceiver(
mScreenStateBroadcastReceiverCaptor.capture(),
@@ -1112,6 +1109,7 @@ public class ClientModeImplTest extends WifiBaseTest {
assertNull(mCmi.getConnectedWifiConfiguration());
triggerConnect();
+ validateConnectionInfo();
assertNotNull(mCmi.getConnectingWifiConfiguration());
assertNull(mCmi.getConnectedWifiConfiguration());
@@ -1136,12 +1134,15 @@ public class ClientModeImplTest extends WifiBaseTest {
new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR,
SupplicantState.ASSOCIATED));
mLooper.dispatchAll();
+ validateConnectionInfo();
WifiSsid wifiSsid = WifiSsid.fromBytes(
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
+ // WifiInfo should be updated if it is primary
+ validateConnectionInfo();
verify(mWifiMetrics).noteFirstL2ConnectionAfterBoot(true);
@@ -1153,6 +1154,7 @@ public class ClientModeImplTest extends WifiBaseTest {
new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR,
SupplicantState.COMPLETED));
mLooper.dispatchAll();
+ validateConnectionInfo();
assertEquals("L3ProvisioningState", getCurrentState().getName());
verify(mContext).sendStickyBroadcastAsUser(
@@ -1235,6 +1237,7 @@ public class ClientModeImplTest extends WifiBaseTest {
verify(mWifiMetrics).setConnectionMaxSupportedLinkSpeedMbps(WIFI_IFACE_NAME, 90, 80);
assertEquals(90, wifiInfo.getMaxSupportedTxLinkSpeedMbps());
verify(mWifiMetrics).noteFirstL3ConnectionAfterBoot(true);
+ validateConnectionInfo();
}
private void setupEapSimConnection() throws Exception {
@@ -1258,7 +1261,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiSsid wifiSsid = WifiSsid.fromBytes(
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
assertEquals("L3ProvisioningState", getCurrentState().getName());
}
@@ -1285,7 +1288,7 @@ public class ClientModeImplTest extends WifiBaseTest {
// send NETWORK_CONNECTION_EVENT for previous network ID
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
new NetworkConnectionEventInfo(
- FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
// should ignore it, stay in L2ConnectingState
@@ -1296,7 +1299,7 @@ public class ClientModeImplTest extends WifiBaseTest {
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(config.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
new NetworkConnectionEventInfo(
- OTHER_NETWORK_ID, wifiSsid, TEST_BSSID_STR1, false));
+ OTHER_NETWORK_ID, wifiSsid, TEST_BSSID_STR1, false, null));
mLooper.dispatchAll();
// then move to next state
@@ -1444,7 +1447,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiSsid wifiSsid = WifiSsid.fromBytes(
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
verify(mWifiNative).getEapAnonymousIdentity(any());
@@ -1498,7 +1501,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiSsid wifiSsid = WifiSsid.fromBytes(
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
verify(mWifiNative).getEapAnonymousIdentity(any());
@@ -1560,7 +1563,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiSsid wifiSsid = WifiSsid.fromBytes(
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
verify(mWifiNative).getEapAnonymousIdentity(any());
@@ -1619,7 +1622,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiSsid wifiSsid = WifiSsid.fromBytes(
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
verify(mWifiNative).getEapAnonymousIdentity(any());
@@ -1683,7 +1686,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiSsid wifiSsid = WifiSsid.fromBytes(
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
verify(mWifiNative).getEapAnonymousIdentity(any());
@@ -2097,6 +2100,34 @@ public class ClientModeImplTest extends WifiBaseTest {
}
/**
+ * If the interface has been switched to scan, the network disconnection event should clear the
+ * current network.
+ * @throws Exception
+ */
+ @Test
+ public void testNetworkDisconnectAfterInterfaceSwitchedToScan() throws Exception {
+ triggerConnect();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connectNetwork(
+ new NetworkUpdateResult(FRAMEWORK_NETWORK_ID),
+ new ActionListenerWrapper(connectActionListener),
+ Binder.getCallingUid(), OP_PACKAGE_NAME);
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
+
+ when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SCAN_ONLY);
+ // Disconnection from previous network.
+ DisconnectEventInfo disconnectEventInfo =
+ new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false);
+ mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo);
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR,
+ SupplicantState.DISCONNECTED));
+ mLooper.dispatchAll();
+ verify(mActiveModeWarden).setCurrentNetwork(null);
+ }
+
+ /**
* If caller tries to connect to a new network while still provisioning the current one,
* the connection attempt should succeed.
*/
@@ -2109,7 +2140,7 @@ public class ClientModeImplTest extends WifiBaseTest {
startConnectSuccess();
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
@@ -2154,7 +2185,7 @@ public class ClientModeImplTest extends WifiBaseTest {
startConnectSuccess();
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
@@ -2234,7 +2265,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
verify(mWifiBlocklistMonitor).handleBssidConnectionSuccess(TEST_BSSID_STR, TEST_SSID);
@@ -2794,18 +2825,26 @@ public class ClientModeImplTest extends WifiBaseTest {
}
@Test
- public void testSyncGetCurrentNetwork() throws Exception {
- // syncGetCurrentNetwork() returns null when disconnected
- mLooper.startAutoDispatch();
- assertNull(mCmi.syncGetCurrentNetwork());
- mLooper.stopAutoDispatch();
-
+ public void testGetCurrentNetwork() throws Exception {
+ // getCurrentNetwork() returns null when disconnected
+ assertNull(mCmi.getCurrentNetwork());
connect();
- // syncGetCurrentNetwork() returns non-null Network when connected
- mLooper.startAutoDispatch();
- assertEquals(mNetwork, mCmi.syncGetCurrentNetwork());
- mLooper.stopAutoDispatch();
+ assertEquals("L3ConnectedState", getCurrentState().getName());
+ // getCurrentNetwork() returns non-null Network when connected
+ assertEquals(mNetwork, mCmi.getCurrentNetwork());
+ // Now trigger disconnect
+ mCmi.disconnect();
+ DisconnectEventInfo disconnectEventInfo =
+ new DisconnectEventInfo(mConnectedNetwork.SSID, TEST_BSSID_STR, 0, false);
+ mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo);
+ mLooper.dispatchAll();
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(0, WifiSsid.fromUtf8Text(mConnectedNetwork.SSID),
+ TEST_BSSID_STR, SupplicantState.DISCONNECTED));
+ mLooper.dispatchAll();
+ assertEquals("DisconnectedState", getCurrentState().getName());
+ assertNull(mCmi.getCurrentNetwork());
}
/**
@@ -2829,7 +2868,7 @@ public class ClientModeImplTest extends WifiBaseTest {
getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult());
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
@@ -3021,9 +3060,6 @@ public class ClientModeImplTest extends WifiBaseTest {
@Test
public void testWifiInfoCleanedUpEnteringExitingConnectableState2() throws Exception {
- String initialBSSID = "aa:bb:cc:dd:ee:ff";
- InOrder inOrderMetrics = inOrder(mWifiMetrics);
-
// Send a SUPPLICANT_STATE_CHANGE_EVENT, verify WifiInfo is not updated
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR,
@@ -3054,7 +3090,7 @@ public class ClientModeImplTest extends WifiBaseTest {
/**
* Test that connected SSID and BSSID are exposed to system server.
- * Also tests that {@link ClientModeImpl#syncRequestConnectionInfo()} always
+ * Also tests that {@link ClientModeImpl#getConnectionInfo()} always
* returns a copy of WifiInfo.
*/
@Test
@@ -3065,10 +3101,7 @@ public class ClientModeImplTest extends WifiBaseTest {
assertEquals(TEST_BSSID_STR, wifiInfo.getBSSID());
assertEquals(TEST_WIFI_SSID, wifiInfo.getWifiSsid());
- mLooper.startAutoDispatch();
- WifiInfo connectionInfo = mCmi.syncRequestConnectionInfo();
- mLooper.stopAutoDispatch();
-
+ WifiInfo connectionInfo = mCmi.getConnectionInfo();
assertEquals(wifiInfo.getSSID(), connectionInfo.getSSID());
assertEquals(wifiInfo.getBSSID(), connectionInfo.getBSSID());
assertEquals(wifiInfo.getMacAddress(), connectionInfo.getMacAddress());
@@ -3150,7 +3183,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, TEST_BSSID_STR);
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, null, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, null, false, null));
mLooper.dispatchAll();
verify(mWifiConfigManager).clearRecentFailureReason(eq(0));
verify(mWifiConfigManager, never()).setRecentFailureAssociationStatus(anyInt(), anyInt());
@@ -3393,6 +3426,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.enableRssiPolling(true);
connect();
mLooper.dispatchAll();
+ assertRssiChangeBroadcastSent();
when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333);
mLooper.dispatchAll();
WifiInfo wifiInfo = mWifiInfo;
@@ -4554,7 +4588,7 @@ public class ClientModeImplTest extends WifiBaseTest {
Pair.create("aaa", "bbb"));
// Now send a network connection (indicating a roam) event
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR1, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR1, false, null));
mLooper.dispatchAll();
inOrder.verify(mIpClient).updateLayer2Information(any());
@@ -4633,7 +4667,7 @@ public class ClientModeImplTest extends WifiBaseTest {
when(mWifiNative.getMacAddress(WIFI_IFACE_NAME))
.thenReturn(TEST_GLOBAL_MAC_ADDRESS.toString());
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress());
}
@@ -4654,7 +4688,7 @@ public class ClientModeImplTest extends WifiBaseTest {
when(mWifiNative.getMacAddress(WIFI_IFACE_NAME))
.thenReturn(TEST_LOCAL_MAC_ADDRESS.toString());
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
assertEquals(TEST_LOCAL_MAC_ADDRESS.toString(), mWifiInfo.getMacAddress());
}
@@ -5018,7 +5052,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiSsid wifiSsid = WifiSsid.fromBytes(
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
@@ -5100,7 +5134,7 @@ public class ClientModeImplTest extends WifiBaseTest {
* when both Tx and Rx link speed are unavailable.
*/
@Test
- public void verifyNetworkCapabilitiesForSpecificRequest() throws Exception {
+ public void verifyNetworkCapabilitiesForSpecificRequestWithInternet() throws Exception {
mWifiInfo.setFrequency(2437);
when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(30_000);
when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(40_000);
@@ -5147,6 +5181,58 @@ public class ClientModeImplTest extends WifiBaseTest {
}
/**
+ * Verify that we set the INTERNET capability in the network agent when connected
+ * as a result of the new network which indicate the internet capabilites should be set.
+ */
+ @Test
+ public void verifyNetworkCapabilitiesForSpecificRequest() throws Exception {
+ mWifiInfo.setFrequency(2437);
+ when(mPerNetwork.getTxLinkBandwidthKbps()).thenReturn(30_000);
+ when(mPerNetwork.getRxLinkBandwidthKbps()).thenReturn(40_000);
+ when(mWifiNetworkFactory.getSpecificNetworkRequestUids(any(), any()))
+ .thenReturn(Set.of(TEST_UID));
+ when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any(), any()))
+ .thenReturn(Pair.create(TEST_UID, OP_PACKAGE_NAME));
+ when(mWifiNetworkFactory.shouldHaveInternetCapabilities()).thenReturn(true);
+ // Simulate the first connection.
+ connectWithValidInitRssi(-42);
+ ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor =
+ ArgumentCaptor.forClass(NetworkCapabilities.class);
+
+ verify(mWifiInjector).makeWifiNetworkAgent(
+ networkCapabilitiesCaptor.capture(), any(), any(), any(), any());
+
+ NetworkCapabilities networkCapabilities = networkCapabilitiesCaptor.getValue();
+ assertNotNull(networkCapabilities);
+
+ // should not have internet capability.
+ assertTrue(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+
+ NetworkSpecifier networkSpecifier = networkCapabilities.getNetworkSpecifier();
+ assertTrue(networkSpecifier instanceof WifiNetworkAgentSpecifier);
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
+ (WifiNetworkAgentSpecifier) networkSpecifier;
+
+ // createNetworkAgentSpecifier does not write the BSSID to the current wifi configuration.
+ WifiConfiguration expectedConfig = new WifiConfiguration(
+ mCmi.getConnectedWifiConfiguration());
+ expectedConfig.BSSID = TEST_BSSID_STR;
+ WifiNetworkAgentSpecifier expectedWifiNetworkAgentSpecifier =
+ new WifiNetworkAgentSpecifier(expectedConfig, ScanResult.WIFI_BAND_24_GHZ,
+ true /* matchLocalOnlySpecifiers */);
+ assertEquals(expectedWifiNetworkAgentSpecifier, wifiNetworkAgentSpecifier);
+ if (SdkLevel.isAtLeastS()) {
+ assertEquals(Set.of(new Range<Integer>(TEST_UID, TEST_UID)),
+ networkCapabilities.getUids());
+ } else {
+ assertEquals(TEST_UID, networkCapabilities.getRequestorUid());
+ assertEquals(OP_PACKAGE_NAME, networkCapabilities.getRequestorPackageName());
+ }
+ assertEquals(30_000, networkCapabilities.getLinkUpstreamBandwidthKbps());
+ assertEquals(40_000, networkCapabilities.getLinkDownstreamBandwidthKbps());
+ }
+
+ /**
* Verifies that no RSSI change broadcast should be sent
*/
private void failOnRssiChangeBroadcast() throws Exception {
@@ -5166,6 +5252,26 @@ public class ClientModeImplTest extends WifiBaseTest {
}
return null;
}).when(mContext).sendBroadcastAsUser(any(), any(), anyString());
+
+ doAnswer(invocation -> {
+ final Intent intent = invocation.getArgument(0);
+ if (WifiManager.RSSI_CHANGED_ACTION.equals(intent.getAction())) {
+ fail("Should not send RSSI_CHANGED broadcast!");
+ }
+ return null;
+ }).when(mContext).sendBroadcastAsUser(any(), any(), anyString(), any());
+ }
+
+ /**
+ * Verifies that RSSI change broadcast is sent.
+ */
+ private void assertRssiChangeBroadcastSent() throws Exception {
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContext).sendBroadcastAsUser(intentCaptor.capture(),
+ eq(UserHandle.ALL), eq(Manifest.permission.ACCESS_WIFI_STATE), any());
+ Intent intent = intentCaptor.getValue();
+ assertNotNull(intent);
+ assertEquals(WifiManager.RSSI_CHANGED_ACTION, intent.getAction());
}
/**
@@ -5405,6 +5511,18 @@ public class ClientModeImplTest extends WifiBaseTest {
assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress());
verify(mSettingsConfigStore).get(WIFI_STA_FACTORY_MAC_ADDRESS);
+ // Verify secondary MAC is not stored
+ verify(mSettingsConfigStore, never()).put(
+ eq(SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS), any());
+ verify(mSettingsConfigStore, never()).get(SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS);
+
+ // Query again as secondary STA, and then verify the result is saved to secondary.
+ when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED);
+ mCmi.getFactoryMacAddress();
+ verify(mWifiNative).getStaFactoryMacAddress(WIFI_IFACE_NAME);
+ verify(mSettingsConfigStore).put(eq(SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS), any());
+ verify(mSettingsConfigStore).get(SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS);
+
verifyNoMoreInteractions(mWifiNative, mSettingsConfigStore);
}
@@ -5702,7 +5820,7 @@ public class ClientModeImplTest extends WifiBaseTest {
startConnectSuccess();
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
@@ -6151,7 +6269,7 @@ public class ClientModeImplTest extends WifiBaseTest {
verify(mWifiMetrics, times(1)).incrementConnectRequestWithFilsAkmCount();
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, true));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, true, null));
mLooper.dispatchAll();
verify(mWifiMetrics, times(1)).incrementL2ConnectionThroughFilsAuthCount();
@@ -6438,7 +6556,7 @@ public class ClientModeImplTest extends WifiBaseTest {
startConnectSuccess();
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
@@ -6637,6 +6755,41 @@ public class ClientModeImplTest extends WifiBaseTest {
}
@Test
+ public void testIpReachabilityFailureRoamL3ProvisioningState_recreateIpClient()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ connect();
+ expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { });
+ reset(mWifiNetworkAgent);
+
+ // Save current IpClientCallbacks instance and verify the onProvisioningFailure
+ // from this instance won't trigger wifi disconnection after recreating a new
+ // IpClient and IpClientCallbacks in WaitBeforeL3ProvisioningState.
+ final IpClientCallbacks callback = mIpClientCallback;
+
+ // Trigger ip reachability failure and ensure we do not trigger a disconnect.
+ ReachabilityLossInfoParcelable lossInfo =
+ new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ROAM);
+ callback.onReachabilityFailure(lossInfo);
+ mLooper.dispatchAll();
+ verify(mWifiNetworkAgent).unregisterAfterReplacement(anyInt());
+ verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME);
+ assertEquals("L3ProvisioningState", getCurrentState().getName());
+
+ // Verify that onProvisioningFailure from the legacy IpClientCallbacks instance
+ // doesn't trigger wifi disconnection.
+ callback.onProvisioningFailure(new LinkProperties());
+ mLooper.dispatchAll();
+ verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME);
+
+ // Verify that onProvisioningFailure from the current IpClientCallbacks instance
+ // triggers wifi disconnection.
+ mIpClientCallback.onProvisioningFailure(new LinkProperties());
+ mLooper.dispatchAll();
+ verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
+ }
+
+ @Test
public void testIpReachabilityLostAndRoamEventsRace() throws Exception {
connect();
expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { });
@@ -6650,7 +6803,7 @@ public class ClientModeImplTest extends WifiBaseTest {
// Now send a network connection (indicating a roam) event before we get the disconnect
// event.
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
// ensure that we ignored the transient roam while we're disconnecting.
verifyNoMoreInteractions(mWifiNetworkAgent);
@@ -6932,7 +7085,7 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiSsid wifiSsid = WifiSsid.fromBytes(
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
assertEquals("L3ProvisioningState", getCurrentState().getName());
}
@@ -6963,7 +7116,7 @@ public class ClientModeImplTest extends WifiBaseTest {
// Now send a network connection (indicating a roam) event
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR1, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR1, false, null));
mLooper.dispatchAll();
verify(mContext, times(2)).sendStickyBroadcastAsUser(
@@ -7136,7 +7289,7 @@ public class ClientModeImplTest extends WifiBaseTest {
startConnectSuccess();
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
@@ -8389,7 +8542,7 @@ public class ClientModeImplTest extends WifiBaseTest {
}
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false));
+ new NetworkConnectionEventInfo(0, TEST_WIFI_SSID, TEST_BSSID_STR, false, null));
mLooper.dispatchAll();
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
@@ -8607,7 +8760,11 @@ public class ClientModeImplTest extends WifiBaseTest {
private void setScanResultWithMloInfo() {
List<MloLink> mloLinks = new ArrayList<>();
MloLink link1 = new MloLink();
+ link1.setApMacAddress(MacAddress.fromString(TEST_BSSID_STR));
+ link1.setLinkId(TEST_MLO_LINK_ID);
MloLink link2 = new MloLink();
+ link2.setApMacAddress(MacAddress.fromString(TEST_BSSID_STR1));
+ link2.setLinkId(TEST_MLO_LINK_ID_1);
mloLinks.add(link1);
mloLinks.add(link2);
@@ -8620,6 +8777,8 @@ public class ClientModeImplTest extends WifiBaseTest {
}
private void setScanResultWithoutMloInfo() {
+ mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11AC;
+
when(mScanResult.getApMldMacAddress()).thenReturn(null);
when(mScanResult.getApMloLinkId()).thenReturn(MloLink.INVALID_MLO_LINK_ID);
when(mScanResult.getAffiliatedMloLinks()).thenReturn(Collections.emptyList());
@@ -8634,6 +8793,35 @@ public class ClientModeImplTest extends WifiBaseTest {
validateSuccessfulConnectSequence(config);
}
+ private void setConnectionMloLinksInfo() {
+ mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11BE;
+ WifiNative.ConnectionMloLinksInfo info = new WifiNative.ConnectionMloLinksInfo();
+ info.links = new WifiNative.ConnectionMloLink[2];
+ info.links[0] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID,
+ TEST_MLO_LINK_ADDR, Byte.MIN_VALUE, Byte.MAX_VALUE);
+ info.links[1] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID_1, TEST_MLO_LINK_ADDR_1,
+ Byte.MAX_VALUE, Byte.MIN_VALUE);
+ when(mWifiNative.getConnectionMloLinksInfo(WIFI_IFACE_NAME)).thenReturn(info);
+ }
+
+ /**
+ * Verify Affiliated link BSSID matching
+ */
+ @Test
+ public void testAffiliatedLinkBssidMatch() throws Exception {
+ setConnection();
+ setScanResultWithMloInfo();
+ // Associate
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR,
+ SupplicantState.ASSOCIATED));
+ mLooper.dispatchAll();
+ // Validate Affiliated BSSID match
+ assertTrue(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR)));
+ assertTrue(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR1)));
+ assertFalse(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR2)));
+ }
+
/**
* Verify MLO parameters update from ScanResult at association
*/
@@ -8646,9 +8834,7 @@ public class ClientModeImplTest extends WifiBaseTest {
SupplicantState.ASSOCIATED));
mLooper.dispatchAll();
- mLooper.startAutoDispatch();
- WifiInfo connectionInfo = mCmi.syncRequestConnectionInfo();
- mLooper.stopAutoDispatch();
+ WifiInfo connectionInfo = mCmi.getConnectionInfo();
assertNotNull(connectionInfo.getApMldMacAddress());
assertEquals(TEST_AP_MLD_MAC_ADDRESS_STR, connectionInfo.getApMldMacAddress().toString());
assertEquals(TEST_MLO_LINK_ID, connectionInfo.getApMloLinkId());
@@ -8664,16 +8850,13 @@ public class ClientModeImplTest extends WifiBaseTest {
connect();
setScanResultWithMloInfo();
- // Roam to a MLD AP
+ // Roam to an MLD AP
mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR,
SupplicantState.ASSOCIATED));
mLooper.dispatchAll();
- mLooper.startAutoDispatch();
- WifiInfo connectionInfo = mCmi.syncRequestConnectionInfo();
- mLooper.stopAutoDispatch();
-
+ WifiInfo connectionInfo = mCmi.getConnectionInfo();
assertNotNull(connectionInfo.getApMldMacAddress());
assertEquals(TEST_AP_MLD_MAC_ADDRESS_STR, connectionInfo.getApMldMacAddress().toString());
assertEquals(TEST_MLO_LINK_ID, connectionInfo.getApMloLinkId());
@@ -8686,15 +8869,97 @@ public class ClientModeImplTest extends WifiBaseTest {
SupplicantState.ASSOCIATED));
mLooper.dispatchAll();
- mLooper.startAutoDispatch();
- connectionInfo = mCmi.syncRequestConnectionInfo();
- mLooper.stopAutoDispatch();
+ connectionInfo = mCmi.getConnectionInfo();
assertNull(connectionInfo.getApMldMacAddress());
assertEquals(MloLink.INVALID_MLO_LINK_ID, connectionInfo.getApMloLinkId());
assertTrue(connectionInfo.getAffiliatedMloLinks().isEmpty());
}
/**
+ * Verify API calls on affiliated BSSIDs during association and disconnect.
+ */
+ @Test
+ public void verifyAffiliatedBssidsAssocDisconnect() throws Exception {
+ List<String> affiliatedBssids = Arrays.asList(TEST_BSSID_STR1);
+
+ connect();
+ setScanResultWithMloInfo();
+ setConnectionMloLinksInfo();
+ mLooper.dispatchAll();
+
+ // Association
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR,
+ SupplicantState.ASSOCIATED));
+ mLooper.dispatchAll();
+ verify(mWifiBlocklistMonitor).setAffiliatedBssids(eq(TEST_BSSID_STR), eq(affiliatedBssids));
+
+ // Disconnect
+ DisconnectEventInfo disconnectEventInfo =
+ new DisconnectEventInfo(TEST_SSID, TEST_BSSID_STR, 0, false);
+ mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, disconnectEventInfo);
+ mLooper.dispatchAll();
+ verify(mWifiBlocklistMonitor).removeAffiliatedBssids(eq(TEST_BSSID_STR));
+ }
+
+ private void configureMloLinksInfoWithIdleLinks() {
+ mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11BE;
+ WifiNative.ConnectionMloLinksInfo info = new WifiNative.ConnectionMloLinksInfo();
+ info.links = new WifiNative.ConnectionMloLink[2];
+ info.links[0] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID,
+ TEST_MLO_LINK_ADDR, (byte) 0xFF, (byte) 0xFF);
+ info.links[1] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID_1, TEST_MLO_LINK_ADDR_1,
+ (byte) 0, (byte) 0);
+ when(mWifiNative.getConnectionMloLinksInfo(WIFI_IFACE_NAME)).thenReturn(info);
+ }
+
+ private void reconfigureMloLinksInfoWithOneLink() {
+ mConnectionCapabilities.wifiStandard = ScanResult.WIFI_STANDARD_11BE;
+ WifiNative.ConnectionMloLinksInfo info = new WifiNative.ConnectionMloLinksInfo();
+ info.links = new WifiNative.ConnectionMloLink[1];
+ info.links[0] = new WifiNative.ConnectionMloLink(TEST_MLO_LINK_ID,
+ TEST_MLO_LINK_ADDR, (byte) 0xFF, (byte) 0xFF);
+ when(mWifiNative.getConnectionMloLinksInfo(WIFI_IFACE_NAME)).thenReturn(info);
+ }
+
+ @Test
+ public void verifyMloLinkChangeTidToLinkMapping() throws Exception {
+ // Initialize
+ connect();
+ setScanResultWithMloInfo();
+ setConnectionMloLinksInfo();
+ mLooper.dispatchAll();
+
+ // Association
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(FRAMEWORK_NETWORK_ID, TEST_WIFI_SSID, TEST_BSSID_STR,
+ SupplicantState.ASSOCIATED));
+ mLooper.dispatchAll();
+ // Make sure all links are active
+ for (MloLink link: mWifiInfo.getAffiliatedMloLinks()) {
+ assertEquals(link.getState(), MloLink.MLO_LINK_STATE_ACTIVE);
+ }
+
+ // TID to link mapping. Make sure one link is IDLE.
+ configureMloLinksInfoWithIdleLinks();
+ mCmi.sendMessage(WifiMonitor.MLO_LINKS_INFO_CHANGED,
+ WifiMonitor.MloLinkInfoChangeReason.TID_TO_LINK_MAP);
+ mLooper.dispatchAll();
+ List<MloLink> links = mWifiInfo.getAffiliatedMloLinks();
+ assertEquals(links.get(0).getState(), MloLink.MLO_LINK_STATE_ACTIVE);
+ assertEquals(links.get(1).getState(), MloLink.MLO_LINK_STATE_IDLE);
+
+ // LInk Removal. Make sure removed link is UNASSOCIATED.
+ reconfigureMloLinksInfoWithOneLink();
+ mCmi.sendMessage(WifiMonitor.MLO_LINKS_INFO_CHANGED,
+ WifiMonitor.MloLinkInfoChangeReason.MULTI_LINK_RECONFIG_AP_REMOVAL);
+ mLooper.dispatchAll();
+ links = mWifiInfo.getAffiliatedMloLinks();
+ assertEquals(links.get(0).getState(), MloLink.MLO_LINK_STATE_ACTIVE);
+ assertEquals(links.get(1).getState(), MloLink.MLO_LINK_STATE_UNASSOCIATED);
+ }
+
+ /**
* Verify that an event that occurs on a managed network is handled by
* logEventIfManagedNetwork.
*/
@@ -9101,4 +9366,42 @@ public class ClientModeImplTest extends WifiBaseTest {
isWpa2Wpa3EnterpriseTransitionNetworkInRange,
isWpa3EnterpriseOnlyNetworkInRange, shouldDropRequest);
}
+
+ @Test
+ public void testUpdateAkmByConnectionInfo() throws Exception {
+ mConnectedNetwork = spy(WifiConfigurationTestUtil.createPskSaeNetwork());
+
+ triggerConnect();
+
+ // WifiInfo is not updated yet.
+ assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, mWifiInfo.getCurrentSecurityType());
+
+ WifiSsid wifiSsid = WifiSsid.fromBytes(
+ NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
+ BitSet akm = new BitSet();
+ akm.set(WifiConfiguration.KeyMgmt.SAE);
+ mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, akm));
+ mLooper.dispatchAll();
+ // WifiInfo is updated to the actual used type.
+ assertEquals(WifiInfo.SECURITY_TYPE_SAE, mWifiInfo.getCurrentSecurityType());
+
+ // Roam to a PSK BSS.
+ akm.clear();
+ akm.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, akm));
+ mLooper.dispatchAll();
+ // WifiInfo is updated to the actual used type.
+ assertEquals(WifiInfo.SECURITY_TYPE_PSK, mWifiInfo.getCurrentSecurityType());
+
+ // Roam back to a SAE BSS.
+ akm.clear();
+ akm.set(WifiConfiguration.KeyMgmt.SAE);
+ mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, akm));
+ mLooper.dispatchAll();
+ // WifiInfo is updated to the actual used type.
+ assertEquals(WifiInfo.SECURITY_TYPE_SAE, mWifiInfo.getCurrentSecurityType());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java b/service/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java
index 490dc483c6..3884712f51 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java
@@ -35,7 +35,6 @@ public final class ConcreteCandidate implements WifiCandidates.Candidate {
private boolean mIsTrusted = true;
private boolean mIsOemPaid;
private boolean mIsOemPrivate;
- private boolean mSecondaryInternet;
private boolean mCarrierOrPrivileged;
private boolean mIsMetered;
private boolean mHasNoInternetAccess;
@@ -65,7 +64,6 @@ public final class ConcreteCandidate implements WifiCandidates.Candidate {
mIsTrusted = candidate.isTrusted();
mRestricted = candidate.isRestricted();
mIsOemPaid = candidate.isOemPaid();
- mSecondaryInternet = candidate.isSecondaryInternet();
mCarrierOrPrivileged = candidate.isCarrierOrPrivileged();
mIsMetered = candidate.isMetered();
mHasNoInternetAccess = candidate.hasNoInternetAccess();
@@ -166,11 +164,6 @@ public final class ConcreteCandidate implements WifiCandidates.Candidate {
return mIsOemPrivate;
}
- @Override
- public boolean isSecondaryInternet() {
- return mSecondaryInternet;
- }
-
public ConcreteCandidate setCarrierOrPrivileged(boolean carrierOrPrivileged) {
mCarrierOrPrivileged = carrierOrPrivileged;
return this;
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 8ae6cb7131..f79c83c257 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ConcreteClientModeManagerTest.java
@@ -61,6 +61,7 @@ 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 com.android.server.wifi.ClientModeManagerBroadcastQueue.QueuedBroadcast;
@@ -118,6 +119,7 @@ public class ConcreteClientModeManagerTest extends WifiBaseTest {
@Mock DefaultClientModeManager mDefaultClientModeManager;
@Mock ClientModeManagerBroadcastQueue mBroadcastQueue;
@Mock ActiveModeWarden mActiveModeWarden;
+ @Mock LocalLog mLocalLog;
private RegistrationManager.RegistrationCallback mImsMmTelManagerRegistrationCallback = null;
private @RegistrationManager.ImsRegistrationState int mCurrentImsRegistrationState =
@@ -247,6 +249,7 @@ public class ConcreteClientModeManagerTest extends WifiBaseTest {
when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade);
when(mWifiInjector.getWifiDiagnostics()).thenReturn(mWifiDiagnostics);
when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
+ when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog);
mLooper = new TestLooper();
}
@@ -278,6 +281,7 @@ public class ConcreteClientModeManagerTest extends WifiBaseTest {
// DeferStopHandler(): ConnectivityManager.class
verify(mContext).getSystemService(eq(ConnectivityManager.class));
+ verify(mContext).getResources();
// Ensure that no public broadcasts were sent.
verifyNoMoreInteractions(mContext);
@@ -470,6 +474,7 @@ public class ConcreteClientModeManagerTest extends WifiBaseTest {
verify(mContext).getSystemService(eq(SubscriptionManager.class));
verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any());
verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
+ verify(mContext).getResources();
// Ensure that no public broadcasts were sent.
verifyNoMoreInteractions(mContext);
@@ -630,6 +635,10 @@ public class ConcreteClientModeManagerTest extends WifiBaseTest {
when(mClientModeImpl.hasQuit()).thenReturn(true);
mClientModeManager.onClientModeImplQuit();
verify(mListener).onStopped(mClientModeManager);
+
+ mClientModeManager.stop();
+ mLooper.dispatchAll();
+ verify(mWifiNative, never()).teardownInterface(TEST_INTERFACE_NAME);
}
/**
@@ -638,11 +647,11 @@ public class ConcreteClientModeManagerTest extends WifiBaseTest {
@Test
public void noCallbackOnInterfaceDestroyedWhenAlreadyStopped() throws Exception {
startClientInConnectModeAndVerifyEnabled();
-
reset(mListener);
mClientModeManager.stop();
mLooper.dispatchAll();
+ verify(mWifiNative).teardownInterface(TEST_INTERFACE_NAME);
// now trigger interface destroyed and make sure callback doesn't get called
mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
index d9f62e53f0..1b8750e746 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
@@ -23,7 +23,6 @@ import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDG
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_NAN;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_P2P;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
-import static com.android.server.wifi.HalDeviceManager.START_HAL_RETRY_TIMES;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -38,9 +37,9 @@ import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import static org.mockito.Matchers.any;
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.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
@@ -54,31 +53,11 @@ import static org.mockito.Mockito.when;
import android.app.test.MockAnswerUtil;
import android.content.res.Resources;
-import android.hardware.wifi.V1_0.IWifi;
-import android.hardware.wifi.V1_0.IWifiApIface;
-import android.hardware.wifi.V1_0.IWifiChip;
-import android.hardware.wifi.V1_0.IWifiChipEventCallback;
-import android.hardware.wifi.V1_0.IWifiEventCallback;
-import android.hardware.wifi.V1_0.IWifiIface;
-import android.hardware.wifi.V1_0.IWifiNanIface;
-import android.hardware.wifi.V1_0.IWifiP2pIface;
-import android.hardware.wifi.V1_0.IWifiRttController;
-import android.hardware.wifi.V1_0.IWifiStaIface;
-import android.hardware.wifi.V1_0.IfaceType;
-import android.hardware.wifi.V1_0.WifiStatus;
-import android.hardware.wifi.V1_0.WifiStatusCode;
-import android.hardware.wifi.V1_5.WifiBand;
-import android.hardware.wifi.V1_6.IfaceConcurrencyType;
-import android.hardware.wifi.V1_6.WifiRadioCombination;
-import android.hardware.wifi.V1_6.WifiRadioCombinationMatrix;
-import android.hardware.wifi.V1_6.WifiRadioConfiguration;
-import android.hidl.manager.V1_0.IServiceNotification;
-import android.hidl.manager.V1_2.IServiceManager;
import android.net.wifi.WifiContext;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiScanner;
import android.os.Handler;
import android.os.HandlerThread;
-import android.os.IHwBinder;
-import android.os.RemoteException;
import android.os.WorkSource;
import android.os.test.TestLooper;
import android.util.Log;
@@ -89,6 +68,14 @@ import androidx.test.filters.SmallTest;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
+import com.android.server.wifi.hal.WifiApIface;
+import com.android.server.wifi.hal.WifiChip;
+import com.android.server.wifi.hal.WifiHal;
+import com.android.server.wifi.hal.WifiHal.WifiInterface;
+import com.android.server.wifi.hal.WifiNanIface;
+import com.android.server.wifi.hal.WifiP2pIface;
+import com.android.server.wifi.hal.WifiRttController;
+import com.android.server.wifi.hal.WifiStaIface;
import com.android.server.wifi.util.WorkSourceHelper;
import com.android.wifi.resources.R;
@@ -127,10 +114,8 @@ public class HalDeviceManagerTest extends WifiBaseTest {
private static final WorkSource TEST_WORKSOURCE_2 = new WorkSource(452, "com.test.2");
private HalDeviceManager mDut;
- @Mock IServiceManager mServiceManagerMock;
- @Mock IWifi mWifiMock;
- @Mock android.hardware.wifi.V1_5.IWifi mWifiMockV15;
- @Mock IWifiRttController mRttControllerMock;
+ @Mock WifiHal mWifiMock;
+ @Mock WifiRttController mRttControllerMock;
@Mock HalDeviceManager.ManagerStatusListener mManagerStatusListenerMock;
@Mock private WifiContext mContext;
@Mock private Resources mResources;
@@ -138,26 +123,16 @@ public class HalDeviceManagerTest extends WifiBaseTest {
@Mock private WifiInjector mWifiInjector;
@Mock private SoftApManager mSoftApManager;
@Mock private WifiSettingsConfigStore mWifiSettingsConfigStore;
+ @Mock private InterfaceConflictManager mInterfaceConflictManager;
@Mock private WorkSourceHelper mWorkSourceHelper0;
@Mock private WorkSourceHelper mWorkSourceHelper1;
@Mock private WorkSourceHelper mWorkSourceHelper2;
- private android.hardware.wifi.V1_5.IWifiChip mWifiChipV15 = null;
- private android.hardware.wifi.V1_6.IWifiChip mWifiChipV16 = null;
private TestLooper mTestLooper;
private Handler mHandler;
- private ArgumentCaptor<IHwBinder.DeathRecipient> mDeathRecipientCaptor =
- ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
- private ArgumentCaptor<IServiceNotification.Stub> mServiceNotificationCaptor =
- ArgumentCaptor.forClass(IServiceNotification.Stub.class);
- private ArgumentCaptor<IWifiEventCallback> mWifiEventCallbackCaptor = ArgumentCaptor.forClass(
- IWifiEventCallback.class);
- private ArgumentCaptor<android.hardware.wifi.V1_5.IWifiEventCallback>
- mWifiEventCallbackCaptorV15 = ArgumentCaptor.forClass(
- android.hardware.wifi.V1_5.IWifiEventCallback.class);
+ private ArgumentCaptor<WifiHal.Callback> mWifiEventCallbackCaptor = ArgumentCaptor.forClass(
+ WifiHal.Callback.class);
private InOrder mInOrder;
@Rule public ErrorCollector collector = new ErrorCollector();
- private WifiStatus mStatusOk;
- private WifiStatus mStatusFail;
private boolean mIsBridgedSoftApSupported = false;
private boolean mIsStaWithBridgedSoftApConcurrencySupported = false;
private boolean mWifiUserApprovalRequiredForD2dInterfacePriority = false;
@@ -169,52 +144,11 @@ public class HalDeviceManagerTest extends WifiBaseTest {
}
@Override
- protected IWifi getWifiServiceMockable() {
+ protected WifiHal getWifiHalMockable(WifiContext context, WifiInjector wifiInjector) {
return mWifiMock;
}
@Override
- protected android.hardware.wifi.V1_5.IWifi getWifiServiceForV1_5Mockable(IWifi iWifi) {
- return (mWifiMockV15 != null)
- ? mWifiMockV15
- : null;
- }
-
- @Override
- protected IServiceManager getServiceManagerMockable() {
- return mServiceManagerMock;
- }
-
- @Override
- protected android.hardware.wifi.V1_5.IWifiChip getWifiChipForV1_5Mockable(IWifiChip chip) {
- return mWifiChipV15;
- }
-
- @Override
- protected android.hardware.wifi.V1_6.IWifiChip getWifiChipForV1_6Mockable(IWifiChip chip) {
- return mWifiChipV16;
- }
-
- @Override
- protected android.hardware.wifi.V1_5.IWifiApIface getIWifiApIfaceForV1_5Mockable(
- IWifiApIface iface) {
- if (iface instanceof android.hardware.wifi.V1_5.IWifiApIface) {
- return (android.hardware.wifi.V1_5.IWifiApIface) iface;
- }
- return null;
- }
-
- @Override
- protected boolean isBridgedSoftApSupportedMockable() {
- return mIsBridgedSoftApSupported;
- }
-
- @Override
- protected boolean isStaWithBridgedSoftApConcurrencySupportedMockable() {
- return mIsStaWithBridgedSoftApConcurrencySupported;
- }
-
- @Override
protected boolean isWaitForDestroyedListenersMockable() {
return mWaitForDestroyedListeners;
}
@@ -227,12 +161,9 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mTestLooper = new TestLooper();
mHandler = new Handler(mTestLooper.getLooper());
- // initialize placeholder status objects
- mStatusOk = getStatus(WifiStatusCode.SUCCESS);
- mStatusFail = getStatus(WifiStatusCode.ERROR_UNKNOWN);
-
- setupWifiV15(mWifiMock);
-
+ when(mWifiInjector.getInterfaceConflictManager()).thenReturn(mInterfaceConflictManager);
+ when(mInterfaceConflictManager.needsUserApprovalToDelete(anyInt(), any(), anyInt(), any()))
+ .thenReturn(false);
when(mWifiInjector.makeWsHelper(TEST_WORKSOURCE_0)).thenReturn(mWorkSourceHelper0);
when(mWifiInjector.makeWsHelper(TEST_WORKSOURCE_1)).thenReturn(mWorkSourceHelper1);
when(mWifiInjector.makeWsHelper(TEST_WORKSOURCE_2)).thenReturn(mWorkSourceHelper2);
@@ -247,19 +178,11 @@ public class HalDeviceManagerTest extends WifiBaseTest {
when(mWorkSourceHelper2.getWorkSource()).thenReturn(TEST_WORKSOURCE_2);
when(mWifiInjector.getSettingsConfigStore()).thenReturn(mWifiSettingsConfigStore);
- when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
- anyLong())).thenReturn(true);
- when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
- any(IServiceNotification.Stub.class))).thenReturn(true);
- when(mServiceManagerMock.listManifestByInterface(eq(IWifi.kInterfaceName)))
- .thenReturn(new ArrayList(Arrays.asList("default")));
- when(mWifiMock.linkToDeath(any(IHwBinder.DeathRecipient.class), anyLong())).thenReturn(
- true);
- when(mWifiMock.registerEventCallback(any(IWifiEventCallback.class))).thenReturn(mStatusOk);
- when(mWifiMock.start()).thenReturn(mStatusOk);
- when(mWifiMock.stop()).thenReturn(mStatusOk);
+ when(mWifiMock.registerEventCallback(any(WifiHal.Callback.class))).thenReturn(true);
+ when(mWifiMock.start()).thenReturn(WifiHal.WIFI_STATUS_SUCCESS);
+ when(mWifiMock.stop()).thenReturn(true);
when(mWifiMock.isStarted()).thenReturn(true);
- when(mWifiMockV15.isStarted()).thenReturn(true);
+ when(mWifiMock.isInitializationComplete()).thenReturn(true);
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getBoolean(R.bool.config_wifiBridgedSoftApSupported))
.thenReturn(mIsBridgedSoftApSupported);
@@ -288,20 +211,14 @@ public class HalDeviceManagerTest extends WifiBaseTest {
/**
* Test basic startup flow:
- * - IServiceManager registrations
- * - IWifi registrations
- * - IWifi startup delayed
* - Start Wi-Fi -> onStart
* - Stop Wi-Fi -> onStop
*/
@Test
public void testStartStopFlow() throws Exception {
- TestChipV5 chipMock = new TestChipV5();
- setupWifiChipV15(chipMock);
+ TestChipV5 chipMock = new HalDeviceManagerTest.TestChipV5();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// act: stop Wi-Fi
@@ -316,34 +233,14 @@ public class HalDeviceManagerTest extends WifiBaseTest {
}
/**
- * Test the service manager notification coming in after
- * {@link HalDeviceManager#initIWifiIfNecessary()} is already invoked as a part of
- * {@link HalDeviceManager#initialize()}.
- */
- @Test
- public void testServiceRegisterationAfterInitialize() throws Exception {
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
-
- // This should now be ignored since IWifi is already non-null.
- mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", true);
-
- verifyNoMoreInteractions(mManagerStatusListenerMock, mWifiMock, mServiceManagerMock);
- }
-
- /**
* Validate that multiple callback registrations are called and that duplicate ones are
* only called once.
*/
@Test
public void testMultipleCallbackRegistrations() throws Exception {
- TestChipV5 chipMock = new TestChipV5();
- setupWifiChipV15(chipMock);
+ TestChipV5 chipMock = new HalDeviceManagerTest.TestChipV5();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, mManagerStatusListenerMock);
// register another 2 callbacks - one of them twice
HalDeviceManager.ManagerStatusListener callback1 = mock(
@@ -370,44 +267,28 @@ public class HalDeviceManagerTest extends WifiBaseTest {
@Test
public void testWifiDeathAndRegistration() throws Exception {
TestChipV5 chipMock = new TestChipV5();
- setupWifiChipV15(chipMock);
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, mWifiMockV15,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// act: IWifi service death
- mDeathRecipientCaptor.getValue().serviceDied(0);
+ ArgumentCaptor<WifiHal.DeathRecipient> deathRecipientCaptor =
+ ArgumentCaptor.forClass(WifiHal.DeathRecipient.class);
+ verify(mWifiMock, atLeastOnce()).initialize(deathRecipientCaptor.capture());
+ deathRecipientCaptor.getValue().onDeath();
mTestLooper.dispatchAll();
// verify: getting onStop
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
- // act: service startup
- mServiceNotificationCaptor.getValue().onRegistration(IWifi.kInterfaceName, "", false);
-
- // verify: initialization of IWifi
- mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
- if (null != mWifiMockV15) {
- mInOrder.verify(mWifiMockV15).registerEventCallback_1_5(
- mWifiEventCallbackCaptorV15.capture());
- } else {
- mInOrder.verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
- }
-
// act: start
collector.checkThat(mDut.start(), equalTo(true));
- if (null != mWifiMockV15) {
- mWifiEventCallbackCaptorV15.getValue().onStart();
- } else {
- mWifiEventCallbackCaptor.getValue().onStart();
- }
+ mWifiEventCallbackCaptor.getValue().onStart();
mTestLooper.dispatchAll();
// verify: service and callback calls
mInOrder.verify(mWifiMock).start();
- mInOrder.verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
+ mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
verifyNoMoreInteractions(mManagerStatusListenerMock);
}
@@ -417,20 +298,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
*/
@Test
public void testWifiFail() throws Exception {
- TestChipV5 chipMock = new TestChipV5();
- setupWifiChipV15(chipMock);
+ HalDeviceManagerTest.TestChipV5 chipMock = new HalDeviceManagerTest.TestChipV5();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, mWifiMockV15,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// act: IWifi failure
- if (null != mWifiMockV15) {
- mWifiEventCallbackCaptorV15.getValue().onFailure(mStatusFail);
- } else {
- mWifiEventCallbackCaptor.getValue().onFailure(mStatusFail);
- }
+ mWifiEventCallbackCaptor.getValue().onFailure(WifiHal.WIFI_STATUS_ERROR_UNKNOWN);
mTestLooper.dispatchAll();
// verify: getting onStop
@@ -438,16 +312,12 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// act: start again
collector.checkThat(mDut.start(), equalTo(true));
- if (null != mWifiMockV15) {
- mWifiEventCallbackCaptorV15.getValue().onStart();
- } else {
- mWifiEventCallbackCaptor.getValue().onStart();
- }
+ mWifiEventCallbackCaptor.getValue().onStart();
mTestLooper.dispatchAll();
// verify: service and callback calls
mInOrder.verify(mWifiMock).start();
- mInOrder.verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
+ mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
verifyNoMoreInteractions(mManagerStatusListenerMock);
}
@@ -463,9 +333,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testCacheMismatchError() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
@@ -475,7 +343,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
InterfaceDestroyedListener.class);
// Request STA
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -488,7 +356,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("STA can't be created", staIface, IsNull.notNullValue());
// Request NAN
- IWifiIface nanIface = validateInterfaceSequence(chipMock,
+ WifiInterface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_NAN, // ifaceTypeToCreate
@@ -501,17 +369,17 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("NAN can't be created", nanIface, IsNull.notNullValue());
// fiddle with the "chip" by removing the STA
- chipMock.interfaceNames.get(IfaceType.STA).remove("wlan0");
+ chipMock.interfaceNames.get(WifiChip.IFACE_TYPE_STA).remove("wlan0");
- // now try to request another NAN
- IWifiIface nanIface2 =
+ // Now try to request another NAN.
+ WifiNanIface nanIface2 =
mDut.createNanIface(nanDestroyedListener, mHandler, TEST_WORKSOURCE_0);
collector.checkThat("NAN can't be created", nanIface2, IsNull.nullValue());
mTestLooper.dispatchAll();
// verify that Wi-Fi is shut-down: should also get all onDestroyed messages that are
// registered (even if they seem out-of-sync to chip)
- verify(mWifiMock, times(2)).stop();
+ verify(mWifiMock).stop();
verify(mManagerStatusListenerMock, times(2)).onStatusChanged();
verify(staDestroyedListener).onDestroyed(getName(staIface));
verify(nanDestroyedListener).onDestroyed(getName(nanIface));
@@ -542,14 +410,12 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testStartHalRetryUponNotAvailableFailure() throws Exception {
// Override the stubbing for mWifiMock in before().
when(mWifiMock.start())
- .thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE))
- .thenReturn(mStatusOk);
+ .thenReturn(WifiHal.WIFI_STATUS_ERROR_NOT_AVAILABLE)
+ .thenReturn(WifiHal.WIFI_STATUS_SUCCESS);
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence(2, true);
}
@@ -562,13 +428,12 @@ public class HalDeviceManagerTest extends WifiBaseTest {
@Test
public void testStartHalRetryFailUponMultipleNotAvailableFailures() throws Exception {
// Override the stubbing for mWifiMock in before().
- when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE));
+ when(mWifiMock.start()).thenReturn(WifiHal.WIFI_STATUS_ERROR_NOT_AVAILABLE);
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip);
- executeAndValidateInitializationSequence();
- executeAndValidateStartupSequence(START_HAL_RETRY_TIMES + 1, false);
+ mInOrder = inOrder(mWifiMock, chipMock.chip);
+ executeAndValidateStartupSequence(mDut.START_HAL_RETRY_TIMES + 1, false);
}
/**
@@ -580,40 +445,15 @@ public class HalDeviceManagerTest extends WifiBaseTest {
@Test
public void testStartHalRetryFailUponTrueFailure() throws Exception {
// Override the stubbing for mWifiMock in before().
- when(mWifiMock.start()).thenReturn(getStatus(WifiStatusCode.ERROR_UNKNOWN));
+ when(mWifiMock.start()).thenReturn(WifiHal.WIFI_STATUS_ERROR_UNKNOWN);
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip);
executeAndValidateStartupSequence(1, false);
}
/**
- * Validate that isSupported() returns true when IServiceManager finds the vendor HAL daemon in
- * the VINTF.
- */
- @Test
- public void testIsSupportedTrue() throws Exception {
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15);
- executeAndValidateInitializationSequence();
- assertTrue(mDut.isSupported());
- }
-
- /**
- * Validate that isSupported() returns false when IServiceManager does not find the vendor HAL
- * daemon in the VINTF.
- */
- @Test
- public void testIsSupportedFalse() throws Exception {
- when(mServiceManagerMock.listManifestByInterface(eq(IWifi.kInterfaceName)))
- .thenReturn(new ArrayList());
- mInOrder = inOrder(mServiceManagerMock, mWifiMock);
- executeAndValidateInitializationSequence(false);
- assertFalse(mDut.isSupported());
- }
-
- /**
* Validate RTT configuration when the callback is registered first and the chip is
* configured later - i.e. RTT isn't available immediately.
*/
@@ -628,9 +468,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// concurrency in this test).
ChipMockBase chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// register initial cb: don't expect RTT since chip isn't configured
@@ -649,8 +487,8 @@ public class HalDeviceManagerTest extends WifiBaseTest {
null, // destroyedListener
TEST_WORKSOURCE_0 // requestorWs
);
- verify(chipMock.chip).createRttController(any(), any());
- io.verify(cb).onNewRttController(any());
+ verify(chipMock.chip).createRttController();
+ io.verify(cb).onNewRttController(any(WifiRttController.class));
verifyNoMoreInteractions(cb);
}
@@ -686,11 +524,9 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// STA (which will configure the chip).
ChipMockBase chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA,
@@ -700,35 +536,36 @@ public class HalDeviceManagerTest extends WifiBaseTest {
staDestroyedListener, // destroyedListener
TEST_WORKSOURCE_0 // requestorWs
);
- mInOrder.verify(chipMock.chip, times(0)).createRttController(any(), any());
+ mInOrder.verify(chipMock.chip, times(0)).createRttController();
// register initial cb - expect the cb right away
mDut.registerRttControllerLifecycleCallback(cb1, mHandler);
mTestLooper.dispatchAll();
- verify(chipMock.chip).createRttController(any(), any());
- io1.verify(cb1).onNewRttController(mRttControllerMock);
+ verify(chipMock.chip).createRttController();
+ io1.verify(cb1).onNewRttController(any(WifiRttController.class));
// register a second callback and the first one again
mDut.registerRttControllerLifecycleCallback(cb2, mHandler);
mDut.registerRttControllerLifecycleCallback(cb1, mHandler);
mTestLooper.dispatchAll();
- io2.verify(cb2).onNewRttController(mRttControllerMock);
+ io2.verify(cb2).onNewRttController(any(WifiRttController.class));
+ verify(chipMock.chip, times(1)).createRttController();
// change to AP mode (which for TestChipV1 doesn't allow RTT): trigger onDestroyed for all
- doAnswer(new GetBoundIfaceAnswer(false)).when(mRttControllerMock).getBoundIface(any());
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ when(mRttControllerMock.validate()).thenReturn(false);
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_AP,
"wlan0",
TestChipV1.AP_CHIP_MODE_ID,
- new IWifiIface[]{staIface}, // tearDownList
+ new WifiInterface[]{staIface}, // tearDownList
apDestroyedListener, // destroyedListener
TEST_WORKSOURCE_0, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(staIface), staDestroyedListener)
);
mTestLooper.dispatchAll();
- verify(chipMock.chip, times(2)).createRttController(any(), any()); // but returns a null!
+ verify(chipMock.chip, times(2)).createRttController(); // but returns a null!
io1.verify(cb1).onRttControllerDestroyed();
io2.verify(cb2).onRttControllerDestroyed();
@@ -739,15 +576,15 @@ public class HalDeviceManagerTest extends WifiBaseTest {
HDM_CREATE_IFACE_STA,
"wlan0",
TestChipV1.STA_CHIP_MODE_ID,
- new IWifiIface[]{apIface}, // tearDownList
+ new WifiInterface[]{apIface}, // tearDownList
null, // destroyedListener
TEST_WORKSOURCE_0, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(apIface), apDestroyedListener)
);
mTestLooper.dispatchAll();
- verify(chipMock.chip, times(3)).createRttController(any(), any());
- io1.verify(cb1).onNewRttController(mRttControllerMock);
- io2.verify(cb2).onNewRttController(mRttControllerMock);
+ verify(chipMock.chip, times(3)).createRttController();
+ io1.verify(cb1).onNewRttController(any(WifiRttController.class));
+ io2.verify(cb2).onNewRttController(any(WifiRttController.class));
verifyNoMoreInteractions(cb1, cb2);
}
@@ -767,11 +604,9 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// & create a STA (which will configure the chip).
ChipMockBase chipMock = new TestChipV2();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
- IWifiIface sta = validateInterfaceSequence(chipMock,
+ WifiInterface sta = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA,
@@ -781,13 +616,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
null, // destroyedListener
TEST_WORKSOURCE_0 // requestorWs
);
- mInOrder.verify(chipMock.chip, times(0)).createRttController(any(), any());
+ mInOrder.verify(chipMock.chip, times(0)).createRttController();
// register initial cb - expect the cb right away
mDut.registerRttControllerLifecycleCallback(cb, mHandler);
mTestLooper.dispatchAll();
- verify(chipMock.chip).createRttController(any(), any());
- io.verify(cb).onNewRttController(mRttControllerMock);
+ verify(chipMock.chip).createRttController();
+ io.verify(cb).onNewRttController(any(WifiRttController.class));
// create an AP: no mode change for TestChipV2 -> expect no impact on RTT
validateInterfaceSequence(chipMock,
@@ -802,11 +637,11 @@ public class HalDeviceManagerTest extends WifiBaseTest {
);
mTestLooper.dispatchAll();
- doAnswer(new GetBoundIfaceAnswer(false)).when(mRttControllerMock).getBoundIface(any());
+ when(mRttControllerMock.validate()).thenReturn(false);
chipMock.chipModeIdValidForRtt = -1;
mDut.removeIface(sta);
mTestLooper.dispatchAll();
- verify(chipMock.chip, times(2)).createRttController(any(), any());
+ verify(chipMock.chip, times(2)).createRttController();
io.verify(cb).onRttControllerDestroyed();
verifyNoMoreInteractions(cb);
@@ -822,19 +657,17 @@ public class HalDeviceManagerTest extends WifiBaseTest {
@Test
public void testReplaceRequestorWs() throws Exception {
assumeTrue(SdkLevel.isAtLeastS());
- // initialize a test chip & create a P2P (which will configure the chip).
+ // initialize a test chip & create a STA (which will configure the chip).
ChipMockBase chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener p2pDestroyedListener = mock(
InterfaceDestroyedListener.class);
// create P2P interface from privileged app: should succeed.
- IWifiIface p2pIface = validateInterfaceSequence(chipMock,
+ WifiInterface p2pIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_P2P,
@@ -844,7 +677,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
p2pDestroyedListener, // destroyedListener
TEST_WORKSOURCE_0 // requestorWs
);
- collector.checkThat("P2P was not created", p2pIface, IsNull.notNullValue());
+ collector.checkThat("P2P not created", p2pIface, IsNull.notNullValue());
// get NAN interface from a system app: should fail
when(mWorkSourceHelper1.getRequestorWsPriority())
@@ -854,7 +687,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertNull("Should not create this NAN", nanDetails);
nanDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_NAN, true, TEST_WORKSOURCE_1);
assertNull("Should not create this NAN", nanDetails);
- IWifiNanIface nanIface = (IWifiNanIface) mDut.createNanIface(null, null, TEST_WORKSOURCE_1);
+ WifiNanIface nanIface = mDut.createNanIface(null, null, TEST_WORKSOURCE_1);
collector.checkThat("not allocated interface", nanIface, IsNull.nullValue());
// Now replace the requestorWs (fg app now) for the P2P iface.
@@ -862,55 +695,47 @@ public class HalDeviceManagerTest extends WifiBaseTest {
.thenReturn(WorkSourceHelper.PRIORITY_FG_APP);
assertTrue(mDut.replaceRequestorWs(p2pIface, TEST_WORKSOURCE_2));
- // get AP interface again from a system app: should succeed now
+ // get NAN interface again from a system app: should succeed now
when(mWorkSourceHelper1.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- nanIface = (IWifiNanIface) validateInterfaceSequence(chipMock,
+ nanIface = (WifiNanIface) validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_NAN,
"wlan0",
TestChipV1.STA_CHIP_MODE_ID,
- new IWifiIface[]{p2pIface}, // tearDownList
+ new WifiInterface[]{p2pIface}, // tearDownList
null, // destroyedListener
TEST_WORKSOURCE_1, // requestorWs
- new InterfaceDestroyedListenerWithIfaceName(getName(p2pIface), p2pDestroyedListener)
+ new InterfaceDestroyedListenerWithIfaceName(
+ getName(p2pIface), p2pDestroyedListener)
);
collector.checkThat("not allocated interface", nanIface, IsNull.notNullValue());
}
/**
- * Validate a flow sequence for test chip 2 if the
- * |config_wifiUserApprovalRequiredForD2dInterfacePriority| overlay value is true. If enabled,
- * interface requests for AP/P2P/NAN should be approved over other AP/P2P/NAN interfaces as
- * long as the new requestor's worksource priority is > PRIORITY_BG and they aren't the same
- * type.
+ * Validate a flow sequence for test chip 2 if a new interface is able to delete an existing
+ * interface with user approval.
*
* Flow sequence:
* - create P2P (privileged app)
- * - create NAN (foreground app)
- * - tear down NAN
- * - create P2P (privileged app)
- * - create NAN (background app): should fail.
+ * - create NAN (foreground app) but cannot delete P2P with user approval: should fail
+ * - create NAN (foreground app) but can delete P2P with user approval: should succeed
*/
@Test
- public void testInterfaceCreationFlowIfD2dInterfacePriorityOverlayEnabled() throws Exception {
+ public void testInterfaceCreationFlowIfCanDeleteWithUserApproval() throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
- when(mResources.getBoolean(R.bool.config_wifiUserApprovalRequiredForD2dInterfacePriority))
- .thenReturn(true);
mDut = new HalDeviceManagerSpy();
ChipMockBase chipMock = new TestChipV2();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener nanDestroyedListener = mock(
InterfaceDestroyedListener.class);
// Create P2P interface from privileged app: should succeed.
- IWifiIface p2pIface = validateInterfaceSequence(chipMock,
+ WifiInterface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_P2P,
@@ -922,153 +747,35 @@ public class HalDeviceManagerTest extends WifiBaseTest {
);
collector.checkThat("P2P was not created", p2pIface, IsNull.notNullValue());
- // Check if we can create a new P2P interface from foreground app: should fail.
+ // Create NAN interface from foreground app: should fail.
when(mWorkSourceHelper1.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_FG_APP);
- List<Pair<Integer, WorkSource>> p2pDetails = mDut.reportImpactToCreateIface(
- HDM_CREATE_IFACE_P2P, true, TEST_WORKSOURCE_1);
- assertNull("Should not create this P2P", p2pDetails);
-
- // Create NAN interface from foreground app: should succeed.
List<Pair<Integer, WorkSource>> nanDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_NAN, true, TEST_WORKSOURCE_1);
+ assertNull("Should not create this NAN", nanDetails);
+ WifiInterface nanIface = mDut.createNanIface(null, null, TEST_WORKSOURCE_1);
+ collector.checkThat("NAN was created", nanIface, IsNull.nullValue());
+
+ // Can now delete P2P with user approval
+ when(mInterfaceConflictManager.needsUserApprovalToDelete(anyInt(), any(), anyInt(), any()))
+ .thenReturn(true);
+
+ // Can create NAN now.
+ nanDetails = mDut.reportImpactToCreateIface(
+ HDM_CREATE_IFACE_NAN, true, TEST_WORKSOURCE_1);
assertNotNull("Should create this NAN", nanDetails);
- IWifiIface nanIface = validateInterfaceSequence(chipMock,
+ nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_NAN,
"wlan1",
TestChipV2.CHIP_MODE_ID,
- new IWifiIface[]{p2pIface}, // tearDownList
+ new WifiInterface[]{p2pIface}, // tearDownList
null, // destroyedListener
TEST_WORKSOURCE_1, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(p2pIface), nanDestroyedListener)
);
collector.checkThat("NAN was not created", nanIface, IsNull.notNullValue());
-
- // Tear down the NAN interface.
- mDut.removeIface(nanIface);
- mTestLooper.dispatchAll();
-
- // Create a new P2P interface from privileged app: should succeed.
- p2pIface = validateInterfaceSequence(chipMock,
- true, // chipModeValid
- TestChipV2.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
- HDM_CREATE_IFACE_P2P,
- "wlan0",
- TestChipV2.CHIP_MODE_ID,
- null, // tearDownList
- nanDestroyedListener, // destroyedListener
- TEST_WORKSOURCE_0 // requestorWs
- );
- collector.checkThat("P2P was not created", p2pIface, IsNull.notNullValue());
-
- // Check if we can create a new NAN interface from background app: should fail.
- when(mWorkSourceHelper1.getRequestorWsPriority())
- .thenReturn(WorkSourceHelper.PRIORITY_BG);
- nanDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_NAN, true, TEST_WORKSOURCE_1);
- assertNull("Should not create this NAN", nanDetails);
- }
-
- /**
- * Tests that
- * {@link HalDeviceManager#needsUserApprovalToDelete(int, WorkSource, int, WorkSource)} returns
- * true on the following conditions:
- * 1) Requested interface is AP, AP_BRIDGED, P2P, or NAN.
- * 2) Existing interface is AP, AP_BRIDGED, P2P, or NAN (but not the same as the requested).
- * 3) Requestor worksource has higher priority than PRIORITY_BG.
- * 4) Existing worksource is not PRIORITY_INTERNAL.
- */
- @Test
- public void testShouldShowDialogToDelete() throws Exception {
- WorkSourceHelper newWsHelper = mock(WorkSourceHelper.class);
- WorkSourceHelper oldWsHelper = mock(WorkSourceHelper.class);
-
- when(mResources.getBoolean(R.bool.config_wifiUserApprovalRequiredForD2dInterfacePriority))
- .thenReturn(false);
- mDut = new HalDeviceManagerSpy();
-
- // No dialog if dialogs aren't enabled
- when(newWsHelper.getRequestorWsPriority()).thenReturn(WorkSourceHelper.PRIORITY_FG_APP);
- when(oldWsHelper.getRequestorWsPriority()).thenReturn(WorkSourceHelper.PRIORITY_FG_APP);
- assertFalse(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_P2P, newWsHelper,
- HDM_CREATE_IFACE_AP, oldWsHelper));
-
- when(mResources.getBoolean(R.bool.config_wifiUserApprovalRequiredForD2dInterfacePriority))
- .thenReturn(true);
- mDut = new HalDeviceManagerSpy();
-
- // Should show dialog for appropriate types.
-
- // Requesting AP
- assertFalse(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_AP, newWsHelper,
- HDM_CREATE_IFACE_AP, oldWsHelper));
- assertFalse(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_AP, newWsHelper,
- HDM_CREATE_IFACE_AP_BRIDGE, oldWsHelper));
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_AP, newWsHelper,
- HDM_CREATE_IFACE_NAN, oldWsHelper));
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_AP, newWsHelper,
- HDM_CREATE_IFACE_P2P, oldWsHelper));
-
- // Requesting AP_BRIDGE
- assertFalse(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_AP_BRIDGE, newWsHelper,
- HDM_CREATE_IFACE_AP, oldWsHelper));
- assertFalse(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_AP_BRIDGE, newWsHelper,
- HDM_CREATE_IFACE_AP_BRIDGE, oldWsHelper));
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_AP_BRIDGE, newWsHelper,
- HDM_CREATE_IFACE_NAN, oldWsHelper));
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_AP_BRIDGE, newWsHelper,
- HDM_CREATE_IFACE_P2P, oldWsHelper));
-
- // Requesting P2P
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_P2P, newWsHelper,
- HDM_CREATE_IFACE_AP, oldWsHelper));
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_P2P, newWsHelper,
- HDM_CREATE_IFACE_AP_BRIDGE, oldWsHelper));
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_P2P, newWsHelper,
- HDM_CREATE_IFACE_NAN, oldWsHelper));
- assertFalse(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_P2P, newWsHelper,
- HDM_CREATE_IFACE_P2P, oldWsHelper));
-
- // Requesting NAN
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_NAN, newWsHelper,
- HDM_CREATE_IFACE_AP, oldWsHelper));
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_NAN, newWsHelper,
- HDM_CREATE_IFACE_AP_BRIDGE, oldWsHelper));
- assertFalse(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_NAN, newWsHelper,
- HDM_CREATE_IFACE_NAN, oldWsHelper));
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_NAN, newWsHelper,
- HDM_CREATE_IFACE_P2P, oldWsHelper));
-
- // Foreground should show dialog over Privileged
- when(newWsHelper.getRequestorWsPriority()).thenReturn(WorkSourceHelper.PRIORITY_FG_APP);
- when(oldWsHelper.getRequestorWsPriority()).thenReturn(WorkSourceHelper.PRIORITY_PRIVILEGED);
- assertTrue(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_NAN, newWsHelper,
- HDM_CREATE_IFACE_P2P, oldWsHelper));
-
- // Foreground should delete Internal without showing dialog
- when(oldWsHelper.getRequestorWsPriority()).thenReturn(WorkSourceHelper.PRIORITY_INTERNAL);
- assertFalse(mDut.needsUserApprovalToDelete(
- HDM_CREATE_IFACE_NAN, newWsHelper,
- HDM_CREATE_IFACE_P2P, oldWsHelper));
}
//////////////////////////////////////////////////////////////////////////////////////
@@ -1223,15 +930,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
InterfaceDestroyedListener.class);
- IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
+ WifiApIface iface = (WifiApIface) validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.STA_CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
@@ -1302,18 +1007,14 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// Setup Wi-Fi
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, staIdl, chipMock.chip);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, staIdl, chipMock.chip);
// Start Wi-Fi
assertTrue(mDut.start());
// Create STA Iface.
- IWifiStaIface staIface = mock(IWifiStaIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.STA)).when(staIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
- chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
+ WifiStaIface staIface = mock(WifiStaIface.class);
+ when(staIface.getName()).thenReturn("wlan0");
+ doAnswer(new CreateStaIfaceAnswer(chipMock, true, staIface))
+ .when(chipMock.chip).createStaIface();
assertEquals(staIface, mDut.createStaIface(staIdl, staIfaceOnDestroyedHandler,
TEST_WORKSOURCE_0));
// Remove STA interface
@@ -1355,21 +1056,16 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
// start Wi-Fi
assertTrue(mDut.start());
// Create STA Iface.
- IWifiStaIface staIface = mock(IWifiStaIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.STA)).when(staIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
- chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
+ WifiStaIface staIface = mock(WifiStaIface.class);
+ doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName();
+ doAnswer(new CreateStaIfaceAnswer(chipMock, true, staIface))
+ .when(chipMock.chip).createStaIface();
assertEquals(staIface, mDut.createStaIface(staIdl, staIfaceOnDestroyedHandler,
TEST_WORKSOURCE_0));
@@ -1399,9 +1095,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
InterfaceDestroyedListener apIdl = mock(
InterfaceDestroyedListener.class);
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock, staIdl, apIdl);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock, staIdl, apIdl);
// Register listener & start Wi-Fi
mDut.registerStatusListener(mManagerStatusListenerMock, null);
@@ -1409,13 +1103,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
// Create STA Iface first.
- IWifiStaIface staIface = mock(IWifiStaIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.STA)).when(staIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
- chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
+ WifiStaIface staIface = mock(WifiStaIface.class);
+ doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName();
+ doAnswer(new CreateStaIfaceAnswer(chipMock, true, staIface))
+ .when(chipMock.chip).createStaIface();
List<Pair<Integer, WorkSource>> staDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_STA, false, TEST_WORKSOURCE_0);
assertTrue("Expecting nothing to destroy on creating STA", staDetails.isEmpty());
@@ -1426,23 +1117,19 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mInOrder.verify(chipMock.chip).configureChip(TestChipV1.STA_CHIP_MODE_ID);
// Now Create AP Iface.
- IWifiApIface apIface = mock(IWifiApIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(apIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.AP)).when(apIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, apIface)).when(
- chipMock.chip).createApIface(
- any(IWifiChip.createApIfaceCallback.class));
+ WifiApIface apIface = mock(WifiApIface.class);
+ doAnswer(new GetNameAnswer("wlan0")).when(apIface).getName();
+ doAnswer(new CreateApIfaceAnswer(chipMock, true, apIface))
+ .when(chipMock.chip).createApIface();
List<Pair<Integer, WorkSource>> apDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_AP, false, TEST_WORKSOURCE_0);
assertEquals("Should get STA destroy details", 1, apDetails.size());
- assertEquals("Need to destroy the STA", Pair.create(IfaceType.STA, TEST_WORKSOURCE_0),
- apDetails.get(0));
+ assertEquals("Need to destroy the STA",
+ Pair.create(WifiChip.IFACE_TYPE_STA, TEST_WORKSOURCE_0), apDetails.get(0));
apDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_AP, true, TEST_WORKSOURCE_0);
assertEquals("Should get STA destroy details", 1, apDetails.size());
- assertEquals("Need to destroy the STA", Pair.create(IfaceType.STA, TEST_WORKSOURCE_0),
- apDetails.get(0));
+ assertEquals("Need to destroy the STA",
+ Pair.create(WifiChip.IFACE_TYPE_STA, TEST_WORKSOURCE_0), apDetails.get(0));
assertEquals(apIface, mDut.createApIface(
CHIP_CAPABILITY_ANY, apIdl, mHandler, TEST_WORKSOURCE_0, false, mSoftApManager));
mInOrder.verify(chipMock.chip).removeStaIface(getName(staIface));
@@ -1479,9 +1166,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
InterfaceDestroyedListener apIdl = mock(
InterfaceDestroyedListener.class);
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock, staIdl, apIdl);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock, staIdl, apIdl);
// Register listener & start Wi-Fi
mDut.registerStatusListener(mManagerStatusListenerMock, null);
@@ -1489,13 +1174,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
// Create STA Iface first.
- IWifiStaIface staIface = mock(IWifiStaIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.STA)).when(staIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
- chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
+ WifiStaIface staIface = mock(WifiStaIface.class);
+ doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName();
+ doAnswer(new CreateStaIfaceAnswer(chipMock, true, staIface))
+ .when(chipMock.chip).createStaIface();
List<Pair<Integer, WorkSource>> staDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_STA, false, TEST_WORKSOURCE_0);
assertTrue("Expecting nothing to destroy on creating STA", staDetails.isEmpty());
@@ -1508,25 +1190,21 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// Now Create AP Iface.
when(mWorkSourceHelper1.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_FG_APP);
- IWifiApIface apIface = mock(IWifiApIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(apIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.AP)).when(apIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, apIface)).when(
- chipMock.chip).createApIface(
- any(IWifiChip.createApIfaceCallback.class));
+ WifiApIface apIface = mock(WifiApIface.class);
+ doAnswer(new GetNameAnswer("wlan0")).when(apIface).getName();
+ doAnswer(new CreateApIfaceAnswer(chipMock, true, apIface))
+ .when(chipMock.chip).createApIface();
List<Pair<Integer, WorkSource>> apDetails = mDut.reportImpactToCreateIface(
- HDM_CREATE_IFACE_AP, false, TEST_WORKSOURCE_1);
+ HDM_CREATE_IFACE_AP, false, TEST_WORKSOURCE_0);
assertEquals("Should get STA destroy details", 1, apDetails.size());
- assertEquals("Need to destroy the STA", Pair.create(IfaceType.STA, TEST_WORKSOURCE_0),
- apDetails.get(0));
- apDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_AP, true, TEST_WORKSOURCE_1);
+ assertEquals("Need to destroy the STA",
+ Pair.create(WifiChip.IFACE_TYPE_STA, TEST_WORKSOURCE_0), apDetails.get(0));
+ apDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_AP, true, TEST_WORKSOURCE_0);
assertEquals("Should get STA destroy details", 1, apDetails.size());
- assertEquals("Need to destroy the STA", Pair.create(IfaceType.STA, TEST_WORKSOURCE_0),
- apDetails.get(0));
+ assertEquals("Need to destroy the STA",
+ Pair.create(WifiChip.IFACE_TYPE_STA, TEST_WORKSOURCE_0), apDetails.get(0));
assertEquals(apIface, mDut.createApIface(
- CHIP_CAPABILITY_ANY, apIdl, mHandler, TEST_WORKSOURCE_1, false, mSoftApManager));
+ CHIP_CAPABILITY_ANY, apIdl, mHandler, TEST_WORKSOURCE_0, false, mSoftApManager));
mInOrder.verify(chipMock.chip).removeStaIface(getName(staIface));
mInOrder.verify(staIdl).onDestroyed(getName(staIface));
mInOrder.verify(chipMock.chip).configureChip(TestChipV1.AP_CHIP_MODE_ID);
@@ -1552,9 +1230,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
InterfaceDestroyedListener idl = mock(
InterfaceDestroyedListener.class);
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock, idl);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock, idl);
// Register listener & start Wi-Fi
mDut.registerStatusListener(mManagerStatusListenerMock, null);
@@ -1562,47 +1238,32 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mInOrder.verify(mManagerStatusListenerMock).onStatusChanged();
// Create STA Iface will be failure because null handler.
- IWifiStaIface staIface = mock(IWifiStaIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.STA)).when(staIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, staIface)).when(
- chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
+ WifiStaIface staIface = mock(WifiStaIface.class);
+ doAnswer(new GetNameAnswer("wlan0")).when(staIface).getName();
+ doAnswer(new CreateStaIfaceAnswer(chipMock, true, staIface))
+ .when(chipMock.chip).createStaIface();
assertNull(mDut.createStaIface(idl, null, TEST_WORKSOURCE_0));
// Create AP Iface will be failure because null handler.
- IWifiApIface apIface = mock(IWifiApIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(apIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.AP)).when(apIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, apIface)).when(
- chipMock.chip).createApIface(
- any(IWifiChip.createApIfaceCallback.class));
+ WifiApIface apIface = mock(WifiApIface.class);
+ doAnswer(new GetNameAnswer("wlan0")).when(apIface).getName();
+ doAnswer(new CreateApIfaceAnswer(chipMock, true, apIface))
+ .when(chipMock.chip).createApIface();
assertNull(mDut.createApIface(
CHIP_CAPABILITY_ANY, idl, null, TEST_WORKSOURCE_0, false, mSoftApManager));
// Create NAN Iface will be failure because null handler.
- IWifiNanIface nanIface = mock(IWifiNanIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(nanIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(nanIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, nanIface)).when(
- chipMock.chip).createNanIface(
- any(IWifiChip.createNanIfaceCallback.class));
+ WifiNanIface nanIface = mock(WifiNanIface.class);
+ doAnswer(new GetNameAnswer("wlan0")).when(nanIface).getName();
+ doAnswer(new CreateNanIfaceAnswer(chipMock, true, nanIface))
+ .when(chipMock.chip).createNanIface();
assertNull(mDut.createNanIface(idl, null, TEST_WORKSOURCE_0));
// Create P2P Iface will be failure because null handler.
- IWifiP2pIface p2pIface = mock(IWifiP2pIface.class);
- doAnswer(new GetNameAnswer("wlan0")).when(p2pIface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(p2pIface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, p2pIface)).when(
- chipMock.chip).createP2pIface(
- any(IWifiChip.createP2pIfaceCallback.class));
+ WifiP2pIface p2pIface = mock(WifiP2pIface.class);
+ doAnswer(new GetNameAnswer("wlan0")).when(p2pIface).getName();
+ doAnswer(new CreateP2pIfaceAnswer(chipMock, true, p2pIface))
+ .when(chipMock.chip).createP2pIface();
assertNull(mDut.createP2pIface(idl, null, TEST_WORKSOURCE_0));
// Stop Wi-Fi
@@ -1624,15 +1285,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
InterfaceDestroyedListener.class);
- IWifiApIface iface = (IWifiApIface) validateInterfaceSequence(chipMock,
+ WifiApIface iface = (WifiApIface) validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV1.AP_CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
@@ -1681,9 +1340,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testDuplicateStaRequestsFromLowerPriorityAppTestChipV1() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener1 = mock(
@@ -1693,7 +1350,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
InterfaceDestroyedListener.class);
// get STA interface (from a privileged app)
- IWifiIface staIface1 = validateInterfaceSequence(chipMock,
+ WifiInterface staIface1 = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -1714,7 +1371,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, staDetails.size());
staDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_STA, true, TEST_WORKSOURCE_1);
assertNull("Should not be able to create a new STA", staDetails);
- IWifiIface staIface2 = mDut.createStaIface(
+ WifiInterface staIface2 = mDut.createStaIface(
staDestroyedListener2, mHandler, TEST_WORKSOURCE_1);
collector.checkThat("STA created", staIface2, IsNull.nullValue());
@@ -1729,9 +1386,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testGetSupportedIfaceTypesAllTestChipV1() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// try API
@@ -1739,10 +1394,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// verify results
Set<Integer> correctResults = new HashSet<>();
- correctResults.add(IfaceType.AP);
- correctResults.add(IfaceType.STA);
- correctResults.add(IfaceType.P2P);
- correctResults.add(IfaceType.NAN);
+ correctResults.add(WifiChip.IFACE_TYPE_AP);
+ correctResults.add(WifiChip.IFACE_TYPE_STA);
+ correctResults.add(WifiChip.IFACE_TYPE_P2P);
+ correctResults.add(WifiChip.IFACE_TYPE_NAN);
assertEquals(correctResults, results);
}
@@ -1754,9 +1409,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testGetSupportedIfaceTypesOneChipTestChipV1() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// try API
@@ -1764,10 +1417,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// verify results
Set<Integer> correctResults = new HashSet<>();
- correctResults.add(IfaceType.AP);
- correctResults.add(IfaceType.STA);
- correctResults.add(IfaceType.P2P);
- correctResults.add(IfaceType.NAN);
+ correctResults.add(WifiChip.IFACE_TYPE_AP);
+ correctResults.add(WifiChip.IFACE_TYPE_STA);
+ correctResults.add(WifiChip.IFACE_TYPE_P2P);
+ correctResults.add(WifiChip.IFACE_TYPE_NAN);
assertEquals(correctResults, results);
}
@@ -1779,18 +1432,17 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testCanDeviceSupportCreateTypeComboChipV1() throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ chipMock.allowGetCapsBeforeIfaceCreated = false;
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
// Try to query iface support before starting the HAL. Should return false without any
// stored static chip info.
when(mWifiMock.isStarted()).thenReturn(false);
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
}}
));
- verify(mWifiMock, never()).getChipIds(any());
+ verify(mWifiMock, never()).getChipIds();
when(mWifiMock.isStarted()).thenReturn(true);
executeAndValidateStartupSequence();
clearInvocations(mWifiMock);
@@ -1811,45 +1463,45 @@ public class HalDeviceManagerTest extends WifiBaseTest {
verify(mWifiSettingsConfigStore).put(eq(WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO),
eq(new JSONArray(TestChipV1.STATIC_CHIP_INFO_JSON_STRING).toString()));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
}}
));
// AP should now be supported after we read directly from the chip.
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 2);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 2);
}}
));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.P2P, 1);
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
@@ -1865,9 +1517,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
throws Exception {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
// Try to query iface support before starting the HAL. Should return true with the stored
// static chip info.
@@ -1875,44 +1525,44 @@ public class HalDeviceManagerTest extends WifiBaseTest {
when(mWifiSettingsConfigStore.get(WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO))
.thenReturn(TestChipV1.STATIC_CHIP_INFO_JSON_STRING);
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 2);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 2);
}}
));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.P2P, 1);
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
@@ -1926,15 +1576,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// get STA interface from system app.
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -1978,13 +1626,11 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV1 chipMock = new TestChipV1();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// get STA interface.
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -2034,9 +1680,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastS());
TestChipV2 chipMock = new TestChipV2();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
@@ -2057,7 +1701,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
when(mClock.getUptimeSinceBootMillis()).thenReturn(15L);
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -2072,7 +1716,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// create P2P (system app)
when(mWorkSourceHelper1.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface p2pIface = validateInterfaceSequence(chipMock,
+ WifiInterface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_P2P, // ifaceTypeToCreate
@@ -2085,13 +1729,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
// create NAN (system app)
- IWifiIface nanIface = validateInterfaceSequence(chipMock,
+ WifiInterface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV2.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{p2pIface}, // tearDownList
+ new WifiInterface[]{p2pIface}, // tearDownList
nanDestroyedListener, // destroyedListener
TEST_WORKSOURCE_2, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(
@@ -2100,7 +1744,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
// create AP (privileged app)
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
@@ -2119,7 +1763,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, staDetails.size());
staDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_STA, true, TEST_WORKSOURCE_0);
assertNull("should not be able to create a new STA", staDetails);
- IWifiIface staIface2 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
+ WifiInterface staIface2 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// request AP2 (system app): should fail
@@ -2129,7 +1773,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, apDetails.size());
apDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_AP, true, TEST_WORKSOURCE_0);
assertNull("Should not be able to create a new AP", apDetails);
- IWifiIface apIface2 = mDut.createApIface(
+ WifiInterface apIface2 = mDut.createApIface(
CHIP_CAPABILITY_ANY, null, null, TEST_WORKSOURCE_0, false, mSoftApManager);
collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
@@ -2160,7 +1804,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, staDetails.size());
staDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_STA, true, TEST_WORKSOURCE_0);
assertNull("should not create this STA", staDetails);
- IWifiIface staIface3 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
+ WifiInterface staIface3 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
collector.checkThat("STA3 should not be created", staIface3, IsNull.nullValue());
// create AP (privileged app) - this will destroy the last STA created, i.e. STA2
@@ -2170,7 +1814,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV2.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{staIface2}, // tearDownList
+ new WifiInterface[]{staIface2}, // tearDownList
apDestroyedListener, // destroyedListener
TEST_WORKSOURCE_2, // requestorWs
// destroyedInterfacesDestroyedListeners...
@@ -2228,9 +1872,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testGetSupportedIfaceTypesAllTestChipV2() throws Exception {
TestChipV2 chipMock = new TestChipV2();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// try API
@@ -2238,10 +1880,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// verify results
Set<Integer> correctResults = new HashSet<>();
- correctResults.add(IfaceType.AP);
- correctResults.add(IfaceType.STA);
- correctResults.add(IfaceType.P2P);
- correctResults.add(IfaceType.NAN);
+ correctResults.add(WifiChip.IFACE_TYPE_AP);
+ correctResults.add(WifiChip.IFACE_TYPE_STA);
+ correctResults.add(WifiChip.IFACE_TYPE_P2P);
+ correctResults.add(WifiChip.IFACE_TYPE_NAN);
assertEquals(correctResults, results);
}
@@ -2253,9 +1895,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testGetSupportedIfaceTypesOneChipTestChipV2() throws Exception {
TestChipV2 chipMock = new TestChipV2();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// try API
@@ -2263,10 +1903,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// verify results
Set<Integer> correctResults = new HashSet<>();
- correctResults.add(IfaceType.AP);
- correctResults.add(IfaceType.STA);
- correctResults.add(IfaceType.P2P);
- correctResults.add(IfaceType.NAN);
+ correctResults.add(WifiChip.IFACE_TYPE_AP);
+ correctResults.add(WifiChip.IFACE_TYPE_STA);
+ correctResults.add(WifiChip.IFACE_TYPE_P2P);
+ correctResults.add(WifiChip.IFACE_TYPE_NAN);
assertEquals(correctResults, results);
}
@@ -2278,89 +1918,87 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testCanDeviceSupportIfaceComboTestChipV2() throws Exception {
TestChipV2 chipMock = new TestChipV2();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
// Try to query iface support before starting the HAL. Should return true with the stored
// static chip info.
when(mWifiMock.isStarted()).thenReturn(false);
when(mWifiSettingsConfigStore.get(WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO))
.thenReturn(TestChipV2.STATIC_CHIP_INFO_JSON_STRING);
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
}}
));
- verify(mWifiMock, never()).getChipIds(any());
+ verify(mWifiMock, never()).getChipIds();
when(mWifiMock.isStarted()).thenReturn(true);
executeAndValidateStartupSequence();
clearInvocations(mWifiMock);
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 2);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 2);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.P2P, 1);
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.P2P, 1);
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.AP, 1);
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.P2P, 1);
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}}
));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.AP, 2);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 2);
}}
));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.STA, 2);
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 2);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
@@ -2374,15 +2012,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV2 chipMock = new TestChipV2();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// get STA interface from system app.
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -2397,7 +2033,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// get AP interface from system app.
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV2.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
@@ -2459,9 +2095,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastS());
TestChipV3 chipMock = new TestChipV3();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
@@ -2482,7 +2116,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
when(mClock.getUptimeSinceBootMillis()).thenReturn(15L);
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -2497,7 +2131,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// create P2P (system app)
when(mWorkSourceHelper1.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface p2pIface = validateInterfaceSequence(chipMock,
+ WifiInterface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_P2P, // ifaceTypeToCreate
@@ -2510,13 +2144,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
// create NAN (privileged app): will destroy P2P
- IWifiIface nanIface = validateInterfaceSequence(chipMock,
+ WifiInterface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{p2pIface}, // tearDownList
+ new WifiInterface[]{p2pIface}, // tearDownList
nanDestroyedListener, // destroyedListener
TEST_WORKSOURCE_2, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(p2pIface), p2pDestroyedListener)
@@ -2524,13 +2158,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
// create AP (privileged app): will destroy NAN
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{nanIface}, // tearDownList
+ new WifiInterface[]{nanIface}, // tearDownList
apDestroyedListener, // destroyedListener
TEST_WORKSOURCE_2, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(nanIface), nanDestroyedListener)
@@ -2545,7 +2179,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, staDetails.size());
staDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_STA, true, TEST_WORKSOURCE_0);
assertNull("should not create this STA", staDetails);
- IWifiIface staIface2 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
+ WifiInterface staIface2 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// request AP2 (system app): should fail
@@ -2555,7 +2189,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, apDetails.size());
apDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_AP, true, TEST_WORKSOURCE_0);
assertNull("Should not create this AP", apDetails);
- IWifiIface apIface2 = mDut.createApIface(
+ WifiInterface apIface2 = mDut.createApIface(
CHIP_CAPABILITY_ANY, null, null, TEST_WORKSOURCE_0, false, mSoftApManager);
collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
@@ -2563,15 +2197,15 @@ public class HalDeviceManagerTest extends WifiBaseTest {
List<Pair<Integer, WorkSource>> p2pDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_P2P, true, TEST_WORKSOURCE_0);
assertNull("should not create this p2p", p2pDetails);
- p2pIface = mDut.createP2pIface(null, null, TEST_WORKSOURCE_0);
- collector.checkThat("P2P should not be created", p2pIface, IsNull.nullValue());
+ String p2pIfaceName = mDut.createP2pIface(null, null, TEST_WORKSOURCE_0);
+ collector.checkThat("P2P should not be created", p2pIfaceName, IsNull.nullValue());
// request P2P (privileged app): should fail
p2pDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_P2P, true, TEST_WORKSOURCE_2);
assertNull("should not create this p2p", p2pDetails);
- p2pIface = mDut.createP2pIface(null, null, TEST_WORKSOURCE_2);
- collector.checkThat("P2P should not be created", p2pIface, IsNull.nullValue());
+ p2pIfaceName = mDut.createP2pIface(null, null, TEST_WORKSOURCE_2);
+ collector.checkThat("P2P should not be created", p2pIfaceName, IsNull.nullValue());
// tear down AP
mDut.removeIface(apIface);
@@ -2600,7 +2234,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, staDetails.size());
staDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_STA, true, TEST_WORKSOURCE_0);
assertNull("should not create this STA", staDetails);
- IWifiIface staIface3 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
+ WifiInterface staIface3 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
collector.checkThat("STA3 should not be created", staIface3, IsNull.nullValue());
// create NAN (privileged app): should destroy the last created STA (STA2)
@@ -2610,7 +2244,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
HDM_CREATE_IFACE_NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{staIface2}, // tearDownList
+ new WifiInterface[]{staIface2}, // tearDownList
nanDestroyedListener, // destroyedListener
TEST_WORKSOURCE_2, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(
@@ -2661,9 +2295,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testGetSupportedIfaceTypesAllTestChipV3() throws Exception {
TestChipV3 chipMock = new TestChipV3();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// try API
@@ -2671,10 +2303,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// verify results
Set<Integer> correctResults = new HashSet<>();
- correctResults.add(IfaceType.AP);
- correctResults.add(IfaceType.STA);
- correctResults.add(IfaceType.P2P);
- correctResults.add(IfaceType.NAN);
+ correctResults.add(WifiChip.IFACE_TYPE_AP);
+ correctResults.add(WifiChip.IFACE_TYPE_STA);
+ correctResults.add(WifiChip.IFACE_TYPE_P2P);
+ correctResults.add(WifiChip.IFACE_TYPE_NAN);
assertEquals(correctResults, results);
}
@@ -2686,9 +2318,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testGetSupportedIfaceTypesOneChipTestChipV3() throws Exception {
TestChipV3 chipMock = new TestChipV3();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// try API
@@ -2696,10 +2326,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// verify results
Set<Integer> correctResults = new HashSet<>();
- correctResults.add(IfaceType.AP);
- correctResults.add(IfaceType.STA);
- correctResults.add(IfaceType.P2P);
- correctResults.add(IfaceType.NAN);
+ correctResults.add(WifiChip.IFACE_TYPE_AP);
+ correctResults.add(WifiChip.IFACE_TYPE_STA);
+ correctResults.add(WifiChip.IFACE_TYPE_P2P);
+ correctResults.add(WifiChip.IFACE_TYPE_NAN);
assertEquals(correctResults, results);
}
@@ -2711,15 +2341,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV3 chipMock = new TestChipV3();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// get STA interface from system app.
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -2734,7 +2362,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// get AP interface from system app.
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
@@ -2796,9 +2424,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assumeTrue(SdkLevel.isAtLeastS());
TestChipV4 chipMock = new TestChipV4();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
@@ -2819,7 +2445,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
when(mClock.getUptimeSinceBootMillis()).thenReturn(15L);
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -2834,7 +2460,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// create P2P (system app)
when(mWorkSourceHelper1.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface p2pIface = validateInterfaceSequence(chipMock,
+ WifiInterface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_P2P, // ifaceTypeToCreate
@@ -2847,13 +2473,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
// create NAN (privileged app): will destroy P2P
- IWifiIface nanIface = validateInterfaceSequence(chipMock,
+ WifiInterface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV4.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{p2pIface}, // tearDownList
+ new WifiInterface[]{p2pIface}, // tearDownList
nanDestroyedListener, // destroyedListener
TEST_WORKSOURCE_2, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(p2pIface), p2pDestroyedListener)
@@ -2861,13 +2487,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("allocated NAN interface", nanIface, IsNull.notNullValue());
// create AP (privileged app): will destroy NAN
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV4.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{nanIface}, // tearDownList
+ new WifiInterface[]{nanIface}, // tearDownList
apDestroyedListener, // destroyedListener
TEST_WORKSOURCE_2, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(nanIface), nanDestroyedListener)
@@ -2882,7 +2508,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, staDetails.size());
staDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_STA, true, TEST_WORKSOURCE_0);
assertNull("should not create this STA", staDetails);
- IWifiIface staIface2 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
+ WifiInterface staIface2 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// request AP2 (system app): should fail
@@ -2892,7 +2518,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, apDetails.size());
apDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_AP, true, TEST_WORKSOURCE_0);
assertNull("Should not create this AP", apDetails);
- IWifiIface apIface2 = mDut.createApIface(
+ WifiInterface apIface2 = mDut.createApIface(
CHIP_CAPABILITY_ANY, null, null, TEST_WORKSOURCE_0, false, mSoftApManager);
collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
@@ -2900,15 +2526,15 @@ public class HalDeviceManagerTest extends WifiBaseTest {
List<Pair<Integer, WorkSource>> p2pDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_P2P, true, TEST_WORKSOURCE_0);
assertNull("should not create this p2p", p2pDetails);
- p2pIface = mDut.createP2pIface(null, null, TEST_WORKSOURCE_0);
- collector.checkThat("P2P should not be created", p2pIface, IsNull.nullValue());
+ String p2pIfaceName = mDut.createP2pIface(null, null, TEST_WORKSOURCE_0);
+ collector.checkThat("P2P should not be created", p2pIfaceName, IsNull.nullValue());
// request P2P (privileged app): should fail
p2pDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_P2P, true, TEST_WORKSOURCE_2);
assertNull("should not create this p2p", p2pDetails);
- p2pIface = mDut.createP2pIface(null, null, TEST_WORKSOURCE_2);
- collector.checkThat("P2P should not be created", p2pIface, IsNull.nullValue());
+ p2pIfaceName = mDut.createP2pIface(null, null, TEST_WORKSOURCE_2);
+ collector.checkThat("P2P should not be created", p2pIfaceName, IsNull.nullValue());
// tear down AP
mDut.removeIface(apIface);
@@ -2967,9 +2593,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assumeFalse(SdkLevel.isAtLeastS());
TestChipV4 chipMock = new TestChipV4();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
@@ -2987,7 +2611,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
InterfaceDestroyedListener.class);
// create STA
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -3000,7 +2624,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("STA interface wasn't created", staIface, IsNull.notNullValue());
// create P2P
- IWifiIface p2pIface = validateInterfaceSequence(chipMock,
+ WifiInterface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_P2P, // ifaceTypeToCreate
@@ -3013,13 +2637,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("P2P interface wasn't created", p2pIface, IsNull.notNullValue());
// create NAN: will destroy P2P
- IWifiIface nanIface = validateInterfaceSequence(chipMock,
+ WifiInterface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
TestChipV4.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{p2pIface}, // tearDownList
+ new WifiInterface[]{p2pIface}, // tearDownList
nanDestroyedListener, // destroyedListener
TEST_WORKSOURCE_2, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(p2pIface), p2pDestroyedListener)
@@ -3027,13 +2651,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
// create AP: will destroy NAN
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV4.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{nanIface}, // tearDownList
+ new WifiInterface[]{nanIface}, // tearDownList
apDestroyedListener, // destroyedListener
TEST_WORKSOURCE_2, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(nanIface), nanDestroyedListener)
@@ -3048,7 +2672,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, staDetails.size());
staDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_STA, true, TEST_WORKSOURCE_0);
assertNull("Should not create this STA", staDetails);
- IWifiIface staIface2 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
+ WifiInterface staIface2 = mDut.createStaIface(null, null, TEST_WORKSOURCE_0);
collector.checkThat("STA2 should not be created", staIface2, IsNull.nullValue());
// request AP2: should fail
@@ -3058,7 +2682,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(0, apDetails.size());
apDetails = mDut.reportImpactToCreateIface(HDM_CREATE_IFACE_AP, true, TEST_WORKSOURCE_0);
assertNull("Should not create this AP", apDetails);
- IWifiIface apIface2 = mDut.createApIface(
+ WifiInterface apIface2 = mDut.createApIface(
CHIP_CAPABILITY_ANY, null, null, TEST_WORKSOURCE_0, false, mSoftApManager);
collector.checkThat("AP2 should not be created", apIface2, IsNull.nullValue());
@@ -3066,15 +2690,18 @@ public class HalDeviceManagerTest extends WifiBaseTest {
List<Pair<Integer, WorkSource>> p2pDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_P2P, true, TEST_WORKSOURCE_0);
assertNull("should not create this p2p", p2pDetails);
- p2pIface = mDut.createP2pIface(null, null, TEST_WORKSOURCE_0);
- collector.checkThat("P2P should not be created", p2pIface, IsNull.nullValue());
+ String p2pIfaceName = mDut.createP2pIface(null, null, TEST_WORKSOURCE_0);
+ collector.checkThat("P2P should not be created", p2pIfaceName, IsNull.nullValue());
// request NAN: should fail
List<Pair<Integer, WorkSource>> nanDetails = mDut.reportImpactToCreateIface(
HDM_CREATE_IFACE_NAN, true, TEST_WORKSOURCE_0);
assertNull("Should not create this nan", nanDetails);
- nanIface = mDut.createNanIface(null, null, TEST_WORKSOURCE_0);
- collector.checkThat("NAN should not be created", nanIface, IsNull.nullValue());
+ // Expect a WifiNanIface wrapper object this time, since we are calling
+ // createNanIface instead of createIface.
+ WifiNanIface nanIface2 =
+ mDut.createNanIface(null, null, TEST_WORKSOURCE_0);
+ collector.checkThat("NAN should not be created", nanIface2, IsNull.nullValue());
// tear down AP
mDut.removeIface(apIface);
@@ -3115,9 +2742,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testInterfaceCreationFlowTestChipV3WithInternalRequest() throws Exception {
TestChipV3 chipMock = new TestChipV3();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener apDestroyedListener = mock(
@@ -3130,7 +2755,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_INTERNAL);
// create NAN (privileged app): will destroy P2P
- IWifiIface nanIface = validateInterfaceSequence(chipMock,
+ WifiInterface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_NAN, // ifaceTypeToCreate
@@ -3143,13 +2768,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("NAN interface wasn't created", nanIface, IsNull.notNullValue());
// create AP (privileged app): will destroy NAN
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV3.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
"wlan1", // ifaceName
TestChipV3.CHIP_MODE_ID, // finalChipMode
- new IWifiIface[]{nanIface}, // tearDownList
+ new WifiInterface[]{nanIface}, // tearDownList
apDestroyedListener, // destroyedListener
TEST_WORKSOURCE_1, // requestorWs
new InterfaceDestroyedListenerWithIfaceName(getName(nanIface), nanDestroyedListener)
@@ -3193,9 +2818,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testGetSupportedIfaceTypesAllTestChipV4() throws Exception {
TestChipV4 chipMock = new TestChipV4();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// try API
@@ -3203,10 +2826,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// verify results
Set<Integer> correctResults = new HashSet<>();
- correctResults.add(IfaceType.AP);
- correctResults.add(IfaceType.STA);
- correctResults.add(IfaceType.P2P);
- correctResults.add(IfaceType.NAN);
+ correctResults.add(WifiChip.IFACE_TYPE_AP);
+ correctResults.add(WifiChip.IFACE_TYPE_STA);
+ correctResults.add(WifiChip.IFACE_TYPE_P2P);
+ correctResults.add(WifiChip.IFACE_TYPE_NAN);
assertEquals(correctResults, results);
}
@@ -3218,9 +2841,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testGetSupportedIfaceTypesOneChipTestChipV4() throws Exception {
TestChipV4 chipMock = new TestChipV4();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// try API
@@ -3228,10 +2849,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// verify results
Set<Integer> correctResults = new HashSet<>();
- correctResults.add(IfaceType.AP);
- correctResults.add(IfaceType.STA);
- correctResults.add(IfaceType.P2P);
- correctResults.add(IfaceType.NAN);
+ correctResults.add(WifiChip.IFACE_TYPE_AP);
+ correctResults.add(WifiChip.IFACE_TYPE_STA);
+ correctResults.add(WifiChip.IFACE_TYPE_P2P);
+ correctResults.add(WifiChip.IFACE_TYPE_NAN);
assertEquals(correctResults, results);
}
@@ -3243,15 +2864,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV4 chipMock = new TestChipV4();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// get STA interface from system app.
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -3266,7 +2885,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// get AP interface from system app.
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
@@ -3311,13 +2930,11 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV4 chipMock = new TestChipV4();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// get STA interface.
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -3330,7 +2947,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("STA created", staIface, IsNull.notNullValue());
// get AP interface.
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV4.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
@@ -3358,23 +2975,15 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void verify60GhzIfaceCreation(
ChipMockBase chipMock, int chipModeId, int finalChipModeId, boolean isWigigSupported)
throws Exception {
- long requiredChipCapabilities =
- android.hardware.wifi.V1_5.IWifiChip.ChipCapabilityMask.WIGIG;
+ long requiredChipCapabilities = WifiManager.WIFI_FEATURE_INFRA_60G;
chipMock.initialize();
- if (mWifiChipV15 != null) {
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mWifiChipV15, mManagerStatusListenerMock);
- } else {
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- }
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// get STA interface from system app.
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface staIface;
+ WifiInterface staIface;
if (isWigigSupported) {
staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
@@ -3401,7 +3010,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// get AP interface from system app.
when(mWorkSourceHelper0.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface apIface;
+ WifiInterface apIface;
if (isWigigSupported) {
apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
@@ -3428,7 +3037,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
when(mWorkSourceHelper1.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_PRIVILEGED);
assertThat(mDut.isItPossibleToCreateIface(HDM_CREATE_IFACE_P2P,
- android.hardware.wifi.V1_5.IWifiChip.ChipCapabilityMask.WIGIG,
+ WifiManager.WIFI_FEATURE_INFRA_60G,
TEST_WORKSOURCE_1), is(isWigigSupported));
}
}
@@ -3440,49 +3049,34 @@ public class HalDeviceManagerTest extends WifiBaseTest {
@Test
public void testIsItPossibleToCreate60GhzIfaceTestChipV5() throws Exception {
TestChipV5 chipMock = new TestChipV5();
- setupWifiChipV15(chipMock);
verify60GhzIfaceCreation(
chipMock, TestChipV5.CHIP_MODE_ID, TestChipV5.CHIP_MODE_ID, true);
}
/*
- * Verify that 60GHz iface creation request could not be procceed by a chip does
- * not supports WIGIG on V1.5 HAL.
+ * Verify that 60GHz iface creation request cannot be processed by a chip that does
+ * not support WIGIG.
*/
@Test
public void testIsItPossibleToCreate60GhzIfaceTestChipV4() throws Exception {
TestChipV4 chipMock = new TestChipV4();
- setupWifiChipV15(chipMock);
verify60GhzIfaceCreation(
chipMock, TestChipV4.CHIP_MODE_ID, TestChipV4.CHIP_MODE_ID, false);
}
- /*
- * Verify that 60GHz iface creation request could be procceed by a chip does
- * not supports WIGIG on a HAL older than v1.5.
- */
- @Test
- public void testIsItPossibleToCreate60GhzIfaceTestChipV4WithHalOlderThan1_5() throws Exception {
- TestChipV4 chipMock = new TestChipV4();
- verify60GhzIfaceCreation(
- chipMock, TestChipV4.CHIP_MODE_ID, TestChipV4.CHIP_MODE_ID, true);
- }
-
/**
- * Validate creation of AP interface from blank start-up in chip V1.5
+ * Validate creation of AP interface from blank start-up.
*/
@Test
public void testCreateApInterfaceNoInitModeTestChipV15() throws Exception {
- mWifiChipV15 = mock(android.hardware.wifi.V1_5.IWifiChip.class);
runCreateSingleXxxInterfaceNoInitMode(new TestChipV5(), HDM_CREATE_IFACE_AP, "wlan0",
TestChipV5.CHIP_MODE_ID);
}
/**
- * Validate creation of AP Bridge interface from blank start-up in chip V1.5
+ * Validate creation of AP Bridge interface from blank start-up.
*/
@Test
public void testCreateApBridgeInterfaceNoInitModeTestChipV15() throws Exception {
- mWifiChipV15 = mock(android.hardware.wifi.V1_5.IWifiChip.class);
mIsBridgedSoftApSupported = true;
mIsStaWithBridgedSoftApConcurrencySupported = true;
runCreateSingleXxxInterfaceNoInitMode(new TestChipV5(), HDM_CREATE_IFACE_AP_BRIDGE, "wlan0",
@@ -3498,18 +3092,15 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mIsBridgedSoftApSupported = true;
mIsStaWithBridgedSoftApConcurrencySupported = false;
TestChipV5 chipMock = new TestChipV5();
- setupWifiChipV15(chipMock);
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mWifiChipV15, mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
InterfaceDestroyedListener.class);
// Create the STA
- IWifiIface iface = validateInterfaceSequence(chipMock,
+ WifiInterface iface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA,
@@ -3536,17 +3127,14 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mIsBridgedSoftApSupported = true;
mIsStaWithBridgedSoftApConcurrencySupported = true;
TestChipV5 chipMock = new TestChipV5();
- setupWifiChipV15(chipMock);
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mWifiChipV15, mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
InterfaceDestroyedListener.class);
- IWifiIface iface = validateInterfaceSequence(chipMock,
+ WifiInterface iface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA,
@@ -3571,9 +3159,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testCanDeviceSupportIfaceComboTestChipV6() throws Exception {
TestChipV6 testChip = new TestChipV6();
testChip.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, testChip.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, testChip.chip, mManagerStatusListenerMock);
// Try to query iface support before starting the HAL. Should return true with the stored
// static chip info.
when(mWifiMock.isStarted()).thenReturn(false);
@@ -3581,10 +3167,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
.thenReturn(TestChipV6.STATIC_CHIP_INFO_JSON_STRING);
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {
{
- put(IfaceConcurrencyType.STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
}
}));
- verify(mWifiMock, never()).getChipIds(any());
+ verify(mWifiMock, never()).getChipIds();
when(mWifiMock.isStarted()).thenReturn(true);
executeAndValidateStartupSequence();
@@ -3592,47 +3178,47 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {
{
- put(IfaceConcurrencyType.STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
}
}));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {
{
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}
}));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {
{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}
}));
assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {
{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.AP_BRIDGED, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED, 1);
}
}));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {
{
- put(IfaceConcurrencyType.AP, 1);
- put(IfaceConcurrencyType.AP_BRIDGED, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED, 1);
}
}));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {
{
- put(IfaceConcurrencyType.STA, 1);
- put(IfaceConcurrencyType.AP, 1);
- put(IfaceConcurrencyType.AP_BRIDGED, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_STA, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED, 1);
}
}));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {
{
- put(IfaceConcurrencyType.NAN, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_NAN, 1);
}
}));
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {
{
- put(IfaceConcurrencyType.P2P, 2);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_P2P, 2);
}
}));
@@ -3645,7 +3231,6 @@ public class HalDeviceManagerTest extends WifiBaseTest {
@Test
public void testCreateApBridgeInterfaceNoInitModeTestChipV6() throws Exception {
TestChipV6 testChip = new TestChipV6();
- setupWifiChipV15(testChip);
runCreateSingleXxxInterfaceNoInitMode(testChip, HDM_CREATE_IFACE_AP_BRIDGE, "wlan0",
TestChipV6.CHIP_MODE_ID);
}
@@ -3659,11 +3244,8 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mIsBridgedSoftApSupported = true;
mIsStaWithBridgedSoftApConcurrencySupported = false;
TestChipV6 chipMock = new TestChipV6();
- setupWifiChipV15(chipMock);
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mWifiChipV15, mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
@@ -3674,7 +3256,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
bridgedApInstances.add("instance0");
bridgedApInstances.add("instance1");
chipMock.bridgedApInstancesByName.put("wlan0", bridgedApInstances);
- IWifiIface iface = validateInterfaceSequence(chipMock,
+ WifiInterface iface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_AP_BRIDGE,
@@ -3702,25 +3284,23 @@ public class HalDeviceManagerTest extends WifiBaseTest {
assertEquals(2, bridgedApInstances.size());
}
- private IWifiIface setupDbsSupportTest(ChipMockBase testChip, int onlyChipMode,
+ private WifiInterface setupDbsSupportTest(ChipMockBase testChip, int onlyChipMode,
ImmutableList<ArrayList<Integer>> radioCombinationMatrix) throws Exception {
- WifiRadioCombinationMatrix matrix = new WifiRadioCombinationMatrix();
- for (ArrayList<Integer> comb: radioCombinationMatrix) {
- WifiRadioCombination combination = new WifiRadioCombination();
- for (Integer b: comb) {
- WifiRadioConfiguration config = new WifiRadioConfiguration();
- config.bandInfo = b;
- combination.radioConfigurations.add(config);
+ List<WifiChip.WifiRadioCombination> combos = new ArrayList<>();
+ for (ArrayList<Integer> comb : radioCombinationMatrix) {
+ List<WifiChip.WifiRadioConfiguration> configs = new ArrayList<>();
+ for (Integer b : comb) {
+ configs.add(new WifiChip.WifiRadioConfiguration(b, 0));
}
- matrix.radioCombinations.add(combination);
+ combos.add(new WifiChip.WifiRadioCombination(new ArrayList<>(configs)));
}
+ WifiChip.WifiRadioCombinationMatrix matrix =
+ new WifiChip.WifiRadioCombinationMatrix(combos);
testChip.chipSupportedRadioCombinationsMatrix = matrix;
testChip.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, testChip.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, testChip.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
@@ -3730,7 +3310,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
InterfaceDestroyedListener.class);
// Request STA
- IWifiIface staIface = validateInterfaceSequence(testChip,
+ WifiInterface staIface = validateInterfaceSequence(testChip,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // createIfaceType
@@ -3743,7 +3323,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("STA can't be created", staIface, IsNull.notNullValue());
// Request P2P
- IWifiIface p2pIface = validateInterfaceSequence(testChip,
+ WifiInterface p2pIface = validateInterfaceSequence(testChip,
true, // chipModeValid
onlyChipMode, // chipModeId
HDM_CREATE_IFACE_P2P, // ifaceTypeToCreate
@@ -3766,8 +3346,9 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void test24g5gDbsSupport() throws Exception {
TestChipV6 testChip = new TestChipV6();
ImmutableList<ArrayList<Integer>> radioCombinationMatrix = ImmutableList.of(
- new ArrayList(Arrays.asList(WifiBand.BAND_24GHZ, WifiBand.BAND_5GHZ)));
- IWifiIface iface = setupDbsSupportTest(testChip, TestChipV6.CHIP_MODE_ID,
+ new ArrayList(Arrays.asList(
+ WifiScanner.WIFI_BAND_24_GHZ, WifiScanner.WIFI_BAND_5_GHZ)));
+ WifiInterface iface = setupDbsSupportTest(testChip, TestChipV6.CHIP_MODE_ID,
radioCombinationMatrix);
assertTrue(mDut.is24g5gDbsSupported(iface));
@@ -3781,8 +3362,9 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void test5g6gDbsSupport() throws Exception {
TestChipV6 testChip = new TestChipV6();
ImmutableList<ArrayList<Integer>> radioCombinationMatrix = ImmutableList.of(
- new ArrayList(Arrays.asList(WifiBand.BAND_5GHZ, WifiBand.BAND_6GHZ)));
- IWifiIface iface = setupDbsSupportTest(testChip, TestChipV6.CHIP_MODE_ID,
+ new ArrayList(Arrays.asList(
+ WifiScanner.WIFI_BAND_5_GHZ, WifiScanner.WIFI_BAND_6_GHZ)));
+ WifiInterface iface = setupDbsSupportTest(testChip, TestChipV6.CHIP_MODE_ID,
radioCombinationMatrix);
assertFalse(mDut.is24g5gDbsSupported(iface));
@@ -3796,9 +3378,11 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void test24g5gAnd5g6gDbsSupport() throws Exception {
TestChipV6 testChip = new TestChipV6();
ImmutableList<ArrayList<Integer>> radioCombinationMatrix = ImmutableList.of(
- new ArrayList(Arrays.asList(WifiBand.BAND_24GHZ, WifiBand.BAND_5GHZ)),
- new ArrayList(Arrays.asList(WifiBand.BAND_5GHZ, WifiBand.BAND_6GHZ)));
- IWifiIface iface = setupDbsSupportTest(testChip, TestChipV6.CHIP_MODE_ID,
+ new ArrayList(Arrays.asList(
+ WifiScanner.WIFI_BAND_24_GHZ, WifiScanner.WIFI_BAND_5_GHZ)),
+ new ArrayList(Arrays.asList(
+ WifiScanner.WIFI_BAND_5_GHZ, WifiScanner.WIFI_BAND_6_GHZ)));
+ WifiInterface iface = setupDbsSupportTest(testChip, TestChipV6.CHIP_MODE_ID,
radioCombinationMatrix);
assertTrue(mDut.is24g5gDbsSupported(iface));
@@ -3815,13 +3399,11 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV7 chipMock = new TestChipV7();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// get STA interface from privileged app.
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // ifaceTypeToCreate
@@ -3871,10 +3453,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
TestChipV8 chipMock = new TestChipV8();
chipMock.initialize();
- setupWifiChipV15(chipMock);
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mWifiChipV15, mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
// get AP_BRIDGED interface for a privileged app.
@@ -3882,7 +3461,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
bridgedApInstances.add("instance0");
bridgedApInstances.add("instance1");
chipMock.bridgedApInstancesByName.put("wlan0", bridgedApInstances);
- IWifiIface apBridgedIface = validateInterfaceSequence(chipMock,
+ WifiInterface apBridgedIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_AP_BRIDGE, // ifaceTypeToCreate
@@ -3897,7 +3476,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// get AP interface for a system app.
when(mWorkSourceHelper1.getRequestorWsPriority())
.thenReturn(WorkSourceHelper.PRIORITY_SYSTEM);
- IWifiIface apIface = validateInterfaceSequence(chipMock,
+ WifiInterface apIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
TestChipV8.CHIP_MODE_ID, // chipModeId
HDM_CREATE_IFACE_AP, // ifaceTypeToCreate
@@ -3927,11 +3506,8 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mIsBridgedSoftApSupported = true;
mIsStaWithBridgedSoftApConcurrencySupported = false;
TestChipV9 chipMock = new TestChipV9();
- setupWifiChipV15(chipMock);
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mWifiChipV15, mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
@@ -3942,7 +3518,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
bridgedApInstances.add("instance0");
bridgedApInstances.add("instance1");
chipMock.bridgedApInstancesByName.put("wlan0", bridgedApInstances);
- IWifiIface iface = validateInterfaceSequence(chipMock,
+ WifiInterface iface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_AP_BRIDGE,
@@ -3974,11 +3550,8 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mIsBridgedSoftApSupported = true;
mIsStaWithBridgedSoftApConcurrencySupported = false;
TestChipV9 chipMock = new TestChipV9();
- setupWifiChipV15(chipMock);
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mWifiChipV15, mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
@@ -3989,7 +3562,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
bridgedApInstances.add("instance0");
bridgedApInstances.add("instance1");
chipMock.bridgedApInstancesByName.put("wlan0", bridgedApInstances);
- IWifiIface iface = validateInterfaceSequence(chipMock,
+ WifiInterface iface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_AP_BRIDGE,
@@ -4023,18 +3596,17 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void testCanDeviceSupportCreateTypeComboAfterDriverReadyChipV10() throws Exception {
TestChipV10 chipMock = new TestChipV10();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ chipMock.allowGetCapsBeforeIfaceCreated = false;
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
// Try to query AP support before starting the HAL. Should return false without any
// stored static chip info.
when(mWifiMock.isStarted()).thenReturn(false);
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
- verify(mWifiMock, never()).getChipIds(any());
+ verify(mWifiMock, never()).getChipIds();
when(mWifiMock.isStarted()).thenReturn(true);
// Start the HAL
@@ -4042,7 +3614,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// Still can't create AP since driver isn't ready.
assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
- put(IfaceConcurrencyType.AP, 1);
+ put(WifiChip.IFACE_CONCURRENCY_TYPE_AP, 1);
}}
));
@@ -4075,9 +3647,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// Stop and start Wifi and re-initialize the chip to the default available modes.
mDut.stop();
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
// Try creating an AP again -- should succeed since we're using the cached
// available modes we loaded from the driver.
@@ -4093,106 +3663,15 @@ public class HalDeviceManagerTest extends WifiBaseTest {
);
}
- /**
- * Validate only one Bridged AP can be created with TestChipV11, which supports AP + AP.
- */
- @Test
- public void testCreateOnlyOneApBridgedInterfaceTestChipV11() throws Exception {
- mIsBridgedSoftApSupported = true;
- TestChipV11 chipMock = new TestChipV11();
- chipMock.initialize();
- setupWifiChipV15(chipMock);
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mWifiChipV15, mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
- executeAndValidateStartupSequence();
-
- // Get the first Bridged AP
- ArrayList<String> bridgedApInstances = new ArrayList<>();
- bridgedApInstances.add("instance0");
- bridgedApInstances.add("instance1");
- chipMock.bridgedApInstancesByName.put("wlan0", bridgedApInstances);
- IWifiIface apBridgedIface = validateInterfaceSequence(chipMock,
- false, // chipModeValid
- -1000, // chipModeId (only used if chipModeValid is true)
- HDM_CREATE_IFACE_AP_BRIDGE, // ifaceTypeToCreate
- "wlan0", // ifaceName
- TestChipV11.CHIP_MODE_ID, // finalChipMode
- null, // tearDownList
- mock(InterfaceDestroyedListener.class), // destroyedListener
- TEST_WORKSOURCE_0 // requestorWs
- );
- collector.checkThat("Bridged AP not created", apBridgedIface, IsNull.notNullValue());
-
- // Should not be able to create a second Bridged AP.
- assertNull(mDut.reportImpactToCreateIface(
- HDM_CREATE_IFACE_AP_BRIDGE, true, 0, TEST_WORKSOURCE_0));
- }
-
///////////////////////////////////////////////////////////////////////////////////////
// utilities
///////////////////////////////////////////////////////////////////////////////////////
- private void setupWifiChipV15(ChipMockBase chipMock) throws RemoteException {
- mWifiChipV15 = mock(android.hardware.wifi.V1_5.IWifiChip.class);
- doAnswer(new GetCapabilities_1_5Answer(chipMock))
- .when(mWifiChipV15).getCapabilities_1_5(any(
- android.hardware.wifi.V1_5.IWifiChip.getCapabilities_1_5Callback.class));
- when(mWifiChipV15.removeIfaceInstanceFromBridgedApIface(any(), any()))
- .thenAnswer((invocation) -> {
- chipMock.bridgedApInstancesByName.get(invocation.getArgument(0))
- .remove(invocation.getArgument(1));
- return getStatus(WifiStatusCode.SUCCESS);
- });
- }
-
- private void setupWifiV15(IWifi iWifiMock) throws RemoteException {
- mWifiMockV15 = mock(android.hardware.wifi.V1_5.IWifi.class);
- when(mWifiMockV15.registerEventCallback_1_5(
- any(android.hardware.wifi.V1_5.IWifiEventCallback.class))).thenReturn(mStatusOk);
- }
-
private void dumpDut(String prefix) {
StringWriter sw = new StringWriter();
mDut.dump(null, new PrintWriter(sw), null);
Log.e("HalDeviceManager", prefix + sw.toString());
}
- private void executeAndValidateInitializationSequence() throws Exception {
- executeAndValidateInitializationSequence(true);
- }
-
- private void executeAndValidateInitializationSequence(boolean isSupported) throws Exception {
- // act:
- mDut.initialize();
-
- // verify: service manager initialization sequence
- mInOrder.verify(mServiceManagerMock).linkToDeath(any(IHwBinder.DeathRecipient.class),
- anyLong());
- mInOrder.verify(mServiceManagerMock).registerForNotifications(eq(IWifi.kInterfaceName),
- eq(""), mServiceNotificationCaptor.capture());
-
- // If not using the lazy version of the IWifi service, the process should already be up at
- // this point.
- mInOrder.verify(mServiceManagerMock).listManifestByInterface(eq(IWifi.kInterfaceName));
-
- // verify: wifi initialization sequence if vendor HAL is supported.
- if (isSupported) {
- mInOrder.verify(mWifiMock).linkToDeath(mDeathRecipientCaptor.capture(), anyLong());
- // verify: onStop called as a part of initialize.
- mInOrder.verify(mWifiMock).stop();
- if (null != mWifiMockV15) {
- mInOrder.verify(mWifiMockV15).registerEventCallback_1_5(
- mWifiEventCallbackCaptorV15.capture());
- } else {
- mInOrder.verify(mWifiMock).registerEventCallback(
- mWifiEventCallbackCaptor.capture());
- }
- collector.checkThat("isReady is true", mDut.isReady(), equalTo(true));
- } else {
- collector.checkThat("isReady is false", mDut.isReady(), equalTo(false));
- }
- }
-
private void executeAndValidateStartupSequence() throws Exception {
executeAndValidateStartupSequence(1, true);
}
@@ -4200,19 +3679,17 @@ public class HalDeviceManagerTest extends WifiBaseTest {
private void executeAndValidateStartupSequence(int numAttempts, boolean success)
throws Exception {
// act: register listener & start Wi-Fi
+ mDut.initialize();
mDut.registerStatusListener(mManagerStatusListenerMock, mHandler);
collector.checkThat(mDut.start(), equalTo(success));
// verify
+ verify(mWifiMock).registerEventCallback(mWifiEventCallbackCaptor.capture());
mInOrder.verify(mWifiMock, times(numAttempts)).start();
if (success) {
// act: trigger onStart callback of IWifiEventCallback
- if (mWifiMockV15 != null) {
- mWifiEventCallbackCaptorV15.getValue().onStart();
- } else {
- mWifiEventCallbackCaptor.getValue().onStart();
- }
+ mWifiEventCallbackCaptor.getValue().onStart();
mTestLooper.dispatchAll();
// verify: onStart called on registered listener
@@ -4223,20 +3700,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
private void runCreateSingleXxxInterfaceNoInitMode(ChipMockBase chipMock, int ifaceTypeToCreate,
String ifaceName, int finalChipMode) throws Exception {
chipMock.initialize();
- if (mWifiChipV15 != null) {
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mWifiChipV15, mManagerStatusListenerMock);
- } else {
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- }
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener idl = mock(
InterfaceDestroyedListener.class);
- IWifiIface iface = validateInterfaceSequence(chipMock,
+ WifiInterface iface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
ifaceTypeToCreate,
@@ -4292,9 +3762,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
public void runP2pAndNanExclusiveInteractionsTestChip(ChipMockBase chipMock,
int onlyChipMode) throws Exception {
chipMock.initialize();
- mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip,
- mManagerStatusListenerMock);
- executeAndValidateInitializationSequence();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
executeAndValidateStartupSequence();
InterfaceDestroyedListener staDestroyedListener = mock(
@@ -4307,7 +3775,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
InterfaceDestroyedListener.class);
// Request STA
- IWifiIface staIface = validateInterfaceSequence(chipMock,
+ WifiInterface staIface = validateInterfaceSequence(chipMock,
false, // chipModeValid
-1000, // chipModeId (only used if chipModeValid is true)
HDM_CREATE_IFACE_STA, // createIfaceType
@@ -4320,7 +3788,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
collector.checkThat("STA can't be created", staIface, IsNull.notNullValue());
// Request NAN
- IWifiIface nanIface = validateInterfaceSequence(chipMock,
+ WifiInterface nanIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
onlyChipMode, // chipModeId
HDM_CREATE_IFACE_NAN, // ifaceTypeToCreate
@@ -4332,13 +3800,13 @@ public class HalDeviceManagerTest extends WifiBaseTest {
);
// Request P2P
- IWifiIface p2pIface = validateInterfaceSequence(chipMock,
+ WifiInterface p2pIface = validateInterfaceSequence(chipMock,
true, // chipModeValid
onlyChipMode, // chipModeId
HDM_CREATE_IFACE_P2P, // ifaceTypeToCreate
"p2p0", // ifaceName
onlyChipMode, // finalChipMode
- new IWifiIface[]{nanIface}, // tearDownList
+ new WifiInterface[]{nanIface}, // tearDownList
p2pDestroyedListener, // destroyedListener
TEST_WORKSOURCE_0, // requestorWs
// destroyedInterfacesDestroyedListeners...
@@ -4356,7 +3824,7 @@ public class HalDeviceManagerTest extends WifiBaseTest {
HDM_CREATE_IFACE_NAN, // ifaceTypeToCreate
"wlan0", // ifaceName
onlyChipMode, // finalChipMode
- new IWifiIface[]{p2pIface}, // tearDownList
+ new WifiInterface[]{p2pIface}, // tearDownList
nanDestroyedListener, // destroyedListener
TEST_WORKSOURCE_0 // requestorWs
);
@@ -4369,11 +3837,11 @@ public class HalDeviceManagerTest extends WifiBaseTest {
nanDestroyedListener, p2pDestroyedListener);
}
- private IWifiIface validateInterfaceSequence(ChipMockBase chipMock,
+ private WifiInterface validateInterfaceSequence(ChipMockBase chipMock,
boolean chipModeValid, int chipModeId,
int createIfaceType, String ifaceName, int finalChipMode,
long requiredChipCapabilities,
- IWifiIface[] tearDownList,
+ WifiInterface[] tearDownList,
InterfaceDestroyedListener destroyedListener,
WorkSource requestorWs,
InterfaceDestroyedListenerWithIfaceName...destroyedInterfacesDestroyedListeners)
@@ -4393,93 +3861,66 @@ public class HalDeviceManagerTest extends WifiBaseTest {
HAL_IFACE_MAP.get(details.get(0).first.intValue()));
}
- IWifiIface iface = null;
+ WifiInterface iface = null;
// configure: interface to be created
// act: request the interface
switch (createIfaceType) {
case HDM_CREATE_IFACE_STA:
- iface = mock(IWifiStaIface.class);
- doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.STA)).when(iface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
- chipMock.chip).createStaIface(any(IWifiChip.createStaIfaceCallback.class));
-
+ iface = mock(WifiStaIface.class);
+ doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName();
+ doAnswer(new CreateStaIfaceAnswer(chipMock, true, iface))
+ .when(chipMock.chip).createStaIface();
mDut.createStaIface(requiredChipCapabilities,
destroyedListener, mHandler, requestorWs);
break;
case HDM_CREATE_IFACE_AP_BRIDGE:
case HDM_CREATE_IFACE_AP:
- iface = mock(IWifiApIface.class);
- doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.AP)).when(iface).getType(
- any(IWifiIface.getTypeCallback.class));
- if (mWifiChipV15 != null && createIfaceType == HDM_CREATE_IFACE_AP_BRIDGE) {
- android.hardware.wifi.V1_5.IWifiApIface ifaceApV15 =
- mock(android.hardware.wifi.V1_5.IWifiApIface.class);
- doAnswer(new GetNameAnswer(ifaceName)).when(ifaceApV15).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.AP)).when(ifaceApV15).getType(
- any(IWifiIface.getTypeCallback.class));
+ iface = mock(WifiApIface.class);
+ doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName();
+ if (createIfaceType == HDM_CREATE_IFACE_AP_BRIDGE) {
doAnswer(new GetBridgedInstancesAnswer(chipMock, ifaceName))
- .when(ifaceApV15).getBridgedInstances(
- any(android.hardware.wifi.V1_5.IWifiApIface
- .getBridgedInstancesCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, ifaceApV15)).when(
- mWifiChipV15).createBridgedApIface(
- any(android.hardware.wifi.V1_5.IWifiChip
- .createBridgedApIfaceCallback.class));
- } else {
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
- chipMock.chip).createApIface(
- any(IWifiChip.createApIfaceCallback.class));
+ .when((WifiApIface) iface).getBridgedInstances();
}
+ doAnswer(new CreateApIfaceAnswer(chipMock, true, iface))
+ .when(chipMock.chip).createApIface();
+ doAnswer(new CreateApIfaceAnswer(chipMock, true, iface))
+ .when(chipMock.chip).createBridgedApIface();
mDut.createApIface(requiredChipCapabilities,
destroyedListener, mHandler, requestorWs,
createIfaceType == HDM_CREATE_IFACE_AP_BRIDGE, mSoftApManager);
break;
case HDM_CREATE_IFACE_P2P:
- iface = mock(IWifiP2pIface.class);
- doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.P2P)).when(iface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
- chipMock.chip).createP2pIface(any(IWifiChip.createP2pIfaceCallback.class));
-
+ iface = mock(WifiP2pIface.class);
+ doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName();
+ doAnswer(new CreateP2pIfaceAnswer(chipMock, true, iface))
+ .when(chipMock.chip).createP2pIface();
mDut.createP2pIface(requiredChipCapabilities,
destroyedListener, mHandler, requestorWs);
break;
case HDM_CREATE_IFACE_NAN:
- iface = mock(IWifiNanIface.class);
- doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName(
- any(IWifiIface.getNameCallback.class));
- doAnswer(new GetTypeAnswer(IfaceType.NAN)).when(iface).getType(
- any(IWifiIface.getTypeCallback.class));
- doAnswer(new CreateXxxIfaceAnswer(chipMock, mStatusOk, iface)).when(
- chipMock.chip).createNanIface(any(IWifiChip.createNanIfaceCallback.class));
-
+ iface = mock(WifiNanIface.class);
+ doAnswer(new GetNameAnswer(ifaceName)).when(iface).getName();
+ doAnswer(new CreateNanIfaceAnswer(chipMock, true, iface))
+ .when(chipMock.chip).createNanIface();
mDut.createNanIface(destroyedListener, mHandler, requestorWs);
break;
}
// validate: optional tear down of interfaces
if (tearDownList != null) {
- for (IWifiIface tearDownIface: tearDownList) {
+ for (WifiInterface tearDownIface: tearDownList) {
switch (getType(tearDownIface)) {
- case IfaceType.STA:
+ case WifiChip.IFACE_TYPE_STA:
mInOrder.verify(chipMock.chip).removeStaIface(getName(tearDownIface));
break;
- case IfaceType.AP:
+ case WifiChip.IFACE_TYPE_AP:
mInOrder.verify(chipMock.chip).removeApIface(getName(tearDownIface));
break;
- case IfaceType.P2P:
+ case WifiChip.IFACE_TYPE_P2P:
mInOrder.verify(chipMock.chip).removeP2pIface(getName(tearDownIface));
break;
- case IfaceType.NAN:
+ case WifiChip.IFACE_TYPE_NAN:
mInOrder.verify(chipMock.chip).removeNanIface(getName(tearDownIface));
break;
}
@@ -4496,27 +3937,19 @@ public class HalDeviceManagerTest extends WifiBaseTest {
// validate: create interface
switch (createIfaceType) {
case HDM_CREATE_IFACE_STA:
- mInOrder.verify(chipMock.chip).createStaIface(
- any(IWifiChip.createStaIfaceCallback.class));
+ mInOrder.verify(chipMock.chip).createStaIface();
break;
case HDM_CREATE_IFACE_AP_BRIDGE:
+ mInOrder.verify(chipMock.chip).createBridgedApIface();
+ break;
case HDM_CREATE_IFACE_AP:
- if (mWifiChipV15 != null && createIfaceType == HDM_CREATE_IFACE_AP_BRIDGE) {
- mInOrder.verify(mWifiChipV15)
- .createBridgedApIface(any(android.hardware.wifi.V1_5.IWifiChip
- .createBridgedApIfaceCallback.class));
- } else {
- mInOrder.verify(chipMock.chip).createApIface(
- any(IWifiChip.createApIfaceCallback.class));
- }
+ mInOrder.verify(chipMock.chip).createApIface();
break;
case HDM_CREATE_IFACE_P2P:
- mInOrder.verify(chipMock.chip).createP2pIface(
- any(IWifiChip.createP2pIfaceCallback.class));
+ mInOrder.verify(chipMock.chip).createP2pIface();
break;
case HDM_CREATE_IFACE_NAN:
- mInOrder.verify(chipMock.chip).createNanIface(
- any(IWifiChip.createNanIfaceCallback.class));
+ mInOrder.verify(chipMock.chip).createNanIface();
break;
}
@@ -4528,10 +3961,10 @@ public class HalDeviceManagerTest extends WifiBaseTest {
return iface;
}
- private IWifiIface validateInterfaceSequence(ChipMockBase chipMock,
+ private WifiInterface validateInterfaceSequence(ChipMockBase chipMock,
boolean chipModeValid, int chipModeId,
int createIfaceType, String ifaceName, int finalChipMode,
- IWifiIface[] tearDownList,
+ WifiInterface[] tearDownList,
InterfaceDestroyedListener destroyedListener,
WorkSource requestorWs,
InterfaceDestroyedListenerWithIfaceName...destroyedInterfacesDestroyedListeners)
@@ -4543,26 +3976,12 @@ public class HalDeviceManagerTest extends WifiBaseTest {
destroyedInterfacesDestroyedListeners);
}
- private int getType(IWifiIface iface) throws Exception {
- Mutable<Integer> typeResp = new Mutable<>();
- iface.getType((WifiStatus status, int type) -> {
- typeResp.value = type;
- });
- return typeResp.value;
- }
-
- private String getName(IWifiIface iface) throws Exception {
- Mutable<String> nameResp = new Mutable<>();
- iface.getName((WifiStatus status, String name) -> {
- nameResp.value = name;
- });
- return nameResp.value;
+ private int getType(WifiInterface iface) throws Exception {
+ return mDut.getType(iface);
}
- private WifiStatus getStatus(int code) {
- WifiStatus status = new WifiStatus();
- status.code = code;
- return status;
+ private String getName(WifiInterface iface) throws Exception {
+ return mDut.getName(iface);
}
private static class InterfaceDestroyedListenerWithIfaceName {
@@ -4580,44 +3999,33 @@ public class HalDeviceManagerTest extends WifiBaseTest {
}
}
- private static class Mutable<E> {
- public E value;
-
- Mutable() {
- value = null;
- }
-
- Mutable(E value) {
- this.value = value;
- }
- }
-
// Answer objects
private class GetChipIdsAnswer extends MockAnswerUtil.AnswerWithArguments {
- private WifiStatus mStatus;
+ private boolean mSuccess;
private ArrayList<Integer> mChipIds;
- GetChipIdsAnswer(WifiStatus status, ArrayList<Integer> chipIds) {
- mStatus = status;
+ GetChipIdsAnswer(boolean success, ArrayList<Integer> chipIds) {
+ mSuccess = success;
mChipIds = chipIds;
}
- public void answer(IWifi.getChipIdsCallback cb) {
- cb.onValues(mStatus, mChipIds);
+ public List<Integer> answer() {
+ List<Integer> ret = mSuccess ? mChipIds : null;
+ return ret;
}
}
private class GetChipAnswer extends MockAnswerUtil.AnswerWithArguments {
- private WifiStatus mStatus;
- private IWifiChip mChip;
+ private boolean mSuccess;
+ private WifiChip mChip;
- GetChipAnswer(WifiStatus status, IWifiChip chip) {
- mStatus = status;
+ GetChipAnswer(boolean success, WifiChip chip) {
+ mSuccess = success;
mChip = chip;
}
- public void answer(int chipId, IWifi.getChipCallback cb) {
- cb.onValues(mStatus, mChip);
+ public WifiChip answer(int chipId) {
+ return mSuccess ? mChip : null;
}
}
@@ -4628,21 +4036,12 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mChipMockBase = chipMockBase;
}
- public void answer(IWifiChip.getCapabilitiesCallback cb) {
- cb.onValues(mStatusOk, mChipMockBase.chipCapabilities);
- }
- }
-
- private class GetCapabilities_1_5Answer extends MockAnswerUtil.AnswerWithArguments {
- private ChipMockBase mChipMockBase;
-
- GetCapabilities_1_5Answer(ChipMockBase chipMockBase) {
- mChipMockBase = chipMockBase;
- }
-
- public void answer(
- android.hardware.wifi.V1_5.IWifiChip.getCapabilities_1_5Callback cb) {
- cb.onValues(mStatusOk, mChipMockBase.chipCapabilities);
+ public WifiChip.Response<Long> answer() {
+ WifiChip.Response<Long> response =
+ new WifiChip.Response<>(mChipMockBase.chipCapabilities);
+ response.setStatusCode(mChipMockBase.allowGetCapsBeforeIfaceCreated
+ ? WifiHal.WIFI_STATUS_SUCCESS : WifiHal.WIFI_STATUS_ERROR_UNKNOWN);
+ return response;
}
}
@@ -4653,8 +4052,8 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mChipMockBase = chipMockBase;
}
- public void answer(IWifiChip.getIdCallback cb) {
- cb.onValues(mStatusOk, mChipMockBase.chipId);
+ public int answer() {
+ return mChipMockBase.chipId;
}
}
@@ -4665,20 +4064,8 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mChipMockBase = chipMockBase;
}
- public void answer(IWifiChip.getAvailableModesCallback cb) {
- cb.onValues(mStatusOk, mChipMockBase.availableModes);
- }
- }
-
- private class GetAvailableModesAnswer_1_6 extends MockAnswerUtil.AnswerWithArguments {
- private ChipMockBase mChipMockBase;
-
- GetAvailableModesAnswer_1_6(ChipMockBase chipMockBase) {
- mChipMockBase = chipMockBase;
- }
-
- public void answer(android.hardware.wifi.V1_6.IWifiChip.getAvailableModes_1_6Callback cb) {
- cb.onValues(mStatusOk, mChipMockBase.availableModes_1_6);
+ public List<WifiChip.ChipMode> answer() {
+ return mChipMockBase.availableModes;
}
}
@@ -4689,9 +4076,11 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mChipMockBase = chipMockBase;
}
- public void answer(IWifiChip.getModeCallback cb) {
- cb.onValues(mChipMockBase.chipModeValid ? mStatusOk
- : getStatus(WifiStatusCode.ERROR_NOT_AVAILABLE), mChipMockBase.chipModeId);
+ public WifiChip.Response<Integer> answer() {
+ WifiChip.Response<Integer> response = new WifiChip.Response<>(mChipMockBase.chipModeId);
+ response.setStatusCode(mChipMockBase.chipModeValid
+ ? WifiHal.WIFI_STATUS_SUCCESS : WifiHal.WIFI_STATUS_ERROR_NOT_AVAILABLE);
+ return response;
}
}
@@ -4702,143 +4091,165 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mChipMockBase = chipMockBase;
}
- public WifiStatus answer(int chipMode) {
+ public boolean answer(int chipMode) {
mChipMockBase.chipModeValid = true;
mChipMockBase.chipModeId = chipMode;
mChipMockBase.onChipConfigured();
- return mStatusOk;
+ return true;
}
}
private class GetXxxIfaceNamesAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
+ private @WifiChip.IfaceType int mIfaceType;
- GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase) {
+ GetXxxIfaceNamesAnswer(ChipMockBase chipMockBase, @WifiChip.IfaceType int ifaceType) {
mChipMockBase = chipMockBase;
+ mIfaceType = ifaceType;
}
- public void answer(IWifiChip.getStaIfaceNamesCallback cb) {
- cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.STA));
+ public List<String> answer() {
+ return mChipMockBase.interfaceNames.get(mIfaceType);
}
+ }
- public void answer(IWifiChip.getApIfaceNamesCallback cb) {
- cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.AP));
- }
+ private class GetStaIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
+ private ChipMockBase mChipMockBase;
- public void answer(IWifiChip.getP2pIfaceNamesCallback cb) {
- cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.P2P));
+ GetStaIfaceAnswer(ChipMockBase chipMockBase) {
+ mChipMockBase = chipMockBase;
}
- public void answer(IWifiChip.getNanIfaceNamesCallback cb) {
- cb.onValues(mStatusOk, mChipMockBase.interfaceNames.get(IfaceType.NAN));
+ public WifiStaIface answer(String name) {
+ return (WifiStaIface)
+ mChipMockBase.interfacesByName.get(WifiChip.IFACE_TYPE_STA).get(name);
}
}
- private class GetXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
+ private class GetApIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
- GetXxxIfaceAnswer(ChipMockBase chipMockBase) {
+ GetApIfaceAnswer(ChipMockBase chipMockBase) {
mChipMockBase = chipMockBase;
}
- public void answer(String name, IWifiChip.getStaIfaceCallback cb) {
- IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.STA).get(name);
- cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiStaIface) iface);
+ public WifiApIface answer(String name) {
+ return (WifiApIface)
+ mChipMockBase.interfacesByName.get(WifiChip.IFACE_TYPE_AP).get(name);
}
+ }
- public void answer(String name, IWifiChip.getApIfaceCallback cb) {
- IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.AP).get(name);
- cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiApIface) iface);
- }
+ private class GetP2pIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
+ private ChipMockBase mChipMockBase;
- public void answer(String name, IWifiChip.getP2pIfaceCallback cb) {
- IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.P2P).get(name);
- cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiP2pIface) iface);
+ GetP2pIfaceAnswer(ChipMockBase chipMockBase) {
+ mChipMockBase = chipMockBase;
}
- public void answer(String name, IWifiChip.getNanIfaceCallback cb) {
- IWifiIface iface = mChipMockBase.interfacesByName.get(IfaceType.NAN).get(name);
- cb.onValues(iface != null ? mStatusOk : mStatusFail, (IWifiNanIface) iface);
+ public WifiP2pIface answer(String name) {
+ return (WifiP2pIface)
+ mChipMockBase.interfacesByName.get(WifiChip.IFACE_TYPE_P2P).get(name);
}
}
- private class CreateXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
+ private class GetNanIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
private ChipMockBase mChipMockBase;
- private WifiStatus mStatus;
- private IWifiIface mWifiIface;
- CreateXxxIfaceAnswer(ChipMockBase chipMockBase, WifiStatus status, IWifiIface wifiIface) {
+ GetNanIfaceAnswer(ChipMockBase chipMockBase) {
mChipMockBase = chipMockBase;
- mStatus = status;
+ }
+
+ public WifiNanIface answer(String name) {
+ return (WifiNanIface)
+ mChipMockBase.interfacesByName.get(WifiChip.IFACE_TYPE_NAN).get(name);
+ }
+ }
+
+ private class CreateXxxIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
+ protected ChipMockBase mChipMockBase;
+ protected boolean mSuccess;
+ protected WifiInterface mWifiIface;
+ private @WifiChip.IfaceType int mType;
+
+ CreateXxxIfaceAnswer(ChipMockBase chipMockBase, boolean success, WifiInterface wifiIface,
+ @WifiChip.IfaceType int type) {
+ mChipMockBase = chipMockBase;
+ mSuccess = success;
mWifiIface = wifiIface;
+ mType = type;
}
- private void addInterfaceInfo(int type) {
- if (mStatus.code == WifiStatusCode.SUCCESS) {
+ protected void addInterfaceInfo() {
+ if (mSuccess) {
try {
- mChipMockBase.interfaceNames.get(type).add(getName(mWifiIface));
- mChipMockBase.interfacesByName.get(type).put(getName(mWifiIface), mWifiIface);
+ String ifaceName = getName(mWifiIface);
+ mChipMockBase.interfaceNames.get(mType).add(ifaceName);
+ mChipMockBase.interfacesByName.get(mType).put(ifaceName, mWifiIface);
} catch (Exception e) {
// do nothing
}
}
}
+ }
+
+ private class CreateStaIfaceAnswer extends CreateXxxIfaceAnswer {
+ CreateStaIfaceAnswer(ChipMockBase chipMockBase, boolean success, WifiInterface wifiIface) {
+ super(chipMockBase, success, wifiIface, WifiChip.IFACE_TYPE_STA);
+ }
- public void answer(IWifiChip.createStaIfaceCallback cb) {
- cb.onValues(mStatus, (IWifiStaIface) mWifiIface);
- addInterfaceInfo(IfaceType.STA);
+ public WifiStaIface answer() {
+ addInterfaceInfo();
+ return mSuccess ? (WifiStaIface) mWifiIface : null;
}
+ }
- public void answer(IWifiChip.createApIfaceCallback cb) {
- cb.onValues(mStatus, (IWifiApIface) mWifiIface);
- addInterfaceInfo(IfaceType.AP);
+ private class CreateApIfaceAnswer extends CreateXxxIfaceAnswer {
+ CreateApIfaceAnswer(ChipMockBase chipMockBase, boolean success, WifiInterface wifiIface) {
+ super(chipMockBase, success, wifiIface, WifiChip.IFACE_TYPE_AP);
}
- public void answer(android.hardware.wifi.V1_5.IWifiChip.createBridgedApIfaceCallback cb) {
- cb.onValues(mStatus, (android.hardware.wifi.V1_5.IWifiApIface) mWifiIface);
- addInterfaceInfo(IfaceType.AP);
+ public WifiApIface answer() {
+ addInterfaceInfo();
+ return mSuccess ? (WifiApIface) mWifiIface : null;
}
+ }
- public void answer(IWifiChip.createP2pIfaceCallback cb) {
- cb.onValues(mStatus, (IWifiP2pIface) mWifiIface);
- addInterfaceInfo(IfaceType.P2P);
+ private class CreateP2pIfaceAnswer extends CreateXxxIfaceAnswer {
+ CreateP2pIfaceAnswer(ChipMockBase chipMockBase, boolean success, WifiInterface wifiIface) {
+ super(chipMockBase, success, wifiIface, WifiChip.IFACE_TYPE_P2P);
}
- public void answer(IWifiChip.createNanIfaceCallback cb) {
- cb.onValues(mStatus, (IWifiNanIface) mWifiIface);
- addInterfaceInfo(IfaceType.NAN);
+ public WifiP2pIface answer() {
+ addInterfaceInfo();
+ return mSuccess ? (WifiP2pIface) mWifiIface : null;
+ }
+ }
+
+ private class CreateNanIfaceAnswer extends CreateXxxIfaceAnswer {
+ CreateNanIfaceAnswer(ChipMockBase chipMockBase, boolean success, WifiInterface wifiIface) {
+ super(chipMockBase, success, wifiIface, WifiChip.IFACE_TYPE_NAN);
+ }
+
+ public WifiNanIface answer() {
+ addInterfaceInfo();
+ return mSuccess ? (WifiNanIface) mWifiIface : null;
}
}
private class CreateRttControllerAnswer extends MockAnswerUtil.AnswerWithArguments {
private final ChipMockBase mChipMockBase;
- private final IWifiRttController mRttController;
+ private final WifiRttController mRttController;
- CreateRttControllerAnswer(ChipMockBase chipMockBase, IWifiRttController rttController) {
+ CreateRttControllerAnswer(ChipMockBase chipMockBase, WifiRttController rttController) {
mChipMockBase = chipMockBase;
mRttController = rttController;
}
- public void answer(IWifiIface boundIface, IWifiChip.createRttControllerCallback cb) {
+ public WifiRttController answer() {
if (mChipMockBase.chipModeIdValidForRtt == mChipMockBase.chipModeId) {
- cb.onValues(mStatusOk, mRttController);
- } else {
- cb.onValues(mStatusFail, null);
- }
- }
- }
- private class GetBoundIfaceAnswer extends MockAnswerUtil.AnswerWithArguments {
- private final boolean mIsValid;
-
- GetBoundIfaceAnswer(boolean isValid) {
- mIsValid = isValid;
- }
-
- public void answer(IWifiRttController.getBoundIfaceCallback cb) {
- if (mIsValid) {
- cb.onValues(mStatusOk, null);
+ return mRttController;
} else {
- cb.onValues(mStatusFail, null);
+ return null;
}
}
}
@@ -4847,27 +4258,23 @@ public class HalDeviceManagerTest extends WifiBaseTest {
private ChipMockBase mChipMockBase;
private int mType;
- RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, int type) {
+ RemoveXxxIfaceAnswer(ChipMockBase chipMockBase, @WifiChip.IfaceType int type) {
mChipMockBase = chipMockBase;
mType = type;
}
- private WifiStatus removeIface(int type, String ifname) {
+ public boolean answer(String ifname) {
try {
- if (!mChipMockBase.interfaceNames.get(type).remove(ifname)) {
- return mStatusFail;
+ if (!mChipMockBase.interfaceNames.get(mType).remove(ifname)) {
+ return false;
}
- if (mChipMockBase.interfacesByName.get(type).remove(ifname) == null) {
- return mStatusFail;
+ if (mChipMockBase.interfacesByName.get(mType).remove(ifname) == null) {
+ return false;
}
} catch (Exception e) {
- return mStatusFail;
+ return false;
}
- return mStatusOk;
- }
-
- public WifiStatus answer(String ifname) {
- return removeIface(mType, ifname);
+ return true;
}
}
@@ -4878,20 +4285,8 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mName = name;
}
- public void answer(IWifiIface.getNameCallback cb) {
- cb.onValues(mStatusOk, mName);
- }
- }
-
- private class GetTypeAnswer extends MockAnswerUtil.AnswerWithArguments {
- private int mType;
-
- GetTypeAnswer(int type) {
- mType = type;
- }
-
- public void answer(IWifiIface.getTypeCallback cb) {
- cb.onValues(mStatusOk, mType);
+ public String answer() {
+ return mName;
}
}
@@ -4903,10 +4298,8 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mChipMockBase = chipMockBase;
}
- public void answer(
- android.hardware.wifi.V1_6.IWifiChip.getSupportedRadioCombinationsMatrixCallback
- cb) {
- cb.onValues(mStatusOk, mChipMockBase.chipSupportedRadioCombinationsMatrix);
+ public WifiChip.WifiRadioCombinationMatrix answer() {
+ return mChipMockBase.chipSupportedRadioCombinationsMatrix;
}
}
@@ -4919,18 +4312,33 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mName = name;
}
- public void answer(android.hardware.wifi.V1_5.IWifiApIface.getBridgedInstancesCallback cb) {
+ public List<String> answer() {
ArrayList<String> bridgedApInstances =
mChipMockBase.bridgedApInstancesByName.get(mName);
if (bridgedApInstances == null) {
bridgedApInstances = new ArrayList<>();
}
- cb.onValues(mStatusOk, bridgedApInstances);
+ return bridgedApInstances;
}
}
// chip configuration
+ WifiChip.ChipConcurrencyCombinationLimit createConcurrencyComboLimit(
+ int maxIfaces, Integer... ifaceTypes) {
+ // Assume we will always get at least 1 iface type.
+ return new WifiChip.ChipConcurrencyCombinationLimit(maxIfaces, Arrays.asList(ifaceTypes));
+ }
+
+ WifiChip.ChipConcurrencyCombination createConcurrencyCombo(
+ WifiChip.ChipConcurrencyCombinationLimit... limits) {
+ return new WifiChip.ChipConcurrencyCombination(Arrays.asList(limits));
+ }
+
+ WifiChip.ChipMode createChipMode(int modeId, WifiChip.ChipConcurrencyCombination... combos) {
+ return new WifiChip.ChipMode(modeId, Arrays.asList(combos));
+ }
+
private static final int CHIP_MOCK_V1 = 0;
private static final int CHIP_MOCK_V2 = 1;
private static final int CHIP_MOCK_V3 = 2;
@@ -4941,76 +4349,72 @@ public class HalDeviceManagerTest extends WifiBaseTest {
private class ChipMockBase {
public int chipMockId;
- public android.hardware.wifi.V1_6.IWifiChip chip;
+ public WifiChip chip;
public int chipId;
public boolean chipModeValid = false;
public int chipModeId = -1000;
public int chipModeIdValidForRtt = -1; // single chip mode ID where RTT can be created
- public int chipCapabilities = 0;
- public WifiRadioCombinationMatrix chipSupportedRadioCombinationsMatrix = null;
+ public long chipCapabilities = 0L;
+ public boolean allowGetCapsBeforeIfaceCreated = true;
+ public WifiChip.WifiRadioCombinationMatrix chipSupportedRadioCombinationsMatrix = null;
public Map<Integer, ArrayList<String>> interfaceNames = new HashMap<>();
- public Map<Integer, Map<String, IWifiIface>> interfacesByName = new HashMap<>();
+ public Map<Integer, Map<String, WifiInterface>> interfacesByName = new HashMap<>();
public Map<String, ArrayList<String>> bridgedApInstancesByName = new HashMap<>();
- public ArrayList<IWifiChip.ChipMode> availableModes;
- public ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> availableModes_1_6;
+ public ArrayList<WifiChip.ChipMode> availableModes;
void initialize() throws Exception {
- chip = mock(android.hardware.wifi.V1_6.IWifiChip.class);
+ chip = mock(WifiChip.class);
- interfaceNames.put(IfaceType.STA, new ArrayList<>());
- interfaceNames.put(IfaceType.AP, new ArrayList<>());
- interfaceNames.put(IfaceType.P2P, new ArrayList<>());
- interfaceNames.put(IfaceType.NAN, new ArrayList<>());
+ interfaceNames.put(WifiChip.IFACE_TYPE_STA, new ArrayList<>());
+ interfaceNames.put(WifiChip.IFACE_TYPE_AP, new ArrayList<>());
+ interfaceNames.put(WifiChip.IFACE_TYPE_P2P, new ArrayList<>());
+ interfaceNames.put(WifiChip.IFACE_TYPE_NAN, new ArrayList<>());
- interfacesByName.put(IfaceType.STA, new HashMap<>());
- interfacesByName.put(IfaceType.AP, new HashMap<>());
- interfacesByName.put(IfaceType.P2P, new HashMap<>());
- interfacesByName.put(IfaceType.NAN, new HashMap<>());
+ interfacesByName.put(WifiChip.IFACE_TYPE_STA, new HashMap<>());
+ interfacesByName.put(WifiChip.IFACE_TYPE_AP, new HashMap<>());
+ interfacesByName.put(WifiChip.IFACE_TYPE_P2P, new HashMap<>());
+ interfacesByName.put(WifiChip.IFACE_TYPE_NAN, new HashMap<>());
- when(chip.registerEventCallback(any(IWifiChipEventCallback.class))).thenReturn(
- mStatusOk);
+ when(chip.registerCallback(any(WifiChip.Callback.class))).thenReturn(true);
when(chip.configureChip(anyInt())).thenAnswer(new ConfigureChipAnswer(this));
doAnswer(new GetCapabilitiesAnswer(this))
- .when(chip).getCapabilities(any(IWifiChip.getCapabilitiesCallback.class));
- doAnswer(new GetIdAnswer(this)).when(chip).getId(any(IWifiChip.getIdCallback.class));
- doAnswer(new GetModeAnswer(this)).when(chip).getMode(
- any(IWifiChip.getModeCallback.class));
- GetXxxIfaceNamesAnswer getXxxIfaceNamesAnswer = new GetXxxIfaceNamesAnswer(this);
- doAnswer(getXxxIfaceNamesAnswer).when(chip).getStaIfaceNames(
- any(IWifiChip.getStaIfaceNamesCallback.class));
- doAnswer(getXxxIfaceNamesAnswer).when(chip).getApIfaceNames(
- any(IWifiChip.getApIfaceNamesCallback.class));
- doAnswer(getXxxIfaceNamesAnswer).when(chip).getP2pIfaceNames(
- any(IWifiChip.getP2pIfaceNamesCallback.class));
- doAnswer(getXxxIfaceNamesAnswer).when(chip).getNanIfaceNames(
- any(IWifiChip.getNanIfaceNamesCallback.class));
- GetXxxIfaceAnswer getXxxIfaceAnswer = new GetXxxIfaceAnswer(this);
- doAnswer(getXxxIfaceAnswer).when(chip).getStaIface(anyString(),
- any(IWifiChip.getStaIfaceCallback.class));
- doAnswer(getXxxIfaceAnswer).when(chip).getApIface(anyString(),
- any(IWifiChip.getApIfaceCallback.class));
- doAnswer(getXxxIfaceAnswer).when(chip).getP2pIface(anyString(),
- any(IWifiChip.getP2pIfaceCallback.class));
- doAnswer(getXxxIfaceAnswer).when(chip).getNanIface(anyString(),
- any(IWifiChip.getNanIfaceCallback.class));
- doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.STA)).when(chip).removeStaIface(
- anyString());
- doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.AP)).when(chip).removeApIface(
- anyString());
- doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.P2P)).when(chip).removeP2pIface(
- anyString());
- doAnswer(new RemoveXxxIfaceAnswer(this, IfaceType.NAN)).when(chip).removeNanIface(
- anyString());
-
- doAnswer(new CreateRttControllerAnswer(this, mRttControllerMock)).when(
- chip).createRttController(any(), any());
-
- doAnswer(new GetBoundIfaceAnswer(true)).when(mRttControllerMock).getBoundIface(any());
+ .when(chip).getCapabilitiesBeforeIfacesExist();
+ doAnswer(new GetIdAnswer(this)).when(chip).getId();
+ doAnswer(new GetModeAnswer(this)).when(chip).getMode();
+ doAnswer(new GetXxxIfaceNamesAnswer(this, WifiChip.IFACE_TYPE_STA))
+ .when(chip).getStaIfaceNames();
+ doAnswer(new GetXxxIfaceNamesAnswer(this, WifiChip.IFACE_TYPE_AP))
+ .when(chip).getApIfaceNames();
+ doAnswer(new GetXxxIfaceNamesAnswer(this, WifiChip.IFACE_TYPE_P2P))
+ .when(chip).getP2pIfaceNames();
+ doAnswer(new GetXxxIfaceNamesAnswer(this, WifiChip.IFACE_TYPE_NAN))
+ .when(chip).getNanIfaceNames();
+ doAnswer(new GetStaIfaceAnswer(this)).when(chip).getStaIface(anyString());
+ doAnswer(new GetApIfaceAnswer(this)).when(chip).getApIface(anyString());
+ doAnswer(new GetP2pIfaceAnswer(this)).when(chip).getP2pIface(anyString());
+ doAnswer(new GetNanIfaceAnswer(this)).when(chip).getNanIface(anyString());
+ doAnswer(new RemoveXxxIfaceAnswer(this, WifiChip.IFACE_TYPE_STA))
+ .when(chip).removeStaIface(anyString());
+ doAnswer(new RemoveXxxIfaceAnswer(this, WifiChip.IFACE_TYPE_AP))
+ .when(chip).removeApIface(anyString());
+ doAnswer(new RemoveXxxIfaceAnswer(this, WifiChip.IFACE_TYPE_P2P))
+ .when(chip).removeP2pIface(anyString());
+ doAnswer(new RemoveXxxIfaceAnswer(this, WifiChip.IFACE_TYPE_NAN))
+ .when(chip).removeNanIface(anyString());
+ when(chip.removeIfaceInstanceFromBridgedApIface(anyString(), anyString()))
+ .thenAnswer((invocation) -> {
+ this.bridgedApInstancesByName.get(invocation.getArgument(0))
+ .remove(invocation.getArgument(1));
+ return true;
+ });
+
+ doAnswer(new CreateRttControllerAnswer(this, mRttControllerMock))
+ .when(chip).createRttController();
+ when(mRttControllerMock.setup()).thenReturn(true);
+ when(mRttControllerMock.validate()).thenReturn(true);
doAnswer(new GetSupportedRadioCombinationsMatrixAnswer(this))
- .when(chip).getSupportedRadioCombinationsMatrix(
- any(android.hardware.wifi.V1_6.IWifiChip
- .getSupportedRadioCombinationsMatrixCallback.class));
+ .when(chip).getSupportedRadioCombinationsMatrix();
}
void onChipConfigured() {
@@ -5073,52 +4477,26 @@ public class HalDeviceManagerTest extends WifiBaseTest {
chipId = 10;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(10),
- any(IWifi.getChipCallback.class));
+ // Initialize availableModes
+ availableModes = new ArrayList<>();
- // initialize placeholder chip modes
- IWifiChip.ChipMode cm;
- IWifiChip.ChipIfaceCombination cic;
- IWifiChip.ChipIfaceCombinationLimit cicl;
+ // Mode 0: 1xSTA + 1x{P2P,NAN}
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_P2P,
+ WifiChip.IFACE_CONCURRENCY_TYPE_NAN));
+ availableModes.add(createChipMode(STA_CHIP_MODE_ID, combo1));
- // Mode 0: 1xSTA + 1x{P2P,NAN}
- // Mode 1: 1xAP
- availableModes = new ArrayList<>();
- cm = new IWifiChip.ChipMode();
- cm.id = STA_CHIP_MODE_ID;
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.P2P);
- cicl.types.add(IfaceType.NAN);
- cic.limits.add(cicl);
- cm.availableCombinations.add(cic);
- availableModes.add(cm);
-
- cm = new IWifiChip.ChipMode();
- cm.id = AP_CHIP_MODE_ID;
- cic = new IWifiChip.ChipIfaceCombination();
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.AP);
- cic.limits.add(cicl);
- cm.availableCombinations.add(cic);
- availableModes.add(cm);
+ // Mode 1: 1xAP
+ WifiChip.ChipConcurrencyCombination combo2 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP));
+ availableModes.add(createChipMode(AP_CHIP_MODE_ID, combo2));
chipModeIdValidForRtt = STA_CHIP_MODE_ID;
-
- doAnswer(new GetAvailableModesAnswer(this)).when(chip)
- .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
}
@@ -5167,47 +4545,23 @@ public class HalDeviceManagerTest extends WifiBaseTest {
chipId = 12;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
-
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(12),
- any(IWifi.getChipCallback.class));
-
- // initialize placeholder chip modes
- IWifiChip.ChipMode cm;
- IWifiChip.ChipIfaceCombination cic;
- IWifiChip.ChipIfaceCombinationLimit cicl;
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
- // Mode 0 (only one): 1xSTA + 1x{STA,AP} + 1x{P2P,NAN}
+ // Initialize availableModes
availableModes = new ArrayList<>();
- cm = new IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cicl.types.add(IfaceType.AP);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.P2P);
- cicl.types.add(IfaceType.NAN);
- cic.limits.add(cicl);
- cm.availableCombinations.add(cic);
- availableModes.add(cm);
- chipModeIdValidForRtt = CHIP_MODE_ID;
+ // Mode (only one): 1xSTA + 1x{STA,AP} + 1x{P2P,NAN}
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA,
+ WifiChip.IFACE_CONCURRENCY_TYPE_AP),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_P2P,
+ WifiChip.IFACE_CONCURRENCY_TYPE_NAN));
+ availableModes.add(createChipMode(CHIP_MODE_ID, combo1));
- doAnswer(new GetAvailableModesAnswer(this)).when(chip)
- .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
+ chipModeIdValidForRtt = CHIP_MODE_ID;
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
}
@@ -5229,57 +4583,25 @@ public class HalDeviceManagerTest extends WifiBaseTest {
chipId = 15;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(15),
- any(IWifi.getChipCallback.class));
-
- // initialize placeholder chip modes
- IWifiChip.ChipMode cm;
- IWifiChip.ChipIfaceCombination cic;
- IWifiChip.ChipIfaceCombinationLimit cicl;
-
- // Mode 0 (only one): 1xSTA + 1x{STA,AP}, 1xSTA + 1x{P2P,NAN}
+ // Initialize availableModes
availableModes = new ArrayList<>();
- cm = new IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cicl.types.add(IfaceType.AP);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.P2P);
- cicl.types.add(IfaceType.NAN);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
- availableModes.add(cm);
+ // Mode (only one): 1xSTA + 1x{STA,AP}, 1xSTA + 1x{P2P,NAN}
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA,
+ WifiChip.IFACE_CONCURRENCY_TYPE_AP));
+ WifiChip.ChipConcurrencyCombination combo2 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_P2P,
+ WifiChip.IFACE_CONCURRENCY_TYPE_NAN));
+ availableModes.add(createChipMode(CHIP_MODE_ID, combo1, combo2));
chipModeIdValidForRtt = CHIP_MODE_ID;
-
- doAnswer(new GetAvailableModesAnswer(this)).when(chip)
- .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
}
@@ -5301,56 +4623,24 @@ public class HalDeviceManagerTest extends WifiBaseTest {
chipId = 23;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(23),
- any(IWifi.getChipCallback.class));
-
- // initialize placeholder chip modes
- IWifiChip.ChipMode cm;
- IWifiChip.ChipIfaceCombination cic;
- IWifiChip.ChipIfaceCombinationLimit cicl;
-
- // Mode 0 (only one): 1xSTA + 1xAP, 1xSTA + 1x{P2P,NAN}
+ // Initialize availableModes
availableModes = new ArrayList<>();
- cm = new IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.AP);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.P2P);
- cicl.types.add(IfaceType.NAN);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
- availableModes.add(cm);
+ // Mode (only one): 1xSTA + 1xAP, 1xSTA + 1x{P2P,NAN}
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP));
+ WifiChip.ChipConcurrencyCombination combo2 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_P2P,
+ WifiChip.IFACE_CONCURRENCY_TYPE_NAN));
+ availableModes.add(createChipMode(CHIP_MODE_ID, combo1, combo2));
chipModeIdValidForRtt = CHIP_MODE_ID;
-
- doAnswer(new GetAvailableModesAnswer(this)).when(chip)
- .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
}
@@ -5367,63 +4657,49 @@ public class HalDeviceManagerTest extends WifiBaseTest {
super.initialize();
chipMockId = CHIP_MOCK_V5;
- chipCapabilities |= android.hardware.wifi.V1_5.IWifiChip.ChipCapabilityMask.WIGIG;
+ chipCapabilities |= WifiManager.WIFI_FEATURE_INFRA_60G;
// chip Id configuration
ArrayList<Integer> chipIds;
chipId = CHIP_ID;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(CHIP_ID),
- any(IWifi.getChipCallback.class));
-
- // initialize placeholder chip modes
- IWifiChip.ChipMode cm;
- IWifiChip.ChipIfaceCombination cic;
- IWifiChip.ChipIfaceCombinationLimit cicl;
-
- // Mode 0 (only one): 1xSTA + 1xAP, 1xSTA + 1x{P2P,NAN}
+ // Initialize availableModes
availableModes = new ArrayList<>();
- cm = new IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.AP);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.P2P);
- cicl.types.add(IfaceType.NAN);
- cic.limits.add(cicl);
+ List<WifiChip.ChipConcurrencyCombination> combos = new ArrayList<>();
+
+ // Mode (only one): 1xSTA + 1xAP, 1xSTA + 1x{P2P,NAN}
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP));
+ combos.add(combo1);
+
+ // Simulate HIDL 1.0 to 1.6 conversion for the 1xSTA + 1xAP combo.
+ if (mIsBridgedSoftApSupported) {
+ List<WifiChip.ChipConcurrencyCombinationLimit> limits = new ArrayList<>();
+ limits.add(createConcurrencyComboLimit(
+ 1, WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED));
+ if (mIsStaWithBridgedSoftApConcurrencySupported) {
+ limits.add(createConcurrencyComboLimit(
+ 1, WifiChip.IFACE_CONCURRENCY_TYPE_STA));
+ }
+ WifiChip.ChipConcurrencyCombination combo2 =
+ new WifiChip.ChipConcurrencyCombination(limits);
+ combos.add(combo2);
+ }
- cm.availableCombinations.add(cic);
- availableModes.add(cm);
+ WifiChip.ChipConcurrencyCombination combo3 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_P2P,
+ WifiChip.IFACE_CONCURRENCY_TYPE_NAN));
+ combos.add(combo3);
+ availableModes.add(new WifiChip.ChipMode(CHIP_MODE_ID, combos));
chipModeIdValidForRtt = CHIP_MODE_ID;
-
- doAnswer(new GetAvailableModesAnswer(this)).when(chip)
- .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
}
@@ -5470,61 +4746,25 @@ public class HalDeviceManagerTest extends WifiBaseTest {
chipId = CHIP_ID;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
-
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(CHIP_ID),
- any(IWifi.getChipCallback.class));
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
- // initialize placeholder chip modes
- android.hardware.wifi.V1_6.IWifiChip.ChipMode cm;
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination ccc;
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit cccl;
+ // Initialize availableModes
+ availableModes = new ArrayList<>();
// Mode 60 (only one): 1xSTA + 1x{AP,AP_BRIDGED}, 1xSTA + 1x{P2P,NAN}
- availableModes_1_6 = new ArrayList<>();
- cm = new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
-
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
-
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.STA);
- ccc.limits.add(cccl);
-
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP);
- cccl.types.add(IfaceConcurrencyType.AP_BRIDGED);
- ccc.limits.add(cccl);
-
- cm.availableCombinations.add(ccc);
-
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
-
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceType.STA);
- ccc.limits.add(cccl);
-
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceType.P2P);
- cccl.types.add(IfaceType.NAN);
- ccc.limits.add(cccl);
-
- cm.availableCombinations.add(ccc);
-
- availableModes_1_6.add(cm);
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP,
+ WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED));
+ WifiChip.ChipConcurrencyCombination combo2 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_P2P,
+ WifiChip.IFACE_CONCURRENCY_TYPE_NAN));
+ availableModes.add(createChipMode(CHIP_MODE_ID, combo1, combo2));
chipModeIdValidForRtt = CHIP_MODE_ID;
-
- doAnswer(new GetAvailableModesAnswer_1_6(this))
- .when(chip).getAvailableModes_1_6(any(
- android.hardware.wifi.V1_6.IWifiChip.getAvailableModes_1_6Callback
- .class));
- mWifiChipV16 = chip;
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
}
@@ -5545,70 +4785,33 @@ public class HalDeviceManagerTest extends WifiBaseTest {
chipId = 70;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(chipId),
- any(IWifi.getChipCallback.class));
+ // Initialize availableModes
+ availableModes = new ArrayList<>();
- // initialize placeholder chip modes
- android.hardware.wifi.V1_6.IWifiChip.ChipMode cm;
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination ccc;
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit cccl;
-
- availableModes_1_6 = new ArrayList<>();
-
- cm = new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
- cm.id = DUAL_STA_CHIP_MODE_ID;
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 2;
- cccl.types.add(IfaceConcurrencyType.STA);
- ccc.limits.add(cccl);
- cm.availableCombinations.add(ccc);
- availableModes_1_6.add(cm);
-
- cm = new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
- cm.id = AP_CHIP_MODE_ID;
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP);
- ccc.limits.add(cccl);
- cm.availableCombinations.add(ccc);
- availableModes_1_6.add(cm);
-
- cm = new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
- cm.id = AP_AP_BRIDGED_CHIP_MODE_ID;
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.STA);
- ccc.limits.add(cccl);
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP);
- ccc.limits.add(cccl);
- cm.availableCombinations.add(ccc);
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP);
- ccc.limits.add(cccl);
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP_BRIDGED);
- ccc.limits.add(cccl);
- cm.availableCombinations.add(ccc);
- availableModes_1_6.add(cm);
+ // Mode: 2xSTA
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(2, WifiChip.IFACE_CONCURRENCY_TYPE_STA));
+ availableModes.add(createChipMode(DUAL_STA_CHIP_MODE_ID, combo1));
+
+ // Mode: 1xAP
+ WifiChip.ChipConcurrencyCombination combo2 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP));
+ availableModes.add(createChipMode(AP_CHIP_MODE_ID, combo2));
+
+ // Mode: 1xSTA + 1xAP, 1xAP + 1xAP_BRIDGED
+ WifiChip.ChipConcurrencyCombination combo3 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP));
+ WifiChip.ChipConcurrencyCombination combo4 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED));
+ availableModes.add(createChipMode(AP_AP_BRIDGED_CHIP_MODE_ID, combo3, combo4));
chipModeIdValidForRtt = DUAL_STA_CHIP_MODE_ID;
-
- doAnswer(new GetAvailableModesAnswer_1_6(this))
- .when(chip).getAvailableModes_1_6(any(
- android.hardware.wifi.V1_6.IWifiChip.getAvailableModes_1_6Callback
- .class));
- mWifiChipV16 = chip;
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
}
@@ -5625,50 +4828,24 @@ public class HalDeviceManagerTest extends WifiBaseTest {
chipId = 80;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
-
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(chipId),
- any(IWifi.getChipCallback.class));
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
// initialize placeholder chip modes
- android.hardware.wifi.V1_6.IWifiChip.ChipMode cm;
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination ccc;
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit cccl;
-
- availableModes_1_6 = new ArrayList<>();
-
- cm = new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.STA);
- ccc.limits.add(cccl);
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP);
- ccc.limits.add(cccl);
- cm.availableCombinations.add(ccc);
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP);
- ccc.limits.add(cccl);
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP_BRIDGED);
- ccc.limits.add(cccl);
- cm.availableCombinations.add(ccc);
- availableModes_1_6.add(cm);
+ availableModes = new ArrayList<>();
+ List<WifiChip.ChipConcurrencyCombinationLimit> limits = new ArrayList<>();
- chipModeIdValidForRtt = CHIP_MODE_ID;
+ // Mode: 1xSTA + 1xAP, 1xAP + 1xAP_BRIDGED
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP));
+ WifiChip.ChipConcurrencyCombination combo2 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED));
+ availableModes.add(createChipMode(CHIP_MODE_ID, combo1, combo2));
- doAnswer(new GetAvailableModesAnswer_1_6(this))
- .when(chip).getAvailableModes_1_6(any(
- android.hardware.wifi.V1_6.IWifiChip.getAvailableModes_1_6Callback
- .class));
- mWifiChipV16 = chip;
+ chipModeIdValidForRtt = CHIP_MODE_ID;
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
}
@@ -5686,57 +4863,26 @@ public class HalDeviceManagerTest extends WifiBaseTest {
chipId = 9;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(chipId),
- any(IWifi.getChipCallback.class));
-
- // initialize placeholder chip modes
- android.hardware.wifi.V1_6.IWifiChip.ChipMode cm;
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination ccc;
- android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit cccl;
+ // Initialize availableModes
+ availableModes = new ArrayList<>();
// Mode 90 (only one): (1xSTA + 1xAP) || (1xAP_BRIDGED)
- availableModes_1_6 = new ArrayList<>();
- cm = new android.hardware.wifi.V1_6.IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
-
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.STA);
- ccc.limits.add(cccl);
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP);
- ccc.limits.add(cccl);
- cm.availableCombinations.add(ccc);
-
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 1;
- cccl.types.add(IfaceConcurrencyType.AP_BRIDGED);
- ccc.limits.add(cccl);
- cm.availableCombinations.add(ccc);
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP));
+ WifiChip.ChipConcurrencyCombination combo2 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED));
// Add a combo which doesn't allow any AP.
- ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination();
- cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit();
- cccl.maxIfaces = 2;
- cccl.types.add(IfaceConcurrencyType.STA);
- ccc.limits.add(cccl);
- cm.availableCombinations.add(ccc);
-
- availableModes_1_6.add(cm);
+ WifiChip.ChipConcurrencyCombination combo3 = createConcurrencyCombo(
+ createConcurrencyComboLimit(2, WifiChip.IFACE_CONCURRENCY_TYPE_STA));
+ availableModes.add(createChipMode(CHIP_MODE_ID, combo1, combo2, combo3));
chipModeIdValidForRtt = CHIP_MODE_ID;
-
- doAnswer(new GetAvailableModesAnswer_1_6(this))
- .when(chip).getAvailableModes_1_6(any(
- android.hardware.wifi.V1_6.IWifiChip.getAvailableModes_1_6Callback
- .class));
- mWifiChipV16 = chip;
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
}
@@ -5782,66 +4928,31 @@ public class HalDeviceManagerTest extends WifiBaseTest {
chipId = 10;
chipIds = new ArrayList<>();
chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
-
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(10),
- any(IWifi.getChipCallback.class));
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
// initialize placeholder chip modes
configureDefaultAvailableModes();
chipModeIdValidForRtt = CHIP_MODE_ID;
-
- doAnswer(new GetAvailableModesAnswer(this)).when(chip)
- .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
}
// STA
void configureDefaultAvailableModes() {
- IWifiChip.ChipMode cm;
- IWifiChip.ChipIfaceCombination cic;
- IWifiChip.ChipIfaceCombinationLimit cicl;
-
availableModes = new ArrayList<>();
- cm = new IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
- availableModes.add(cm);
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA));
+ availableModes.add(createChipMode(CHIP_MODE_ID, combo1));
}
// STA + AP
void configureDriverAvailableModes() {
- IWifiChip.ChipMode cm;
- IWifiChip.ChipIfaceCombination cic;
- IWifiChip.ChipIfaceCombinationLimit cicl;
-
availableModes = new ArrayList<>();
- cm = new IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
-
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.AP);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
- availableModes.add(cm);
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP));
+ availableModes.add(createChipMode(CHIP_MODE_ID, combo1));
}
@Override
@@ -5849,90 +4960,4 @@ public class HalDeviceManagerTest extends WifiBaseTest {
configureDriverAvailableModes();
}
}
-
- // Test chip configuration V11 to test HAL V1.0 AP + AP combination with bridged AP:
- private class TestChipV11 extends ChipMockBase {
- static final int CHIP_MODE_ID = 110;
-
- void initialize() throws Exception {
- super.initialize();
- // chip Id configuration
- ArrayList<Integer> chipIds;
- chipId = 11;
- chipIds = new ArrayList<>();
- chipIds.add(chipId);
- doAnswer(new GetChipIdsAnswer(mStatusOk, chipIds)).when(mWifiMock).getChipIds(
- any(IWifi.getChipIdsCallback.class));
-
- doAnswer(new GetChipAnswer(mStatusOk, chip)).when(mWifiMock).getChip(eq(chipId),
- any(IWifi.getChipCallback.class));
-
- // initialize placeholder chip modes
- IWifiChip.ChipMode cm;
- IWifiChip.ChipIfaceCombination cic;
- IWifiChip.ChipIfaceCombinationLimit cicl;
-
- availableModes = new ArrayList<>();
- cm = new IWifiChip.ChipMode();
- cm.id = CHIP_MODE_ID;
-
- // STA + AP
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.AP);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
-
- // STA + (P2P || NAN)
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 1;
- cicl.types.add(IfaceType.P2P);
- cicl.types.add(IfaceType.NAN);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
-
- // STA + STA
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 2;
- cicl.types.add(IfaceType.STA);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
-
- // AP + AP
- cic = new IWifiChip.ChipIfaceCombination();
-
- cicl = new IWifiChip.ChipIfaceCombinationLimit();
- cicl.maxIfaces = 2;
- cicl.types.add(IfaceType.AP);
- cic.limits.add(cicl);
-
- cm.availableCombinations.add(cic);
-
- availableModes.add(cm);
-
- chipModeIdValidForRtt = CHIP_MODE_ID;
-
- doAnswer(new GetAvailableModesAnswer(this)).when(chip)
- .getAvailableModes(any(IWifiChip.getAvailableModesCallback.class));
- }
- }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/InterfaceConflictManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/InterfaceConflictManagerTest.java
index 81cfd3e76a..387b5c54dc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/InterfaceConflictManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/InterfaceConflictManagerTest.java
@@ -16,11 +16,17 @@
package com.android.server.wifi;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_NAN;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_P2P;
+
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -88,6 +94,7 @@ public class InterfaceConflictManagerTest {
private static final WorkSource TEST_WS = new WorkSource(TEST_UID, TEST_PACKAGE_NAME);
private static final int EXISTING_UID = 5678;
private static final String EXISTING_PACKAGE_NAME = "existing.package.name";
+ private static final String EXISTING_APP_NAME = "Existing App Name";
private static final WorkSource EXISTING_WS =
new WorkSource(EXISTING_UID, EXISTING_PACKAGE_NAME);
@@ -107,14 +114,21 @@ public class InterfaceConflictManagerTest {
when(mResources.getBoolean(
R.bool.config_wifiUserApprovalRequiredForD2dInterfacePriority)).thenReturn(true);
- when(mHdm.needsUserApprovalToDelete(anyInt(), any(), anyInt(), any())).thenReturn(true);
-
- when(mFrameworkFacade.getAppName(any(), anyString(), anyInt())).thenReturn(TEST_APP_NAME);
+ when(mFrameworkFacade.getAppName(any(), eq(TEST_PACKAGE_NAME), anyInt()))
+ .thenReturn(TEST_APP_NAME);
+ when(mFrameworkFacade.getAppName(any(), eq(EXISTING_PACKAGE_NAME), anyInt()))
+ .thenReturn(EXISTING_APP_NAME);
when(mWifiDialogManager.createSimpleDialog(
any(), any(), any(), any(), any(), any(), any())).thenReturn(mDialogHandle);
when(mWifiInjector.makeWsHelper(eq(TEST_WS))).thenReturn(mWsHelper);
when(mWifiInjector.makeWsHelper(eq(EXISTING_WS))).thenReturn(mExistingWsHelper);
+ when(mWsHelper.getRequestorWsPriority())
+ .thenReturn(WorkSourceHelper.PRIORITY_FG_APP);
+ when(mExistingWsHelper.getRequestorWsPriority())
+ .thenReturn(WorkSourceHelper.PRIORITY_FG_APP);
+ when(mWsHelper.getWorkSource()).thenReturn(TEST_WS);
+ when(mExistingWsHelper.getWorkSource()).thenReturn(EXISTING_WS);
}
private void initInterfaceConflictManager() {
@@ -226,30 +240,6 @@ public class InterfaceConflictManagerTest {
}
/**
- * Verify that if interface cannot be created or if interface can be created w/o side effects
- * then command simply proceeds.
- */
- @Test
- public void testUserApprovalNotNeeded() {
- initInterfaceConflictManager();
-
- int interfaceType = HalDeviceManager.HDM_CREATE_IFACE_P2P;
- Message msg = Message.obtain();
-
- // can delete iface without user approval
- when(mHdm.reportImpactToCreateIface(eq(interfaceType), eq(false), eq(TEST_WS))).thenReturn(
- Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN,
- new WorkSource(10, "something else"))));
- when(mHdm.needsUserApprovalToDelete(anyInt(), any(), anyInt(), any())).thenReturn(false);
-
- // request should pass through without the dialog
- assertEquals(InterfaceConflictManager.ICM_EXECUTE_COMMAND,
- mDut.manageInterfaceConflictForStateMachine("Some Tag", msg,
- mStateMachine, mWaitingState, mTargetState,
- interfaceType, TEST_WS, false));
- }
-
- /**
* Verify flow with user approval.
*/
@Test
@@ -261,8 +251,7 @@ public class InterfaceConflictManagerTest {
// can create interface - but with side effects
when(mHdm.reportImpactToCreateIface(eq(interfaceType), eq(false), eq(TEST_WS))).thenReturn(
- Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN,
- new WorkSource(10, "something else"))));
+ Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN, EXISTING_WS)));
// send request
assertEquals(InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER,
@@ -302,8 +291,7 @@ public class InterfaceConflictManagerTest {
// can create interface - but with side effects
when(mHdm.reportImpactToCreateIface(eq(interfaceType), eq(false), eq(TEST_WS))).thenReturn(
- Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN,
- new WorkSource(10, "something else"))));
+ Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN, EXISTING_WS)));
// send request
assertEquals(InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER,
@@ -343,8 +331,7 @@ public class InterfaceConflictManagerTest {
// can create interface - but with side effects
when(mHdm.reportImpactToCreateIface(eq(interfaceType), eq(false), eq(TEST_WS))).thenReturn(
- Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN,
- new WorkSource(10, "something else"))));
+ Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN, EXISTING_WS)));
// send request
assertEquals(InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER,
@@ -395,7 +382,7 @@ public class InterfaceConflictManagerTest {
// Unexpected impact to create, launch the dialog again
when(mHdm.reportImpactToCreateIface(eq(interfaceType), eq(false), eq(TEST_WS)))
.thenReturn(Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN,
- new WorkSource(10, "something else"))));
+ EXISTING_WS)));
assertEquals(InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER,
mDut.manageInterfaceConflictForStateMachine("Some Tag", waitingMsg,
mStateMachine, mWaitingState, mTargetState, interfaceType, TEST_WS,
@@ -422,8 +409,7 @@ public class InterfaceConflictManagerTest {
// can create interface - but with side effects
when(mHdm.reportImpactToCreateIface(eq(interfaceType), eq(false), eq(TEST_WS))).thenReturn(
- Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN,
- new WorkSource(10, "something else"))));
+ Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN, EXISTING_WS)));
// send request
assertEquals(InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER,
@@ -503,8 +489,7 @@ public class InterfaceConflictManagerTest {
// can create interface - but with side effects
when(mHdm.reportImpactToCreateIface(eq(interfaceType), eq(false), eq(TEST_WS))).thenReturn(
- Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_P2P,
- new WorkSource(10, "something else"))));
+ Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_P2P, EXISTING_WS)));
// send request
assertEquals(InterfaceConflictManager.ICM_EXECUTE_COMMAND,
@@ -543,8 +528,7 @@ public class InterfaceConflictManagerTest {
// can create interface - but with side effects
when(mHdm.reportImpactToCreateIface(eq(interfaceType), eq(false), eq(TEST_WS))).thenReturn(
- Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_P2P,
- new WorkSource(10, "something else"))));
+ Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_P2P, EXISTING_WS)));
// send request
assertEquals(InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER,
@@ -571,8 +555,7 @@ public class InterfaceConflictManagerTest {
// can create interface - but with side effects
when(mHdm.reportImpactToCreateIface(eq(interfaceType), eq(false), eq(TEST_WS))).thenReturn(
- Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN,
- new WorkSource(10, "something else"))));
+ Arrays.asList(Pair.create(HalDeviceManager.HDM_CREATE_IFACE_NAN, EXISTING_WS)));
// send request
assertEquals(InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER,
@@ -604,4 +587,137 @@ public class InterfaceConflictManagerTest {
any(), any(), any(), any(), any(), any(), any());
verify(mDialogHandle, times(2)).launchDialog();
}
+
+ /**
+ * Tests that
+ * {@link InterfaceConflictManager#needsUserApprovalToDelete(int, WorkSourceHelper, int,
+ * WorkSourceHelper)} returns true on the following conditions:
+ * 1) Requested interface is AP, AP_BRIDGED, P2P, or NAN.
+ * 2) Existing interface is AP, AP_BRIDGED, P2P, or NAN (but not the same as the requested).
+ * 3) Requestor worksource has higher priority than PRIORITY_BG.
+ * 4) Existing worksource is not PRIORITY_INTERNAL.
+ * 5) User approval is required (by overlay or override).
+ * 6) Requestor package is not exempt from user approval.
+ */
+ @Test
+ public void testCanDeleteWithUserApproval() throws Exception {
+ // No dialog if dialogs aren't enabled.
+ when(mResources.getBoolean(R.bool.config_wifiUserApprovalRequiredForD2dInterfacePriority))
+ .thenReturn(false);
+ initInterfaceConflictManager();
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_P2P, mWsHelper,
+ HDM_CREATE_IFACE_AP, mExistingWsHelper));
+
+ // No dialog if requesting package is exempt.
+ when(mResources.getBoolean(R.bool.config_wifiUserApprovalRequiredForD2dInterfacePriority))
+ .thenReturn(true);
+ when(mResources.getStringArray(
+ R.array.config_wifiExcludedFromUserApprovalForD2dInterfacePriority)).thenReturn(
+ new String[]{TEST_PACKAGE_NAME});
+ initInterfaceConflictManager();
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_P2P, mWsHelper,
+ HDM_CREATE_IFACE_AP, mExistingWsHelper));
+
+ // No dialog if override is set to false.
+ when(mResources.getStringArray(
+ R.array.config_wifiExcludedFromUserApprovalForD2dInterfacePriority))
+ .thenReturn(null);
+ initInterfaceConflictManager();
+ mDut.setUserApprovalNeededOverride(true, false);
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_P2P, mWsHelper,
+ HDM_CREATE_IFACE_AP, mExistingWsHelper));
+
+ // Dialog if overlay is false but override is true.
+ when(mResources.getBoolean(R.bool.config_wifiUserApprovalRequiredForD2dInterfacePriority))
+ .thenReturn(false);
+ initInterfaceConflictManager();
+ mDut.setUserApprovalNeededOverride(true, true);
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP, mWsHelper,
+ HDM_CREATE_IFACE_NAN, mExistingWsHelper));
+
+ // No dialog if overlay is false and override is changed from true to false.
+ mDut.setUserApprovalNeededOverride(false, false);
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP, mWsHelper,
+ HDM_CREATE_IFACE_NAN, mExistingWsHelper));
+
+ // Should show dialog for appropriate types if overlay is set to true.
+ when(mResources.getBoolean(R.bool.config_wifiUserApprovalRequiredForD2dInterfacePriority))
+ .thenReturn(true);
+ initInterfaceConflictManager();
+
+ // Requesting AP
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP, mWsHelper,
+ HDM_CREATE_IFACE_AP, mExistingWsHelper));
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP, mWsHelper,
+ HDM_CREATE_IFACE_AP_BRIDGE, mExistingWsHelper));
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP, mWsHelper,
+ HDM_CREATE_IFACE_NAN, mExistingWsHelper));
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP, mWsHelper,
+ HDM_CREATE_IFACE_P2P, mExistingWsHelper));
+
+ // Requesting AP_BRIDGE
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP_BRIDGE, mWsHelper,
+ HDM_CREATE_IFACE_AP, mExistingWsHelper));
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP_BRIDGE, mWsHelper,
+ HDM_CREATE_IFACE_AP_BRIDGE, mExistingWsHelper));
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP_BRIDGE, mWsHelper,
+ HDM_CREATE_IFACE_NAN, mExistingWsHelper));
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_AP_BRIDGE, mWsHelper,
+ HDM_CREATE_IFACE_P2P, mExistingWsHelper));
+
+ // Requesting P2P
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_P2P, mWsHelper,
+ HDM_CREATE_IFACE_AP, mExistingWsHelper));
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_P2P, mWsHelper,
+ HDM_CREATE_IFACE_AP_BRIDGE, mExistingWsHelper));
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_P2P, mWsHelper,
+ HDM_CREATE_IFACE_NAN, mExistingWsHelper));
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_P2P, mWsHelper,
+ HDM_CREATE_IFACE_P2P, mExistingWsHelper));
+
+ // Requesting NAN
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_NAN, mWsHelper,
+ HDM_CREATE_IFACE_AP, mExistingWsHelper));
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_NAN, mWsHelper,
+ HDM_CREATE_IFACE_AP_BRIDGE, mExistingWsHelper));
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_NAN, mWsHelper,
+ HDM_CREATE_IFACE_NAN, mExistingWsHelper));
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_NAN, mWsHelper,
+ HDM_CREATE_IFACE_P2P, mExistingWsHelper));
+
+ // Foreground should show dialog over Privileged
+ when(mExistingWsHelper.getRequestorWsPriority())
+ .thenReturn(WorkSourceHelper.PRIORITY_PRIVILEGED);
+ assertTrue(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_NAN, mWsHelper,
+ HDM_CREATE_IFACE_P2P, mExistingWsHelper));
+
+ // Foreground should delete Internal without showing dialog
+ when(mExistingWsHelper.getRequestorWsPriority())
+ .thenReturn(WorkSourceHelper.PRIORITY_INTERNAL);
+ assertFalse(mDut.needsUserApprovalToDelete(
+ HDM_CREATE_IFACE_NAN, mWsHelper,
+ HDM_CREATE_IFACE_P2P, mExistingWsHelper));
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/MemoryStoreImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/MemoryStoreImplTest.java
index 926fe544f5..b3c655c20e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/MemoryStoreImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/MemoryStoreImplTest.java
@@ -30,8 +30,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-//import java.util.HashMap;
-//import java.util.Map;
+import java.util.Arrays;
/**
* Unit tests for {@link com.android.server.wifi.MemoryStoreImpl}.
@@ -106,7 +105,7 @@ public class MemoryStoreImplTest extends WifiBaseTest {
@Test
public void wifiScoreCardReadShouldCallIpMemoryStoreRetrieveBlob() throws Exception {
final byte[] myBlob = new byte[]{0x0, 0x3};
- final String myL2Key = "L2Key:" + myBlob;
+ final String myL2Key = "L2Key:" + Arrays.toString(myBlob);
final android.net.ipmemorystore.Status statusSuccess =
new android.net.ipmemorystore.Status(android.net.ipmemorystore.Status.SUCCESS);
@@ -144,7 +143,7 @@ public class MemoryStoreImplTest extends WifiBaseTest {
@Test
public void wifiScoreCardWriteShouldCallIpMemoryStoreStoreBlob() throws Exception {
final byte[] myBlob = new byte[]{0x0, 0x3, 0x1};
- final String myL2Key = "L2Key:" + myBlob;
+ final String myL2Key = "L2Key:" + Arrays.toString(myBlob);
when(mWifiInjector.getIpMemoryStore()).thenReturn(mIpMemoryStore);
mMemoryStoreImpl.start();
mMemoryStoreImpl.write(myL2Key, DATA_NAME, myBlob);
@@ -167,7 +166,7 @@ public class MemoryStoreImplTest extends WifiBaseTest {
@Test
public void exceptionDisablesFurtherOperations() throws Exception {
final byte[] myBlob = new byte[]{0x0, 0x3, 0x1};
- final String myL2Key = "L2Key:" + myBlob;
+ final String myL2Key = "L2Key:" + Arrays.toString(myBlob);
when(mWifiInjector.getIpMemoryStore()).thenReturn(mIpMemoryStore);
when(mActiveModeWarden.isShuttingDown()).thenReturn(false);
doThrow(new RuntimeException("Just a test"))
diff --git a/service/tests/wifitests/src/com/android/server/wifi/MultiInternetManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/MultiInternetManagerTest.java
index 4a3d649a20..77e185c854 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/MultiInternetManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/MultiInternetManagerTest.java
@@ -22,6 +22,7 @@ import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LO
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -52,6 +53,7 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/** Unit tests for {@link MultiInternetManager}. */
@SmallTest
@@ -159,9 +161,9 @@ public class MultiInternetManagerTest extends WifiBaseTest {
when(mActiveModeWarden.isStaStaConcurrencySupportedForMultiInternet()).thenReturn(true);
when(mPrimaryCmm.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
- when(mPrimaryCmm.syncRequestConnectionInfo()).thenReturn(null);
+ when(mPrimaryCmm.getConnectionInfo()).thenReturn(null);
when(mSecondaryCmm.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED);
- when(mSecondaryCmm.syncRequestConnectionInfo()).thenReturn(null);
+ when(mSecondaryCmm.getConnectionInfo()).thenReturn(mock(WifiInfo.class));
when(mSecondaryCmm.isSecondaryInternet()).thenReturn(true);
when(mActiveModeWarden.getPrimaryClientModeManagerNullable()).thenReturn(mPrimaryCmm);
@@ -171,8 +173,6 @@ public class MultiInternetManagerTest extends WifiBaseTest {
List.of(mPrimaryCmm, mSecondaryCmm));
when(mActiveModeWarden.getClientModeManagersInRoles(ROLE_CLIENT_PRIMARY))
.thenReturn(List.of(mPrimaryCmm));
- when(mActiveModeWarden.getClientModeManagersInRoles(ROLE_CLIENT_SECONDARY_LONG_LIVED))
- .thenReturn(List.of(mSecondaryCmm));
when(mActiveModeWarden.getClientModeManagerInRole(ROLE_CLIENT_SECONDARY_LONG_LIVED))
.thenReturn(mSecondaryCmm);
@@ -188,14 +188,16 @@ public class MultiInternetManagerTest extends WifiBaseTest {
}
private void fakePrimaryCmmConnected(boolean isConnected) {
- when(mPrimaryCmm.syncRequestConnectionInfo()).thenReturn(isConnected ? mPrimaryInfo : null);
+ when(mPrimaryCmm.getConnectionInfo()).thenReturn(isConnected ? mPrimaryInfo : null);
when(mPrimaryCmm.isConnected()).thenReturn(isConnected);
}
private void fakeSecondaryCmmConnected(boolean isConnected) {
- when(mSecondaryCmm.syncRequestConnectionInfo()).thenReturn(
+ when(mSecondaryCmm.getConnectionInfo()).thenReturn(
isConnected ? mSecondaryInfo : null);
when(mSecondaryCmm.isConnected()).thenReturn(isConnected);
+ when(mSecondaryCmm.getConnectedBssid()).thenReturn(
+ isConnected ? mSecondaryInfo.getBSSID() : null);
}
@Test
@@ -207,7 +209,7 @@ public class MultiInternetManagerTest extends WifiBaseTest {
mModeChangeCallbackCaptor.getValue().onActiveModeManagerRoleChanged(mSecondaryCmm);
mModeChangeCallbackCaptor.getValue().onActiveModeManagerAdded(mSecondaryCmm);
- verify(mSecondaryCmm, never()).syncRequestConnectionInfo();
+ verify(mSecondaryCmm, never()).getConnectionInfo();
assertEquals(0, mMultiInternetManager.getNetworkConnectionState().size());
}
@@ -263,13 +265,14 @@ public class MultiInternetManagerTest extends WifiBaseTest {
assertTrue(mMultiInternetManager.isStaConcurrencyForMultiInternetEnabled());
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
assertTrue(mMultiInternetManager.hasPendingConnectionRequests());
assertTrue(mMultiInternetManager.getNetworkConnectionState()
.contains(ScanResult.WIFI_BAND_5_GHZ));
verify(mConnectionStatusListener).onStatusChange(
MultiInternetManager.MULTI_INTERNET_STATE_CONNECTION_REQUESTED, TEST_WORKSOURCE);
verify(mConnectionStatusListener).onStartScan(TEST_WORKSOURCE);
+ assertEquals(0, mMultiInternetManager.getSpecifiedBssids().size());
}
@Test
@@ -286,7 +289,7 @@ public class MultiInternetManagerTest extends WifiBaseTest {
// Set for 2.4G
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_24_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
assertTrue(mMultiInternetManager.hasPendingConnectionRequests());
assertTrue(mMultiInternetManager.getNetworkConnectionState()
.contains(ScanResult.WIFI_BAND_24_GHZ));
@@ -295,7 +298,7 @@ public class MultiInternetManagerTest extends WifiBaseTest {
verify(mConnectionStatusListener).onStartScan(TEST_WORKSOURCE);
// Set for 5G
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
assertTrue(mMultiInternetManager.getNetworkConnectionState()
.contains(ScanResult.WIFI_BAND_5_GHZ));
verify(mConnectionStatusListener).onStatusChange(
@@ -303,11 +306,12 @@ public class MultiInternetManagerTest extends WifiBaseTest {
verify(mConnectionStatusListener, times(2)).onStartScan(TEST_WORKSOURCE);
// Clear the WorkSource
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_24_GHZ,
- null);
+ null, null);
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
- null);
+ null, null);
assertFalse(mMultiInternetManager.hasPendingConnectionRequests());
assertEquals(0, mMultiInternetManager.getNetworkConnectionState().size());
+ assertEquals(0, mMultiInternetManager.getSpecifiedBssids().size());
}
@Test
@@ -315,7 +319,7 @@ public class MultiInternetManagerTest extends WifiBaseTest {
assertTrue(mMultiInternetManager.setStaConcurrencyForMultiInternetMode(
WifiManager.WIFI_MULTI_INTERNET_MODE_MULTI_AP));
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
- TEST_WORKSOURCE);
+ TEST_BSSID2, TEST_WORKSOURCE);
assertTrue(mMultiInternetManager.hasPendingConnectionRequests());
fakePrimaryCmmConnected(true);
fakeSecondaryCmmConnected(true);
@@ -325,6 +329,23 @@ public class MultiInternetManagerTest extends WifiBaseTest {
.contains(ScanResult.WIFI_BAND_5_GHZ));
assertTrue(mMultiInternetManager.getNetworkConnectionState()
.get(ScanResult.WIFI_BAND_5_GHZ).isValidated());
+ assertEquals(1, mMultiInternetManager.getSpecifiedBssids().size());
+
+ // Add another request with the same band and BSSID specified and verify no disconnect
+ mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
+ TEST_BSSID2, TEST_WORKSOURCE);
+ verify(mSecondaryCmm, never()).disconnect();
+
+ // Add another request with a different band and BSSID specified and verify no disconnect
+ mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_24_GHZ,
+ TEST_BSSID2, TEST_WORKSOURCE);
+ verify(mSecondaryCmm, never()).disconnect();
+
+ // Add another request with the same band but different BSSID and verify disconnect
+ mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
+ TEST_BSSID3, TEST_WORKSOURCE);
+ verify(mSecondaryCmm).disconnect();
+ assertEquals(2, mMultiInternetManager.getSpecifiedBssids().size());
}
@Test
@@ -332,9 +353,9 @@ public class MultiInternetManagerTest extends WifiBaseTest {
assertTrue(mMultiInternetManager.setStaConcurrencyForMultiInternetMode(
WifiManager.WIFI_MULTI_INTERNET_MODE_MULTI_AP));
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_24_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
assertTrue(mMultiInternetManager.hasPendingConnectionRequests());
fakePrimaryCmmConnected(true);
fakeSecondaryCmmConnected(true);
@@ -342,6 +363,7 @@ public class MultiInternetManagerTest extends WifiBaseTest {
assertFalse(mMultiInternetManager.hasPendingConnectionRequests());
assertTrue(mMultiInternetManager.getNetworkConnectionState()
.get(ScanResult.WIFI_BAND_5_GHZ).isConnected());
+ assertEquals(0, mMultiInternetManager.getSpecifiedBssids().size());
}
@Test
@@ -349,9 +371,9 @@ public class MultiInternetManagerTest extends WifiBaseTest {
assertTrue(mMultiInternetManager.setStaConcurrencyForMultiInternetMode(
WifiManager.WIFI_MULTI_INTERNET_MODE_MULTI_AP));
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_24_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
assertTrue(mMultiInternetManager.hasPendingConnectionRequests());
fakePrimaryCmmConnected(true);
fakeSecondaryCmmConnected(true);
@@ -362,6 +384,7 @@ public class MultiInternetManagerTest extends WifiBaseTest {
mCmiListenerCaptor.getValue().onConnectionEnd(mPrimaryCmm);
verify(mSecondaryCmm).disconnect();
assertTrue(mMultiInternetManager.hasPendingConnectionRequests());
+ assertEquals(0, mMultiInternetManager.getSpecifiedBssids().size());
}
@Test
@@ -373,9 +396,9 @@ public class MultiInternetManagerTest extends WifiBaseTest {
long currentTimeStamp = 1000;
when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_24_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
- TEST_WORKSOURCE2);
+ null, TEST_WORKSOURCE2);
assertTrue(mMultiInternetManager.hasPendingConnectionRequests());
for (int i = 0; i < 5; i++) {
currentTimeStamp += SCAN_INTERVAL;
@@ -385,6 +408,7 @@ public class MultiInternetManagerTest extends WifiBaseTest {
verify(mConnectionStatusListener, times(1)).onStatusChange(
MultiInternetManager.MULTI_INTERNET_STATE_CONNECTION_REQUESTED, TEST_WORKSOURCE2);
verify(mConnectionStatusListener, times(1)).onStartScan(TEST_WORKSOURCE2);
+ assertEquals(0, mMultiInternetManager.getSpecifiedBssids().size());
}
@Test
@@ -392,9 +416,9 @@ public class MultiInternetManagerTest extends WifiBaseTest {
assertTrue(mMultiInternetManager.setStaConcurrencyForMultiInternetMode(
WifiManager.WIFI_MULTI_INTERNET_MODE_MULTI_AP));
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_24_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
- TEST_WORKSOURCE);
+ null, TEST_WORKSOURCE);
assertTrue(mMultiInternetManager.hasPendingConnectionRequests());
fakePrimaryCmmConnected(true);
fakeSecondaryCmmConnected(true);
@@ -403,9 +427,32 @@ public class MultiInternetManagerTest extends WifiBaseTest {
// Primary roamed to same frequency as secondary
mPrimaryInfo.setBSSID(TEST_BSSID3);
mPrimaryInfo.setFrequency(TEST_FREQUENCY2);
- when(mPrimaryCmm.syncRequestConnectionInfo()).thenReturn(mPrimaryInfo);
+ when(mPrimaryCmm.getConnectionInfo()).thenReturn(mPrimaryInfo);
mMultiInternetManager.notifyBssidAssociatedEvent(mPrimaryCmm);
verify(mSecondaryCmm).disconnect();
assertTrue(mMultiInternetManager.hasPendingConnectionRequests());
+ assertEquals(0, mMultiInternetManager.getSpecifiedBssids().size());
+ }
+
+ @Test
+ public void testGetSpecifiedBssids() {
+ assertTrue(mMultiInternetManager.setStaConcurrencyForMultiInternetMode(
+ WifiManager.WIFI_MULTI_INTERNET_MODE_MULTI_AP));
+ mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_24_GHZ,
+ TEST_BSSID1, TEST_WORKSOURCE);
+ mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
+ TEST_BSSID2, TEST_WORKSOURCE);
+ Map<Integer, String> specifiedBssids = mMultiInternetManager.getSpecifiedBssids();
+ assertEquals(2, specifiedBssids.size());
+ assertEquals(TEST_BSSID1, specifiedBssids.get(ScanResult.WIFI_BAND_24_GHZ));
+ assertEquals(TEST_BSSID2, specifiedBssids.get(ScanResult.WIFI_BAND_5_GHZ));
+
+ // verify overriding existing BSSID mapping
+ mMultiInternetManager.setMultiInternetConnectionWorksource(ScanResult.WIFI_BAND_5_GHZ,
+ TEST_BSSID3, TEST_WORKSOURCE);
+ specifiedBssids = mMultiInternetManager.getSpecifiedBssids();
+ assertEquals(2, specifiedBssids.size());
+ assertEquals(TEST_BSSID1, specifiedBssids.get(ScanResult.WIFI_BAND_24_GHZ));
+ assertEquals(TEST_BSSID3, specifiedBssids.get(ScanResult.WIFI_BAND_5_GHZ));
}
}
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 a3ece062e5..70412573f0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/MultiInternetWifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/MultiInternetWifiNetworkFactoryTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyObject;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -121,14 +122,19 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
@Test
public void testIsWifiMultiInternetRequest() {
- assertFalse(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(mNetworkRequest2G));
- assertFalse(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(mNetworkRequest5G));
+ // Test when caller is no settings
+ assertFalse(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(
+ mNetworkRequest2G, false));
+ assertFalse(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(
+ mNetworkRequest5G, false));
mNetworkRequest2G.networkCapabilities.addCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET);
mNetworkRequest5G.networkCapabilities.addCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET);
- assertTrue(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(mNetworkRequest2G));
- assertTrue(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(mNetworkRequest5G));
+ assertTrue(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(
+ mNetworkRequest2G, false));
+ assertTrue(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(
+ mNetworkRequest5G, false));
final NetworkRequest networkRequestNoBandSpecifier = new NetworkRequest.Builder()
.setCapabilities(mNetworkCapabilities)
.setNetworkSpecifier(new WifiNetworkSpecifier.Builder()
@@ -136,7 +142,7 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
.build())
.build();
assertFalse(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(
- networkRequestNoBandSpecifier));
+ networkRequestNoBandSpecifier, false));
final NetworkRequest networkRequestSSIDSpecifier = new NetworkRequest.Builder()
.setCapabilities(mNetworkCapabilities)
.setNetworkSpecifier(new WifiNetworkSpecifier.Builder()
@@ -146,7 +152,7 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
.build())
.build();
assertFalse(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(
- networkRequestSSIDSpecifier));
+ networkRequestSSIDSpecifier, false));
final NetworkRequest networkRequestBSSIDSpecifier = new NetworkRequest.Builder()
.setCapabilities(mNetworkCapabilities)
.setNetworkSpecifier(new WifiNetworkSpecifier.Builder()
@@ -154,8 +160,14 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
.setBand(ScanResult.WIFI_BAND_5_GHZ)
.build())
.build();
+ networkRequestBSSIDSpecifier.networkCapabilities.addCapability(
+ NetworkCapabilities.NET_CAPABILITY_INTERNET);
assertFalse(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(
- networkRequestBSSIDSpecifier));
+ networkRequestBSSIDSpecifier, false));
+
+ // test when the caller is settings
+ assertTrue(MultiInternetWifiNetworkFactory.isWifiMultiInternetRequest(
+ networkRequestBSSIDSpecifier, true));
}
/**
@@ -170,7 +182,7 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
mMultiInternetWifiNetworkFactory.needNetworkFor(mNetworkRequest2G);
// First network request should notify MultiInternetManager.
verify(mMultiInternetManager).setMultiInternetConnectionWorksource(
- ScanResult.WIFI_BAND_24_GHZ, TEST_WORKSOURCE);
+ ScanResult.WIFI_BAND_24_GHZ, null, TEST_WORKSOURCE);
// Subsequent ones should do nothing.
mMultiInternetWifiNetworkFactory.needNetworkFor(mNetworkRequest2G);
@@ -178,6 +190,34 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
}
/**
+ * Validates handling of needNetworkFor.
+ */
+ @Test
+ public void testMultiInternetHandleNetworkRequestFromSettingsWithBssid() {
+ when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+ when(mMultiInternetManager.isStaConcurrencyForMultiInternetEnabled()).thenReturn(true);
+ final NetworkRequest networkRequestBSSIDSpecifier = new NetworkRequest.Builder()
+ .setCapabilities(mNetworkCapabilities)
+ .setNetworkSpecifier(new WifiNetworkSpecifier.Builder()
+ .setBssid(MacAddress.fromString(TEST_BSSID))
+ .setBand(ScanResult.WIFI_BAND_5_GHZ)
+ .build())
+ .build();
+ networkRequestBSSIDSpecifier.networkCapabilities.addCapability(
+ NetworkCapabilities.NET_CAPABILITY_INTERNET);
+
+ mMultiInternetWifiNetworkFactory.needNetworkFor(networkRequestBSSIDSpecifier);
+ // First network request should notify MultiInternetManager.
+ verify(mMultiInternetManager).setMultiInternetConnectionWorksource(
+ ScanResult.WIFI_BAND_5_GHZ, TEST_BSSID, TEST_WORKSOURCE);
+
+ // Subsequent ones send it to MultiInternetManagerAgain since it's from Settings.
+ mMultiInternetWifiNetworkFactory.needNetworkFor(networkRequestBSSIDSpecifier);
+ verify(mMultiInternetManager, times(2)).setMultiInternetConnectionWorksource(
+ ScanResult.WIFI_BAND_5_GHZ, TEST_BSSID, TEST_WORKSOURCE);
+ }
+
+ /**
* Validates handling of needNetworkFor of dual bands.
*/
@Test
@@ -192,16 +232,16 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
mMultiInternetWifiNetworkFactory.needNetworkFor(mNetworkRequest5G);
// First network request should notify MultiInternetManager.
verify(mMultiInternetManager).setMultiInternetConnectionWorksource(
- ScanResult.WIFI_BAND_24_GHZ, TEST_WORKSOURCE);
+ ScanResult.WIFI_BAND_24_GHZ, null, TEST_WORKSOURCE);
verify(mMultiInternetManager).setMultiInternetConnectionWorksource(
- ScanResult.WIFI_BAND_5_GHZ, TEST_WORKSOURCE);
+ ScanResult.WIFI_BAND_5_GHZ, null, TEST_WORKSOURCE);
reset(mMultiInternetManager);
// Subsequent ones should do nothing.
mMultiInternetWifiNetworkFactory.needNetworkFor(mNetworkRequest2G);
mMultiInternetWifiNetworkFactory.needNetworkFor(mNetworkRequest5G);
verify(mMultiInternetManager, never()).setMultiInternetConnectionWorksource(anyInt(),
- anyObject());
+ anyObject(), anyObject());
verifyNoMoreInteractions(mWifiConnectivityManager);
}
@@ -219,11 +259,11 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
// Now request & then release the network request
mMultiInternetWifiNetworkFactory.needNetworkFor(mNetworkRequest2G);
verify(mMultiInternetManager).setMultiInternetConnectionWorksource(
- ScanResult.WIFI_BAND_24_GHZ, TEST_WORKSOURCE);
+ ScanResult.WIFI_BAND_24_GHZ, null, TEST_WORKSOURCE);
mMultiInternetWifiNetworkFactory.releaseNetworkFor(mNetworkRequest2G);
verify(mMultiInternetManager).setMultiInternetConnectionWorksource(
- ScanResult.WIFI_BAND_24_GHZ, null);
+ ScanResult.WIFI_BAND_24_GHZ, null, null);
}
/**
@@ -240,7 +280,7 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
// Now request & then release the network request
mMultiInternetWifiNetworkFactory.needNetworkFor(mNetworkRequest5G);
verify(mMultiInternetManager).setMultiInternetConnectionWorksource(
- ScanResult.WIFI_BAND_5_GHZ, TEST_WORKSOURCE);
+ ScanResult.WIFI_BAND_5_GHZ, null, TEST_WORKSOURCE);
// Now request the network again for 2 times.
mMultiInternetWifiNetworkFactory.needNetworkFor(mNetworkRequest5G);
@@ -248,10 +288,10 @@ public class MultiInternetWifiNetworkFactoryTest extends WifiBaseTest {
mMultiInternetWifiNetworkFactory.releaseNetworkFor(mNetworkRequest5G);
verify(mMultiInternetManager, never()).setMultiInternetConnectionWorksource(
- ScanResult.WIFI_BAND_5_GHZ, null);
+ ScanResult.WIFI_BAND_5_GHZ, null, null);
mMultiInternetWifiNetworkFactory.releaseNetworkFor(mNetworkRequest5G);
mMultiInternetWifiNetworkFactory.releaseNetworkFor(mNetworkRequest5G);
verify(mMultiInternetManager).setMultiInternetConnectionWorksource(
- ScanResult.WIFI_BAND_5_GHZ, null);
+ ScanResult.WIFI_BAND_5_GHZ, null, null);
}
}
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 694638ebab..84cca7fd50 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
@@ -267,6 +267,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
? "<null name=\"DecoratedIdentityPrefix\" />\n" : "")
+ "<boolean name=\"TrustOnFirstUse\" value=\"false\" />\n"
+ "<boolean name=\"UserApproveNoCaCert\" value=\"false\" />\n"
+ + "<int name=\"MinimumTlsVersion\" value=\"3\" />\n"
+ "</WifiEnterpriseConfiguration>\n"
+ "</Network>\n";;
@@ -457,6 +458,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
? "<null name=\"DecoratedIdentityPrefix\" />\n" : "")
+ "<boolean name=\"TrustOnFirstUse\" value=\"false\" />\n"
+ "<boolean name=\"UserApproveNoCaCert\" value=\"false\" />\n"
+ + "<int name=\"MinimumTlsVersion\" value=\"0\" />\n"
+ "</WifiEnterpriseConfiguration>\n"
+ "</Network>\n";;
@@ -594,6 +596,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
eapNetwork.setIpConfiguration(
WifiConfigurationTestUtil.createDHCPIpConfigurationWithNoProxy());
eapNetwork.setRandomizedMacAddress(TEST_RANDOMIZED_MAC);
+ eapNetwork.enterpriseConfig.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_V1_3);
WifiConfiguration saeNetwork = WifiConfigurationTestUtil.createSaeNetwork();
saeNetwork.shared = shared;
saeNetwork.creatorName = TEST_CREATOR_NAME;
@@ -943,20 +946,6 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
saeNetwork.shared, saeNetwork.creatorUid,
saeNetwork.creatorName, saeNetwork.getRandomizedMacAddress());
- saeNetworkWithOpenAuthXml.replaceAll("name=\"AllowedAuthAlgos\" num=\"0\"></byte-array>",
- "<name=\"AllowedAuthAlgos\" num=\"1\">01</byte-array>");
-
- saeNetworkWithOpenAuthXml.replaceAll("name=\"AllowedProtocols\" num=\"1\">02</byte-array>",
- "name=\"AllowedProtocols\" num=\"1\">03</byte-array>");
-
- saeNetworkWithOpenAuthXml.replaceAll(
- "name=\"AllowedGroupCiphers\" num=\"1\">28</byte-array>",
- "name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>");
-
- saeNetworkWithOpenAuthXml.replaceAll(
- "name=\"AllowedPairwiseCiphers\" num=\"1\">0c</byte-array>",
- "name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>");
-
List<WifiConfiguration> retrievedNetworkList =
deserializeData(saeNetworkWithOpenAuthXml.getBytes(StandardCharsets.UTF_8));
@@ -1006,7 +995,7 @@ public class NetworkListStoreDataTest extends WifiBaseTest {
pskNetwork.setRandomizedMacAddress(TEST_RANDOMIZED_MAC);
pskNetwork.creatorName = TEST_CREATOR_NAME;
String invalidConfigKey = pskNetwork.getKey();
- invalidConfigKey.replace("WPA_PSK", "NONE");
+ invalidConfigKey = invalidConfigKey.replace("WPA_PSK", "NONE");
// XML data has 2 things that needs to be corrected:
// - ConfigKey is set to "SSID"NONE instead of "SSID"WPA_PSK
// - KeyMgmt has KeyMgmt.OSEN bit set instead of KeyMgmt.WPA_PSK
diff --git a/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
index 904b578f73..37639825ab 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
@@ -42,7 +42,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -117,9 +116,8 @@ public class NetworkRequestStoreDataTest extends WifiBaseTest {
AccessPoint accessPoint = new AccessPoint(
WifiConfigurationTestUtil.createPskNetwork().SSID,
MacAddressUtils.createRandomUnicastAddress(), WifiConfiguration.SECURITY_TYPE_PSK);
- Set<AccessPoint> accessPoints = new HashSet<AccessPoint>() {{
- add(accessPoint);
- }};
+ Set<AccessPoint> accessPoints = Set.of(accessPoint);
+
approvedAccessPointsMap.put(TEST_PACKAGE_NAME_1, accessPoints);
assertSerializeDeserialize(approvedAccessPointsMap);
@@ -135,17 +133,15 @@ public class NetworkRequestStoreDataTest extends WifiBaseTest {
AccessPoint accessPoint1 = new AccessPoint(
WifiConfigurationTestUtil.createPskNetwork().SSID,
MacAddressUtils.createRandomUnicastAddress(), WifiConfiguration.SECURITY_TYPE_PSK);
- Set<AccessPoint> accessPoints1 = new HashSet<AccessPoint>() {{
- add(accessPoint1);
- }};
+ Set<AccessPoint> accessPoints1 = Set.of(accessPoint1);
+
approvedAccessPointsMap.put(TEST_PACKAGE_NAME_1, accessPoints1);
AccessPoint accessPoint2 = new AccessPoint(
WifiConfigurationTestUtil.createPskNetwork().SSID,
MacAddressUtils.createRandomUnicastAddress(), WifiConfiguration.SECURITY_TYPE_PSK);
- Set<AccessPoint> accessPoints2 = new HashSet<AccessPoint>() {{
- add(accessPoint2);
- }};
+ Set<AccessPoint> accessPoints2 = Set.of(accessPoint2);
+
approvedAccessPointsMap.put(TEST_PACKAGE_NAME_2, accessPoints2);
assertSerializeDeserialize(approvedAccessPointsMap);
@@ -164,10 +160,10 @@ public class NetworkRequestStoreDataTest extends WifiBaseTest {
AccessPoint accessPoint2 = new AccessPoint(
WifiConfigurationTestUtil.createOpenNetwork().SSID,
MacAddressUtils.createRandomUnicastAddress(), WifiConfiguration.SECURITY_TYPE_OPEN);
- Set<AccessPoint> accessPoints1 = new HashSet<AccessPoint>() {{
- add(accessPoint1);
- add(accessPoint2);
- }};
+ Set<AccessPoint> accessPoints1 = Set.of(
+ accessPoint1,
+ accessPoint2);
+
approvedAccessPointsMap.put(TEST_PACKAGE_NAME_1, accessPoints1);
AccessPoint accessPoint3 = new AccessPoint(
@@ -176,10 +172,10 @@ public class NetworkRequestStoreDataTest extends WifiBaseTest {
AccessPoint accessPoint4 = new AccessPoint(
WifiConfigurationTestUtil.createOpenNetwork().SSID,
MacAddressUtils.createRandomUnicastAddress(), WifiConfiguration.SECURITY_TYPE_OPEN);
- Set<AccessPoint> accessPoints2 = new HashSet<AccessPoint>() {{
- add(accessPoint3);
- add(accessPoint4);
- }};
+ Set<AccessPoint> accessPoints2 = Set.of(
+ accessPoint3,
+ accessPoint4);
+
approvedAccessPointsMap.put(TEST_PACKAGE_NAME_2, accessPoints2);
assertSerializeDeserialize(approvedAccessPointsMap);
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 6e9f26c79b..5b2e901c95 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionNominatorTest.java
@@ -1792,12 +1792,9 @@ public class NetworkSuggestionNominatorTest extends WifiBaseTest {
for (int i = 0; i < minLength; i++) {
ScanDetail scanDetail = scanDetails[i];
final ExtendedWifiNetworkSuggestion matchingSuggestion = suggestions[i];
- HashSet<ExtendedWifiNetworkSuggestion> matchingSuggestions =
- new HashSet<ExtendedWifiNetworkSuggestion>() {{
- add(matchingSuggestion);
- }};
+ Set<ExtendedWifiNetworkSuggestion> matchingSuggestions = Set.of(matchingSuggestion);
when(mWifiNetworkSuggestionsManager.getNetworkSuggestionsForScanDetail(eq(scanDetail)))
- .thenReturn((matchingSuggestions));
+ .thenReturn(matchingSuggestions);
}
if (scanDetails.length > suggestions.length) {
// No match for the remaining scan details.
@@ -1812,7 +1809,7 @@ public class NetworkSuggestionNominatorTest extends WifiBaseTest {
Arrays.asList(suggestions).subList(minLength - 1, suggestions.length));
ScanDetail lastScanDetail = scanDetails[minLength - 1];
when(mWifiNetworkSuggestionsManager.getNetworkSuggestionsForScanDetail(
- eq(lastScanDetail))).thenReturn((matchingSuggestions));
+ eq(lastScanDetail))).thenReturn(matchingSuggestions);
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
index de777a1e8c..abaa8e4e8a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
@@ -447,7 +447,7 @@ public class NetworkSuggestionStoreDataTest extends WifiBaseTest {
// Old format with empty suggestion
String preRFormatXml = String.format(
- TEST_PRE_R_APP_WITH_EMPTY_SUGGESTION, TEST_PACKAGE_NAME_1, TEST_UID_1);
+ TEST_PRE_R_APP_WITH_EMPTY_SUGGESTION, TEST_PACKAGE_NAME_1);
deserializeData(preRFormatXml.getBytes());
// New format with empty suggestion
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java b/service/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java
index ef2c0fac11..430099e603 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java
@@ -39,13 +39,13 @@ import android.net.wifi.WifiScanner.ScanSettings.HiddenNetwork;
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
-import android.os.WorkSource;
import android.os.test.TestLooper;
import android.text.TextUtils;
import androidx.test.filters.SmallTest;
import com.android.modules.utils.build.SdkLevel;
+import com.android.server.wifi.scanner.WifiScannerInternal;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.wifi.resources.R;
@@ -71,24 +71,19 @@ public class ScanRequestProxyTest extends WifiBaseTest {
private static final String TEST_PACKAGE_NAME_2 = "com.test.2";
private static final String TEST_HIDDEN_NETWORK_MAC = "10:22:34:56:78:92";
private static final String TEST_HIDDEN_NETWORK_SSID = "HideMe";
- private static final List<HiddenNetwork> TEST_HIDDEN_NETWORKS_LIST =
- new ArrayList<HiddenNetwork>() {{
- add(new HiddenNetwork("test_ssid_1"));
- add(new HiddenNetwork("test_ssid_2"));
-
- }};
- private static final List<HiddenNetwork> TEST_HIDDEN_NETWORKS_LIST_NS =
- new ArrayList<HiddenNetwork>() {{
- add(new HiddenNetwork("test_ssid_3"));
- add(new HiddenNetwork("test_ssid_4"));
- }};
+ private static final List<HiddenNetwork> TEST_HIDDEN_NETWORKS_LIST = List.of(
+ new HiddenNetwork("test_ssid_1"),
+ new HiddenNetwork("test_ssid_2"));
+ private static final List<HiddenNetwork> TEST_HIDDEN_NETWORKS_LIST_NS = List.of(
+ new HiddenNetwork("test_ssid_3"),
+ new HiddenNetwork("test_ssid_4"));
@Mock private Context mContext;
@Mock private AppOpsManager mAppOps;
@Mock private ActivityManager mActivityManager;
@Mock private WifiInjector mWifiInjector;
@Mock private WifiConfigManager mWifiConfigManager;
- @Mock private WifiScanner mWifiScanner;
+ @Mock private WifiScannerInternal mWifiScanner;
@Mock private WifiPermissionsUtil mWifiPermissionsUtil;
@Mock private WifiMetrics mWifiMetrics;
@Mock private WifiMetrics.ScanMetrics mScanMetrics;
@@ -97,23 +92,20 @@ public class ScanRequestProxyTest extends WifiBaseTest {
@Mock private WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
@Mock private IScanResultsCallback mScanResultsCallback;
@Mock private IScanResultsCallback mAnotherScanResultsCallback;
- @Mock private TestLooper mLooper;
@Mock private IBinder mBinder;
@Mock private IBinder mAnotherBinder;
- private ArgumentCaptor<WorkSource> mWorkSourceArgumentCaptor =
- ArgumentCaptor.forClass(WorkSource.class);
private ArgumentCaptor<WifiScanner.ScanSettings> mScanSettingsArgumentCaptor =
ArgumentCaptor.forClass(WifiScanner.ScanSettings.class);
- private ArgumentCaptor<WifiScanner.ScanListener> mScanRequestListenerArgumentCaptor =
- ArgumentCaptor.forClass(WifiScanner.ScanListener.class);
- private ArgumentCaptor<WifiScanner.ScanListener> mGlobalScanListenerArgumentCaptor =
- ArgumentCaptor.forClass(WifiScanner.ScanListener.class);
+ private ArgumentCaptor<WifiScannerInternal.ScanListener> mScanRequestListenerArgumentCaptor =
+ ArgumentCaptor.forClass(WifiScannerInternal.ScanListener.class);
+ private ArgumentCaptor<WifiScannerInternal.ScanListener> mGlobalScanListenerArgumentCaptor =
+ ArgumentCaptor.forClass(WifiScannerInternal.ScanListener.class);
private WifiScanner.ScanData[] mTestScanDatas1;
private WifiScanner.ScanData[] mTestScanDatas2;
private WifiScanner.ScanData[] mTestHiddenNetworkScanDatas;
private InOrder mInOrder;
-
+ private TestLooper mLooper;
private ScanRequestProxy mScanRequestProxy;
private MockResources mResources;
@@ -125,10 +117,11 @@ public class ScanRequestProxyTest extends WifiBaseTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
-
+ mLooper = new TestLooper();
mResources = getMockResources();
when(mContext.getResources()).thenReturn(mResources);
- when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
+ WifiLocalServices.removeServiceForTest(WifiScannerInternal.class);
+ WifiLocalServices.addService(WifiScannerInternal.class, mWifiScanner);
when(mWifiInjector.getWifiNetworkSuggestionsManager())
.thenReturn(mWifiNetworkSuggestionsManager);
when(mWifiConfigManager.retrieveHiddenNetworkList(false /* autoJoinOnly */))
@@ -137,13 +130,10 @@ public class ScanRequestProxyTest extends WifiBaseTest {
.thenReturn(TEST_HIDDEN_NETWORKS_LIST_NS);
when(mWifiMetrics.getScanMetrics()).thenReturn(mScanMetrics);
doNothing().when(mWifiScanner).registerScanListener(
- any(),
mGlobalScanListenerArgumentCaptor.capture());
doNothing().when(mWifiScanner).startScan(
mScanSettingsArgumentCaptor.capture(),
- any(),
- mScanRequestListenerArgumentCaptor.capture(),
- mWorkSourceArgumentCaptor.capture());
+ mScanRequestListenerArgumentCaptor.capture(), any());
mInOrder = inOrder(mWifiScanner, mWifiConfigManager,
mContext, mWifiNetworkSuggestionsManager);
@@ -158,7 +148,6 @@ public class ScanRequestProxyTest extends WifiBaseTest {
// Scan throttling is enabled by default.
when(mWifiSettingsConfigStore.get(eq(WIFI_SCAN_THROTTLE_ENABLED))).thenReturn(true);
- mLooper = new TestLooper();
mScanRequestProxy =
new ScanRequestProxy(mContext, mAppOps, mActivityManager, mWifiInjector,
mWifiConfigManager, mWifiPermissionsUtil, mWifiMetrics, mClock,
@@ -176,7 +165,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
private void enableScanning() {
// Enable scanning
mScanRequestProxy.enableScanning(true, false);
- mInOrder.verify(mWifiScanner).registerScanListener(any(), any());
+ mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).setScanningEnabled(true);
validateScanAvailableBroadcastSent(true);
@@ -205,7 +194,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
@Test
public void testEnableScanning() {
mScanRequestProxy.enableScanning(true, false);
- mInOrder.verify(mWifiScanner).registerScanListener(any(), any());
+ mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).setScanningEnabled(true);
validateScanAvailableBroadcastSent(true);
}
@@ -216,7 +205,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
@Test
public void testDisableScanning() {
mScanRequestProxy.enableScanning(false, false);
- mInOrder.verify(mWifiScanner).registerScanListener(any(), any());
+ mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).setScanningEnabled(false);
validateScanAvailableBroadcastSent(false);
}
@@ -238,10 +227,8 @@ public class ScanRequestProxyTest extends WifiBaseTest {
public void testStartScanSuccess() {
enableScanning();
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
- assertTrue(mWorkSourceArgumentCaptor.getValue().equals(
- new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1)));
validateScanSettings(mScanSettingsArgumentCaptor.getValue(), false);
verifyScanMetricsDataWasSet();
@@ -255,10 +242,8 @@ public class ScanRequestProxyTest extends WifiBaseTest {
enableScanning();
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID)).thenReturn(true);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
- assertTrue(mWorkSourceArgumentCaptor.getValue().equals(
- new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1)));
validateScanSettings(mScanSettingsArgumentCaptor.getValue(), false, true);
verifyScanMetricsDataWasSet(0, 1);
if (SdkLevel.isAtLeastS()) {
@@ -275,10 +260,8 @@ public class ScanRequestProxyTest extends WifiBaseTest {
enableScanning();
when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(TEST_UID)).thenReturn(true);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
- assertEquals(mWorkSourceArgumentCaptor.getValue(),
- new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1));
validateScanSettings(mScanSettingsArgumentCaptor.getValue(), false, true);
verifyScanMetricsDataWasSet(0, 1);
}
@@ -289,7 +272,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
@Test
public void testStartScanWithHiddenNetworkScanningDisabled() {
mScanRequestProxy.enableScanning(true, false);
- mInOrder.verify(mWifiScanner).registerScanListener(any(), any());
+ mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).setScanningEnabled(true);
validateScanAvailableBroadcastSent(true);
@@ -298,10 +281,8 @@ public class ScanRequestProxyTest extends WifiBaseTest {
.retrieveHiddenNetworkList(false /* autoJoinOnly */);
mInOrder.verify(mWifiNetworkSuggestionsManager, never())
.retrieveHiddenNetworkList(false /* autoJoinOnly */);
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
- assertEquals(mWorkSourceArgumentCaptor.getValue(),
- new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1));
validateScanSettings(mScanSettingsArgumentCaptor.getValue(), false);
verifyScanMetricsDataWasSet();
@@ -313,7 +294,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
@Test
public void testStartScanWithHiddenNetworkScanningEnabled() {
mScanRequestProxy.enableScanning(true, true);
- mInOrder.verify(mWifiScanner).registerScanListener(any(), any());
+ mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).setScanningEnabled(true);
validateScanAvailableBroadcastSent(true);
@@ -323,10 +304,8 @@ public class ScanRequestProxyTest extends WifiBaseTest {
.retrieveHiddenNetworkList(false /* autoJoinOnly */);
mInOrder.verify(mWifiNetworkSuggestionsManager)
.retrieveHiddenNetworkList(false /* autoJoinOnly */);
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
- assertEquals(mWorkSourceArgumentCaptor.getValue(),
- new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1));
validateScanSettings(mScanSettingsArgumentCaptor.getValue(), true);
verifyScanMetricsDataWasSet();
@@ -336,12 +315,13 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* Verify a successful scan request and processing of scan results.
*/
@Test
- public void testScanSuccess() {
+ public void testScanSuccess() throws Exception {
// Make a scan request.
testStartScanSuccess();
// Verify the scan results processing.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
@@ -358,12 +338,13 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* Verify a successful scan request and processing of scan failure.
*/
@Test
- public void testScanFailure() {
+ public void testScanFailure() throws Exception {
// Make a scan request.
testStartScanSuccess();
// Verify the scan failure processing.
mScanRequestListenerArgumentCaptor.getValue().onFailure(0, "failed");
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(false);
// Ensure scan results in the cache is empty.
@@ -377,13 +358,14 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* Verify processing of successive successful scans.
*/
@Test
- public void testScanSuccessOverwritesPreviousResults() {
+ public void testScanSuccessOverwritesPreviousResults() throws Exception {
enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -394,9 +376,10 @@ public class ScanRequestProxyTest extends WifiBaseTest {
// Make scan request 2.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 2.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas2);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -412,13 +395,14 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* Verify processing of a successful scan followed by a failure.
*/
@Test
- public void testScanFailureDoesNotOverwritePreviousResults() {
+ public void testScanFailureDoesNotOverwritePreviousResults() throws Exception {
enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -429,9 +413,10 @@ public class ScanRequestProxyTest extends WifiBaseTest {
// Make scan request 2.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan failure processing.
mScanRequestListenerArgumentCaptor.getValue().onFailure(0, "failed");
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(false);
// Validate the scan results from a previous successful scan in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -448,13 +433,14 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* Verify that we send out two broadcasts (two successes).
*/
@Test
- public void testNewScanRequestAfterPreviousScanSucceeds() {
+ public void testNewScanRequestAfterPreviousScanSucceeds() throws Exception {
enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Now send the scan results for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -466,9 +452,10 @@ public class ScanRequestProxyTest extends WifiBaseTest {
// Make scan request 2.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
// Ensure that we did send a second scan request to scanner.
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Now send the scan results for request 2.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas2);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -486,15 +473,16 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* Verify that we send out two broadcasts (one failure & one success).
*/
@Test
- public void testNewScanRequestAfterPreviousScanSucceedsWithInvalidScanDatas() {
+ public void testNewScanRequestAfterPreviousScanSucceedsWithInvalidScanDatas() throws Exception {
enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Now send scan success for request 1, but with invalid scan datas.
mGlobalScanListenerArgumentCaptor.getValue().onResults(
new WifiScanner.ScanData[] {mTestScanDatas1[0], mTestScanDatas2[0]});
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(false);
// Validate the scan results in the cache.
assertTrue(mScanRequestProxy.getScanResults().isEmpty());
@@ -503,9 +491,10 @@ public class ScanRequestProxyTest extends WifiBaseTest {
// Make scan request 2.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
// Ensure that we did send a second scan request to scanner.
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Now send the scan results for request 2.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas2);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -523,14 +512,15 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* Verify that we send out two broadcasts (one failure & one success).
*/
@Test
- public void testNewScanRequestAfterPreviousScanFailure() {
+ public void testNewScanRequestAfterPreviousScanFailure() throws Exception {
enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Now send scan failure for request 1.
mScanRequestListenerArgumentCaptor.getValue().onFailure(0, "failed");
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(false);
// Validate the scan results in the cache.
assertTrue(mScanRequestProxy.getScanResults().isEmpty());
@@ -539,9 +529,10 @@ public class ScanRequestProxyTest extends WifiBaseTest {
// Make scan request 2.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
// Ensure that we did send a second scan request to scanner.
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Now send the scan results for request 2.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas2);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -557,18 +548,19 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* Verify that we clear scan results when scan state is toggled.
*/
@Test
- public void testToggleScanStateClearsScanResults() {
+ public void testToggleScanStateClearsScanResults() throws Exception {
// Enable scanning
mScanRequestProxy.enableScanning(true, false);
- mInOrder.verify(mWifiScanner).registerScanListener(any(), any());
+ mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).setScanningEnabled(true);
validateScanAvailableBroadcastSent(true);
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -606,17 +598,17 @@ public class ScanRequestProxyTest extends WifiBaseTest {
@Test
public void testSuccessiveScanRequestsDontUseSameListener() {
enableScanning();
- WifiScanner.ScanListener listener1;
- WifiScanner.ScanListener listener2;
+ WifiScannerInternal.ScanListener listener1;
+ WifiScannerInternal.ScanListener listener2;
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
listener1 = mScanRequestListenerArgumentCaptor.getValue();
// Make scan request 2.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
// Ensure that we did send a second scan request to scanner.
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
listener2 = mScanRequestListenerArgumentCaptor.getValue();
assertNotEquals(listener1, listener2);
@@ -638,11 +630,11 @@ public class ScanRequestProxyTest extends WifiBaseTest {
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Make next scan request from the same package name & ensure that it is not throttled.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
verifyScanMetricsDataWasSet(SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS + 1);
if (SdkLevel.isAtLeastS()) {
assertTrue("6Ghz PSC should be enabled for scan requests from normal apps.",
@@ -663,7 +655,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Make next scan request from the same package name & ensure that it is throttled.
assertFalse(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
@@ -687,13 +679,13 @@ public class ScanRequestProxyTest extends WifiBaseTest {
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
long lastRequestMs = firstRequestMs + SCAN_REQUEST_THROTTLE_TIME_WINDOW_FG_APPS_MS + 1;
when(mClock.getElapsedSinceBootMillis()).thenReturn(lastRequestMs);
// Make next scan request from the same package name & ensure that it is not throttled.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
verifyScanMetricsDataWasSet(SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS + 1);
}
@@ -712,11 +704,11 @@ public class ScanRequestProxyTest extends WifiBaseTest {
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Make next scan request from the same package name & ensure that it is not throttled.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
verifyScanMetricsDataWasSet(0, SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS + 1);
}
@@ -735,11 +727,11 @@ public class ScanRequestProxyTest extends WifiBaseTest {
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Make next scan request from the same package name & ensure that it is not throttled.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
verifyScanMetricsDataWasSet(0, SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS + 1);
}
@@ -760,11 +752,11 @@ public class ScanRequestProxyTest extends WifiBaseTest {
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Make next scan request from the same package name & ensure that it is not throttled.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
verifyScanMetricsDataWasSet(0, SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS + 1);
}
@@ -780,18 +772,18 @@ public class ScanRequestProxyTest extends WifiBaseTest {
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS / 2; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS / 2; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Make next scan request from both the package name & ensure that it is not throttled.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
verifyScanMetricsDataWasSet(SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS + 2);
}
@@ -809,7 +801,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Now simulate removing the app.
mScanRequestProxy.clearScanRequestTimestampsForApp(TEST_PACKAGE_NAME_1, TEST_UID);
@@ -817,7 +809,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
// Make next scan request from the same package name (simulating a reinstall) & ensure that
// it is not throttled.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
verifyScanMetricsDataWasSet(SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS + 1);
}
@@ -835,7 +827,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS; i++) {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs + i);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Now simulate removing the app for another user (User 1).
mScanRequestProxy.clearScanRequestTimestampsForApp(
@@ -875,11 +867,11 @@ public class ScanRequestProxyTest extends WifiBaseTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Make scan request 2 from the different package name & ensure that it is not throttled.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
verifyScanMetricsDataWasSet(2);
}
@@ -899,7 +891,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Make scan request 2 from the different package name & ensure that it is throttled.
assertFalse(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
@@ -925,14 +917,14 @@ public class ScanRequestProxyTest extends WifiBaseTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
long secondRequestMs =
firstRequestMs + ScanRequestProxy.SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS + 1;
when(mClock.getElapsedSinceBootMillis()).thenReturn(secondRequestMs);
// Make scan request 2 from the different package name & ensure that it is throttled.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_2));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
verifyScanMetricsDataWasSet(2);
}
@@ -942,13 +934,14 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* internal scans.
*/
@Test
- public void testFullInternalScanResultsOverwritesPreviousResults() {
+ public void testFullInternalScanResultsOverwritesPreviousResults() throws Exception {
enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -958,6 +951,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
// Now send results from an internal full scan request.
// Verify the scan failure processing.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas2);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -972,13 +966,14 @@ public class ScanRequestProxyTest extends WifiBaseTest {
* internal scans.
*/
@Test
- public void testPartialInternalScanResultsDoesNotOverwritePreviousResults() {
+ public void testPartialInternalScanResultsDoesNotOverwritePreviousResults() throws Exception {
enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).startScan(any(), any(), any(), any());
+ mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
validateScanResultsAvailableBroadcastSent(true);
// Validate the scan results in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
@@ -991,6 +986,7 @@ public class ScanRequestProxyTest extends WifiBaseTest {
new int[]{WifiScanner.WIFI_BAND_24_GHZ});
// Verify the scan failure processing.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas2);
+ mLooper.dispatchAll();
// Validate the scan results from a previous successful scan in the cache.
ScanTestUtil.assertScanResultsEqualsAnyOrder(
mTestScanDatas1[0].getResults(),
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 f04195e85f..824303655e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -78,6 +78,7 @@ import android.os.UserHandle;
import android.os.WorkSource;
import android.os.test.TestLooper;
import android.provider.Settings;
+import android.util.LocalLog;
import android.util.SparseIntArray;
import androidx.test.filters.SmallTest;
@@ -166,10 +167,10 @@ public class SoftApManagerTest extends WifiBaseTest {
private SoftApInfo mTestSoftApInfoOnSecondInstance; // Use for briged Ap mode test case
private Map<String, SoftApInfo> mTestSoftApInfoMap = new HashMap<>();
private Map<String, List<WifiClient>> mTestWifiClientsMap = new HashMap<>();
- private Map<String, List<WifiClient>> mTempConnectedClientListMap = new HashMap<>() {{
- put(TEST_INTERFACE_NAME, new ArrayList());
- put(TEST_FIRST_INSTANCE_NAME, new ArrayList());
- put(TEST_SECOND_INSTANCE_NAME, new ArrayList()); }};
+ private Map<String, List<WifiClient>> mTempConnectedClientListMap = Map.of(
+ TEST_INTERFACE_NAME, new ArrayList(),
+ TEST_FIRST_INSTANCE_NAME, new ArrayList(),
+ TEST_SECOND_INSTANCE_NAME, new ArrayList());
private SoftApCapability mTestSoftApCapability;
private List<ClientModeManager> mTestClientModeManagers = new ArrayList<>();
@@ -195,6 +196,8 @@ public class SoftApManagerTest extends WifiBaseTest {
@Mock WifiInfo mSecondWifiInfo;
@Mock BatteryManager mBatteryManager;
@Mock InterfaceConflictManager mInterfaceConflictManager;
+ @Mock WifiInjector mWifiInjector;
+ @Mock LocalLog mLocalLog;
final ArgumentCaptor<WifiNative.InterfaceCallback> mWifiNativeInterfaceCallbackCaptor =
ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
@@ -344,11 +347,13 @@ public class SoftApManagerTest extends WifiBaseTest {
when(mActiveModeWarden.getClientModeManagers())
.thenReturn(mTestClientModeManagers);
mTestClientModeManagers.add(mPrimaryConcreteClientModeManager);
- when(mPrimaryConcreteClientModeManager.syncRequestConnectionInfo())
+ when(mPrimaryConcreteClientModeManager.getConnectionInfo())
.thenReturn(mPrimaryWifiInfo);
- when(mConcreteClientModeManager.syncRequestConnectionInfo())
+ when(mConcreteClientModeManager.getConnectionInfo())
.thenReturn(mPrimaryWifiInfo);
when(mWifiNative.forceClientDisconnect(any(), any(), anyInt())).thenReturn(true);
+ when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog);
+ when(mContext.getResources()).thenReturn(mResources);
// Init Test SoftAp infos
mTestSoftApInfo = new SoftApInfo();
@@ -395,10 +400,7 @@ public class SoftApManagerTest extends WifiBaseTest {
private SoftApManager createSoftApManager(SoftApModeConfiguration config,
ActiveModeManager.SoftApRole role) {
SoftApManager newSoftApManager = new SoftApManager(
- mContext,
- mLooper.getLooper(),
- mFrameworkFacade,
- mWifiNative,
+ mContext, mLooper.getLooper(), mFrameworkFacade, mWifiNative, mWifiInjector,
mCoexManager,
mBatteryManager,
mInterfaceConflictManager,
@@ -1001,7 +1003,7 @@ public class SoftApManagerTest extends WifiBaseTest {
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
mTestSoftApCapability, TEST_COUNTRY_CODE);
startSoftApAndVerifyEnabled(softApModeConfig);
-
+ verify(mListener, never()).onStopped(mSoftApManager);
mSoftApManager.stop();
mLooper.dispatchAll();
verify(mListener).onStopped(mSoftApManager);
@@ -3154,7 +3156,7 @@ public class SoftApManagerTest extends WifiBaseTest {
// Prepare second ClientModeManager
List<ClientModeManager> testClientModeManagers = new ArrayList<>(mTestClientModeManagers);
testClientModeManagers.add(mSecondConcreteClientModeManager);
- when(mSecondConcreteClientModeManager.syncRequestConnectionInfo())
+ when(mSecondConcreteClientModeManager.getConnectionInfo())
.thenReturn(mSecondWifiInfo);
when(mActiveModeWarden.getClientModeManagers()).thenReturn(testClientModeManagers);
// TEST_SUPPORTED_5G_CHANNELS = 36, 149, mark to unsafe. Let Wifi connect to 5200 (CH40)
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 44c46634b1..4f44d4a2b1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
@@ -74,6 +74,8 @@ import android.hardware.wifi.supplicant.IfaceInfo;
import android.hardware.wifi.supplicant.IfaceType;
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.OceRssiBasedAssocRejectAttr;
import android.hardware.wifi.supplicant.OsuMethod;
import android.hardware.wifi.supplicant.PortRange;
@@ -129,6 +131,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -142,11 +145,10 @@ import java.util.Set;
*/
@SmallTest
public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
- private static final Map<Integer, String> NETWORK_ID_TO_SSID = new HashMap<Integer, String>() {{
- put(1, "\"ssid1\"");
- put(2, "\"ssid2\"");
- put(3, "\"ssid3\"");
- }};
+ private static final Map<Integer, String> NETWORK_ID_TO_SSID = Map.of(
+ 1, "\"ssid1\"",
+ 2, "\"ssid2\"",
+ 3, "\"ssid3\"");
private static final int SUPPLICANT_NETWORK_ID = 2;
private static final String SUPPLICANT_SSID = NETWORK_ID_TO_SSID.get(SUPPLICANT_NETWORK_ID);
private static final WifiSsid TRANSLATED_SUPPLICANT_SSID =
@@ -231,6 +233,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
mIfaceInfoList[2] = createIfaceInfo(IfaceType.P2P, P2P_IFACE_NAME);
doReturn(CONNECTED_MAC_ADDRESS_BYTES).when(mISupplicantStaIfaceMock).getMacAddress();
mHandler = spy(new Handler(mLooper.getLooper()));
+ when(mISupplicantMock.asBinder()).thenReturn(mServiceBinderMock);
when(mSsidTranslator.getTranslatedSsid(any())).thenReturn(TRANSLATED_SUPPLICANT_SSID);
when(mSsidTranslator.getOriginalSsid(any())).thenAnswer((Answer<WifiSsid>) invocation ->
WifiSsid.fromString(((WifiConfiguration) invocation.getArgument(0)).SSID));
@@ -991,7 +994,38 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
wifiMonitorInOrder.verify(mWifiMonitor).broadcastNetworkConnectionEvent(
eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), eq(false),
- eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID));
+ eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(null));
+ wifiMonitorInOrder.verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
+ eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
+ eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(SupplicantState.COMPLETED));
+ }
+
+ /**
+ * Tests the handling of state change notification with key management
+ * to completed after configuring a network.
+ */
+ @Test
+ public void testStateChangeToCompletedCallbackWithAkm() throws Exception {
+ InOrder wifiMonitorInOrder = inOrder(mWifiMonitor);
+ executeAndValidateInitializationSequence();
+ int frameworkNetworkId = 6;
+ executeAndValidateConnectSequence(frameworkNetworkId, false,
+ TRANSLATED_SUPPLICANT_SSID.toString());
+ assertNotNull(mISupplicantStaIfaceCallback);
+
+ int supplicantAkmMask = android.hardware.wifi.supplicant.KeyMgmtMask.WPA_PSK;
+ BitSet expectedAkmMask = new BitSet();
+ expectedAkmMask.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+
+ mISupplicantStaIfaceCallback.onStateChangedWithAkm(
+ StaIfaceCallbackState.COMPLETED,
+ NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
+ NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(SUPPLICANT_SSID)), false,
+ supplicantAkmMask);
+
+ wifiMonitorInOrder.verify(mWifiMonitor).broadcastNetworkConnectionEvent(
+ eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), eq(false),
+ eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(expectedAkmMask));
wifiMonitorInOrder.verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(SupplicantState.COMPLETED));
@@ -1446,7 +1480,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
assertTrue(mDut.isInitializationComplete());
assertTrue(mDut.registerDeathHandler(mSupplicantHalDeathHandler));
- mSupplicantDeathCaptor.getValue().binderDied();
+ mSupplicantDeathCaptor.getValue().binderDied(mServiceBinderMock);
mLooper.dispatchAll();
assertFalse(mDut.isInitializationComplete());
@@ -1478,7 +1512,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
// Now trigger a death notification and ensure it's handled.
assertNotNull(mSupplicantDeathCaptor.getValue());
- mSupplicantDeathCaptor.getValue().binderDied();
+ mSupplicantDeathCaptor.getValue().binderDied(mServiceBinderMock);
mLooper.dispatchAll();
// External death notification fires only once!
@@ -1641,7 +1675,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
// Check that all internal state is cleared once the death notification is received.
assertTrue(mDut.isInitializationComplete());
- mSupplicantDeathCaptor.getValue().binderDied();
+ mSupplicantDeathCaptor.getValue().binderDied(mServiceBinderMock);
assertFalse(mDut.isInitializationComplete());
}
@@ -2123,7 +2157,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
wifiMonitorInOrder.verify(mWifiMonitor).broadcastNetworkConnectionEvent(
eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), eq(true),
- eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID));
+ eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(null));
wifiMonitorInOrder.verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
eq(TRANSLATED_SUPPLICANT_SSID), eq(BSSID), eq(SupplicantState.COMPLETED));
@@ -2803,4 +2837,63 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
}
return true;
}
+
+ /**
+ * Test getConnectionMloLinkInfo returns WifiNative.ConnectionMloLinksInfo from interface name.
+ */
+ @Test
+ public void testGetConnectionMloLinksInfo() throws Exception {
+ final int mDownlinkTid = 3;
+ final int mUplinkTid = 6;
+ // initialize MLO Links
+ MloLinksInfo info = new MloLinksInfo();
+ MloLink[] links = new MloLink[3];
+ links[0] = new android.hardware.wifi.supplicant.MloLink();
+ links[0].linkId = 1;
+ links[0].staLinkMacAddress = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x01};
+ links[0].tidsDownlinkMap = Byte.MAX_VALUE;
+ links[0].tidsDownlinkMap = Byte.MIN_VALUE;
+ links[1] = new android.hardware.wifi.supplicant.MloLink();
+ links[1].linkId = 2;
+ links[1].staLinkMacAddress = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x02};
+ links[1].tidsDownlinkMap = 1 << mDownlinkTid;
+ links[1].tidsUplinkMap = 1 << mUplinkTid;
+ links[2] = new android.hardware.wifi.supplicant.MloLink();
+ links[2].linkId = 3;
+ links[2].staLinkMacAddress = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x03};
+ links[2].tidsDownlinkMap = 0;
+ links[2].tidsUplinkMap = 0;
+ info.links = links;
+ executeAndValidateInitializationSequence();
+ // Mock MloLinksInfo as null.
+ when(mISupplicantStaIfaceMock.getConnectionMloLinksInfo()).thenReturn(null);
+ // Pass wrong interface.
+ assertNull(mDut.getConnectionMloLinksInfo(WLAN1_IFACE_NAME));
+ // Pass correct interface.
+ assertNull(mDut.getConnectionMloLinksInfo(WLAN0_IFACE_NAME));
+ // Mock MloLinksInfo.
+ when(mISupplicantStaIfaceMock.getConnectionMloLinksInfo()).thenReturn(info);
+ // Pass wrong interface with mock MloLinksInfo.
+ assertNull(mDut.getConnectionMloLinksInfo(WLAN1_IFACE_NAME));
+ // Pass correct interface with mock MloLinksInfo.
+ WifiNative.ConnectionMloLinksInfo nativeInfo = mDut.getConnectionMloLinksInfo(
+ WLAN0_IFACE_NAME);
+ // Check all return values.
+ assertNotNull(nativeInfo);
+ assertEquals(nativeInfo.links.length, info.links.length);
+ assertEquals(nativeInfo.links[0].getLinkId(), info.links[0].linkId);
+ assertEquals(nativeInfo.links[0].getMacAddress(),
+ MacAddress.fromBytes(info.links[0].staLinkMacAddress));
+ assertTrue(nativeInfo.links[0].isAnyTidMapped());
+ assertEquals(nativeInfo.links[1].getLinkId(), info.links[1].linkId);
+ assertEquals(nativeInfo.links[1].getMacAddress(),
+ MacAddress.fromBytes(info.links[1].staLinkMacAddress));
+ assertTrue(nativeInfo.links[1].isAnyTidMapped());
+ assertTrue(nativeInfo.links[1].isTidMappedtoDownlink((byte) mDownlinkTid));
+ assertTrue(nativeInfo.links[1].isTidMappedToUplink((byte) mUplinkTid));
+ assertEquals(nativeInfo.links[2].getLinkId(), info.links[2].linkId);
+ assertEquals(nativeInfo.links[2].getMacAddress(),
+ MacAddress.fromBytes(info.links[2].staLinkMacAddress));
+ assertFalse(nativeInfo.links[2].isAnyTidMapped());
+ }
}
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 87d881cffb..be9a64378e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
@@ -118,11 +118,10 @@ import java.util.Random;
*/
@SmallTest
public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
- private static final Map<Integer, String> NETWORK_ID_TO_SSID = new HashMap<Integer, String>() {{
- put(1, "\"ssid1\"");
- put(2, "\"ssid2\"");
- put(3, "\"ssid3\"");
- }};
+ private static final Map<Integer, String> NETWORK_ID_TO_SSID = Map.of(
+ 1, "\"ssid1\"",
+ 2, "\"ssid2\"",
+ 3, "\"ssid3\"");
private static final int SUPPLICANT_NETWORK_ID = 2;
private static final String SUPPLICANT_SSID = NETWORK_ID_TO_SSID.get(SUPPLICANT_NETWORK_ID);
private static final WifiSsid TRANSLATED_SUPPLICANT_SSID =
@@ -2035,13 +2034,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
public void testTerminateV1_0() throws Exception {
executeAndValidateInitializationSequence();
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public boolean answer(IHwBinder.DeathRecipient cb, long cookie) throws RemoteException {
- mHandler.post(() -> cb.serviceDied(cookie));
- return true;
- }
- }).when(mISupplicantMock).linkToDeath(any(IHwBinder.DeathRecipient.class), any(long.class));
mDut.terminate();
+ mSupplicantDeathCaptor.getValue().serviceDied(mDeathRecipientCookieCaptor.getValue());
mLooper.dispatchAll();
verify(mFrameworkFacade).stopSupplicant();
@@ -2057,16 +2051,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
setupMocksForHalV1_1();
executeAndValidateInitializationSequenceV1_1(false, false);
-
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public boolean answer(IHwBinder.DeathRecipient cb, long cookie) throws RemoteException {
- mHandler.post(() -> cb.serviceDied(cookie));
- return true;
- }
- }).when(mISupplicantMockV11).linkToDeath(any(IHwBinder.DeathRecipient.class),
- any(long.class));
-
mDut.terminate();
+ mSupplicantDeathCaptor.getValue().serviceDied(mDeathRecipientCookieCaptor.getValue());
mLooper.dispatchAll();
verify(mFrameworkFacade, never()).stopSupplicant();
verify(mISupplicantMockV11).terminate();
@@ -2797,7 +2783,7 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
assertTrue(mDut.isInitializationComplete());
assertTrue(mDut.setupIface(WLAN0_IFACE_NAME) == shouldSucceed);
mInOrder.verify(mISupplicantMockV11).linkToDeath(mSupplicantDeathCaptor.capture(),
- anyLong());
+ mDeathRecipientCookieCaptor.capture());
// verify: addInterface is called
mInOrder.verify(mISupplicantMockV11)
.addInterface(any(ISupplicant.IfaceInfo.class),
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 500ceaeb13..bd528df028 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
@@ -46,6 +47,7 @@ import android.hardware.wifi.supplicant.NetworkResponseEapSimUmtsAuthParams;
import android.hardware.wifi.supplicant.PairwiseCipherMask;
import android.hardware.wifi.supplicant.SaeH2eMode;
import android.hardware.wifi.supplicant.SupplicantStatusCode;
+import android.hardware.wifi.supplicant.TlsVersion;
import android.net.wifi.SecurityParams;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
@@ -99,6 +101,7 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
@Mock private WifiMonitor mWifiMonitor;
@Mock private WifiGlobals mWifiGlobals;
private long mAdvanceKeyMgmtFeatures = 0;
+ private long mWpaDriverFeatures = 0;
private SupplicantNetworkVariables mSupplicantVariables;
private MockResources mResources;
@@ -115,9 +118,9 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
mAdvanceKeyMgmtFeatures |= WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
- mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(
+ mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(1,
mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor,
- mWifiGlobals, mAdvanceKeyMgmtFeatures);
+ mWifiGlobals, mAdvanceKeyMgmtFeatures, mWpaDriverFeatures);
}
/**
@@ -751,6 +754,98 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
}
/**
+ * Tests ciphers are merged when the device supports auto upgrade offload feature
+ * and when candidate security type is PSK.
+ */
+ @Test
+ public void testCiphersMergedWhenAutoUpgradeOffloadIsSupportedAndPskSelected()
+ throws Exception {
+ when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_PSK));
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ assertEquals(PairwiseCipherMask.CCMP | PairwiseCipherMask.TKIP
+ | PairwiseCipherMask.GCMP_128 | PairwiseCipherMask.GCMP_256,
+ mSupplicantVariables.pairwiseCipherMask);
+ assertEquals(GroupCipherMask.CCMP | GroupCipherMask.TKIP
+ | GroupCipherMask.WEP40 | GroupCipherMask.WEP104
+ | GroupCipherMask.GCMP_128 | GroupCipherMask.GCMP_256,
+ mSupplicantVariables.groupCipherMask);
+ }
+
+ /**
+ * Tests ciphers are not changed when the device does not supports auto upgrade offload feature
+ * and when candidate security type is PSK.
+ */
+ @Test
+ public void testCiphersNotChangedWhenAutoUpgradeOffloadNotSupportedAndPskSelected()
+ throws Exception {
+ when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(false);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_PSK));
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ assertEquals(PairwiseCipherMask.CCMP | PairwiseCipherMask.TKIP,
+ mSupplicantVariables.pairwiseCipherMask);
+ assertEquals(GroupCipherMask.CCMP | GroupCipherMask.TKIP
+ | GroupCipherMask.WEP40 | GroupCipherMask.WEP104,
+ mSupplicantVariables.groupCipherMask);
+ }
+
+ /**
+ * Tests ciphers are merged when the device supports auto upgrade offload feature
+ * and when candidate security type is SAE.
+ */
+ @Test
+ public void testCiphersMergedWhenAutoUpgradeOffloadIsSupportedAndSaeSelected()
+ throws Exception {
+ when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_SAE));
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ assertEquals(PairwiseCipherMask.CCMP | PairwiseCipherMask.TKIP
+ | PairwiseCipherMask.GCMP_128 | PairwiseCipherMask.GCMP_256,
+ mSupplicantVariables.pairwiseCipherMask);
+ assertEquals(GroupCipherMask.CCMP | GroupCipherMask.TKIP
+ | GroupCipherMask.WEP40 | GroupCipherMask.WEP104
+ | GroupCipherMask.GCMP_128 | GroupCipherMask.GCMP_256,
+ mSupplicantVariables.groupCipherMask);
+ }
+
+ /**
+ * Tests ciphers are not changed when the device does not supports auto upgrade offload feature
+ * and when candidate security type is SAE.
+ */
+ @Test
+ public void testCiphersNotChangedWhenAutoUpgradeOffloadNotSupportedAndSaeSelected()
+ throws Exception {
+ when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(false);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_SAE));
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ assertEquals(PairwiseCipherMask.CCMP | PairwiseCipherMask.GCMP_128
+ | PairwiseCipherMask.GCMP_256,
+ mSupplicantVariables.pairwiseCipherMask);
+ assertEquals(GroupCipherMask.CCMP | GroupCipherMask.GCMP_128 | GroupCipherMask.GCMP_256,
+ mSupplicantVariables.groupCipherMask);
+ }
+
+ /**
* Tests the retrieval of WPS NFC token.
*/
@Test
@@ -1075,9 +1170,9 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
public void testSupportedCiphersNoGcmp256() throws Exception {
// Reinitialize mSupplicantNetwork without support for WPA3 SUITE-B
mAdvanceKeyMgmtFeatures = 0;
- mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(
+ mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(1,
mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor,
- mWifiGlobals, mAdvanceKeyMgmtFeatures);
+ mWifiGlobals, mAdvanceKeyMgmtFeatures, mWpaDriverFeatures);
WifiConfiguration config = WifiConfigurationTestUtil.createSaeNetwork();
int expectedHalPairwiseCiphers = getExpectedPairwiseCiphers(config);
expectedHalPairwiseCiphers &= ~PairwiseCipherMask.GCMP_256;
@@ -1135,6 +1230,62 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
}
/**
+ * Tests setting TLS minimum version API with AIDL v1
+ */
+ @Test
+ public void testEapMinimumTlsVersionWifiConfigurationSaveLoadWithAidlV1() throws Exception {
+ // Default is AIDL v1
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
+ config.enterpriseConfig.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_V1_3);
+ // Assume that the default params is used for this test.
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ config.getDefaultSecurityParams());
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+ verify(mISupplicantStaNetworkMock, never()).setMinimumTlsVersionEapPhase1Param(anyInt());
+ }
+
+ /**
+ * Tests setting TLS minimum version API with AIDL v2, but TLS v1.3 is not supported.
+ */
+ @Test
+ public void testEapMinimumTlsVersionWifiConfigurationSaveLoadWithAidlV2TlsV13NotSupported()
+ throws Exception {
+ // Re-init mock to AIDL v2 without TLS v1.3 support.
+ mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(2,
+ mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor,
+ mWifiGlobals, mAdvanceKeyMgmtFeatures, 0);
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
+ config.enterpriseConfig.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_V1_3);
+ // Assume that the default params is used for this test.
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ config.getDefaultSecurityParams());
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+ // Should fallback to TLS v1.2
+ verify(mISupplicantStaNetworkMock).setMinimumTlsVersionEapPhase1Param(TlsVersion.TLS_V1_2);
+ }
+
+ /**
+ * Tests setting TLS minimum version API with AIDL v2, and TLS v1.3 is supported.
+ */
+ @Test
+ public void testEapMinimumTlsVersionWifiConfigurationSaveLoadWithAidlV2TlsV13Supported()
+ throws Exception {
+ // Re-init mock to AIDL v2 with TLS v1.3 support.
+ mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(2,
+ mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor,
+ mWifiGlobals, mAdvanceKeyMgmtFeatures,
+ WifiManager.WIFI_FEATURE_TLS_V1_3);
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
+ config.enterpriseConfig.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_V1_3);
+ // Assume that the default params is used for this test.
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ config.getDefaultSecurityParams());
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+ // Should fallback to TLS v1.2
+ verify(mISupplicantStaNetworkMock).setMinimumTlsVersionEapPhase1Param(TlsVersion.TLS_V1_3);
+ }
+
+ /**
* 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.
*/
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java
index 9f1a5f4644..052eb4673c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java
@@ -1027,6 +1027,130 @@ public class SupplicantStaNetworkHalHidlImplTest extends WifiBaseTest {
}
/**
+ * Tests ciphers are merged when the device supports auto upgrade offload feature
+ * and when candidate security type is PSK.
+ */
+ @Test
+ public void testCiphersMergedWhenAutoUpgradeOffloadIsSupportedAndPskSelected()
+ throws Exception {
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_4);
+ when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_PSK));
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ assertEquals(ISupplicantStaNetwork.PairwiseCipherMask.CCMP
+ | ISupplicantStaNetwork.PairwiseCipherMask.TKIP
+ | android.hardware.wifi.supplicant.V1_4
+ .ISupplicantStaNetwork.PairwiseCipherMask.GCMP_128
+ | android.hardware.wifi.supplicant.V1_2
+ .ISupplicantStaNetwork.PairwiseCipherMask.GCMP_256,
+ mSupplicantVariables.pairwiseCipherMask);
+ assertEquals(ISupplicantStaNetwork.GroupCipherMask.CCMP
+ | ISupplicantStaNetwork.GroupCipherMask.TKIP
+ | ISupplicantStaNetwork.GroupCipherMask.WEP40
+ | ISupplicantStaNetwork.GroupCipherMask.WEP104
+ | android.hardware.wifi.supplicant.V1_4
+ .ISupplicantStaNetwork.GroupCipherMask.GCMP_128
+ | android.hardware.wifi.supplicant.V1_2
+ .ISupplicantStaNetwork.GroupCipherMask.GCMP_256,
+ mSupplicantVariables.groupCipherMask);
+ }
+
+ /**
+ * Tests ciphers are not changed when the device does not supports auto upgrade offload feature
+ * and when candidate security type is PSK.
+ */
+ @Test
+ public void testCiphersNotChangedWhenAutoUpgradeOffloadNotSupportedAndPskSelected()
+ throws Exception {
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_4);
+ when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(false);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_PSK));
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ assertEquals(ISupplicantStaNetwork.PairwiseCipherMask.CCMP
+ | ISupplicantStaNetwork.PairwiseCipherMask.TKIP,
+ mSupplicantVariables.pairwiseCipherMask);
+ assertEquals(ISupplicantStaNetwork.GroupCipherMask.CCMP
+ | ISupplicantStaNetwork.GroupCipherMask.TKIP
+ | ISupplicantStaNetwork.GroupCipherMask.WEP40
+ | ISupplicantStaNetwork.GroupCipherMask.WEP104,
+ mSupplicantVariables.groupCipherMask);
+ }
+
+ /**
+ * Tests ciphers are merged when the device supports auto upgrade offload feature
+ * and when candidate security type is SAE.
+ */
+ @Test
+ public void testCiphersMergedWhenAutoUpgradeOffloadIsSupportedAndSaeSelected()
+ throws Exception {
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_4);
+ when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_SAE));
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ assertEquals(ISupplicantStaNetwork.PairwiseCipherMask.CCMP
+ | ISupplicantStaNetwork.PairwiseCipherMask.TKIP
+ | android.hardware.wifi.supplicant.V1_4
+ .ISupplicantStaNetwork.PairwiseCipherMask.GCMP_128
+ | android.hardware.wifi.supplicant.V1_2
+ .ISupplicantStaNetwork.PairwiseCipherMask.GCMP_256,
+ mSupplicantVariables.pairwiseCipherMask);
+ assertEquals(ISupplicantStaNetwork.GroupCipherMask.CCMP
+ | ISupplicantStaNetwork.GroupCipherMask.TKIP
+ | ISupplicantStaNetwork.GroupCipherMask.WEP40
+ | ISupplicantStaNetwork.GroupCipherMask.WEP104
+ | android.hardware.wifi.supplicant.V1_4
+ .ISupplicantStaNetwork.GroupCipherMask.GCMP_128
+ | android.hardware.wifi.supplicant.V1_2
+ .ISupplicantStaNetwork.GroupCipherMask.GCMP_256,
+ mSupplicantVariables.groupCipherMask);
+ }
+
+ /**
+ * Tests ciphers are not changed when the device does not supports auto upgrade offload feature
+ * and when candidate security type is SAE.
+ */
+ @Test
+ public void testCiphersNotChangedWhenAutoUpgradeOffloadNotSupportedAndSaeSelected()
+ throws Exception {
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_4);
+ when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(false);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskSaeNetwork();
+ config.getNetworkSelectionStatus().setCandidateSecurityParams(
+ SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_SAE));
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ assertEquals(ISupplicantStaNetwork.PairwiseCipherMask.CCMP
+ | android.hardware.wifi.supplicant.V1_4
+ .ISupplicantStaNetwork.PairwiseCipherMask.GCMP_128
+ | android.hardware.wifi.supplicant.V1_2
+ .ISupplicantStaNetwork.PairwiseCipherMask.GCMP_256,
+ mSupplicantVariables.pairwiseCipherMask);
+ assertEquals(ISupplicantStaNetwork.GroupCipherMask.CCMP
+ | android.hardware.wifi.supplicant.V1_4
+ .ISupplicantStaNetwork.GroupCipherMask.GCMP_128
+ | android.hardware.wifi.supplicant.V1_2
+ .ISupplicantStaNetwork.GroupCipherMask.GCMP_256,
+ mSupplicantVariables.groupCipherMask);
+ }
+
+ /**
* Tests the retrieval of WPS NFC token.
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
index acd2b923e5..0023ebfb98 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
@@ -497,10 +497,9 @@ public class WakeupControllerTest extends WifiBaseTest {
unknownScanResult));
// intersection of most recent scan + saved configs/suggestions
- Set<ScanResultMatchInfo> expectedMatchInfos = new HashSet<ScanResultMatchInfo>() {{
- add(ScanResultMatchInfo.fromScanResult(savedScanResult));
- add(ScanResultMatchInfo.fromScanResult(suggestionScanResult));
- }};
+ Set<ScanResultMatchInfo> expectedMatchInfos = Set.of(
+ ScanResultMatchInfo.fromScanResult(savedScanResult),
+ ScanResultMatchInfo.fromScanResult(suggestionScanResult));
initializeWakeupController(true /* enabled */);
mWakeupController.start();
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 cd9938fb14..57d2f00eb6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
@@ -1067,9 +1067,7 @@ public class WifiBackupRestoreTest extends WifiBaseTest {
expectedConfiguration.preSharedKey = WifiConfigurationTestUtil.TEST_PSK;
expectedConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- ArrayList<WifiConfiguration> expectedConfigurations = new ArrayList<WifiConfiguration>() {{
- add(expectedConfiguration);
- }};
+ List<WifiConfiguration> expectedConfigurations = List.of(expectedConfiguration);
WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
expectedConfigurations, retrievedConfigurations);
}
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 6000573073..5b9faf9844 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiBlocklistMonitorTest.java
@@ -48,6 +48,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -80,6 +81,8 @@ public class WifiBlocklistMonitorTest {
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);
+ private static final long BASE_VALIDATION_FAILURE_BSSID_BLOCKLIST_DURATION =
+ TimeUnit.SECONDS.toMillis(60);
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;
@@ -100,6 +103,29 @@ public class WifiBlocklistMonitorTest {
Map.entry(WifiBlocklistMonitor.REASON_NONLOCAL_DISCONNECT_CONNECTING, 2),
Map.entry(WifiBlocklistMonitor.REASON_FAILURE_NO_RESPONSE, 1)
);
+ private static final Map<Integer, Integer> CONFIG_DISABLE_REASON_TO_THRESHOLD_OVERLAY_MAP =
+ Map.ofEntries(
+ Map.entry(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION,
+ R.integer.config_wifiDisableReasonAssociationRejectionThreshold),
+ Map.entry(NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE,
+ R.integer.config_wifiDisableReasonAuthenticationFailureThreshold),
+ Map.entry(NetworkSelectionStatus.DISABLED_DHCP_FAILURE,
+ R.integer.config_wifiDisableReasonDhcpFailureThreshold),
+ Map.entry(NetworkSelectionStatus.DISABLED_NETWORK_NOT_FOUND,
+ R.integer.config_wifiDisableReasonNetworkNotFoundThreshold),
+ Map.entry(NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY,
+ R.integer.config_wifiDisableReasonNoInternetTemporaryThreshold),
+ Map.entry(NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_CREDENTIALS,
+ R.integer.config_wifiDisableReasonAuthenticationNoCredentialsThreshold),
+ Map.entry(NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT,
+ R.integer.config_wifiDisableReasonNoInternetPermanentThreshold),
+ Map.entry(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD,
+ R.integer.config_wifiDisableReasonByWrongPasswordThreshold),
+ Map.entry(NetworkSelectionStatus.DISABLED_CONSECUTIVE_FAILURES,
+ R.integer.config_wifiDisableReasonConsecutiveFailuresThreshold),
+ Map.entry(NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_SUBSCRIPTION,
+ R.integer.config_wifiDisableReasonAuthenticationNoSubscriptionThreshold)
+ );
private static final int NUM_FAILURES_TO_BLOCKLIST =
BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(TEST_L2_FAILURE);
@@ -112,6 +138,7 @@ public class WifiBlocklistMonitorTest {
@Mock private ScoringParams mScoringParams;
@Mock private WifiMetrics mWifiMetrics;
@Mock private WifiPermissionsUtil mWifiPermissionsUtil;
+ @Mock private ScanRequestProxy mScanRequestProxy;
@Mock private WifiScoreCard.PerNetwork mPerNetwork;
@Mock private WifiScoreCard.NetworkConnectionStats mRecentStats;
@@ -135,6 +162,9 @@ public class WifiBlocklistMonitorTest {
mResources.setInteger(
R.integer.config_wifiBssidBlocklistMonitorConnectedScoreBaseBlockDurationMs,
(int) BASE_CONNECTED_SCORE_BLOCKLIST_DURATION);
+ mResources.setInteger(
+ R.integer.config_wifiBssidBlocklistMonitorValidationFailureBaseBlockDurationMs,
+ (int) BASE_VALIDATION_FAILURE_BSSID_BLOCKLIST_DURATION);
mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorFailureStreakCap,
FAILURE_STREAK_CAP);
mResources.setInteger(R.integer.config_wifiBssidBlocklistAbnormalDisconnectTimeWindowMs,
@@ -181,24 +211,35 @@ public class WifiBlocklistMonitorTest {
BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
WifiBlocklistMonitor.REASON_FAILURE_NO_RESPONSE));
+ for (Map.Entry<Integer, Integer> entry :
+ CONFIG_DISABLE_REASON_TO_THRESHOLD_OVERLAY_MAP.entrySet()) {
+ mResources.setInteger(
+ entry.getValue(),
+ NetworkSelectionStatus.DISABLE_REASON_INFOS.get(entry.getKey())
+ .mDisableThreshold);
+ }
+
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonNoInternetTemporaryDurationMs, 600000);
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonAssociationRejectionDurationMs, 300000);
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonAuthenticationFailureDurationMs, 300000);
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonDhcpFailureDurationMs, 300000);
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonNetworkNotFoundDurationMs, 300000);
mResources.setInteger(
- R.integer.config_wifiDisableReasonAssociationRejectionThreshold,
- NetworkSelectionStatus.DISABLE_REASON_INFOS
- .get(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION)
- .mDisableThreshold);
+ R.integer.config_wifiDisableReasonConsecutiveFailuresDurationMs, 300000);
mResources.setInteger(
- R.integer.config_wifiDisableReasonAuthenticationFailureThreshold,
- NetworkSelectionStatus.DISABLE_REASON_INFOS
- .get(NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE)
- .mDisableThreshold);
+ R.integer.config_wifiDisableReasonAuthenticationNoCredentialsDurationMs, -1);
mResources.setInteger(
- R.integer.config_wifiDisableReasonDhcpFailureThreshold,
- NetworkSelectionStatus.DISABLE_REASON_INFOS
- .get(NetworkSelectionStatus.DISABLED_DHCP_FAILURE).mDisableThreshold);
+ R.integer.config_wifiDisableReasonNoInternetPermanentDurationMs, -1);
mResources.setInteger(
- R.integer.config_wifiDisableReasonNetworkNotFoundThreshold,
- NetworkSelectionStatus.DISABLE_REASON_INFOS
- .get(NetworkSelectionStatus.DISABLED_NETWORK_NOT_FOUND).mDisableThreshold);
+ R.integer.config_wifiDisableReasonByWrongPasswordDurationMs, -1);
+ mResources.setInteger(
+ R.integer.config_wifiDisableReasonAuthenticationNoSubscriptionDurationMs, -1);
+
when(mContext.getResources()).thenReturn(mResources);
when(mPerNetwork.getRecentStats()).thenReturn(mRecentStats);
when(mWifiScoreCard.lookupNetwork(anyString())).thenReturn(mPerNetwork);
@@ -208,6 +249,7 @@ public class WifiBlocklistMonitorTest {
mWifiBlocklistMonitor = new WifiBlocklistMonitor(mContext, mWifiConnectivityHelper,
mWifiLastResortWatchdog, mClock, mLocalLog, mWifiScoreCard, mScoringParams,
mWifiMetrics, mWifiPermissionsUtil);
+ mWifiBlocklistMonitor.setScanRequestProxy(mScanRequestProxy);
}
private void verifyAddTestBssidToBlocklist() {
@@ -719,7 +761,8 @@ public class WifiBlocklistMonitorTest {
verify(mWifiMetrics).incrementBssidBlocklistCount(reason);
// Verify that TEST_BSSID_1 is removed from the blocklist after the timeout duration.
- when(mClock.getWallClockMillis()).thenReturn(BASE_BLOCKLIST_DURATION + 1);
+ when(mClock.getWallClockMillis()).thenReturn(
+ getExpectedBaseBssidBlockDurationMillis(reason) + 1);
assertEquals(0, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
// But the blocklist streak count is not cleared
@@ -728,6 +771,17 @@ public class WifiBlocklistMonitorTest {
}
}
+ private long getExpectedBaseBssidBlockDurationMillis(int blockReason) {
+ switch (blockReason) {
+ case WifiBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE:
+ return BASE_CONNECTED_SCORE_BLOCKLIST_DURATION;
+ case WifiBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE:
+ return BASE_VALIDATION_FAILURE_BSSID_BLOCKLIST_DURATION;
+ default:
+ return BASE_BLOCKLIST_DURATION;
+ }
+ }
+
/**
* Verify that when a failure signal is received for a BSSID with different SSID from before,
* then the failure counts are reset.
@@ -922,6 +976,230 @@ public class WifiBlocklistMonitorTest {
}
/**
+ * Verify that blockBssidForDurationMs adds a BSSID, and it's affiliated BSSIDs to blocklist for
+ * the specified duration.
+ */
+ @Test
+ public void testBlockAffiliatedBssidsForDurationMs() {
+ List<String> bssidList = Arrays.asList(TEST_BSSID_2, TEST_BSSID_3);
+ // Affiliated BSSID mapping: TEST_BSSID_1 -> {TEST_BSSID_2, TEST_BSSID_3}
+ mWifiBlocklistMonitor.setAffiliatedBssids(TEST_BSSID_1, bssidList);
+
+ // Add to block list
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID_1);
+ when(mClock.getWallClockMillis()).thenReturn(0L);
+ long testDuration = 5500L;
+ mWifiBlocklistMonitor.blockBssidForDurationMs(TEST_BSSID_1, config, testDuration,
+ TEST_FRAMEWORK_BLOCK_REASON, TEST_GOOD_RSSI);
+ assertEquals(3, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+
+ // Verify that the BSSIDs are removed from blocklist by clearBssidBlocklistForSsid
+ mWifiBlocklistMonitor.clearBssidBlocklistForSsid(TEST_SSID_1);
+ assertEquals(0, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+
+ // Add to blocklist again.
+ mWifiBlocklistMonitor.blockBssidForDurationMs(TEST_BSSID_1, config, testDuration,
+ TEST_FRAMEWORK_BLOCK_REASON, TEST_GOOD_RSSI);
+ assertEquals(3, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+
+ // Verify that the BSSIDs are removed from blocklist once the specified duration is over.
+ when(mClock.getWallClockMillis()).thenReturn(testDuration + 1);
+ assertEquals(0, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+ }
+
+ /**
+ * Verify that connection failure block list all affiliated bssids.
+ */
+ @Test
+ public void testHandleAffiliatedBssidsConnectionFailure() {
+ List<String> bssidList = Arrays.asList(TEST_BSSID_2, TEST_BSSID_3);
+ // Affiliated BSSID mapping: TEST_BSSID_1 -> {TEST_BSSID_2, TEST_BSSID_3}
+ mWifiBlocklistMonitor.setAffiliatedBssids(TEST_BSSID_1, bssidList);
+
+ // Connection failure, reason REASON_AP_UNABLE_TO_HANDLE_NEW_STA
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID_1);
+ mWifiBlocklistMonitor.handleBssidConnectionFailure(
+ TEST_BSSID_1, config,
+ WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA, TEST_GOOD_RSSI);
+
+ // Make sure affiliated BSSIDs are also in the block list
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_1));
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_2));
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_3));
+
+ // Verify incrementBssidBlocklistStreak() API is called
+ verify(mWifiScoreCard).incrementBssidBlocklistStreak(TEST_SSID_1,
+ TEST_BSSID_1, WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA);
+ verify(mWifiScoreCard).incrementBssidBlocklistStreak(TEST_SSID_1,
+ TEST_BSSID_2, WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA);
+ verify(mWifiScoreCard).incrementBssidBlocklistStreak(TEST_SSID_1,
+ TEST_BSSID_3, WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA);
+ }
+
+ private void verifyResetBssidBlockStreak(String ssid, String bssid) {
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(ssid, bssid,
+ WifiBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(ssid, bssid,
+ WifiBlocklistMonitor.REASON_WRONG_PASSWORD);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(ssid, bssid,
+ WifiBlocklistMonitor.REASON_EAP_FAILURE);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(ssid, bssid,
+ WifiBlocklistMonitor.REASON_ASSOCIATION_REJECTION);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(ssid, bssid,
+ WifiBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(ssid, bssid,
+ WifiBlocklistMonitor.REASON_AUTHENTICATION_FAILURE);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(ssid, bssid,
+ WifiBlocklistMonitor.REASON_ABNORMAL_DISCONNECT);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(ssid, bssid,
+ WifiBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(ssid, bssid,
+ WifiBlocklistMonitor.REASON_NONLOCAL_DISCONNECT_CONNECTING);
+ }
+
+ /**
+ * Verify that connection success clears the block list for all affiliated bssids.
+ */
+ @Test
+ public void testHandleAffiliatedBssidConnectionSuccess() {
+ List<String> bssidList = Arrays.asList(TEST_BSSID_2, TEST_BSSID_3);
+ // Affiliated BSSID mapping: TEST_BSSID_1 -> {TEST_BSSID_2, TEST_BSSID_3}
+ mWifiBlocklistMonitor.setAffiliatedBssids(TEST_BSSID_1, bssidList);
+
+ // Multiple failures, add bssid to block list along with affiliated bssids
+ handleBssidConnectionFailureMultipleTimes(TEST_BSSID_1, TEST_L2_FAILURE,
+ NUM_FAILURES_TO_BLOCKLIST);
+ when(mClock.getWallClockMillis()).thenReturn(ABNORMAL_DISCONNECT_RESET_TIME_MS + 1);
+
+ // Connection success
+ mWifiBlocklistMonitor.handleBssidConnectionSuccess(TEST_BSSID_1, TEST_SSID_1);
+
+ // Verify resetBssidBlocklistStreak() API is called
+ verifyResetBssidBlockStreak(TEST_SSID_1, TEST_BSSID_1);
+ verifyResetBssidBlockStreak(TEST_SSID_1, TEST_BSSID_2);
+ verifyResetBssidBlockStreak(TEST_SSID_1, TEST_BSSID_3);
+
+ verify(mWifiScoreCard).setBssidConnectionTimestampMs(TEST_SSID_1, TEST_BSSID_1,
+ ABNORMAL_DISCONNECT_RESET_TIME_MS + 1);
+ verify(mWifiScoreCard).setBssidConnectionTimestampMs(TEST_SSID_1, TEST_BSSID_2,
+ ABNORMAL_DISCONNECT_RESET_TIME_MS + 1);
+ verify(mWifiScoreCard).setBssidConnectionTimestampMs(TEST_SSID_1, TEST_BSSID_3,
+ ABNORMAL_DISCONNECT_RESET_TIME_MS + 1);
+
+ }
+
+ /**
+ * Verify that network validation success clears the block list for all affiliated bssids.
+ */
+ @Test
+ public void testHandleNetworkValidationSuccess() {
+ List<String> bssidList = Arrays.asList(TEST_BSSID_2, TEST_BSSID_3);
+ // Affiliated BSSID mapping: TEST_BSSID_1 -> {TEST_BSSID_2, TEST_BSSID_3}
+ mWifiBlocklistMonitor.setAffiliatedBssids(TEST_BSSID_1, bssidList);
+
+ // Add to block list with reason code REASON_AP_UNABLE_TO_HANDLE_NEW_STA
+ verifyAddTestBssidToBlocklist();
+
+ // Network validation success resets with resetBssidBlocklistStreak()
+ mWifiBlocklistMonitor.handleNetworkValidationSuccess(TEST_BSSID_1, TEST_SSID_1);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1,
+ WifiBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_2,
+ WifiBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_3,
+ WifiBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE);
+
+ // All BSSID's are removed from block list
+ assertEquals(0, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+ }
+
+ /**
+ * Verify that DHCP provisioning success clears the block list for all affiliated bssids.
+ */
+ @Test
+ public void testHandleDhcpProvisioningSuccess() {
+ List<String> bssidList = Arrays.asList(TEST_BSSID_2, TEST_BSSID_3);
+ // Affiliated BSSID mapping: TEST_BSSID_1 -> {TEST_BSSID_2, TEST_BSSID_3}
+ mWifiBlocklistMonitor.setAffiliatedBssids(TEST_BSSID_1, bssidList);
+
+ // DHCP failures leads to block list
+ handleBssidConnectionFailureMultipleTimes(TEST_BSSID_1, TEST_DHCP_FAILURE,
+ NUM_FAILURES_TO_BLOCKLIST);
+ assertEquals(3, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+
+ // DHCP success clears appropriate failure counters
+ mWifiBlocklistMonitor.handleDhcpProvisioningSuccess(TEST_BSSID_1, TEST_SSID_1);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1,
+ WifiBlocklistMonitor.REASON_DHCP_FAILURE);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_2,
+ WifiBlocklistMonitor.REASON_DHCP_FAILURE);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_3,
+ WifiBlocklistMonitor.REASON_DHCP_FAILURE);
+ }
+
+ @Test
+ public void testReadRssiFromLatestScanResultsWhenInvalid() {
+ // mock latest scan results with GOOD RSSI for TEST_BSSID_1
+ ScanResult fakeScanResult = mock(ScanResult.class);
+ fakeScanResult.level = TEST_GOOD_RSSI;
+ when(mScanRequestProxy.getScanResult(TEST_BSSID_1)).thenReturn(fakeScanResult);
+
+ // verify TEST_BSSID_1, 2 and 3 are block listed after connection failure using
+ // INVALID RSSI.
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID_1);
+ when(mClock.getWallClockMillis()).thenReturn(0L);
+ mWifiBlocklistMonitor.handleBssidConnectionFailure(
+ TEST_BSSID_1, config, WifiBlocklistMonitor.REASON_EAP_FAILURE,
+ WifiConfiguration.INVALID_RSSI);
+ mWifiBlocklistMonitor.handleBssidConnectionFailure(
+ TEST_BSSID_2, config, WifiBlocklistMonitor.REASON_EAP_FAILURE,
+ WifiConfiguration.INVALID_RSSI);
+ mWifiBlocklistMonitor.handleBssidConnectionFailure(
+ TEST_BSSID_3, config, WifiBlocklistMonitor.REASON_EAP_FAILURE,
+ WifiConfiguration.INVALID_RSSI);
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_1));
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_2));
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_3));
+ assertEquals(3, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+
+ // Simulate both TEST_BSSID_1 and TEST_BSSID_2 improving RSSI, but only TEST_BSSID_2 should
+ // be removed from blocklist.
+ List<ScanDetail> enabledDetails = simulateRssiUpdate(TEST_BSSID_1, TEST_GOOD_RSSI);
+ assertEquals(0, enabledDetails.size());
+ assertEquals(3, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+
+ enabledDetails = simulateRssiUpdate(TEST_BSSID_2, TEST_GOOD_RSSI);
+ assertEquals(1, enabledDetails.size());
+ assertEquals(2, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+ }
+
+ /**
+ * Verify that if the RSSI is low when the BSSID is blocked, a RSSI improvement to sufficient
+ * RSSI will remove the BSSID from blocklist along with affiliated BSSIDs.
+ */
+ @Test
+ public void testUnblockAffiliatedBssidAfterRssiBreachSufficient() {
+ List<String> bssidList = Arrays.asList(TEST_BSSID_2, TEST_BSSID_3);
+ // Affiliated BSSID mapping: TEST_BSSID_1 -> {TEST_BSSID_2, TEST_BSSID_3}
+ mWifiBlocklistMonitor.setAffiliatedBssids(TEST_BSSID_1, bssidList);
+
+ // verify TEST_BSSID_1, 2 and 3 are block listed after connection failure
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID_1);
+ when(mClock.getWallClockMillis()).thenReturn(0L);
+ mWifiBlocklistMonitor.handleBssidConnectionFailure(
+ TEST_BSSID_1, config, WifiBlocklistMonitor.REASON_EAP_FAILURE,
+ TEST_SUFFICIENT_RSSI - MIN_RSSI_DIFF_TO_UNBLOCK_BSSID);
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_1));
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_2));
+ assertTrue(mWifiBlocklistMonitor.updateAndGetBssidBlocklist().contains(TEST_BSSID_3));
+
+ // verify TEST_BSSID_1 is removed from the blocklist after RSSI improves
+ List<ScanDetail> enabledDetails = simulateRssiUpdate(TEST_BSSID_1, TEST_SUFFICIENT_RSSI);
+ assertEquals(1, enabledDetails.size());
+ assertEquals(0, mWifiBlocklistMonitor.updateAndGetBssidBlocklist().size());
+ }
+
+ /**
* Verify that |blockBssidForDurationMs| adds a BSSID to blocklist for the specified duration.
*/
@Test
@@ -1069,6 +1347,7 @@ public class WifiBlocklistMonitorTest {
/**
* Verify the failure reasons for all blocked BSSIDs are retrieved.
*/
+ @SuppressWarnings("ReturnValueIgnored")
@Test
public void testGetFailureReasonsForSsid() {
WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork(TEST_SSID_1);
@@ -1383,23 +1662,47 @@ public class WifiBlocklistMonitorTest {
*/
@Test
public void testNetworkSelectionDisableReasonCustomConfigOverride() {
- int oldThreshold = NetworkSelectionStatus.DISABLE_REASON_INFOS
- .get(NetworkSelectionStatus.DISABLED_DHCP_FAILURE).mDisableThreshold;
-
- // Modify the overlay value and create WifiConfigManager again.
- int newThreshold = oldThreshold + 1;
- mResources.setInteger(
- R.integer.config_wifiDisableReasonDhcpFailureThreshold, newThreshold);
- mWifiBlocklistMonitor = new WifiBlocklistMonitor(mContext, mWifiConnectivityHelper,
- mWifiLastResortWatchdog, mClock, mLocalLog, mWifiScoreCard, mScoringParams,
- mWifiMetrics, mWifiPermissionsUtil);
+ for (Map.Entry<Integer, Integer> entry :
+ CONFIG_DISABLE_REASON_TO_THRESHOLD_OVERLAY_MAP.entrySet()) {
+ int disableReason = entry.getKey();
+ int oldThreshold = NetworkSelectionStatus.DISABLE_REASON_INFOS
+ .get(disableReason).mDisableThreshold;
+ assertEquals(oldThreshold, mWifiBlocklistMonitor.getNetworkSelectionDisableThreshold(
+ disableReason));
+ assertEquals(getExpectedBaseConfigDisableTimeoutMillis(disableReason),
+ mWifiBlocklistMonitor.getNetworkSelectionDisableTimeoutMillis(disableReason));
+
+ // Modify the overlay value and create WifiConfigManager again.
+ int newThreshold = oldThreshold + 1;
+ mResources.setInteger(entry.getValue(), newThreshold);
+ mWifiBlocklistMonitor = new WifiBlocklistMonitor(mContext, mWifiConnectivityHelper,
+ mWifiLastResortWatchdog, mClock, mLocalLog, mWifiScoreCard, mScoringParams,
+ mWifiMetrics, mWifiPermissionsUtil);
+ mWifiBlocklistMonitor.setScanRequestProxy(mScanRequestProxy);
+
+ // Verify that the threshold is updated in the copied version
+ assertEquals(newThreshold, mWifiBlocklistMonitor.getNetworkSelectionDisableThreshold(
+ disableReason));
+ // Verify the original DISABLE_REASON_INFOS is unchanged
+ assertEquals(oldThreshold, NetworkSelectionStatus.DISABLE_REASON_INFOS
+ .get(disableReason).mDisableThreshold);
+ }
+ }
- // Verify that the threshold is updated in the copied version
- assertEquals(newThreshold, mWifiBlocklistMonitor.getNetworkSelectionDisableThreshold(
- NetworkSelectionStatus.DISABLED_DHCP_FAILURE));
- // Verify the original DISABLE_REASON_INFOS is unchanged
- assertEquals(oldThreshold, NetworkSelectionStatus.DISABLE_REASON_INFOS
- .get(NetworkSelectionStatus.DISABLED_DHCP_FAILURE).mDisableThreshold);
+ private int getExpectedBaseConfigDisableTimeoutMillis(int disableReason) {
+ switch (disableReason) {
+ case NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY:
+ return 10 * 60 * 1000; // 10 minutes - should match value configured via overlay
+ case NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_CREDENTIALS:
+ case NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT:
+ case NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER:
+ case NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD:
+ case NetworkSelectionStatus.DISABLED_AUTHENTICATION_NO_SUBSCRIPTION:
+ case NetworkSelectionStatus.DISABLED_TRANSITION_DISABLE_INDICATION:
+ return -1;
+ default:
+ return 5 * 60 * 1000; // 5 minutes
+ }
}
/**
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 3559c6a304..655693bf74 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
@@ -1953,6 +1953,7 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
public void testSetAndGetUnmergedCarrierNetworkOffload() {
assertTrue(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(DATA_SUBID, false));
mWifiCarrierInfoManager.setCarrierNetworkOffloadEnabled(DATA_SUBID, false, false);
+ mLooper.dispatchAll();
verify(mWifiConfigManager).saveToStore(true);
assertFalse(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(DATA_SUBID, false));
}
@@ -1974,6 +1975,7 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
listenerCaptor.getValue().onDataEnabledChanged(true, DATA_ENABLED_REASON_USER);
mWifiCarrierInfoManager.setCarrierNetworkOffloadEnabled(DATA_SUBID, true, false);
+ mLooper.dispatchAll();
verify(mWifiConfigManager).saveToStore(true);
assertFalse(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(DATA_SUBID, true));
@@ -2023,9 +2025,7 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
when(mContext.getPackageManager()).thenReturn(mockPackageManager);
PackageInfo pi = new PackageInfo();
pi.packageName = "com.example.app";
- List<PackageInfo> pis = new ArrayList<>() {{
- add(pi);
- }};
+ List<PackageInfo> pis = List.of(pi);
when(mockPackageManager.getPackagesHoldingPermissions(
eq(new String[] {android.Manifest.permission.NETWORK_CARRIER_PROVISIONING}),
anyInt())).thenReturn(pis);
@@ -2201,6 +2201,7 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
verify(mDataTelephonyManager).registerTelephonyCallback(any(), captor.capture());
mWifiCarrierInfoManager.setCarrierNetworkOffloadEnabled(DATA_SUBID, true, false);
+ mLooper.dispatchAll();
verify(mOnCarrierOffloadDisabledListener).onCarrierOffloadDisabled(DATA_SUBID, true);
captor.getValue().onDataEnabledChanged(false, DATA_ENABLED_REASON_CARRIER);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoStoreManagerDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoStoreManagerDataTest.java
index d0409beb49..5ba6c1af60 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoStoreManagerDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoStoreManagerDataTest.java
@@ -17,11 +17,13 @@
package com.android.server.wifi;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.util.SparseBooleanArray;
import android.util.Xml;
import com.android.internal.util.FastXmlSerializer;
@@ -49,8 +51,8 @@ public class WifiCarrierInfoStoreManagerDataTest {
private WifiCarrierInfoStoreManagerData mWifiCarrierInfoStoreManagerData;
private final Map<Integer, Boolean> mImsiPrivacyProtectionExemptionMap = new HashMap<>();
- private final Map<Integer, Boolean> mMergedCarrierOffloadMap = new HashMap<>();
- private final Map<Integer, Boolean> mUnmergedCarrierOffloadMap = new HashMap<>();
+ private final SparseBooleanArray mMergedCarrierOffloadMap = new SparseBooleanArray();
+ private final SparseBooleanArray mUnmergedCarrierOffloadMap = new SparseBooleanArray();
@Before
public void setUp() throws Exception {
@@ -126,25 +128,24 @@ public class WifiCarrierInfoStoreManagerDataTest {
private void assertSerializeDeserialize() throws Exception {
InOrder inOrder = inOrder(mDataSource);
// Setup the data to serialize.
- when(mDataSource.toSerializeMergedCarrierNetworkOffloadMap()).thenReturn(
+ when(mDataSource.getCarrierNetworkOffloadMap(true)).thenReturn(
mMergedCarrierOffloadMap);
- when(mDataSource.toSerializeUnmergedCarrierNetworkOffloadMap())
+ when(mDataSource.getCarrierNetworkOffloadMap(false))
.thenReturn(mUnmergedCarrierOffloadMap);
// Serialize/deserialize data.
deserializeData(serializeData());
inOrder.verify(mDataSource).serializeComplete();
// Verify the deserialized data.
- ArgumentCaptor<HashMap> deserializedMap =
- ArgumentCaptor.forClass(HashMap.class);
+ ArgumentCaptor<SparseBooleanArray> deserializedMap =
+ ArgumentCaptor.forClass(SparseBooleanArray.class);
- verify(mDataSource)
- .fromMergedCarrierNetworkOffloadMapDeserialized(deserializedMap.capture());
+ verify(mDataSource).setCarrierNetworkOffloadMap(deserializedMap.capture(), eq(true));
assertEquals(mMergedCarrierOffloadMap,
deserializedMap.getValue());
verify(mDataSource)
- .fromUnmergedCarrierNetworkOffloadMapDeserialized(deserializedMap.capture());
+ .setCarrierNetworkOffloadMap(deserializedMap.capture(), eq(false));
assertEquals(mUnmergedCarrierOffloadMap,
deserializedMap.getValue());
}
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 fb3e668a91..0183a09194 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -829,34 +829,32 @@ public class WifiConfigManagerTest extends WifiBaseTest {
openNetwork.SSID));
}
- /**
- * Verifies that the organization owned device admin could modify other other fields in the
- * Wificonfiguration but not the macRandomizationSetting field for networks they do not own.
- */
@Test
- public void testCannotUpdateMacRandomizationSettingWithoutPermissionDO() {
+ public void testOverrideWifiConfigModifyAllNetworks() {
ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
ArgumentCaptor.forClass(WifiConfiguration.class);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false);
- mockIsOrganizationOwnedDeviceAdmin(true);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
openNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO;
verifyAddNetworkToWifiConfigManager(openNetwork);
verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
+ assertNotEquals(WifiConfiguration.INVALID_NETWORK_ID, openNetwork.networkId);
reset(mWcmListener);
- // Change BSSID for the network and verify success
- assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
- NetworkUpdateResult networkUpdateResult = updateNetworkToWifiConfigManager(openNetwork);
- assertNotEquals(WifiConfiguration.INVALID_NETWORK_ID, networkUpdateResult.getNetworkId());
+ // try to modify the network with another UID and assert failure
+ WifiConfiguration configToUpdate = wifiConfigCaptor.getValue();
+ configToUpdate.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
+ NetworkUpdateResult result =
+ mWifiConfigManager.addOrUpdateNetwork(configToUpdate, TEST_OTHER_USER_UID);
+ assertEquals(WifiConfiguration.INVALID_NETWORK_ID, result.getNetworkId());
- // Now change the macRandomizationSetting and verify failure
- openNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
- networkUpdateResult = updateNetworkToWifiConfigManager(openNetwork);
- assertEquals(WifiConfiguration.INVALID_NETWORK_ID, networkUpdateResult.getNetworkId());
+ // give the override wifi config permission and verify success
+ when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
+ result = mWifiConfigManager.addOrUpdateNetwork(configToUpdate, TEST_OTHER_USER_UID);
+ assertEquals(configToUpdate.networkId, result.getNetworkId());
}
@Test
@@ -875,6 +873,36 @@ public class WifiConfigManagerTest extends WifiBaseTest {
}
/**
+ * Verifies that the organization owned device admin could modify other other fields in the
+ * Wificonfiguration but not the macRandomizationSetting field for networks they do not own.
+ */
+ @Test
+ public void testCannotUpdateMacRandomizationSettingWithoutPermissionDO() {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
+ when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
+ when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false);
+ mockIsOrganizationOwnedDeviceAdmin(true);
+ WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+ openNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO;
+
+ verifyAddNetworkToWifiConfigManager(openNetwork);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
+ reset(mWcmListener);
+
+ // Change BSSID for the network and verify success
+ assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
+ NetworkUpdateResult networkUpdateResult = updateNetworkToWifiConfigManager(openNetwork);
+ assertNotEquals(WifiConfiguration.INVALID_NETWORK_ID, networkUpdateResult.getNetworkId());
+
+ // Now change the macRandomizationSetting and verify failure
+ openNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
+ networkUpdateResult = updateNetworkToWifiConfigManager(openNetwork);
+ assertEquals(WifiConfiguration.INVALID_NETWORK_ID, networkUpdateResult.getNetworkId());
+ }
+
+ /**
* Verifies that the admin could set and modify the macRandomizationSetting field
* for networks they own.
*/
@@ -1892,9 +1920,9 @@ public class WifiConfigManagerTest extends WifiBaseTest {
WifiConfiguration originalNetwork = new WifiConfiguration(network);
// Now set all the public fields to null and try updating the network.
+ // except for allowedKeyManagement which is not allowed to be empty.
network.allowedAuthAlgorithms.clear();
network.allowedProtocols.clear();
- network.allowedKeyManagement.clear();
network.allowedPairwiseCiphers.clear();
network.allowedGroupCiphers.clear();
@@ -2600,7 +2628,6 @@ public class WifiConfigManagerTest extends WifiBaseTest {
public void testNonPersistentRandomizationDbsMacAddress() {
setUpWifiConfigurationForNonPersistentRandomization();
WifiConfiguration config = getFirstInternalWifiConfiguration();
- config.dbsSecondaryInternet = true;
MacAddress randomMac = config.getRandomizedMacAddress();
MacAddress newMac = mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config,
true);
@@ -7586,18 +7613,18 @@ public class WifiConfigManagerTest extends WifiBaseTest {
mWifiConfigManager.addCustomDhcpOptions(WifiSsid.fromString(TEST_SSID), oui3, option3);
mLooper.dispatchAll();
assertEquals(1, mWifiConfigManager.getCustomDhcpOptions(
- WifiSsid.fromString(TEST_SSID), Arrays.asList(oui1)).size());
+ WifiSsid.fromString(TEST_SSID), Collections.singletonList(oui1)).size());
assertEquals(1, mWifiConfigManager.getCustomDhcpOptions(
- WifiSsid.fromString(TEST_SSID), Arrays.asList(oui2)).size());
+ WifiSsid.fromString(TEST_SSID), Collections.singletonList(oui2)).size());
assertEquals(2, mWifiConfigManager.getCustomDhcpOptions(
WifiSsid.fromString(TEST_SSID), Arrays.asList(oui2, oui3)).size());
mWifiConfigManager.removeCustomDhcpOptions(WifiSsid.fromString(TEST_SSID), oui1);
mLooper.dispatchAll();
assertEquals(0, mWifiConfigManager.getCustomDhcpOptions(
- WifiSsid.fromString(TEST_SSID), Arrays.asList(oui1)).size());
- List<DhcpOption> actual2 = mWifiConfigManager
- .getCustomDhcpOptions(WifiSsid.fromString(TEST_SSID), Arrays.asList(oui2));
+ WifiSsid.fromString(TEST_SSID), Collections.singletonList(oui1)).size());
+ List<DhcpOption> actual2 = mWifiConfigManager.getCustomDhcpOptions(
+ WifiSsid.fromString(TEST_SSID), Collections.singletonList(oui2));
assertEquals(option2, actual2);
List<DhcpOption> actual23 = mWifiConfigManager
.getCustomDhcpOptions(WifiSsid.fromString(TEST_SSID), Arrays.asList(oui2, oui3));
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
index 29c85417b5..65b130838a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
@@ -301,6 +301,7 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
@Test
public void testValidatePositiveCases_OnlyUpdateIgnoresNullSsid() {
WifiConfiguration config = new WifiConfiguration();
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
assertFalse(WifiConfigurationUtil.validate(config, SUPPORTED_FEATURES_ALL,
WifiConfigurationUtil.VALIDATE_FOR_ADD));
assertTrue(WifiConfigurationUtil.validate(
@@ -699,8 +700,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS),
ScanResult.UNSPECIFIED,
- WifiConfigurationTestUtil.createOpenNetwork());
- assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenNetwork(), new int[0]);
+ assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
/**
@@ -713,8 +714,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB),
Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS),
ScanResult.UNSPECIFIED,
- WifiConfigurationTestUtil.createOpenNetwork());
- assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenNetwork(), new int[0]);
+ assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
/**
@@ -727,8 +728,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS),
ScanResult.UNSPECIFIED,
- WifiConfigurationTestUtil.createOpenNetwork());
- assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenNetwork(), new int[0]);
+ assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
/**
@@ -742,8 +743,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS),
ScanResult.WIFI_BAND_5_GHZ,
- WifiConfigurationTestUtil.createOpenNetwork());
- assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenNetwork(), new int[0]);
+ assertTrue(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
@@ -757,8 +758,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS),
ScanResult.UNSPECIFIED,
- WifiConfigurationTestUtil.createOpenNetwork());
- assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenNetwork(), new int[0]);
+ assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
/**
@@ -771,8 +772,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher("", PatternMatcher.PATTERN_LITERAL),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS),
ScanResult.UNSPECIFIED,
- WifiConfigurationTestUtil.createOpenNetwork());
- assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenNetwork(), new int[0]);
+ assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
/**
@@ -785,8 +786,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS),
ScanResult.UNSPECIFIED,
- WifiConfigurationTestUtil.createOpenNetwork());
- assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenNetwork(), new int[0]);
+ assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
/**
@@ -799,8 +800,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID), WifiManager.ALL_ZEROS_MAC_ADDRESS),
ScanResult.UNSPECIFIED,
- WifiConfigurationTestUtil.createOpenNetwork());
- assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenNetwork(), new int[0]);
+ assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
/**
@@ -813,8 +814,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_PREFIX),
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS),
ScanResult.UNSPECIFIED,
- WifiConfigurationTestUtil.createOpenHiddenNetwork());
- assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenHiddenNetwork(), new int[0]);
+ assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
/**
@@ -826,8 +827,8 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL),
Pair.create(MacAddress.fromString(TEST_BSSID), MacAddress.BROADCAST_ADDRESS),
42, // invalid
- WifiConfigurationTestUtil.createOpenNetwork());
- assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier));
+ WifiConfigurationTestUtil.createOpenNetwork(), new int[0]);
+ assertFalse(WifiConfigurationUtil.validateNetworkSpecifier(specifier, 5));
}
/**
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 9d7b5ec0e0..a7c5b51b8f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -66,6 +66,7 @@ import android.app.test.TestAlarmManager;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.net.IpConfiguration;
import android.net.MacAddress;
import android.net.wifi.IPnoScanResultsCallback;
import android.net.wifi.ScanResult;
@@ -73,14 +74,13 @@ import android.net.wifi.ScanResult.InformationElement;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiContext;
+import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
-import android.net.wifi.WifiScanner.PnoScanListener;
import android.net.wifi.WifiScanner.PnoSettings;
import android.net.wifi.WifiScanner.ScanData;
-import android.net.wifi.WifiScanner.ScanListener;
import android.net.wifi.WifiScanner.ScanSettings;
import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.PasspointConfiguration;
@@ -96,6 +96,7 @@ import android.os.Process;
import android.os.SystemClock;
import android.os.WorkSource;
import android.os.test.TestLooper;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LocalLog;
@@ -106,7 +107,9 @@ import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.ActiveModeWarden.ExternalClientModeManagerRequestListener;
import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
+import com.android.server.wifi.scanner.WifiScannerInternal;
import com.android.server.wifi.util.LruConnectionTracker;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.wifi.resources.R;
import org.junit.After;
@@ -135,7 +138,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.Executor;
import java.util.stream.Collectors;
/**
@@ -158,12 +160,13 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConfigManager = mockWifiConfigManager();
mWifiInfo = getWifiInfo();
mScanData = mockScanData();
- mWifiScanner = mockWifiScanner();
+ mockWifiScanner();
mWifiConnectivityHelper = mockWifiConnectivityHelper();
mWifiNS = mockWifiNetworkSelector();
mLooper = new TestLooper(mClock::getElapsedSinceBootMillis);
mTestHandler = new TestHandler(mLooper.getLooper());
- when(mContext.getSystemService(WifiScanner.class)).thenReturn(mWifiScanner);
+ WifiLocalServices.removeServiceForTest(WifiScannerInternal.class);
+ WifiLocalServices.addService(WifiScannerInternal.class, mWifiScanner);
when(mWifiNetworkSuggestionsManager.retrieveHiddenNetworkList(anyBoolean()))
.thenReturn(new ArrayList<>());
when(mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions())
@@ -177,7 +180,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(mContext.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(powerManager.isInteractive()).thenReturn(false);
when(mPrimaryClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
- when(mPrimaryClientModeManager.syncRequestConnectionInfo()).thenReturn(mWifiInfo);
+ when(mPrimaryClientModeManager.getConnectionInfo()).thenReturn(mWifiInfo);
when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mPrimaryClientModeManager);
doAnswer(new AnswerWithArguments() {
public void answer(ExternalClientModeManagerRequestListener listener,
@@ -280,13 +283,13 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
private TestHandler mTestHandler;
private WifiConnectivityManager mWifiConnectivityManager;
private WifiNetworkSelector mWifiNS;
- private WifiScanner mWifiScanner;
private WifiConnectivityHelper mWifiConnectivityHelper;
private ScanData mScanData;
private WifiConfigManager mWifiConfigManager;
private WifiInfo mWifiInfo;
private LocalLog mLocalLog;
private LruConnectionTracker mLruConnectionTracker;
+ @Mock private WifiScannerInternal mWifiScanner;
@Mock private Clock mClock;
@Mock private WifiLastResortWatchdog mWifiLastResortWatchdog;
@Mock private OpenNetworkNotifier mOpenNetworkNotifier;
@@ -312,8 +315,12 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
@Mock private WifiGlobals mWifiGlobals;
@Mock private ExternalPnoScanRequestManager mExternalPnoScanRequestManager;
@Mock private SsidTranslator mSsidTranslator;
+ @Mock private WifiPermissionsUtil mWifiPermissionsUtil;
+ @Mock private WifiCarrierInfoManager mWifiCarrierInfoManager;
@Mock WifiCandidates.Candidate mCandidate1;
@Mock WifiCandidates.Candidate mCandidate2;
+ @Mock WifiCandidates.Candidate mCandidate3;
+ @Mock WifiCandidates.Candidate mCandidate4;
private WifiConfiguration mCandidateWifiConfig1;
private WifiConfiguration mCandidateWifiConfig2;
private List<WifiCandidates.Candidate> mCandidateList;
@@ -332,8 +339,11 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
private static final int CANDIDATE_NETWORK_ID = 0;
private static final int CANDIDATE_NETWORK_ID_2 = 2;
private static final String CANDIDATE_SSID = "\"AnSsid\"";
+ private static final String CANDIDATE_SSID_2 = "\"AnSsid2\"";
private static final String CANDIDATE_BSSID = "6c:f3:7f:ae:8c:f3";
private static final String CANDIDATE_BSSID_2 = "6c:f3:7f:ae:8d:f3";
+ private static final String CANDIDATE_BSSID_3 = "6c:f3:7f:ae:8c:f4";
+ private static final String CANDIDATE_BSSID_4 = "6c:f3:7f:ae:8c:f5";
private static final String INVALID_SCAN_RESULT_BSSID = "6c:f3:7f:ae:8c:f4";
private static final int TEST_FREQUENCY = 2420;
private static final long CURRENT_SYSTEM_TIME_MS = 1000;
@@ -385,12 +395,12 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
* scheduled at a time. The scheduled delayed message intervals are recorded and returned by
* {@link #getIntervals}. The intervals are cleared by calling {@link #reset}.
*/
- private class TestHandler extends Handler {
+ private class TestHandler extends RunnerHandler {
private ArrayList<Long> mIntervals = new ArrayList<>();
private Message mMessage;
TestHandler(Looper looper) {
- super(looper);
+ super(looper, 100, new LocalLog(128));
}
public List<Long> getIntervals() {
@@ -446,38 +456,30 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
return scanData;
}
- WifiScanner mockWifiScanner() {
- WifiScanner scanner = mock(WifiScanner.class);
- ArgumentCaptor<ScanListener> allSingleScanListenerCaptor =
- ArgumentCaptor.forClass(ScanListener.class);
+ void mockWifiScanner() {
+ ArgumentCaptor<WifiScannerInternal.ScanListener> allSingleScanListenerCaptor =
+ ArgumentCaptor.forClass(WifiScannerInternal.ScanListener.class);
- doNothing().when(scanner).registerScanListener(
- any(), allSingleScanListenerCaptor.capture());
+ doNothing().when(mWifiScanner).registerScanListener(allSingleScanListenerCaptor.capture());
ScanData[] scanDatas = new ScanData[1];
scanDatas[0] = mScanData;
- // do a synchronous answer for the ScanListener callbacks
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, ScanListener listener,
- WorkSource workSource) throws Exception {
- listener.onResults(scanDatas);
- }}).when(scanner).startBackgroundScan(anyObject(), anyObject(), anyObject());
-
- doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, Executor executor, ScanListener listener,
- WorkSource workSource) throws Exception {
- listener.onResults(scanDatas);
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
+ listener.getWifiScannerListener().onResults(scanDatas);
// WCM processes scan results received via onFullResult (even though they're the
// same as onResult for single scans).
if (mScanData != null && mScanData.getResults() != null) {
for (int i = 0; i < mScanData.getResults().length; i++) {
- allSingleScanListenerCaptor.getValue().onFullResult(
- mScanData.getResults()[i]);
+ allSingleScanListenerCaptor.getValue().getWifiScannerListener()
+ .onFullResult(mScanData.getResults()[i]);
}
}
- allSingleScanListenerCaptor.getValue().onResults(scanDatas);
- }}).when(scanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ allSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(
+ scanDatas);
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
// This unfortunately needs to be a somewhat valid scan result, otherwise
// |ScanDetailUtil.toScanDetail| raises exceptions.
@@ -493,12 +495,13 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
doAnswer(new AnswerWithArguments() {
public void answer(ScanSettings settings, PnoSettings pnoSettings,
- Executor executor, PnoScanListener listener) throws Exception {
- listener.onPnoNetworkFound(scanResults);
- }}).when(scanner).startDisconnectedPnoScan(
- anyObject(), anyObject(), anyObject(), anyObject());
+ WifiScannerInternal.ScanListener listener) throws Exception {
+ WifiScanner.PnoScanListener l =
+ (WifiScanner.PnoScanListener) listener.getWifiScannerListener();
+ l.onPnoNetworkFound(scanResults);
+ }}).when(mWifiScanner).startPnoScan(
+ anyObject(), anyObject(), anyObject());
- return scanner;
}
WifiConnectivityHelper mockWifiConnectivityHelper() {
@@ -593,7 +596,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiMetrics, mTestHandler, mClock,
mLocalLog, mWifiScoreCard, mWifiBlocklistMonitor, mWifiChannelUtilization,
mPasspointManager, mMultiInternetManager, mDeviceConfigFacade, mActiveModeWarden,
- mFacade, mWifiGlobals, mExternalPnoScanRequestManager, mSsidTranslator);
+ mFacade, mWifiGlobals, mExternalPnoScanRequestManager, mSsidTranslator,
+ mWifiPermissionsUtil, mWifiCarrierInfoManager);
mLooper.dispatchAll();
verify(mActiveModeWarden, atLeastOnce()).registerModeChangeCallback(
mModeChangeCallbackCaptor.capture());
@@ -624,6 +628,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
+ mLooper.dispatchAll();
}
/**
@@ -673,7 +678,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mActiveModeWarden, never()).requestSecondaryTransientClientModeManager(
any(), any(), any(), any());
verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
@@ -694,7 +699,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
verify(mPrimaryClientModeManager).enableRoaming(true);
@@ -727,7 +732,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mActiveModeWarden).requestSecondaryTransientClientModeManager(
any(),
eq(ActiveModeWarden.INTERNAL_REQUESTOR_WS),
@@ -771,7 +776,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mActiveModeWarden).requestSecondaryTransientClientModeManager(
any(),
eq(ActiveModeWarden.INTERNAL_REQUESTOR_WS),
@@ -810,7 +815,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
-
+ mLooper.dispatchAll();
// Request secondary STA and connect using it.
verify(mActiveModeWarden).requestSecondaryTransientClientModeManager(
any(),
@@ -851,7 +856,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
-
+ mLooper.dispatchAll();
// Don't request secondary STA, fallback to primary STA.
verify(mActiveModeWarden, never()).requestSecondaryTransientClientModeManager(
any(), any(), any(), any());
@@ -904,7 +909,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
verify(mActiveModeWarden, never()).requestSecondaryLongLivedClientModeManager(
@@ -931,7 +936,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
verify(mActiveModeWarden, never()).requestSecondaryLongLivedClientModeManager(
@@ -958,7 +963,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
verify(mActiveModeWarden, never()).requestSecondaryLongLivedClientModeManager(
@@ -985,7 +990,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
verify(mActiveModeWarden, never()).requestSecondaryLongLivedClientModeManager(
@@ -1013,7 +1018,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
verify(mActiveModeWarden, never()).requestSecondaryLongLivedClientModeManager(
@@ -1043,7 +1048,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// No connection triggered (even on primary since wifi is off).
verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
@@ -1074,7 +1079,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// connection triggered on primary
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
@@ -1102,7 +1107,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// connection triggered on secondary
verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
@@ -1147,7 +1152,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// connection triggered on secondary
verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
@@ -1188,7 +1193,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// connection triggered on primary & secondary
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID_2, Process.WIFI_UID, "any");
@@ -1237,7 +1242,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// connection triggered on only on primary to CANDIDATE_NETWORK_ID_2.
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID_2, Process.WIFI_UID, "any");
@@ -1258,38 +1263,76 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
return scanDatas[0];
}
+ private WifiConfiguration getTestWifiConfig(int networkId, String ssid) {
+ WifiConfiguration config = generateWifiConfig(
+ networkId, 0, ssid, false, true, null, null,
+ WifiConfigurationTestUtil.SECURITY_PSK);
+ config.BSSID = ClientModeImpl.SUPPLICANT_BSSID_ANY;
+ config.oemPaid = false;
+ config.oemPrivate = false;
+ config.ephemeral = true;
+ when(mWifiConfigManager.getConfiguredNetwork(networkId)).thenReturn(config);
+ return config;
+ }
+
+ private WifiCandidates.Candidate getTestWifiCandidate(int networkId, String ssid, String bssid,
+ int rssi, int frequency) {
+ WifiCandidates.Candidate candidate = mock(WifiCandidates.Candidate.class);
+ when(candidate.isOemPaid()).thenReturn(false);
+ 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);
+ ScanResultMatchInfo matchInfo = ScanResultMatchInfo.fromScanResult(result);
+ WifiCandidates.Key key = new WifiCandidates.Key(matchInfo, MacAddress.fromString(bssid),
+ networkId, WifiConfiguration.SECURITY_TYPE_PSK);
+ when(candidate.getKey()).thenReturn(key);
+ when(candidate.getScanRssi()).thenReturn(rssi);
+ when(candidate.getFrequency()).thenReturn(frequency);
+ return candidate;
+ }
+
/**
- * Setup all the mocks for the positive case, individual negative test cases below override
- * specific params.
+ * Set up the mocks for the multi internet use case unit tests.
*/
- private void setupMocksForMultiInternetTests() {
+ private void setupMocksForMultiInternetTests(boolean isDbs) {
+ mCandidateWifiConfig1 = getTestWifiConfig(CANDIDATE_NETWORK_ID, CANDIDATE_SSID);
+ mCandidateWifiConfig2 = getTestWifiConfig(CANDIDATE_NETWORK_ID_2, CANDIDATE_SSID_2);
+
mScanData = createScanDataWithDifferentBands();
when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true);
when(mActiveModeWarden.isStaStaConcurrencySupportedForMultiInternet()).thenReturn(true);
when(mActiveModeWarden.getPrimaryClientModeManagerNullable())
.thenReturn(mPrimaryClientModeManager);
- when(mCandidate1.isOemPaid()).thenReturn(false);
- when(mCandidate1.isOemPrivate()).thenReturn(false);
- ScanResultMatchInfo matchInfo = mock(ScanResultMatchInfo.class);
- when(matchInfo.getDefaultSecurityParams()).thenReturn(
- mCandidateWifiConfig1.getDefaultSecurityParams());
- WifiCandidates.Key key = new WifiCandidates.Key(matchInfo,
- MacAddress.fromString(CANDIDATE_BSSID), 0);
- when(mCandidate1.getKey()).thenReturn(key);
- when(mCandidate1.getScanRssi()).thenReturn(-40);
- when(mCandidate1.getFrequency()).thenReturn(TEST_FREQUENCY);
- when(mCandidate1.getKey()).thenReturn(key);
-
- mCandidateWifiConfig1.oemPaid = false;
- mCandidateWifiConfig1.oemPrivate = false;
- mCandidateWifiConfig1.ephemeral = true;
- mCandidateWifiConfig1.dbsSecondaryInternet = true;
- when(mWifiNS.selectNetwork(argThat(
- candidates -> (candidates != null)), eq(false))).thenReturn(mCandidateWifiConfig1);
when(mActiveModeWarden.isStaStaConcurrencySupportedForRestrictedConnections())
.thenReturn(true);
when(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
any(), eq(ROLE_CLIENT_SECONDARY_LONG_LIVED), eq(false))).thenReturn(true);
+ mCandidate1 = getTestWifiCandidate(CANDIDATE_NETWORK_ID, CANDIDATE_SSID, CANDIDATE_BSSID,
+ -40,
+ TEST_FREQUENCY);
+ mCandidate2 = getTestWifiCandidate(CANDIDATE_NETWORK_ID_2, CANDIDATE_SSID_2,
+ CANDIDATE_BSSID_2, -60,
+ TEST_FREQUENCY_2);
+ mCandidate4 = getTestWifiCandidate(CANDIDATE_NETWORK_ID_2,
+ CANDIDATE_SSID_2, CANDIDATE_BSSID_4,
+ -40,
+ TEST_FREQUENCY_3);
+
+ // A DBS candidate with same SSID as mCandidate1
+ mCandidate3 = getTestWifiCandidate(CANDIDATE_NETWORK_ID, CANDIDATE_SSID, CANDIDATE_BSSID_3,
+ -40,
+ TEST_FREQUENCY_3);
+ mCandidateList = new ArrayList<WifiCandidates.Candidate>(
+ Arrays.asList(mCandidate1, mCandidate2, mCandidate4));
+ if (isDbs) {
+ mCandidateList.add(mCandidate3);
+ }
+ when(mWifiNS.getCandidatesFromScan(any(), any(), any(), anyBoolean(), anyBoolean(),
+ anyBoolean(), any(), anyBoolean())).thenReturn(mCandidateList);
+
doAnswer(new AnswerWithArguments() {
public void answer(ExternalClientModeManagerRequestListener listener,
WorkSource requestorWs, String ssid, String bssid) {
@@ -1300,36 +1343,91 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(mSecondaryClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED);
}
- @Test
- public void multiInternetSecondaryConnectionRequestSucceedsWithDbsApOnly() {
- setupMocksForMultiInternetTests();
- when(mMultiInternetManager.isStaConcurrencyForMultiInternetMultiApAllowed())
- .thenReturn(false);
+ /**
+ * Set up the primary network selection mocks for the multi internet use case unit tests.
+ */
+ 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));
+ // Selection for primary
+ when(mWifiNS.selectNetwork(any()))
+ .then(new AnswerWithArguments() {
+ public WifiConfiguration answer(List<WifiCandidates.Candidate> candidateList) {
+ if (candidateList != null) {
+ for (WifiCandidates.Candidate candidate : candidateList) {
+ if (networkId == candidate.getKey().networkId) {
+ return config;
+ }
+ }
+ }
+ return null;
+ }
+ });
+ }
+ /**
+ * Set up the secondary network selection mocks for the multi internet use case unit tests.
+ */
+ private void setupMockSecondaryNetworkSelect(int networkId, int rssi) {
+ WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(networkId);
+ // Selection for secondary
+ when(mWifiNS.selectNetwork(any(), anyBoolean()))
+ .then(new AnswerWithArguments() {
+ public WifiConfiguration answer(List<WifiCandidates.Candidate> candidateList,
+ boolean override) {
+ if (candidateList != null) {
+ for (WifiCandidates.Candidate candidate : candidateList) {
+ // 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));
+ return config;
+ }
+ }
+ }
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Set up the client manager wifi info mocks for the multi internet use case unit tests.
+ */
+ private void mockClientManagerInfo(ConcreteClientModeManager clientManager,
+ WifiConfiguration configuration) {
+ WifiInfo wifiInfo = getWifiInfo();
+ wifiInfo.setNetworkId(configuration.networkId);
+ wifiInfo.setSSID(WifiSsid.fromString(configuration.SSID));
+ wifiInfo.setBSSID(configuration.BSSID);
+ wifiInfo.setFrequency(
+ configuration.getNetworkSelectionStatus().getCandidate().frequency);
+ wifiInfo.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PSK);
+ when(clientManager.isConnected()).thenReturn(true);
+ when(clientManager.isDisconnected()).thenReturn(false);
+ when(clientManager.getConnectionInfo()).thenReturn(wifiInfo);
+ }
+
+ private void testMultiInternetSecondaryConnectionRequest(boolean isDbsOnly, boolean isDhcp,
+ boolean success, String expectedBssidToConnect) {
+ when(mMultiInternetManager.isStaConcurrencyForMultiInternetMultiApAllowed())
+ .thenReturn(!isDbsOnly);
+ setupMockPrimaryNetworkSelect(CANDIDATE_NETWORK_ID, CANDIDATE_BSSID, -50, TEST_FREQUENCY);
+ WifiConfiguration targetConfig = isDbsOnly ? mCandidateWifiConfig1 : mCandidateWifiConfig2;
+ String targetBssid = expectedBssidToConnect;
+ targetConfig.setIpAssignment(
+ isDhcp ? IpConfiguration.IpAssignment.DHCP : IpConfiguration.IpAssignment.STATIC);
+ setupMockSecondaryNetworkSelect(targetConfig.networkId, -50);
// Set screen to on
setScreenState(true);
- when(mCandidate1.isSecondaryInternet()).thenReturn(true);
- mCandidateWifiConfig1.ephemeral = true;
- mCandidateWifiConfig1.dbsSecondaryInternet = true;
-
- // Set up the scan candidates
- MacAddress macAddress = MacAddress.fromString(CANDIDATE_BSSID);
- ScanResult result1 = new ScanResult(WifiSsid.fromUtf8Text(CANDIDATE_SSID),
- TEST_SSID, TEST_CONNECTED_BSSID, 1245, 0, "some caps", -78, 2450,
- 1025, 22, 33, 20, 0, 0, true);
- ScanResultMatchInfo matchInfo1 = ScanResultMatchInfo.fromScanResult(result1);
- WifiCandidates.Key key = new WifiCandidates.Key(matchInfo1, macAddress,
- TEST_CONNECTED_NETWORK_ID,
- WifiConfiguration.SECURITY_TYPE_OPEN);
- WifiCandidates.Candidate otherCandidate = mock(WifiCandidates.Candidate.class);
- when(otherCandidate.getKey()).thenReturn(key);
- List<WifiCandidates.Candidate> candidateList = new ArrayList<>();
- candidateList.add(mCandidate1);
- candidateList.add(otherCandidate);
- when(mWifiNS.getCandidatesFromScan(any(), any(), any(), anyBoolean(), anyBoolean(),
- anyBoolean(), any(), anyBoolean())).thenReturn(candidateList);
-
// Set WiFi to disconnected state to trigger scan
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
@@ -1337,27 +1435,30 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mLooper.dispatchAll();
// Verify a connection starting
verify(mWifiNS).selectNetwork((List<WifiCandidates.Candidate>)
- argThat(new WifiCandidatesListSizeMatcher(2)));
+ argThat(new WifiCandidatesListSizeMatcher(mCandidateList.size())));
verify(mPrimaryClientModeManager).startConnectToNetwork(anyInt(), anyInt(), any());
- WifiInfo info1 = getWifiInfo();
- info1.setNetworkId(TEST_CONNECTED_NETWORK_ID);
- info1.setSSID(WifiSsid.fromUtf8Text(TEST_SSID));
- info1.setBSSID(TEST_CONNECTED_BSSID);
- info1.setFrequency(TEST_FREQUENCY_5G);
- info1.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_OPEN);
- when(mPrimaryClientModeManager.isConnected()).thenReturn(true);
- when(mPrimaryClientModeManager.isDisconnected()).thenReturn(false);
- when(mPrimaryClientModeManager.syncRequestConnectionInfo()).thenReturn(info1);
+ // mCandidateWifiConfig1 is connected as primary
+ mockClientManagerInfo(mPrimaryClientModeManager, mCandidateWifiConfig1);
+
when(mMultiInternetManager.hasPendingConnectionRequests()).thenReturn(true);
- WorkSource testWorkSource = new WorkSource();
// Set the connection pending status
mMultiInternetConnectionStatusListenerCaptor.getValue().onStatusChange(
MultiInternetManager.MULTI_INTERNET_STATE_CONNECTION_REQUESTED,
- testWorkSource);
- mMultiInternetConnectionStatusListenerCaptor.getValue().onStartScan(testWorkSource);
+ new WorkSource());
+ mMultiInternetConnectionStatusListenerCaptor.getValue().onStartScan(new WorkSource());
+ mLooper.dispatchAll();
+ if (!success) {
+ verify(mSecondaryClientModeManager, never()).startConnectToNetwork(
+ targetConfig.networkId, Process.WIFI_UID, targetBssid);
+ verify(mSecondaryClientModeManager, never()).enableRoaming(false);
+ verify(mActiveModeWarden, never()).requestSecondaryLongLivedClientModeManager(
+ any(), any(), any(), any());
+ return;
+ }
+
verify(mSecondaryClientModeManager, times(2)).startConnectToNetwork(
- CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+ targetConfig.networkId, Process.WIFI_UID, targetBssid);
verify(mSecondaryClientModeManager, times(2)).enableRoaming(false);
verify(mActiveModeWarden, times(2)).requestSecondaryLongLivedClientModeManager(
any(), any(), any(), any());
@@ -1378,71 +1479,64 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
}
@Test
- public void multiInternetSecondaryConnectionRequestSucceedsWithMultiApAllowed() {
- setupMocksForMultiInternetTests();
- when(mMultiInternetManager.isStaConcurrencyForMultiInternetMultiApAllowed())
- .thenReturn(true);
-
- // Set screen to on
- setScreenState(true);
+ public void multiInternetSecondaryConnectionRequestSucceedsWithDbsApOnly() {
+ setupMocksForMultiInternetTests(true);
+ testMultiInternetSecondaryConnectionRequest(true, true, true, CANDIDATE_BSSID_3);
+ }
- when(mCandidate1.isSecondaryInternet()).thenReturn(true);
- mCandidateWifiConfig1.ephemeral = true;
- mCandidateWifiConfig1.dbsSecondaryInternet = true;
+ @Test
+ public void multiInternetSecondaryConnectionRequestSucceedsWithDbsApOnlyFailOnStaticIp() {
+ setupMocksForMultiInternetTests(true);
+ testMultiInternetSecondaryConnectionRequest(true, false, false, CANDIDATE_BSSID_3);
+ }
- // Set up the scan candidates
- MacAddress macAddress = MacAddress.fromString(CANDIDATE_BSSID);
- WifiCandidates.Key key = new WifiCandidates.Key(mock(ScanResultMatchInfo.class),
- macAddress, 0, WifiConfiguration.SECURITY_TYPE_OPEN);
- WifiCandidates.Candidate otherCandidate = mock(WifiCandidates.Candidate.class);
- when(otherCandidate.getKey()).thenReturn(key);
- List<WifiCandidates.Candidate> candidateList = new ArrayList<>();
- candidateList.add(mCandidate1);
- candidateList.add(otherCandidate);
- when(mWifiNS.getCandidatesFromScan(any(), any(), any(), anyBoolean(), anyBoolean(),
- anyBoolean(), any(), anyBoolean())).thenReturn(candidateList);
+ @Test
+ public void multiInternetSecondaryConnectionRequestSucceedsWithMultiApAllowed() {
+ setupMocksForMultiInternetTests(false);
+ testMultiInternetSecondaryConnectionRequest(false, true, true, CANDIDATE_BSSID_2);
+ }
- // Set WiFi to disconnected state to trigger scan
- mWifiConnectivityManager.handleConnectionStateChanged(
- mPrimaryClientModeManager,
- WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
- mLooper.dispatchAll();
- // Verify a connection starting
- verify(mWifiNS).selectNetwork((List<WifiCandidates.Candidate>)
- argThat(new WifiCandidatesListSizeMatcher(2)));
- verify(mPrimaryClientModeManager).startConnectToNetwork(anyInt(), anyInt(), any());
+ @Test
+ public void multiInternetSecondaryConnectionDisconnectedBeforeNetworkSelection() {
+ setupMocksForMultiInternetTests(false);
+ testMultiInternetSecondaryConnectionRequest(false, true, true, CANDIDATE_BSSID_2);
+ setupMockPrimaryNetworkSelect(CANDIDATE_NETWORK_ID_2, CANDIDATE_BSSID_2, -50,
+ TEST_FREQUENCY);
+ when(mMultiInternetManager.hasPendingConnectionRequests()).thenReturn(false);
+ when(mSecondaryClientModeManager.isConnected()).thenReturn(true);
+ when(mSecondaryClientModeManager.getConnectedWifiConfiguration()).thenReturn(
+ mCandidateWifiConfig2);
+ when(mActiveModeWarden.getClientModeManagerInRole(
+ ROLE_CLIENT_SECONDARY_LONG_LIVED)).thenReturn(mSecondaryClientModeManager);
+ mMultiInternetConnectionStatusListenerCaptor.getValue().onStartScan(new WorkSource());
+ verify(mSecondaryClientModeManager).disconnect();
+ }
- WifiInfo info1 = getWifiInfo();
- info1.setFrequency(TEST_FREQUENCY_5G);
- when(mPrimaryClientModeManager.isConnected()).thenReturn(true);
- when(mPrimaryClientModeManager.isDisconnected()).thenReturn(false);
- when(mPrimaryClientModeManager.syncRequestConnectionInfo()).thenReturn(info1);
- when(mMultiInternetManager.hasPendingConnectionRequests()).thenReturn(true);
- WorkSource testWorkSource = new WorkSource();
- // Set the connection pending status
- mMultiInternetConnectionStatusListenerCaptor.getValue().onStatusChange(
- MultiInternetManager.MULTI_INTERNET_STATE_CONNECTION_REQUESTED,
- testWorkSource);
- mMultiInternetConnectionStatusListenerCaptor.getValue().onStartScan(testWorkSource);
- verify(mSecondaryClientModeManager, times(2)).startConnectToNetwork(
- CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
- verify(mSecondaryClientModeManager, times(2)).enableRoaming(false);
- verify(mActiveModeWarden, times(2)).requestSecondaryLongLivedClientModeManager(
- any(), any(), any(), any());
+ @Test
+ public void multiInternetSecondaryConnectionRequest_filteredBssidExists() {
+ setupMocksForMultiInternetTests(false);
+ Map<Integer, String> specifiedBssids = new ArrayMap<>();
+ // Verify connect to the filtered BSSID
+ specifiedBssids.put(ScanResult.toBand(mCandidate4.getFrequency()),
+ mCandidate4.getKey().bssid.toString());
+ when(mMultiInternetManager.getSpecifiedBssids()).thenReturn(specifiedBssids);
+ testMultiInternetSecondaryConnectionRequest(false, true, true,
+ mCandidate4.getKey().bssid.toString());
+ }
- // Simulate connection failing on the secondary
- clearInvocations(mSecondaryClientModeManager, mPrimaryClientModeManager, mWifiNS);
- mWifiConnectivityManager.handleConnectionAttemptEnded(
- mSecondaryClientModeManager,
- WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION,
- WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, CANDIDATE_BSSID,
- WifiConfigurationTestUtil.createPskNetwork(CANDIDATE_SSID));
- // verify connection is never restarted when a connection on the secondary STA fails.
- verify(mWifiNS, never()).selectNetwork(any());
- verify(mSecondaryClientModeManager, never()).startConnectToNetwork(
- anyInt(), anyInt(), any());
- verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
- anyInt(), anyInt(), any());
+ @Test
+ public void multiInternetSecondaryConnectionRequest_filterBssidNotExist() {
+ setupMocksForMultiInternetTests(false);
+ Map<Integer, String> specifiedBssids = new ArrayMap<>();
+ // Verify filtering by a BSSID that does not exist in the candidate list still
+ // results in a connection.
+ specifiedBssids.put(ScanResult.toBand(mCandidate2.getFrequency()),
+ mCandidate3.getKey().bssid.toString());
+ specifiedBssids.put(ScanResult.toBand(mCandidate4.getFrequency()),
+ mCandidate3.getKey().bssid.toString());
+ when(mMultiInternetManager.getSpecifiedBssids()).thenReturn(specifiedBssids);
+ testMultiInternetSecondaryConnectionRequest(false, true, true,
+ mCandidate2.getKey().bssid.toString());
}
/**
@@ -1461,7 +1555,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
}
@@ -1483,7 +1577,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
}
@@ -1501,7 +1595,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// Set screen to on
setScreenState(true);
@@ -1523,7 +1617,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Set screen to on
setScreenState(true);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager, atLeastOnce()).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
}
@@ -1579,6 +1673,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
numAttempts++;
}
// Now trigger another connection attempt before the rate interval, this should be
@@ -1588,7 +1683,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// Verify that we attempt to connect upto the rate.
verify(mPrimaryClientModeManager, times(numAttempts)).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
@@ -1620,6 +1715,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
numAttempts++;
}
// Now trigger another connection attempt after the rate interval, this should not be
@@ -1630,6 +1726,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
numAttempts++;
// Verify that all the connection attempts went through
@@ -1663,6 +1760,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
numAttempts++;
}
@@ -1675,6 +1773,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
numAttempts++;
}
@@ -1708,6 +1807,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
numAttempts++;
}
@@ -1720,6 +1820,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
numAttempts++;
}
@@ -1753,6 +1854,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
numAttempts++;
}
@@ -1766,6 +1868,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
numAttempts++;
}
@@ -1792,7 +1895,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mWifiMetrics).noteFirstNetworkSelectionAfterBoot(false);
// Get the retry delay value after QNS didn't select a
@@ -1808,6 +1911,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
}
int lowRssiNetworkRetryDelayAfterThreePnoMs = mWifiConnectivityManager
.getLowRssiNetworkRetryDelay();
@@ -1830,7 +1934,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// Now fire the watchdog alarm and verify the metrics were incremented.
mAlarmManager.dispatch(WifiConnectivityManager.WATCHDOG_TIMER_TAG);
mLooper.dispatchAll();
@@ -1857,7 +1961,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// Now fire the watchdog alarm and verify the metrics were incremented.
mAlarmManager.dispatch(WifiConnectivityManager.WATCHDOG_TIMER_TAG);
mLooper.dispatchAll();
@@ -1875,7 +1979,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// Verify the watchdog alarm has been set
assertTrue(mAlarmManager.isPending(WifiConnectivityManager.WATCHDOG_TIMER_TAG));
@@ -1965,7 +2069,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mWifiScanner).startScan((ScanSettings) argThat(new WifiPartialScanSettingMatcher()),
- any(), any(), any());
+ any());
}
private class WifiPartialScanSettingMatcher implements ArgumentMatcher<ScanSettings> {
@@ -2113,6 +2217,48 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
verify(mPrimaryClientModeManager).startConnectToNetwork(anyInt(), anyInt(), any());
}
+ /**
+ * Verify that we do not try to reconnect to an admin restricted network
+ */
+ @Test
+ public void testRetryConnectionIgnoreNetworkWithAdminRestriction() {
+ // Setup WifiNetworkSelector to return 2 valid candidates from scan results
+ MacAddress macAddress = MacAddress.fromString(CANDIDATE_BSSID_2);
+ WifiCandidates.Key key = new WifiCandidates.Key(mock(ScanResultMatchInfo.class),
+ macAddress, 0, WifiConfiguration.SECURITY_TYPE_OPEN);
+ WifiCandidates.Candidate otherCandidate = mock(WifiCandidates.Candidate.class);
+ when(otherCandidate.getKey()).thenReturn(key);
+ List<WifiCandidates.Candidate> candidateList = new ArrayList<>();
+ candidateList.add(mCandidate1);
+ candidateList.add(otherCandidate);
+ when(mWifiNS.getCandidatesFromScan(any(), any(), any(), anyBoolean(), anyBoolean(),
+ anyBoolean(), any(), anyBoolean())).thenReturn(candidateList);
+
+ // Set WiFi to disconnected state to trigger scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ mPrimaryClientModeManager,
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
+ // Verify a connection starting
+ verify(mWifiNS).selectNetwork((List<WifiCandidates.Candidate>)
+ argThat(new WifiCandidatesListSizeMatcher(2)));
+ verify(mPrimaryClientModeManager).startConnectToNetwork(anyInt(), anyInt(), any());
+
+ // mock the WifiConfiguration to have an admin restriction
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork(CANDIDATE_SSID);
+ when(mWifiPermissionsUtil.isAdminRestrictedNetwork(config)).thenReturn(true);
+
+ // Simulate the connection failing
+ mWifiConnectivityManager.handleConnectionAttemptEnded(
+ mPrimaryClientModeManager,
+ WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION,
+ WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, CANDIDATE_BSSID,
+ config);
+
+ // Verify another connection do not start.
+ verify(mPrimaryClientModeManager).startConnectToNetwork(anyInt(), anyInt(), any());
+ }
+
private class WifiCandidatesListSizeMatcher implements
ArgumentMatcher<List<WifiCandidates.Candidate>> {
int mSize;
@@ -2569,8 +2715,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
int[] intervalSchedule, int[] scheduleScanType) {
// Verify the scans actually happened for expected times, one scan for state change and
// each for scan timer triggered.
- verify(mWifiScanner, times(scanTimes)).startScan(anyObject(), anyObject(), anyObject(),
- anyObject());
+ verify(mWifiScanner, times(scanTimes)).startScan(anyObject(), anyObject());
// Verify scans are happening using the expected scan type.
Map<Integer, Integer> scanTypeToTimesMap = new HashMap<>();
@@ -2585,7 +2730,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
public boolean matches(ScanSettings scanSettings) {
return scanSettings.type == entry.getKey();
}
- }), any(), any(), any());
+ }), any());
}
// Verify the scan intervals are same as expected interval schedule.
@@ -2594,8 +2739,9 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// TestHandler#sendMessageAtTime is not perfectly mocked and uses
// SystemClock.uptimeMillis() to generate |intervals|. This sometimes results in error
// margins of ~1ms and cause flaky test failures.
- assertTrue("Interval " + i + " not in 1ms error margin",
- Math.abs(expected - intervals.get(i).longValue()) < 2);
+ final long delta = Math.abs(expected - intervals.get(i).longValue());
+ assertTrue("Interval " + i + " (" + delta + ") not in 1ms error margin",
+ delta < 2);
}
}
@@ -2603,8 +2749,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
int expectedInterval) {
// Verify the scans actually happened for expected times, one scan for state change and
// each for scan timer triggered.
- verify(mWifiScanner, times(scanTimes)).startScan(anyObject(), anyObject(), anyObject(),
- anyObject());
+ verify(mWifiScanner, times(scanTimes)).startScan(anyObject(), anyObject());
// The actual interval should be same as scheduled.
assertEquals(expectedInterval * 1000, intervals.get(0).longValue());
@@ -3175,8 +3320,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
- verify(mWifiScanner, times(1)).startScan(
- anyObject(), anyObject(), anyObject(), anyObject());
+ verify(mWifiScanner, times(1)).startScan(anyObject(), anyObject());
// Set up time stamp for when entering CONNECTED state
currentTimeStamp += 2000;
@@ -3218,8 +3362,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
- verify(mWifiScanner, never()).startScan(anyObject(), anyObject(), anyObject(),
- anyObject());
+ verify(mWifiScanner, never()).startScan(anyObject(), anyObject());
}
/**
@@ -3248,8 +3391,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Set WiFi to connected state to trigger the periodic scan
setWifiStateConnected();
- verify(mWifiScanner, times(1)).startScan(
- anyObject(), anyObject(), anyObject(), anyObject());
+ verify(mWifiScanner, times(1)).startScan(anyObject(), anyObject());
// Set up the time stamp for when entering DISCONNECTED state
currentTimeStamp += 2000;
@@ -3343,11 +3485,19 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(mPerNetwork.getFrequencies(anyLong())).thenReturn(new ArrayList<>());
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, ScanListener listener,
- WorkSource workSource) throws Exception {
- assertEquals(settings.band, WifiScanner.WIFI_BAND_ALL);
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
+ if (SdkLevel.isAtLeastS()) {
+ assertEquals(WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ, settings.band);
+ assertEquals("RNR should be enabled for full scans",
+ WifiScanner.WIFI_RNR_ENABLED, settings.getRnrSetting());
+ assertTrue("PSC should be enabled for full scans",
+ settings.is6GhzPscOnlyEnabled());
+ } else {
+ assertEquals(WifiScanner.WIFI_BAND_ALL, settings.band);
+ }
assertNull(settings.channels);
- }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject());
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
// Set screen to ON
@@ -3357,8 +3507,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
-
- verify(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ mLooper.dispatchAll();
+ verify(mWifiScanner).startScan(anyObject(), anyObject());
// Verify case 2
when(mWifiNS.isNetworkSufficient(eq(mWifiInfo))).thenReturn(true);
@@ -3371,8 +3521,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
- verify(mWifiScanner, times(2)).startScan(anyObject(), anyObject(), anyObject(),
- anyObject());
+ verify(mWifiScanner, times(2)).startScan(anyObject(), anyObject());
// Verify case 3
when(mWifiNS.isNetworkSufficient(eq(mWifiInfo))).thenReturn(false);
@@ -3385,8 +3534,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
- verify(mWifiScanner, times(2)).startScan(anyObject(), anyObject(), anyObject(),
- anyObject());
+ verify(mWifiScanner, times(2)).startScan(anyObject(), anyObject());
}
/**
@@ -3419,8 +3567,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(false);
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, Executor executor, ScanListener listener,
- WorkSource workSource) throws Exception {
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
assertEquals(settings.band, WifiScanner.WIFI_BAND_UNSPECIFIED);
assertEquals(settings.channels.length, channelList.size());
if (SdkLevel.isAtLeastS()) {
@@ -3432,7 +3580,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
for (int chanIdx = 0; chanIdx < settings.channels.length; chanIdx++) {
assertTrue(channelList.contains(settings.channels[chanIdx].frequency));
}
- }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ mLooper.dispatchAll();
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
// Set screen to ON
setScreenState(true);
@@ -3442,7 +3591,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
- verify(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ verify(mWifiScanner).startScan(anyObject(), anyObject());
}
/**
@@ -3475,14 +3624,15 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(false);
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, Executor executor, ScanListener listener,
- WorkSource workSource) throws Exception {
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
assertEquals(settings.band, WifiScanner.WIFI_BAND_UNSPECIFIED);
assertEquals(settings.channels.length, channelList.size());
for (int chanIdx = 0; chanIdx < settings.channels.length; chanIdx++) {
assertTrue(channelList.contains(settings.channels[chanIdx].frequency));
}
- }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ mLooper.dispatchAll();
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
// Set screen to ON
setScreenState(true);
@@ -3492,7 +3642,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
- verify(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ verify(mWifiScanner).startScan(anyObject(), anyObject());
}
@@ -3521,8 +3671,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
.thenReturn(new WifiConfiguration());
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, Executor executor, ScanListener listener,
- WorkSource workSource) throws Exception {
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
assertNull(settings.channels);
if (SdkLevel.isAtLeastS()) {
assertEquals(WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ, settings.band);
@@ -3533,7 +3683,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
} else {
assertEquals(WifiScanner.WIFI_BAND_ALL, settings.band);
}
- }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ mLooper.dispatchAll();
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
// Set screen to ON
setScreenState(true);
@@ -3543,7 +3694,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_CONNECTED);
- verify(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ verify(mWifiScanner).startScan(anyObject(), anyObject());
}
/**
@@ -3559,10 +3710,11 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
setScreenState(true);
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, Executor executor, ScanListener listener,
- WorkSource workSource) throws Exception {
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
listener.onFailure(-1, "ScanFailure");
- }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ mLooper.dispatchAll();
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
// Set WiFi to disconnected state to trigger the single scan based periodic scan
mWifiConnectivityManager.handleConnectionStateChanged(
@@ -3580,7 +3732,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// The very first scan is the initial one, and the other MAX_SCAN_RESTART_ALLOWED
// are the retrial ones.
verify(mWifiScanner, times(WifiConnectivityManager.MAX_SCAN_RESTART_ALLOWED + 1)).startScan(
- anyObject(), anyObject(), anyObject(), anyObject());
+ anyObject(), anyObject());
}
@Test
@@ -3589,10 +3741,11 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
setScreenState(true);
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, Executor executor, ScanListener listener,
- WorkSource workSource) throws Exception {
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
listener.onFailure(-1, "ScanFailure");
- }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ mLooper.dispatchAll();
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
// Set WiFi to disconnected state to trigger the single scan based periodic scan
mWifiConnectivityManager.handleConnectionStateChanged(
@@ -3611,8 +3764,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Verify that the connectivity scan has happened 2 times. Note, the first scan is due
// to the initial request, and the second scan is the first retry after failure.
// There are no more retries afterwards because the screen is off.
- verify(mWifiScanner, times(2)).startScan(
- anyObject(), anyObject(), anyObject(), anyObject());
+ verify(mWifiScanner, times(2)).startScan(anyObject(), anyObject());
}
/**
@@ -3630,32 +3782,35 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
setScreenState(true);
// Setup WifiScanner to fail
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, Executor executor, ScanListener listener,
- WorkSource workSource) throws Exception {
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
listener.onFailure(-1, "ScanFailure");
- }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ mLooper.dispatchAll();
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
mWifiConnectivityManager.forceConnectivityScan(null);
// make the retry succeed
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, Executor executor, ScanListener listener,
- WorkSource workSource) throws Exception {
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
listener.onResults(null);
- }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ mLooper.dispatchAll();
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
mAlarmManager.dispatch(WifiConnectivityManager.RESTART_SINGLE_SCAN_TIMER_TAG);
mLooper.dispatchAll();
// Verify that startScan is called once for the original scan, plus once for the retry.
// The successful retry should have now cleared the restart count
verify(mWifiScanner, times(2)).startScan(
- anyObject(), anyObject(), anyObject(), anyObject());
+ anyObject(), anyObject());
// Now force a new scan and verify we retry MAX_SCAN_RESTART_ALLOWED times
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, Executor executor, ScanListener listener,
- WorkSource workSource) throws Exception {
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
listener.onFailure(-1, "ScanFailure");
- }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject(), anyObject());
+ mLooper.dispatchAll();
+ }}).when(mWifiScanner).startScan(anyObject(), anyObject());
mWifiConnectivityManager.forceConnectivityScan(null);
// Fire the alarm timer 2x timers
for (int i = 0; i < (WifiConnectivityManager.MAX_SCAN_RESTART_ALLOWED * 2); i++) {
@@ -3668,7 +3823,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// and additionally MAX_SCAN_RESTART_ALLOWED + 1 times from forceConnectivityScan and
// subsequent retries.
verify(mWifiScanner, times(WifiConnectivityManager.MAX_SCAN_RESTART_ALLOWED + 3)).startScan(
- anyObject(), anyObject(), anyObject(), anyObject());
+ anyObject(), anyObject());
}
/**
@@ -3682,11 +3837,12 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
@Test
public void listenToAllSingleScanResults() {
ScanSettings settings = new ScanSettings();
- ScanListener scanListener = mock(ScanListener.class);
+ WifiScannerInternal.ScanListener scanListener = new WifiScannerInternal.ScanListener(mock(
+ WifiScanner.ScanListener.class), mTestHandler);
// Request a single scan outside of WifiConnectivityManager.
- mWifiScanner.startScan(settings, mock(Executor.class), scanListener, WIFI_WORK_SOURCE);
-
+ mWifiScanner.startScan(settings, scanListener);
+ mLooper.dispatchAll();
// Verify that WCM receives the scan results and initiates a connection
// to the network.
verify(mPrimaryClientModeManager).startConnectToNetwork(
@@ -3712,7 +3868,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Force a connectivity scan which enables WifiConnectivityManager
// to wait for full band scan results.
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
-
+ mLooper.dispatchAll();
// No roaming because no full band scan results.
verify(mPrimaryClientModeManager, times(0)).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
@@ -3723,7 +3879,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Force a connectivity scan which enables WifiConnectivityManager
// to wait for full band scan results.
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
-
+ mLooper.dispatchAll();
// Roaming attempt because full band scan results are available.
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
@@ -3754,6 +3910,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
.thenReturn(passpointNetworks);
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
+ mLooper.dispatchAll();
ArgumentCaptor<ArrayList<String>> listArgumentCaptor =
ArgumentCaptor.forClass(ArrayList.class);
verify(mWifiConfigManager).updateUserDisabledList(listArgumentCaptor.capture());
@@ -3767,6 +3924,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
public void verifyClearExpiredRecentFailureStatusAfterScan() {
// mWifiScanner is mocked to directly return scan results when a scan is triggered.
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
+ mLooper.dispatchAll();
verify(mWifiConfigManager).cleanupExpiredRecentFailureReasons();
}
@@ -3790,7 +3948,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
inOrder.verify(mWifiBlocklistMonitor, never())
.updateAndGetBssidBlocklistForSsids(anySet());
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
-
+ mLooper.dispatchAll();
inOrder.verify(mWifiBlocklistMonitor).tryEnablingBlockedBssids(any());
inOrder.verify(mWifiConfigManager).updateNetworkSelectionStatus(disabledConfig.networkId,
WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE);
@@ -3933,7 +4091,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, ClientModeImpl.SUPPLICANT_BSSID_ANY);
}
@@ -3970,7 +4128,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
verify(mPrimaryClientModeManager).enableRoaming(false);
@@ -3995,7 +4153,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
}
@@ -4023,12 +4181,12 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Set screen to on
setScreenState(true);
-
+ mLooper.dispatchAll();
// Set WiFi to disconnected state
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
}
@@ -4047,7 +4205,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Set screen to on
setScreenState(true);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager).startRoamToNetwork(eq(CANDIDATE_NETWORK_ID),
mCandidateBssidCaptor.capture());
assertEquals(mCandidateBssidCaptor.getValue(), CANDIDATE_BSSID);
@@ -4073,7 +4231,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Set screen to on
setScreenState(true);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager, never()).startRoamToNetwork(anyInt(), anyObject());
verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
anyInt(), anyInt(), anyObject());
@@ -4108,7 +4266,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
verify(mPrimaryClientModeManager, times(0)).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
}
@@ -4253,7 +4411,6 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
// We should have filtered out the 3rd scan result.
assertEquals(3, capturedScanDetails.size());
List<ScanResult> capturedScanResults =
@@ -4313,7 +4470,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
mPrimaryClientModeManager,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
// We should not filter any of the scan results.
assertEquals(4, capturedScanDetails.size());
List<ScanResult> capturedScanResults =
@@ -4354,16 +4511,16 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Enable trusted connection. This should NOT trigger a pno scan for auto-join.
mWifiConnectivityManager.setTrustedConnectionAllowed(true);
- verify(mWifiScanner, never()).startDisconnectedPnoScan(any(), any(), any(), any());
+ verify(mWifiScanner, never()).startPnoScan(any(), any(), any());
// End of processing a specific request. This should NOT trigger a new pno scan for
// auto-join.
mWifiConnectivityManager.setSpecificNetworkRequestInProgress(false);
- verify(mWifiScanner, never()).startDisconnectedPnoScan(any(), any(), any(), any());
+ verify(mWifiScanner, never()).startPnoScan(any(), any(), any());
// Enable untrusted connection. This should NOT trigger a pno scan for auto-join.
mWifiConnectivityManager.setUntrustedConnectionAllowed(true);
- verify(mWifiScanner, never()).startDisconnectedPnoScan(any(), any(), any(), any());
+ verify(mWifiScanner, never()).startPnoScan(any(), any(), any());
}
/**
@@ -4390,7 +4547,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Enable trusted connection. This should trigger a pno scan for auto-join.
mWifiConnectivityManager.setTrustedConnectionAllowed(true);
- verify(mWifiScanner).startDisconnectedPnoScan(any(), any(), any(), any());
+ verify(mWifiScanner).startPnoScan(any(), any(), any());
// Start of processing a specific request. This should stop any pno scan for auto-join.
mWifiConnectivityManager.setSpecificNetworkRequestInProgress(true);
@@ -4399,7 +4556,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// End of processing a specific request. This should now trigger a new pno scan for
// auto-join.
mWifiConnectivityManager.setSpecificNetworkRequestInProgress(false);
- verify(mWifiScanner, times(2)).startDisconnectedPnoScan(any(), any(), any(), any());
+ verify(mWifiScanner, times(2)).startPnoScan(any(), any(), any());
// Disable trusted connection. This should stop any pno scan for auto-join.
mWifiConnectivityManager.setTrustedConnectionAllowed(false);
@@ -4407,7 +4564,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Enable untrusted connection. This should trigger a pno scan for auto-join.
mWifiConnectivityManager.setUntrustedConnectionAllowed(true);
- verify(mWifiScanner, times(3)).startDisconnectedPnoScan(any(), any(), any(), any());
+ verify(mWifiScanner, times(3)).startPnoScan(any(), any(), any());
}
/**
@@ -4457,8 +4614,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
ScanSettings.class);
InOrder inOrder = inOrder(mWifiScanner);
- inOrder.verify(mWifiScanner).startDisconnectedPnoScan(
- scanSettingsCaptor.capture(), any(), any(), any());
+ inOrder.verify(mWifiScanner).startPnoScan(scanSettingsCaptor.capture(), any(), any());
assertEquals(interval, scanSettingsCaptor.getValue().periodInMs);
}
@@ -4480,8 +4636,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
ScanSettings.class);
InOrder inOrder = inOrder(mWifiScanner);
- inOrder.verify(mWifiScanner).startDisconnectedPnoScan(
- scanSettingsCaptor.capture(), any(), any(), any());
+ inOrder.verify(mWifiScanner).startPnoScan(scanSettingsCaptor.capture(), any(), any());
assertEquals(scanSettingsCaptor.getValue().periodInMs, MOVING_PNO_SCAN_INTERVAL_MILLIS);
// initial connectivity state uses moving PNO scan interval, now set it to stationary
@@ -4489,8 +4644,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
WifiManager.DEVICE_MOBILITY_STATE_STATIONARY);
inOrder.verify(mWifiScanner).stopPnoScan(any());
- inOrder.verify(mWifiScanner).startDisconnectedPnoScan(
- scanSettingsCaptor.capture(), any(), any(), any());
+ inOrder.verify(mWifiScanner).startPnoScan(scanSettingsCaptor.capture(), any(), any());
assertEquals(scanSettingsCaptor.getValue().periodInMs, STATIONARY_PNO_SCAN_INTERVAL_MILLIS);
verify(mScoringParams, times(2)).getEntryRssi(ScanResult.BAND_6_GHZ_START_FREQ_MHZ);
verify(mScoringParams, times(2)).getEntryRssi(ScanResult.BAND_5_GHZ_START_FREQ_MHZ);
@@ -4515,8 +4669,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
ScanSettings.class);
InOrder inOrder = inOrder(mWifiScanner);
inOrder.verify(mWifiScanner, never()).stopPnoScan(any());
- inOrder.verify(mWifiScanner).startDisconnectedPnoScan(
- scanSettingsCaptor.capture(), any(), any(), any());
+ inOrder.verify(mWifiScanner).startPnoScan(scanSettingsCaptor.capture(), any(), any());
assertEquals(scanSettingsCaptor.getValue().periodInMs, MOVING_PNO_SCAN_INTERVAL_MILLIS);
mWifiConnectivityManager.setDeviceMobilityState(
@@ -4540,7 +4693,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
WifiManager.DEVICE_MOBILITY_STATE_STATIONARY);
// no scans should start or stop because no PNO scan is running
- verify(mWifiScanner, never()).startDisconnectedPnoScan(any(), any(), any(), any());
+ verify(mWifiScanner, never()).startPnoScan(any(), any(), any());
verify(mWifiScanner, never()).stopPnoScan(any());
// starts a PNO scan
@@ -4552,8 +4705,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
ArgumentCaptor<ScanSettings> scanSettingsCaptor = ArgumentCaptor.forClass(
ScanSettings.class);
- verify(mWifiScanner).startDisconnectedPnoScan(
- scanSettingsCaptor.capture(), any(), any(), any());
+ verify(mWifiScanner).startPnoScan(scanSettingsCaptor.capture(), any(), any());
// check that now the PNO scan uses the stationary interval, even though it was set before
// the PNO scan started
assertEquals(scanSettingsCaptor.getValue().periodInMs, STATIONARY_PNO_SCAN_INTERVAL_MILLIS);
@@ -4622,7 +4774,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Force a connectivity scan
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
-
+ mLooper.dispatchAll();
verify(mWifiChannelUtilization).refreshChannelStatsAndChannelUtilization(
llstats, WifiChannelUtilization.UNKNOWN_FREQ);
}
@@ -4667,17 +4819,17 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Auto-join enabled
mWifiConnectivityManager.setAutoJoinEnabledExternal(true, false);
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
- verify(mWifiScanner).startScan(any(), any(), any(), any());
+ verify(mWifiScanner).startScan(any(), any());
// Auto-join disabled, no new scans
mWifiConnectivityManager.setAutoJoinEnabledExternal(false, false);
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
- verify(mWifiScanner, times(1)).startScan(any(), any(), any(), any());
+ verify(mWifiScanner, times(1)).startScan(any(), any());
// Wifi disabled, no new scans
setWifiEnabled(false);
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
- verify(mWifiScanner, times(1)).startScan(any(), any(), any(), any());
+ verify(mWifiScanner, times(1)).startScan(any(), any());
}
@Test
@@ -4792,11 +4944,12 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
InOrder inOrder = inOrder(mWifiScanner, mExternalPnoScanRequestManager);
- inOrder.verify(mWifiScanner).startDisconnectedPnoScan(any(), any(), any(), any());
+ inOrder.verify(mWifiScanner).startPnoScan(any(), any(), any());
inOrder.verify(mExternalPnoScanRequestManager).onScanResultsAvailable(any());
// mock connectivity scan
mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE);
+ mLooper.dispatchAll();
// verify mExternalPnoScanRequestManager is notified again
inOrder.verify(mExternalPnoScanRequestManager).onScanResultsAvailable(any());
}
@@ -4811,14 +4964,21 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
WifiConfiguration network1 = WifiConfigurationTestUtil.createEapNetwork();
WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
WifiConfiguration network3 = WifiConfigurationTestUtil.createOpenHiddenNetwork();
+ WifiConfiguration network4 = WifiConfigurationTestUtil.createEapNetwork(
+ WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
+ network4.carrierId = 123; // Assign a valid carrier ID
network1.getNetworkSelectionStatus().setHasEverConnected(true);
network2.getNetworkSelectionStatus().setHasEverConnected(true);
network3.getNetworkSelectionStatus().setHasEverConnected(true);
+ network4.getNetworkSelectionStatus().setHasEverConnected(true);
+ when(mWifiCarrierInfoManager.isSimReady(anyInt())).thenReturn(true);
List<WifiConfiguration> networkList = new ArrayList<>();
networkList.add(network1);
networkList.add(network2);
networkList.add(network3);
+ networkList.add(network4);
+ mLruConnectionTracker.addNetwork(network4);
mLruConnectionTracker.addNetwork(network3);
mLruConnectionTracker.addNetwork(network2);
mLruConnectionTracker.addNetwork(network1);
@@ -4827,15 +4987,18 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
List<WifiScanner.PnoSettings.PnoNetwork> pnoNetworks =
mWifiConnectivityManager.retrievePnoNetworkList();
verify(mWifiNetworkSuggestionsManager).getAllScanOptimizationSuggestionNetworks();
- assertEquals(4, pnoNetworks.size());
+ assertEquals(5, pnoNetworks.size());
assertEquals(network1.SSID, pnoNetworks.get(0).ssid);
assertEquals(UNTRANSLATED_HEX_SSID, pnoNetworks.get(1).ssid); // Possible untranslated SSID
assertEquals(network2.SSID, pnoNetworks.get(2).ssid);
assertEquals(network3.SSID, pnoNetworks.get(3).ssid);
+ assertEquals(network4.SSID, pnoNetworks.get(4).ssid);
// Now permanently disable |network3|. This should remove network 3 from the list.
network3.getNetworkSelectionStatus().setNetworkSelectionStatus(
WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
+ // Mock the SIM card to be not ready. This should remove network 4 from the list.
+ when(mWifiCarrierInfoManager.isSimReady(anyInt())).thenReturn(false);
// Retrieve the Pno network list & verify.
pnoNetworks = mWifiConnectivityManager.retrievePnoNetworkList();
@@ -5075,7 +5238,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
InOrder inOrder = inOrder(mWifiScanner);
- inOrder.verify(mWifiScanner).startDisconnectedPnoScan(any(), any(), any(), any());
+ inOrder.verify(mWifiScanner).startPnoScan(any(), any(), any());
// Add or update suggestions.
mSuggestionUpdateListenerCaptor.getValue().onSuggestionsAddedOrUpdated(
@@ -5084,7 +5247,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mNetworkUpdateListenerCaptor.getValue().onNetworkAdded(new WifiConfiguration());
// Ensure that we don't immediately restarted PNO.
inOrder.verify(mWifiScanner, never()).stopPnoScan(any());
- inOrder.verify(mWifiScanner, never()).startDisconnectedPnoScan(any(), any(), any(), any());
+ inOrder.verify(mWifiScanner, never()).startPnoScan(any(), any(), any());
// Verify there is only 1 delayed scan scheduled
assertEquals(1, mTestHandler.getIntervals().size());
@@ -5096,7 +5259,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Ensure that we restarted PNO.
inOrder.verify(mWifiScanner).stopPnoScan(any());
- inOrder.verify(mWifiScanner).startDisconnectedPnoScan(any(), any(), any(), any());
+ inOrder.verify(mWifiScanner).startPnoScan(any(), any(), any());
}
@Test
@@ -5110,7 +5273,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(primaryCmm.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
when(primaryCmm.isConnected()).thenReturn(false);
when(primaryCmm.isDisconnected()).thenReturn(true);
- when(primaryCmm.syncRequestConnectionInfo()).thenReturn(wifiInfo1);
+ when(primaryCmm.getConnectionInfo()).thenReturn(wifiInfo1);
ConcreteClientModeManager secondaryCmm = mock(ConcreteClientModeManager.class);
WifiInfo wifiInfo2 = mock(WifiInfo.class);
@@ -5118,7 +5281,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(secondaryCmm.getRole()).thenReturn(ROLE_CLIENT_SECONDARY_LONG_LIVED);
when(secondaryCmm.isConnected()).thenReturn(false);
when(secondaryCmm.isDisconnected()).thenReturn(true);
- when(secondaryCmm.syncRequestConnectionInfo()).thenReturn(wifiInfo2);
+ when(secondaryCmm.getConnectionInfo()).thenReturn(wifiInfo2);
when(mActiveModeWarden.getInternetConnectivityClientModeManagers())
.thenReturn(Arrays.asList(primaryCmm, secondaryCmm));
@@ -5127,7 +5290,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
primaryCmm,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
List<WifiNetworkSelector.ClientModeManagerState> expectedCmmStates =
Arrays.asList(new WifiNetworkSelector.ClientModeManagerState(
"wlan0", false, true, wifiInfo1),
@@ -5152,7 +5315,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(primaryCmm.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
when(primaryCmm.isConnected()).thenReturn(false);
when(primaryCmm.isDisconnected()).thenReturn(true);
- when(primaryCmm.syncRequestConnectionInfo()).thenReturn(wifiInfo1);
+ when(primaryCmm.getConnectionInfo()).thenReturn(wifiInfo1);
when(mActiveModeWarden.getInternetConnectivityClientModeManagers())
.thenReturn(Arrays.asList(primaryCmm));
@@ -5164,7 +5327,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
mWifiConnectivityManager.handleConnectionStateChanged(
primaryCmm,
WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
+ mLooper.dispatchAll();
List<WifiNetworkSelector.ClientModeManagerState> expectedCmmStates =
Arrays.asList(new WifiNetworkSelector.ClientModeManagerState(
"wlan0", false, true, wifiInfo1),
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 bb90b345b6..3a23a66c7b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
@@ -115,7 +115,7 @@ public class WifiCountryCodeTest extends WifiBaseTest {
when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
when(mClientModeManager.setCountryCode(anyString())).thenReturn(true);
when(mClientModeManager.isConnected()).thenReturn(true);
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(mWifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(mWifiInfo);
when(mWifiInfo.getSuccessfulTxPacketsPerSecond()).thenReturn(10.0);
when(mWifiInfo.getSuccessfulRxPacketsPerSecond()).thenReturn(5.0);
when(mContext.getSystemService(Context.TELEPHONY_SERVICE))
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 c5b3d06b54..fca154f2bc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
@@ -82,12 +83,14 @@ public class WifiDialogManagerTest extends WifiBaseTest {
@Mock FrameworkFacade mFrameworkFacade;
@Mock Resources mResources;
@Mock PowerManager mPowerManager;
+ @Mock ActivityManager mActivityManager;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mWifiContext.getWifiDialogApkPkgName()).thenReturn(WIFI_DIALOG_APK_PKG_NAME);
when(mWifiContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
+ when(mWifiContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
when(mWifiContext.getResources()).thenReturn(mResources);
when(mPowerManager.isInteractive()).thenReturn(true);
doThrow(SecurityException.class).when(mWifiContext).startActivityAsUser(any(), any(),
@@ -326,6 +329,7 @@ public class WifiDialogManagerTest extends WifiBaseTest {
dismissDialogSynchronous(dialogHandle, mWifiThreadRunner);
intent = verifyStartActivityAsUser(2, mWifiContext);
verifyDismissIntent(intent);
+ verify(mActivityManager).forceStopPackage(WIFI_DIALOG_APK_PKG_NAME);
// A reply to the same dialog id should not trigger callback
wifiDialogManager.replyToSimpleDialog(dialogId, WifiManager.DIALOG_REPLY_POSITIVE);
@@ -1004,6 +1008,7 @@ public class WifiDialogManagerTest extends WifiBaseTest {
dismissDialogSynchronous(dialogHandle, mWifiThreadRunner);
intent = verifyStartActivityAsUser(2, mWifiContext);
verifyDismissIntent(intent);
+ verify(mActivityManager).forceStopPackage(WIFI_DIALOG_APK_PKG_NAME);
// A reply to the same dialog id should not trigger callback
wifiDialogManager.replyToP2pInvitationReceivedDialog(dialogId, true, null);
@@ -1119,6 +1124,7 @@ public class WifiDialogManagerTest extends WifiBaseTest {
TEST_DEVICE_NAME, null);
dismissDialogSynchronous(dialogHandle, mWifiThreadRunner);
verifyDismissIntent(verifyStartActivityAsUser(2, mWifiContext));
+ verify(mActivityManager).forceStopPackage(WIFI_DIALOG_APK_PKG_NAME);
// Another call to dismiss should not send another dismiss intent.
dismissDialogSynchronous(dialogHandle, mWifiThreadRunner);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java
index b186ab7e6d..5509711bfc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java
@@ -37,12 +37,11 @@ import android.net.wifi.ScanResult.InformationElement;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiScanner.ScanData;
-import android.net.wifi.WifiScanner.ScanListener;
import android.net.wifi.WifiScanner.ScanSettings;
import android.net.wifi.WifiSsid;
import android.os.Build;
-import android.os.Handler;
import android.os.test.TestLooper;
+import android.util.LocalLog;
import androidx.test.filters.SmallTest;
@@ -56,6 +55,7 @@ import com.android.server.wifi.WifiScoreCard.PerNetwork;
import com.android.server.wifi.proto.WifiScoreCardProto.SystemInfoStats;
import com.android.server.wifi.proto.WifiStatsLog;
import com.android.server.wifi.proto.nano.WifiMetricsProto.HealthMonitorMetrics;
+import com.android.server.wifi.scanner.WifiScannerInternal;
import com.android.wifi.resources.R;
import org.junit.Before;
@@ -127,9 +127,10 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
private TestAlarmManager mAlarmManager;
private TestLooper mLooper = new TestLooper();
private List<WifiConfiguration> mConfiguredNetworks;
- private WifiScanner mWifiScanner;
+ private WifiScannerInternal mWifiScanner;
private ScanData mScanData;
- private ScanListener mScanListener;
+ private ArgumentCaptor<WifiScannerInternal.ScanListener> mScanListenerArgumentCaptor =
+ ArgumentCaptor.forClass(WifiScannerInternal.ScanListener.class);
private OnNetworkUpdateListener mOnNetworkUpdateListener;
private ModeChangeCallback mModeChangeCallback;
@@ -183,7 +184,6 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
mScanData = mockScanData();
mWifiScanner = mockWifiScanner(WifiScanner.WIFI_BAND_ALL);
- when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
when(mWifiNative.getDriverVersion()).thenReturn(mDriverVersion);
when(mWifiNative.getFirmwareVersion()).thenReturn(mFirmwareVersion);
when(mDeviceConfigFacade.getConnectionFailureHighThrPercent()).thenReturn(
@@ -236,7 +236,8 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
when(mResources.getIntArray(R.array.config_wifiRssiLevelThresholds))
.thenReturn(new int[]{-88, -77, -66, -55});
mWifiHealthMonitor = new WifiHealthMonitor(mContext, mWifiInjector, mClock,
- mWifiConfigManager, mWifiScoreCard, new Handler(mLooper.getLooper()), mWifiNative,
+ mWifiConfigManager, mWifiScoreCard,
+ new RunnerHandler(mLooper.getLooper(), 100, new LocalLog(128)), mWifiNative,
"some seed", mDeviceConfigFacade, mActiveModeWarden);
mLooper.dispatchAll();
ArgumentCaptor<ModeChangeCallback> modeChangeCallbackArgumentCaptor =
@@ -299,20 +300,16 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
return scanDatas[0];
}
- WifiScanner mockWifiScanner(@WifiScanner.WifiBand int wifiBand) {
- WifiScanner scanner = mock(WifiScanner.class);
-
- doAnswer(new AnswerWithArguments() {
- public void answer(ScanListener listener) throws Exception {
- mScanListener = listener;
- }
- }).when(scanner).registerScanListener(anyObject());
+ WifiScannerInternal mockWifiScanner(@WifiScanner.WifiBand int wifiBand) {
+ WifiScannerInternal scanner = mock(WifiScannerInternal.class);
+ doNothing().when(scanner).registerScanListener(mScanListenerArgumentCaptor.capture());
ScanData[] scanDatas = new ScanData[1];
scanDatas[0] = mock(ScanData.class);
when(scanDatas[0].getScannedBandsInternal()).thenReturn(wifiBand);
doAnswer(new AnswerWithArguments() {
- public void answer(ScanSettings settings, ScanListener listener) throws Exception {
+ public void answer(ScanSettings settings, WifiScannerInternal.ScanListener listener)
+ throws Exception {
if (mScanData != null && mScanData.getResults() != null) {
for (int i = 0; i < mScanData.getResults().length; i++) {
listener.onFullResult(
@@ -322,7 +319,8 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
listener.onResults(scanDatas);
}
}).when(scanner).startScan(anyObject(), anyObject());
-
+ WifiLocalServices.removeServiceForTest(WifiScannerInternal.class);
+ WifiLocalServices.addService(WifiScannerInternal.class, scanner);
return scanner;
}
@@ -367,7 +365,7 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
assertEquals(MODULE_VERSION, mWifiHealthMonitor.getWifiStackVersion());
millisecondsPass(5000);
- mWifiScanner.startScan(mScanSettings, mScanListener);
+ mWifiScanner.startScan(mScanSettings, mScanListenerArgumentCaptor.getValue());
mAlarmManager.dispatch(WifiHealthMonitor.POST_BOOT_DETECTION_TIMER_TAG);
mLooper.dispatchAll();
// serialized now has currSoftwareBuildInfo and scan results
@@ -443,7 +441,7 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
mWifiHealthMonitor.installMemoryStoreSetUpDetectionAlarm(mMemoryStore);
setWifiEnabled(true);
millisecondsPass(5000);
- mWifiScanner.startScan(mScanSettings, mScanListener);
+ mWifiScanner.startScan(mScanSettings, mScanListenerArgumentCaptor.getValue());
mAlarmManager.dispatch(WifiHealthMonitor.POST_BOOT_DETECTION_TIMER_TAG);
mLooper.dispatchAll();
WifiSystemInfoStats wifiSystemInfoStats = mWifiHealthMonitor.getWifiSystemInfoStats();
@@ -707,7 +705,8 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
public void testFullBandScan() throws Exception {
millisecondsPass(5000);
setWifiEnabled(true);
- mWifiScanner.startScan(mScanSettings, mScanListener);
+ mWifiScanner.startScan(mScanSettings, mScanListenerArgumentCaptor.getValue());
+ mLooper.dispatchAll();
ScanStats scanStats = mWifiHealthMonitor.getWifiSystemInfoStats().getCurrScanStats();
assertEquals(1_500_000_005_000L, scanStats.getLastScanTimeMs());
assertEquals(2, scanStats.getNumBssidLastScanAbove2g());
@@ -720,10 +719,9 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
@Test
public void test2GScan() throws Exception {
mWifiScanner = mockWifiScanner(WifiScanner.WIFI_BAND_24_GHZ);
- when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
millisecondsPass(5000);
setWifiEnabled(true);
- mWifiScanner.startScan(mScanSettings, mScanListener);
+ mWifiScanner.startScan(mScanSettings, mScanListenerArgumentCaptor.getValue());
ScanStats scanStats = mWifiHealthMonitor.getWifiSystemInfoStats().getCurrScanStats();
assertEquals(TS_NONE, scanStats.getLastScanTimeMs());
assertEquals(0, scanStats.getNumBssidLastScanAbove2g());
@@ -779,10 +777,10 @@ public class WifiHealthMonitorTest extends WifiBaseTest {
// Add Above2G only scan data
mScanData = mockScanDataAbove2GOnly();
mWifiScanner = mockWifiScanner(WifiScanner.WIFI_BAND_ALL);
- when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
+
millisecondsPass(5000);
setWifiEnabled(true);
- mWifiScanner.startScan(mScanSettings, mScanListener);
+ mWifiScanner.startScan(mScanSettings, mScanListenerArgumentCaptor.getValue());
mAlarmManager.dispatch(WifiHealthMonitor.POST_BOOT_DETECTION_TIMER_TAG);
mLooper.dispatchAll();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java
index ba1dc64f07..97e2675989 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java
@@ -88,7 +88,7 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest {
when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery);
when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mClientModeManager);
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(mWifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(mWifiInfo);
when(mDeviceConfigFacade.isAbnormalConnectionBugreportEnabled()).thenReturn(true);
when(mDeviceConfigFacade.getAbnormalConnectionDurationMs()).thenReturn(
DEFAULT_ABNORMAL_CONNECTION_DURATION_MS);
@@ -293,7 +293,6 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest {
Arrays.copyOfRange(isEphemeral, 0, 2));
for (int i = 0; i < WifiLastResortWatchdog.MAX_BSSID_AGE - 1; i++) {
mLastResortWatchdog.updateAvailableNetworks(candidates);
- mLastResortWatchdog.toString();
assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[0]).age, 0);
assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[1]).age, 0);
assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[2]).age,
@@ -306,7 +305,6 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest {
// One more buffering should age and cull candidates 2 & 3
mLastResortWatchdog.updateAvailableNetworks(candidates);
assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 2);
- mLastResortWatchdog.toString();
};
/**
@@ -2238,7 +2236,8 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest {
Handler handler = mHandlerCaptor.getValue();
handler.sendMessage(handler.obtainMessage(
WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false)));
+ new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false,
+ null)));
mLooper.dispatchAll();
verify(mWifiDiagnostics, never()).takeBugReport(anyString(), anyString());
@@ -2249,7 +2248,8 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest {
2L * DEFAULT_ABNORMAL_CONNECTION_DURATION_MS + 1);
handler.sendMessage(handler.obtainMessage(
WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false)));
+ new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false,
+ null)));
mLooper.dispatchAll();
verify(mWifiDiagnostics).takeBugReport(anyString(), anyString());
@@ -2259,7 +2259,8 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest {
4L * DEFAULT_ABNORMAL_CONNECTION_DURATION_MS);
handler.sendMessage(handler.obtainMessage(
WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false)));
+ new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false,
+ null)));
mLooper.dispatchAll();
verify(mWifiDiagnostics).takeBugReport(anyString(), anyString());
}
@@ -2280,14 +2281,16 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest {
2L * DEFAULT_ABNORMAL_CONNECTION_DURATION_MS + 1);
handler.sendMessage(handler.obtainMessage(
WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(TEST_NETWORK_ID_2, TEST_WIFI_SSID, null, false)));
+ new NetworkConnectionEventInfo(TEST_NETWORK_ID_2, TEST_WIFI_SSID, null, false,
+ null)));
mLooper.dispatchAll();
verify(mWifiDiagnostics, never()).takeBugReport(anyString(), anyString());
// network1 connected after a long time, should trigger BR
handler.sendMessage(handler.obtainMessage(
WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false)));
+ new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false,
+ null)));
mLooper.dispatchAll();
verify(mWifiDiagnostics).takeBugReport(anyString(), anyString());
}
@@ -2310,7 +2313,8 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest {
Handler handler = mHandlerCaptor.getValue();
handler.sendMessage(handler.obtainMessage(
WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false)));
+ new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false,
+ null)));
mLooper.dispatchAll();
verify(mWifiDiagnostics).takeBugReport(anyString(), anyString());
}
@@ -2333,7 +2337,8 @@ public class WifiLastResortWatchdogTest extends WifiBaseTest {
Handler handler = mHandlerCaptor.getValue();
handler.sendMessage(handler.obtainMessage(
WifiMonitor.NETWORK_CONNECTION_EVENT,
- new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false)));
+ new NetworkConnectionEventInfo(TEST_NETWORK_ID, TEST_WIFI_SSID, null, false,
+ null)));
mLooper.dispatchAll();
verify(mWifiDiagnostics, never()).takeBugReport(anyString(), anyString());
}
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 f17ff64565..9618f620ab 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -1142,7 +1142,7 @@ public class WifiMetricsTest extends WifiBaseTest {
// Channel switch info should be added to the last Soft AP UP event in the list
- mWifiMetrics.addSoftApChannelSwitchedEvent(new ArrayList<>() {{ add(testSoftApInfo_2G); }},
+ mWifiMetrics.addSoftApChannelSwitchedEvent(List.of(testSoftApInfo_2G),
WifiManager.IFACE_IP_MODE_TETHERED, false);
SoftApConfiguration testSoftApConfig = new SoftApConfiguration.Builder()
.setSsid("Test_Metric_SSID")
@@ -1172,10 +1172,8 @@ public class WifiMetricsTest extends WifiBaseTest {
// Bridged mode test, total NUM_SOFT_AP_EVENT_ENTRIES_FOR_BRIDGED_AP events for bridged mode
mWifiMetrics.addSoftApUpChangedEvent(true, WifiManager.IFACE_IP_MODE_TETHERED,
SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING, true);
- mWifiMetrics.addSoftApChannelSwitchedEvent(new ArrayList<>() {{
- add(testSoftApInfo_2G);
- add(testSoftApInfo_5G);
- }},
+ mWifiMetrics.addSoftApChannelSwitchedEvent(
+ List.of(testSoftApInfo_2G, testSoftApInfo_5G),
WifiManager.IFACE_IP_MODE_TETHERED, true);
mWifiMetrics.updateSoftApConfiguration(testSoftApConfig,
@@ -5046,19 +5044,17 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiNetworkSuggestionsManager.APP_TYPE_NETWORK_PROVISIONING);
- mWifiMetrics.noteNetworkSuggestionApiListSizeHistogram(new ArrayList<Integer>() {{
- add(5);
- add(100);
- add(50);
- add(120);
- }});
+ mWifiMetrics.noteNetworkSuggestionApiListSizeHistogram(List.of(
+ 5,
+ 100,
+ 50,
+ 120));
// Second update should overwrite the prevous write.
- mWifiMetrics.noteNetworkSuggestionApiListSizeHistogram(new ArrayList<Integer>() {{
- add(7);
- add(110);
- add(40);
- add(60);
- }});
+ mWifiMetrics.noteNetworkSuggestionApiListSizeHistogram(List.of(
+ 7,
+ 110,
+ 40,
+ 60));
mWifiMetrics.incrementNetworkSuggestionUserRevokePermission();
mWifiMetrics.incrementNetworkSuggestionUserRevokePermission();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java
index d6454b4c7e..2fa5fffad4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java
@@ -31,6 +31,7 @@ import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback.WpsErro
import android.net.DscpPolicy;
import android.net.MacAddress;
import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
@@ -53,6 +54,7 @@ import org.mockito.ArgumentCaptor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.List;
/**
@@ -474,6 +476,33 @@ public class WifiMonitorTest extends WifiBaseTest {
}
/**
+ * Broadcast network connection with akm test.
+ */
+ @Test
+ public void testBroadcastNetworkConnectionEventWithAkm() {
+ mWifiMonitor.registerHandler(
+ WLAN_IFACE_NAME, WifiMonitor.NETWORK_CONNECTION_EVENT, mHandlerSpy);
+ int networkId = NETWORK_ID;
+ WifiSsid wifiSsid = WifiSsid.fromBytes(new byte[]{'a', 'b', 'c'});
+ String bssid = BSSID;
+ BitSet akm = new BitSet();
+ akm.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ mWifiMonitor.broadcastNetworkConnectionEvent(WLAN_IFACE_NAME, networkId, false,
+ wifiSsid, bssid, akm);
+ mLooper.dispatchAll();
+
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(mHandlerSpy).handleMessage(messageCaptor.capture());
+ assertEquals(WifiMonitor.NETWORK_CONNECTION_EVENT, messageCaptor.getValue().what);
+ NetworkConnectionEventInfo info = (NetworkConnectionEventInfo) messageCaptor.getValue().obj;
+ assertEquals(networkId, info.networkId);
+ assertFalse(info.isFilsConnection);
+ assertEquals(wifiSsid, info.wifiSsid);
+ assertEquals(bssid, info.bssid);
+ assertEquals(akm, info.keyMgmtMask);
+ }
+
+ /**
* Broadcast network disconnection test.
*/
@Test
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 f6215c4252..e79cd054dc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
@@ -64,6 +64,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
/**
@@ -76,6 +77,15 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
private static final String IFACE_NAME_1 = "mockWlan1";
private static final WorkSource TEST_WORKSOURCE = new WorkSource();
private static final long TEST_SUPPORTED_FEATURES = 0;
+ private static final int STA_FAILURE_CODE_START_DAEMON = 1;
+ private static final int STA_FAILURE_CODE_SETUP_INTERFACE = 2;
+ private static final int STA_FAILURE_CODE_WIFICOND_SETUP_INTERFACE = 3;
+ private static final int STA_FAILURE_CODE_CREAT_IFACE = 4;
+ private static final int SOFTAP_FAILURE_CODE_SETUP_INTERFACE = 1;
+ 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 TEST_SUPPORTED_BANDS = 15;
MockResources mResources;
@@ -142,10 +152,12 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
when(mWifiVendorHal.createApIface(any(), any(), anyInt(),
anyBoolean(), any())).thenReturn(IFACE_NAME_0);
when(mWifiVendorHal.getBridgedApInstances(any())).thenReturn(
- new ArrayList<String>() {{ add((IFACE_NAME_0)); }});
+ List.of(IFACE_NAME_0));
when(mWifiVendorHal.removeStaIface(any())).thenReturn(true);
when(mWifiVendorHal.removeApIface(any())).thenReturn(true);
when(mWifiVendorHal.replaceStaIfaceRequestorWs(any(), any())).thenReturn(true);
+ when(mWifiVendorHal.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(
+ new ArrayList<>());
when(mBuildProperties.isEngBuild()).thenReturn(false);
when(mBuildProperties.isUserdebugBuild()).thenReturn(false);
@@ -192,6 +204,9 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
when(mWifiSettingsConfigStore.get(
eq(WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_FEATURES)))
.thenReturn(TEST_SUPPORTED_FEATURES);
+ when(mWifiSettingsConfigStore.get(
+ eq(WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_STA_BANDS)))
+ .thenReturn(TEST_SUPPORTED_BANDS);
mInOrder = inOrder(mWifiVendorHal, mWificondControl, mSupplicantStaIfaceHal, mHostapdHal,
mWifiMonitor, mNetdWrapper, mIfaceCallback0, mIfaceCallback1, mWifiMetrics);
@@ -284,7 +299,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0,
mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
- mNetworkObserverCaptor0, true);
+ mNetworkObserverCaptor0, true, true, 0);
assertEquals(Set.of(IFACE_NAME_0), mWifiNative.getSoftApInterfaceNames());
assertEquals(Set.of(), mWifiNative.getClientInterfaceNames());
}
@@ -508,6 +523,31 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback1,
TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
+ validateHostApdStart();
+ // Creation of AP interface should trigger the STA interface destroy
+ validateOnDestroyedClientInterface(
+ false, true, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue());
+ // Now continue with rest of AP interface setup.
+ validateSetupInterfaceForSoftAp(IFACE_NAME_0, mNetworkObserverCaptor1);
+
+ // Execute a teardown of the interface to ensure that the new iface removal works.
+ executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback1,
+ mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
+ }
+
+ private void validateSwitchInterfaceToScan(String ifaceName, WorkSource workSource) {
+ mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
+ mInOrder.verify(mWifiVendorHal).replaceStaIfaceRequestorWs(ifaceName, workSource);
+ mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(ifaceName);
+ mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
+ mInOrder.verify(mSupplicantStaIfaceHal).terminate();
+ mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
+ mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
+ }
+
+ private void validateHostApdStart() {
mInOrder.verify(mHostapdHal).isInitializationStarted();
mInOrder.verify(mHostapdHal).initialize();
mInOrder.verify(mHostapdHal).startDaemon();
@@ -517,20 +557,31 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mWifiVendorHal).createApIface(
mIfaceDestroyedListenerCaptor1.capture(), eq(TEST_WORKSOURCE), anyInt(), eq(false),
eq(mSoftApManager));
- // Creation of AP interface should trigger the STA interface destroy
- validateOnDestroyedClientInterface(
- false, true, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue());
- // Now continue with rest of AP interface setup.
- mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).registerObserver(mNetworkObserverCaptor1.capture());
- mInOrder.verify(mNetdWrapper).isInterfaceUp(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(IFACE_NAME_0);
+ }
- // Execute a teardown of the interface to ensure that the new iface removal works.
- executeAndValidateTeardownSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback1,
- mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
+ private void validateSetupInterfaceForScan(String ifaceName,
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor) {
+ mInOrder.verify(mWificondControl).setupInterfaceForClientMode(eq(ifaceName), any(),
+ any(), any());
+ mInOrder.verify(mNetdWrapper).registerObserver(networkObserverCaptor.capture());
+ mInOrder.verify(mWifiMonitor).startMonitoring(ifaceName);
+ mInOrder.verify(mNetdWrapper).isInterfaceUp(ifaceName);
+ mInOrder.verify(mWifiVendorHal).enableLinkLayerStats(ifaceName);
+ mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
+ mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
+ }
+
+ private void validateSetupInterfaceForSoftAp(String ifaceName,
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor) {
+ mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(ifaceName);
+ mInOrder.verify(mNetdWrapper).registerObserver(networkObserverCaptor.capture());
+ mInOrder.verify(mNetdWrapper).isInterfaceUp(ifaceName);
+ mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
+ mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
/**
@@ -554,14 +605,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
}).when(mWifiVendorHal).createStaIface(any(), any());
assertEquals(IFACE_NAME_0,
- mWifiNative.setupInterfaceForClientInConnectivityMode(
- mIfaceCallback1, TEST_WORKSOURCE));
-
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
- mInOrder.verify(mSupplicantStaIfaceHal).initialize();
- mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
- mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
+ mWifiNative.setupInterfaceForClientInScanMode(mIfaceCallback1, TEST_WORKSOURCE));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).createStaIface(
mIfaceDestroyedListenerCaptor1.capture(), eq(TEST_WORKSOURCE));
@@ -569,23 +613,12 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
validateOnDestroyedSoftApInterface(
true, false, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue());
// Now continue with rest of STA interface setup.
- mInOrder.verify(mWificondControl).setupInterfaceForClientMode(eq(IFACE_NAME_0), any(),
- any(), any());
- mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).registerObserver(mNetworkObserverCaptor1.capture());
- mInOrder.verify(mWifiMonitor).startMonitoring(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).isInterfaceUp(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).enableLinkLayerStats(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).clearInterfaceAddresses(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).setInterfaceIpv6PrivacyExtensions(IFACE_NAME_0, true);
- mInOrder.verify(mNetdWrapper).disableIpv6(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(IFACE_NAME_0);
+ validateSetupInterfaceForScan(IFACE_NAME_0, mNetworkObserverCaptor1);
// Execute a teardown of the interface to ensure that the new iface removal works.
- executeAndValidateTeardownClientInterface(false, false, IFACE_NAME_0, mIfaceCallback1,
- mIfaceDestroyedListenerCaptor1.getValue(), mNetworkObserverCaptor1.getValue());
+ executeAndValidateTeardownClientInterfaceForScan(false, false, IFACE_NAME_0,
+ mIfaceCallback1, mIfaceDestroyedListenerCaptor1.getValue(),
+ mNetworkObserverCaptor1.getValue());
}
/**
@@ -779,25 +812,12 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback1,
TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
- mInOrder.verify(mHostapdHal).isInitializationStarted();
- mInOrder.verify(mHostapdHal).initialize();
- mInOrder.verify(mHostapdHal).startDaemon();
- mInOrder.verify(mHostapdHal).isInitializationComplete();
- mInOrder.verify(mHostapdHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createApIface(
- mIfaceDestroyedListenerCaptor1.capture(), eq(TEST_WORKSOURCE), anyInt(), eq(false),
- eq(mSoftApManager));
+ validateHostApdStart();
// Creation of AP interface should trigger the STA interface destroy
validateOnDestroyedClientInterface(
false, true, IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue());
// Now continue with rest of AP interface setup.
- mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).registerObserver(mNetworkObserverCaptor1.capture());
- mInOrder.verify(mNetdWrapper).isInterfaceUp(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(IFACE_NAME_0);
+ validateSetupInterfaceForSoftAp(IFACE_NAME_0, mNetworkObserverCaptor1);
// Step (c) - Iface up on old iface, ignored!
mNetworkObserverCaptor0.getValue().interfaceLinkStateChanged(IFACE_NAME_0, true);
@@ -875,7 +895,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
when(mHostapdHal.isApInfoCallbackSupported()).thenReturn(true);
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
- mNetworkObserverCaptor0, false);
+ mNetworkObserverCaptor0, false, true, 0);
// Start softap
assertTrue(mWifiNative.startSoftAp(IFACE_NAME_0, new SoftApConfiguration.Builder().build(),
@@ -902,7 +922,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
public void testStartSoftApWithWifiCondCallbackAndHostapdDied() throws Exception {
executeAndValidateSetupSoftApInterface(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
- mNetworkObserverCaptor0, false);
+ mNetworkObserverCaptor0, false, true, 0);
// Start softap
assertTrue(mWifiNative.startSoftAp(IFACE_NAME_0, new SoftApConfiguration.Builder().build(),
@@ -922,23 +942,36 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
verify(mStatusListener).onStatusChanged(true);
}
+ private void validateInterfaceTearDown(String ifaceName) {
+ // To test if the failure is handled cleanly, invoke teardown and ensure that
+ // none of the mocks are used because the iface does not exist in the internal
+ // database.
+ if (mWifiNative.hasAnyIface()) {
+ mWifiNative.teardownInterface(ifaceName);
+ mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
+ if (mWifiNative.hasAnyStaIfaceForScan()) {
+ mInOrder.verify(mWifiVendorHal).removeStaIface(anyString());
+ }
+ if (mWifiNative.hasAnyApIface()) {
+ mInOrder.verify(mWifiVendorHal).removeApIface(anyString());
+ }
+ }
+ }
+
/**
* Verifies failure handling in setup of a client interface.
*/
@Test
public void testSetupClientInterfaceFailureInStartHal() throws Exception {
when(mWifiVendorHal.startVendorHal()).thenReturn(false);
- assertNull(mWifiNative.setupInterfaceForClientInConnectivityMode(
+ assertNull(mWifiNative.setupInterfaceForClientInScanMode(
mIfaceCallback0, TEST_WORKSOURCE));
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToHal();
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -946,25 +979,14 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
*/
@Test
public void testSetupClientInterfaceFailureInStartSupplicant() throws Exception {
+ executeAndValidateSetupClientInterfaceForScan(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0);
when(mSupplicantStaIfaceHal.startDaemon()).thenReturn(false);
- assertNull(mWifiNative.setupInterfaceForClientInConnectivityMode(
- mIfaceCallback0, TEST_WORKSOURCE));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
- mInOrder.verify(mSupplicantStaIfaceHal).initialize();
- mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
- mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToSupplicant();
+ executeAndValidateSwitchClientInterfaceToConnectivityMode(false, false, IFACE_NAME_0,
+ TEST_WORKSOURCE, true, STA_FAILURE_CODE_START_DAEMON);
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -973,28 +995,11 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
@Test
public void testSetupClientInterfaceFailureInHalCreateStaIface() throws Exception {
when(mWifiVendorHal.createStaIface(any(), any())).thenReturn(null);
- assertNull(mWifiNative.setupInterfaceForClientInConnectivityMode(
- mIfaceCallback0, TEST_WORKSOURCE));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
- mInOrder.verify(mSupplicantStaIfaceHal).initialize();
- mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
- mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createStaIface(any(), any());
- mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToHal();
+ executeAndValidateSetupClientInterfaceForScan(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0, true, STA_FAILURE_CODE_CREAT_IFACE);
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -1005,37 +1010,17 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
throws Exception {
when(mWificondControl.setupInterfaceForClientMode(any(), any(), any(), any())).thenReturn(
false);
- assertNull(mWifiNative.setupInterfaceForClientInConnectivityMode(
- mIfaceCallback0, TEST_WORKSOURCE));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
- mInOrder.verify(mSupplicantStaIfaceHal).initialize();
- mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
- mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createStaIface(
- mIfaceDestroyedListenerCaptor0.capture(), eq(TEST_WORKSOURCE));
- mInOrder.verify(mWificondControl).setupInterfaceForClientMode(any(), any(), any(), any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).removeStaIface(any());
- mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToWificond();
+ assertNull(mWifiNative.setupInterfaceForClientInScanMode(mIfaceCallback0, TEST_WORKSOURCE));
+ validateSetupClientInterfaceForScan(
+ false, false, IFACE_NAME_0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0, true, STA_FAILURE_CODE_WIFICOND_SETUP_INTERFACE);
// Trigger the HAL interface destroyed callback to verify the whole removal sequence.
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
- validateOnDestroyedClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
+ validateOnDestroyedClientInterfaceForScan(false, false, IFACE_NAME_0, mIfaceCallback0,
null);
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -1043,39 +1028,19 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
*/
@Test
public void testSetupClientInterfaceFailureInSupplicantSetupIface() throws Exception {
+ executeAndValidateSetupClientInterfaceForScan(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0);
when(mSupplicantStaIfaceHal.setupIface(any())).thenReturn(false);
- assertNull(mWifiNative.setupInterfaceForClientInConnectivityMode(
- mIfaceCallback0, TEST_WORKSOURCE));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
- mInOrder.verify(mSupplicantStaIfaceHal).initialize();
- mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
- mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createStaIface(
- mIfaceDestroyedListenerCaptor0.capture(), eq(TEST_WORKSOURCE));
- mInOrder.verify(mWificondControl).setupInterfaceForClientMode(any(), any(), any(), any());
- mInOrder.verify(mSupplicantStaIfaceHal).setupIface(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).removeStaIface(any());
- mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToSupplicant();
+ executeAndValidateSwitchClientInterfaceToConnectivityMode(false, false, IFACE_NAME_0,
+ TEST_WORKSOURCE, true, STA_FAILURE_CODE_SETUP_INTERFACE);
// Trigger the HAL interface destroyed callback to verify the whole removal sequence.
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
- validateOnDestroyedClientInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
- null);
+ validateOnDestroyedClientInterfaceForScan(false, false, IFACE_NAME_0, mIfaceCallback0,
+ mNetworkObserverCaptor0.getValue());
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -1091,10 +1056,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mWifiVendorHal).startVendorHal();
mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHal();
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -1103,24 +1065,10 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
@Test
public void testSetupSoftApInterfaceFailureInStartHostapd() throws Exception {
when(mHostapdHal.startDaemon()).thenReturn(false);
- assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0, TEST_WORKSOURCE,
- SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mHostapdHal).isInitializationStarted();
- mInOrder.verify(mHostapdHal).initialize();
- mInOrder.verify(mHostapdHal).startDaemon();
- mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHostapd();
-
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ executeAndValidateSetupSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
+ mIfaceDestroyedListenerCaptor0, mNetworkObserverCaptor0,
+ false, true, SOFTAP_FAILURE_CODE_START_DAEMON);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -1128,31 +1076,11 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
*/
@Test
public void testSetupSoftApInterfaceFailureInHalCreateApIface() throws Exception {
- when(mWifiVendorHal.createApIface(any(), any(), anyInt(), anyBoolean(), any()))
- .thenReturn(null);
- assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0, TEST_WORKSOURCE,
- SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mHostapdHal).isInitializationStarted();
- mInOrder.verify(mHostapdHal).initialize();
- mInOrder.verify(mHostapdHal).startDaemon();
- mInOrder.verify(mHostapdHal).isInitializationComplete();
- mInOrder.verify(mHostapdHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createApIface(any(), any(), anyInt(), anyBoolean(),
- eq(mSoftApManager));
- mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHal();
+ executeAndValidateSetupSoftApInterface(
+ false, false, null, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0, false, true, SOFTAP_FAILURE_CODE_CREATE_IFACE);
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -1161,39 +1089,16 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
@Test
public void testSetupSoftApInterfaceFailureInHalGetBridgedInstances() throws Exception {
when(mWifiVendorHal.getBridgedApInstances(any())).thenReturn(null);
- assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0, TEST_WORKSOURCE,
- SoftApConfiguration.BAND_2GHZ, true, mSoftApManager));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mHostapdHal).isInitializationStarted();
- mInOrder.verify(mHostapdHal).initialize();
- mInOrder.verify(mHostapdHal).startDaemon();
- mInOrder.verify(mHostapdHal).isInitializationComplete();
- mInOrder.verify(mHostapdHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createApIface(
- mIfaceDestroyedListenerCaptor0.capture(), eq(TEST_WORKSOURCE), anyInt(), eq(true),
- eq(mSoftApManager));
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).getBridgedApInstances(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).removeApIface(any());
- mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHal();
+ executeAndValidateSetupSoftApInterface(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0, true, true, SOFTAP_FAILURE_CODE_BRIDGED_AP_INSTANCES);
// Trigger the HAL interface destroyed callback to verify the whole removal sequence.
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
validateOnDestroyedSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
null);
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -1203,38 +1108,16 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
public void testSetupSoftApInterfaceFailureInWificondSetupInterfaceForSoftapMode()
throws Exception {
when(mWificondControl.setupInterfaceForSoftApMode(any())).thenReturn(false);
- assertNull(mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0, TEST_WORKSOURCE,
- SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mHostapdHal).isInitializationStarted();
- mInOrder.verify(mHostapdHal).initialize();
- mInOrder.verify(mHostapdHal).startDaemon();
- mInOrder.verify(mHostapdHal).isInitializationComplete();
- mInOrder.verify(mHostapdHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createApIface(
- mIfaceDestroyedListenerCaptor0.capture(), eq(TEST_WORKSOURCE), anyInt(), eq(false),
- eq(mSoftApManager));
- mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).removeApIface(any());
- mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToWificond();
+ executeAndValidateSetupSoftApInterface(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0, false, true, SOFTAP_FAILURE_CODE_SETUP_INTERFACE);
// Trigger the HAL interface destroyed callback to verify the whole removal sequence.
mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0);
validateOnDestroyedSoftApInterface(false, false, IFACE_NAME_0, mIfaceCallback0,
null);
- // To test if the failure is handled cleanly, invoke teardown and ensure that
- // none of the mocks are used because the iface does not exist in the internal
- // database.
- mWifiNative.teardownInterface(IFACE_NAME_0);
+ validateInterfaceTearDown(IFACE_NAME_0);
}
/**
@@ -1312,61 +1195,13 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
when(mPropertyService.getString(any(), any())).thenReturn(IFACE_NAME_0);
// First setup a STA interface and verify.
- assertEquals(IFACE_NAME_0,
- mWifiNative.setupInterfaceForClientInConnectivityMode(
- mIfaceCallback0, TEST_WORKSOURCE));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
- mInOrder.verify(mSupplicantStaIfaceHal).initialize();
- mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
- mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWificondControl).setupInterfaceForClientMode(eq(IFACE_NAME_0), any(),
- any(), any());
- mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).registerObserver(mNetworkObserverCaptor0.capture());
- mInOrder.verify(mWifiMonitor).startMonitoring(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).isInterfaceUp(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).enableLinkLayerStats(eq(IFACE_NAME_0));
- mInOrder.verify(mNetdWrapper).clearInterfaceAddresses(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).setInterfaceIpv6PrivacyExtensions(IFACE_NAME_0, true);
- mInOrder.verify(mNetdWrapper).disableIpv6(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(IFACE_NAME_0);
+ executeAndValidateSetupClientInterfaceForScan(false, false, IFACE_NAME_0,
+ mIfaceCallback0, mIfaceDestroyedListenerCaptor0, mNetworkObserverCaptor0, false, 0);
// Now setup an AP interface.
- assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback1,
- TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
-
- mInOrder.verify(mHostapdHal).isInitializationStarted();
- mInOrder.verify(mHostapdHal).initialize();
- mInOrder.verify(mHostapdHal).startDaemon();
- mInOrder.verify(mHostapdHal).isInitializationComplete();
- mInOrder.verify(mHostapdHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- // Creation of AP interface should trigger the STA interface destroy
- verify(mWifiMonitor).stopMonitoring(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).unregisterObserver(
- mNetworkObserverCaptor0.getValue());
- mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(IFACE_NAME_0);
- mInOrder.verify(mWificondControl).tearDownClientInterface(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
- mInOrder.verify(mSupplicantStaIfaceHal).terminate();
- mInOrder.verify(mWifiVendorHal).isVendorHalReady();
- mInOrder.verify(mIfaceCallback0).onDestroyed(IFACE_NAME_0);
- // Now continue with rest of AP interface setup.
- mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).registerObserver(mNetworkObserverCaptor1.capture());
- mInOrder.verify(mNetdWrapper).isInterfaceUp(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(IFACE_NAME_0);
+ executeAndValidateSetupSoftApInterface(true, false, IFACE_NAME_0,
+ mIfaceCallback1, mIfaceDestroyedListenerCaptor1, mNetworkObserverCaptor1, false,
+ false, 0);
}
/**
@@ -1379,62 +1214,15 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
throws Exception {
when(mWifiVendorHal.isVendorHalSupported()).thenReturn(false);
when(mPropertyService.getString(any(), any())).thenReturn(IFACE_NAME_0);
-
// First setup an AP interface and verify.
- assertEquals(IFACE_NAME_0, mWifiNative.setupInterfaceForSoftApMode(mIfaceCallback0,
- TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- mInOrder.verify(mHostapdHal).isInitializationStarted();
- mInOrder.verify(mHostapdHal).initialize();
- mInOrder.verify(mHostapdHal).startDaemon();
- mInOrder.verify(mHostapdHal).isInitializationComplete();
- mInOrder.verify(mHostapdHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).registerObserver(mNetworkObserverCaptor0.capture());
- mInOrder.verify(mNetdWrapper).isInterfaceUp(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(IFACE_NAME_0);
+ executeAndValidateSetupSoftApInterface(false, false, IFACE_NAME_0,
+ mIfaceCallback0, mIfaceDestroyedListenerCaptor0, mNetworkObserverCaptor0, false,
+ false, 0);
// Now setup a STA interface.
- assertEquals(IFACE_NAME_0,
- mWifiNative.setupInterfaceForClientInConnectivityMode(
- mIfaceCallback1, TEST_WORKSOURCE));
-
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
- mInOrder.verify(mSupplicantStaIfaceHal).initialize();
- mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
- mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- // Creation of STA interface should trigger the AP interface destroy.
- mInOrder.verify(mNetdWrapper).unregisterObserver(
- mNetworkObserverCaptor0.getValue());
- mInOrder.verify(mHostapdHal).removeAccessPoint(IFACE_NAME_0);
- mInOrder.verify(mWificondControl).tearDownSoftApInterface(IFACE_NAME_0);
- mInOrder.verify(mHostapdHal).deregisterDeathHandler();
- mInOrder.verify(mHostapdHal).terminate();
- mInOrder.verify(mWifiVendorHal).isVendorHalReady();
- mInOrder.verify(mIfaceCallback0).onDestroyed(IFACE_NAME_0);
- // Now continue with rest of STA interface setup.
- mInOrder.verify(mWificondControl).setupInterfaceForClientMode(eq(IFACE_NAME_0), any(),
- any(), any());
- mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).registerObserver(mNetworkObserverCaptor1.capture());
- mInOrder.verify(mWifiMonitor).startMonitoring(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).isInterfaceUp(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).enableLinkLayerStats(eq(IFACE_NAME_0));
- mInOrder.verify(mNetdWrapper).clearInterfaceAddresses(IFACE_NAME_0);
- mInOrder.verify(mNetdWrapper).setInterfaceIpv6PrivacyExtensions(IFACE_NAME_0, true);
- mInOrder.verify(mNetdWrapper).disableIpv6(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(IFACE_NAME_0);
+ executeAndValidateSetupClientInterface(
+ false, true, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0, false, 0);
}
/**
@@ -1467,15 +1255,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
assertTrue(mWifiNative.switchClientInterfaceToScanMode(IFACE_NAME_0, TEST_WORKSOURCE));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).replaceStaIfaceRequestorWs(IFACE_NAME_0, TEST_WORKSOURCE);
- mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
- mInOrder.verify(mSupplicantStaIfaceHal).terminate();
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(IFACE_NAME_0);
+ validateSwitchInterfaceToScan(IFACE_NAME_0, TEST_WORKSOURCE);
}
/**
@@ -1489,6 +1269,43 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
assertTrue(mWifiNative.switchClientInterfaceToScanMode(IFACE_NAME_0, TEST_WORKSOURCE));
}
+ private void executeAndValidateSwitchClientInterfaceToConnectivityMode(
+ boolean hasStaIface, boolean hasApIface, String ifaceName, WorkSource workSource,
+ boolean vendorHalSupported, int failureCode) {
+ assertEquals(failureCode == 0 ? true : false,
+ mWifiNative.switchClientInterfaceToConnectivityMode(ifaceName, workSource));
+
+ mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
+ if (vendorHalSupported) {
+ mInOrder.verify(mWifiVendorHal).replaceStaIfaceRequestorWs(ifaceName, workSource);
+ }
+ if (!hasStaIface) {
+ mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
+ mInOrder.verify(mSupplicantStaIfaceHal).initialize();
+ mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
+ if (failureCode == STA_FAILURE_CODE_START_DAEMON) {
+ mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
+ mInOrder.verify(mWifiVendorHal).removeStaIface(ifaceName);
+ mInOrder.verify(
+ mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToSupplicant();
+ return;
+ }
+ mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
+ mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
+ }
+ mInOrder.verify(mSupplicantStaIfaceHal).setupIface(ifaceName);
+ if (failureCode == STA_FAILURE_CODE_SETUP_INTERFACE) {
+ mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
+ mInOrder.verify(mWifiVendorHal).removeStaIface(ifaceName);
+ mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToSupplicant();
+ } else {
+ mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
+ mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
+ }
+ }
+
/**
* Verifies the switch of existing client interface in scan mode to connectivity mode.
*/
@@ -1497,20 +1314,8 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
executeAndValidateSetupClientInterfaceForScan(
false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
mNetworkObserverCaptor0);
- assertTrue(mWifiNative.switchClientInterfaceToConnectivityMode(
- IFACE_NAME_0, TEST_WORKSOURCE));
-
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).replaceStaIfaceRequestorWs(IFACE_NAME_0, TEST_WORKSOURCE);
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
- mInOrder.verify(mSupplicantStaIfaceHal).initialize();
- mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
- mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
- mInOrder.verify(mSupplicantStaIfaceHal).setupIface(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(IFACE_NAME_0);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(IFACE_NAME_0);
+ executeAndValidateSwitchClientInterfaceToConnectivityMode(false, false, IFACE_NAME_0,
+ TEST_WORKSOURCE, true, 0);
}
/**
@@ -1543,54 +1348,27 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
}
private void executeAndValidateSetupClientInterface(
- boolean existingStaIface, boolean existingApIface,
+ boolean hasStaIface, boolean hasApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<NetdEventObserver> networkObserverCaptor) throws Exception {
- when(mWifiVendorHal.createStaIface(any(), any())).thenReturn(ifaceName);
- assertEquals(ifaceName, mWifiNative.setupInterfaceForClientInConnectivityMode(
- callback, TEST_WORKSOURCE));
-
- validateSetupClientInterface(
- existingStaIface, existingApIface, ifaceName, destroyedListenerCaptor,
- networkObserverCaptor);
+ executeAndValidateSetupClientInterface(hasStaIface, hasApIface, ifaceName, callback,
+ destroyedListenerCaptor,
+ networkObserverCaptor, true, 0);
}
- private void validateSetupClientInterface(
- boolean existingStaIface, boolean existingApIface,
- String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
- ArgumentCaptor<NetdEventObserver> networkObserverCaptor) throws Exception {
- if (!existingStaIface && !existingApIface) {
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- }
- if (!existingStaIface) {
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
- mInOrder.verify(mSupplicantStaIfaceHal).initialize();
- mInOrder.verify(mSupplicantStaIfaceHal).startDaemon();
- mInOrder.verify(mSupplicantStaIfaceHal).isInitializationComplete();
- mInOrder.verify(mSupplicantStaIfaceHal).registerDeathHandler(any());
- }
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createStaIface(
- destroyedListenerCaptor.capture(), eq(TEST_WORKSOURCE));
- mInOrder.verify(mWificondControl).setupInterfaceForClientMode(eq(ifaceName), any(), any(),
- any());
- mInOrder.verify(mSupplicantStaIfaceHal).setupIface(ifaceName);
- mInOrder.verify(mNetdWrapper).registerObserver(networkObserverCaptor.capture());
- mInOrder.verify(mWifiMonitor).startMonitoring(ifaceName);
- mInOrder.verify(mNetdWrapper).isInterfaceUp(ifaceName);
- mInOrder.verify(mWifiVendorHal).enableLinkLayerStats(ifaceName);
- mInOrder.verify(mNetdWrapper).clearInterfaceAddresses(ifaceName);
- mInOrder.verify(mNetdWrapper).setInterfaceIpv6PrivacyExtensions(ifaceName, true);
- mInOrder.verify(mNetdWrapper).disableIpv6(ifaceName);
- mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
- mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ private void executeAndValidateSetupClientInterface(
+ boolean hasStaIface, boolean hasApIface,
+ String ifaceName, @Mock WifiNative.InterfaceCallback callback,
+ ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported,
+ int failureCode) throws Exception {
+ when(mWifiVendorHal.createStaIface(any(), any())).thenReturn(ifaceName);
+ executeAndValidateSetupClientInterfaceForScan(
+ hasStaIface, hasApIface, ifaceName, callback, destroyedListenerCaptor,
+ networkObserverCaptor, vendorHalSupported, failureCode);
+ executeAndValidateSwitchClientInterfaceToConnectivityMode(hasStaIface, hasApIface,
+ ifaceName, TEST_WORKSOURCE, vendorHalSupported, failureCode);
}
private void executeAndValidateTeardownClientInterface(
@@ -1635,36 +1413,81 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
}
private void executeAndValidateSetupClientInterfaceForScan(
- boolean existingStaIface, boolean existingApIface,
+ boolean hasStaIface, boolean hasApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<NetdEventObserver> networkObserverCaptor) throws Exception {
- when(mWifiVendorHal.createStaIface(any(), any())).thenReturn(ifaceName);
- assertEquals(ifaceName, mWifiNative.setupInterfaceForClientInScanMode(
- callback, TEST_WORKSOURCE));
+ executeAndValidateSetupClientInterfaceForScan(hasStaIface, hasApIface, ifaceName, callback,
+ destroyedListenerCaptor, networkObserverCaptor, true, 0);
+ }
+
+ private void executeAndValidateSetupClientInterfaceForScan(
+ boolean hasStaIface, boolean hasApIface,
+ 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())).thenReturn(ifaceName);
+ }
+ assertEquals(failureCode == 0 ? ifaceName : null,
+ mWifiNative.setupInterfaceForClientInScanMode(callback, TEST_WORKSOURCE));
validateSetupClientInterfaceForScan(
- existingStaIface, existingApIface, ifaceName, destroyedListenerCaptor,
- networkObserverCaptor);
+ hasStaIface, hasApIface, ifaceName, destroyedListenerCaptor,
+ networkObserverCaptor, vendorHalSupported, failureCode);
+ }
+
+ private void validateStartHal(boolean hasAnyIface, boolean vendorHalSupported) {
+ verify(mWifiVendorHal, atLeastOnce()).isVendorHalSupported();
+ if (!hasAnyIface) {
+ if (vendorHalSupported) {
+ mInOrder.verify(mWifiVendorHal).startVendorHal();
+ if (SdkLevel.isAtLeastS()) {
+ mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
+ }
+ }
+ if (SdkLevel.isAtLeastS()) {
+ mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(),
+ any());
+ }
+ }
}
private void validateSetupClientInterfaceForScan(
- boolean existingStaIface, boolean existingApIface,
+ boolean hasStaIface, boolean hasApIface,
String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
- ArgumentCaptor<NetdEventObserver> networkObserverCaptor) throws Exception {
- if (!existingStaIface && !existingApIface) {
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported,
+ int failureCode) throws Exception {
+ validateStartHal(hasStaIface || hasApIface, vendorHalSupported);
+ if (vendorHalSupported) {
+ mInOrder.verify(mWifiVendorHal).createStaIface(
+ destroyedListenerCaptor.capture(), eq(TEST_WORKSOURCE));
+ if (failureCode == STA_FAILURE_CODE_CREAT_IFACE) {
+ verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToHal();
+ return;
+ }
+ } else {
+ if (hasApIface) {
+ // Creation of STA interface should trigger the AP interface destroy.
+ mInOrder.verify(mNetdWrapper).unregisterObserver(
+ mNetworkObserverCaptor0.getValue());
+ mInOrder.verify(mHostapdHal).removeAccessPoint(ifaceName);
+ mInOrder.verify(mWificondControl).tearDownSoftApInterface(ifaceName);
+ mInOrder.verify(mHostapdHal).deregisterDeathHandler();
+ mInOrder.verify(mHostapdHal).terminate();
+ mInOrder.verify(mWifiVendorHal).isVendorHalReady();
+ mInOrder.verify(mIfaceCallback0).onDestroyed(ifaceName);
}
}
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createStaIface(
- destroyedListenerCaptor.capture(), eq(TEST_WORKSOURCE));
mInOrder.verify(mWificondControl).setupInterfaceForClientMode(eq(ifaceName), any(), any(),
any());
+ if (failureCode == STA_FAILURE_CODE_WIFICOND_SETUP_INTERFACE) {
+ mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
+ verify(mWifiVendorHal).removeStaIface(ifaceName);
+ verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToWificond();
+ return;
+ }
mInOrder.verify(mNetdWrapper).registerObserver(networkObserverCaptor.capture());
mInOrder.verify(mWifiMonitor).startMonitoring(ifaceName);
mInOrder.verify(mNetdWrapper).isInterfaceUp(ifaceName);
@@ -1672,6 +1495,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
private void executeAndValidateTeardownClientInterfaceForScan(
@@ -1711,65 +1535,95 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
}
private void executeAndValidateSetupSoftApInterface(
- boolean existingStaIface, boolean existingApIface,
+ boolean hasStaIface, boolean hasApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
ArgumentCaptor<NetdEventObserver> networkObserverCaptor) throws Exception {
- executeAndValidateSetupSoftApInterface(existingStaIface, existingApIface, ifaceName,
- callback, destroyedListenerCaptor, networkObserverCaptor, false);
+ executeAndValidateSetupSoftApInterface(hasStaIface, hasApIface, ifaceName,
+ callback, destroyedListenerCaptor, networkObserverCaptor, false, true, 0);
}
private void executeAndValidateSetupSoftApInterface(
- boolean existingStaIface, boolean existingApIface,
+ boolean hasStaIface, boolean hasApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
- ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged)
- throws Exception {
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged,
+ boolean vendorHalSupported, int failureCode) throws Exception {
when(mWifiVendorHal.createApIface(any(), any(), anyInt(), eq(isBridged), any()))
.thenReturn(ifaceName);
- assertEquals(ifaceName, mWifiNative.setupInterfaceForSoftApMode(
+ assertEquals(failureCode == 0 ? ifaceName : null, mWifiNative.setupInterfaceForSoftApMode(
callback, TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, isBridged,
mSoftApManager));
validateSetupSoftApInterface(
- existingStaIface, existingApIface, ifaceName, destroyedListenerCaptor,
- networkObserverCaptor, isBridged);
+ hasStaIface, hasApIface, ifaceName, destroyedListenerCaptor,
+ networkObserverCaptor, isBridged, vendorHalSupported, failureCode);
}
private void validateSetupSoftApInterface(
- boolean existingStaIface, boolean existingApIface,
+ boolean hasStaIface, boolean hasApIface,
String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor,
- ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged)
- throws Exception {
- if (!existingStaIface && !existingApIface) {
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).startVendorHal();
- if (SdkLevel.isAtLeastS()) {
- mInOrder.verify(mWifiVendorHal).setCoexUnsafeChannels(any(), anyInt());
- mInOrder.verify(mWificondControl).registerCountryCodeChangedListener(any(), any());
- }
- }
- if (!existingApIface) {
+ ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged,
+ boolean vendorHalSupported, int failureCode) throws Exception {
+ validateStartHal(hasStaIface || hasApIface, vendorHalSupported);
+ if (!hasApIface) {
mInOrder.verify(mHostapdHal).isInitializationStarted();
mInOrder.verify(mHostapdHal).initialize();
mInOrder.verify(mHostapdHal).startDaemon();
+ if (failureCode == SOFTAP_FAILURE_CODE_START_DAEMON) {
+ mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHostapd();
+ return;
+ }
mInOrder.verify(mHostapdHal).isInitializationComplete();
mInOrder.verify(mHostapdHal).registerDeathHandler(any());
}
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createApIface(
- destroyedListenerCaptor.capture(), eq(TEST_WORKSOURCE),
- eq(SoftApConfiguration.BAND_2GHZ), eq(isBridged), eq(mSoftApManager));
+ if (vendorHalSupported) {
+ mInOrder.verify(mWifiVendorHal).createApIface(
+ destroyedListenerCaptor.capture(), eq(TEST_WORKSOURCE),
+ eq(SoftApConfiguration.BAND_2GHZ), eq(isBridged), eq(mSoftApManager));
+ if (failureCode == SOFTAP_FAILURE_CODE_CREATE_IFACE) {
+ mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHal();
+ return;
+ }
+ } else {
+ if (hasStaIface) {
+ // Creation of AP interface should trigger the STA interface destroy
+ mInOrder.verify(mWifiMonitor).stopMonitoring(ifaceName);
+ mInOrder.verify(mNetdWrapper).unregisterObserver(
+ mNetworkObserverCaptor0.getValue());
+ if (mWifiNative.hasAnyStaIfaceForConnectivity()) {
+ mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(ifaceName);
+ }
+ mInOrder.verify(mWificondControl).tearDownClientInterface(ifaceName);
+ if (mWifiNative.hasAnyStaIfaceForConnectivity()) {
+ mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
+ mInOrder.verify(mSupplicantStaIfaceHal).terminate();
+ }
+ mInOrder.verify(mWifiVendorHal).isVendorHalReady();
+ mInOrder.verify(mIfaceCallback0).onDestroyed(ifaceName);
+ }
+ }
if (isBridged) {
- mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
mInOrder.verify(mWifiVendorHal).getBridgedApInstances(eq(ifaceName));
+ if (failureCode == SOFTAP_FAILURE_CODE_BRIDGED_AP_INSTANCES) {
+ mInOrder.verify(mWifiVendorHal).removeApIface(ifaceName);
+ mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToHal();
+ return;
+ }
}
mInOrder.verify(mWificondControl).setupInterfaceForSoftApMode(ifaceName);
+ if (failureCode == SOFTAP_FAILURE_CODE_SETUP_INTERFACE) {
+ mInOrder.verify(mWifiVendorHal).removeApIface(ifaceName);
+ mInOrder.verify(mWifiMetrics).incrementNumSetupSoftApInterfaceFailureDueToWificond();
+ return;
+ }
+ // Now continue with rest of AP interface setup.
mInOrder.verify(mNetdWrapper).registerObserver(networkObserverCaptor.capture());
mInOrder.verify(mNetdWrapper).isInterfaceUp(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
private void executeAndValidateTeardownSoftApInterface(
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 04f1210a30..2b094462d8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
@@ -46,6 +46,7 @@ import android.net.MacAddress;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
+import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiContext;
import android.net.wifi.WifiScanner;
@@ -79,7 +80,6 @@ import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
@@ -155,27 +155,23 @@ public class WifiNativeTest extends WifiBaseTest {
private static final WifiNl80211Manager.SignalPollResult SIGNAL_POLL_RESULT =
new WifiNl80211Manager.SignalPollResult(-60, 12, 6, 5240);
- private static final Set<Integer> SCAN_FREQ_SET =
- new HashSet<Integer>() {{
- add(2410);
- add(2450);
- add(5050);
- add(5200);
- }};
+ private static final Set<Integer> SCAN_FREQ_SET = Set.of(
+ 2410,
+ 2450,
+ 5050,
+ 5200);
+
private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\"";
private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\"";
private static final int[] TEST_FREQUENCIES_1 = {};
private static final int[] TEST_FREQUENCIES_2 = {2500, 5124};
- private static final List<String> SCAN_HIDDEN_NETWORK_SSID_SET =
- new ArrayList<String>() {{
- add(TEST_QUOTED_SSID_1);
- add(TEST_QUOTED_SSID_2);
- }};
- private static final List<byte[]> SCAN_HIDDEN_NETWORK_BYTE_SSID_SET =
- new ArrayList<byte[]>() {{
- add(NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(TEST_QUOTED_SSID_1)));
- add(NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(TEST_QUOTED_SSID_2)));
- }};
+ private static final List<String> SCAN_HIDDEN_NETWORK_SSID_SET = List.of(
+ TEST_QUOTED_SSID_1,
+ TEST_QUOTED_SSID_2);
+
+ private static final List<byte[]> SCAN_HIDDEN_NETWORK_BYTE_SSID_SET = List.of(
+ NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(TEST_QUOTED_SSID_1)),
+ NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(TEST_QUOTED_SSID_2)));
private static final WifiNative.PnoSettings TEST_PNO_SETTINGS =
new WifiNative.PnoSettings() {{
@@ -674,7 +670,7 @@ public class WifiNativeTest extends WifiBaseTest {
*/
@Test
public void testGetWifiLinkLayerStatsForClientInConnectivityMode() throws Exception {
- mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE);
mWifiNative.getWifiLinkLayerStats(WIFI_IFACE_NAME);
mWifiNative.getWifiLinkLayerStats(WIFI_IFACE_NAME);
verify(mWifiVendorHal, times(2)).getWifiLinkLayerStats(eq(WIFI_IFACE_NAME));
@@ -686,7 +682,7 @@ public class WifiNativeTest extends WifiBaseTest {
@Test
public void testClientModeScanSuccess() {
InOrder order = inOrder(mWificondControl, mNetdWrapper, mWifiVendorHal);
- mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE);
order.verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(),
mScanCallbackCaptor.capture(), any());
order.verify(mNetdWrapper).isInterfaceUp(eq(WIFI_IFACE_NAME));
@@ -701,7 +697,7 @@ public class WifiNativeTest extends WifiBaseTest {
*/
@Test
public void testClientModeScanFailure() {
- mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE);
verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(),
mScanCallbackCaptor.capture(), any());
@@ -714,7 +710,7 @@ public class WifiNativeTest extends WifiBaseTest {
*/
@Test
public void testClientModePnoScanSuccess() {
- mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE);
verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(),
any(), mScanCallbackCaptor.capture());
@@ -728,7 +724,7 @@ public class WifiNativeTest extends WifiBaseTest {
*/
@Test
public void testClientModePnoScanFailure() {
- mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE);
verify(mWificondControl).setupInterfaceForClientMode(eq(WIFI_IFACE_NAME), any(),
any(), mScanCallbackCaptor.capture());
@@ -829,7 +825,7 @@ public class WifiNativeTest extends WifiBaseTest {
when(mCoexManager.getCoexRestrictions()).thenReturn(restrictions);
mWifiNative.setCoexUnsafeChannels(unsafeChannels, restrictions);
- mWifiNative.setupInterfaceForClientInConnectivityMode(null, TEST_WORKSOURCE);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE);
verify(mWifiVendorHal, times(2)).setCoexUnsafeChannels(unsafeChannels, restrictions);
mWifiNative.teardownAllInterfaces();
@@ -1075,15 +1071,6 @@ public class WifiNativeTest extends WifiBaseTest {
* Verifies that isSetMacAddressSupported() calls underlying WifiVendorHal.
*/
@Test
- public void testIsStaSetMacAddressSupported() throws Exception {
- mWifiNative.isStaSetMacAddressSupported(WIFI_IFACE_NAME);
- verify(mWifiVendorHal).isStaSetMacAddressSupported(WIFI_IFACE_NAME);
- }
-
- /**
- * Verifies that isSetMacAddressSupported() calls underlying WifiVendorHal.
- */
- @Test
public void testIsApSetMacAddressSupported() throws Exception {
mWifiNative.isApSetMacAddressSupported(WIFI_IFACE_NAME);
verify(mWifiVendorHal).isApSetMacAddressSupported(WIFI_IFACE_NAME);
@@ -1313,7 +1300,7 @@ public class WifiNativeTest extends WifiBaseTest {
@Test
public void testReplaceStaIfaceRequestorWs() {
assertEquals(WIFI_IFACE_NAME,
- mWifiNative.setupInterfaceForClientInConnectivityMode(
+ mWifiNative.setupInterfaceForClientInScanMode(
mInterfaceCallback, TEST_WORKSOURCE));
when(mWifiVendorHal.replaceStaIfaceRequestorWs(WIFI_IFACE_NAME, TEST_WORKSOURCE2))
.thenReturn(true);
@@ -1520,6 +1507,45 @@ public class WifiNativeTest extends WifiBaseTest {
}
/**
+ * Verifies that getSupportedBandsForSta() calls underlying vendor HAL.
+ */
+ @Test
+ public void testGetSupportedBandsFromHal() throws Exception {
+ List<WifiAvailableChannel> usableChannelList = new ArrayList<>();
+ usableChannelList.add(new WifiAvailableChannel(2412, WifiAvailableChannel.OP_MODE_STA));
+ usableChannelList.add(new WifiAvailableChannel(5160, WifiAvailableChannel.OP_MODE_STA));
+ when(mWifiVendorHal.getUsableChannels(WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ,
+ WifiAvailableChannel.OP_MODE_STA,
+ WifiAvailableChannel.FILTER_REGULATORY)).thenReturn(usableChannelList);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE);
+ mWifiNative.switchClientInterfaceToConnectivityMode(WIFI_IFACE_NAME, TEST_WORKSOURCE);
+ assertEquals(3, mWifiNative.getSupportedBandsForSta(WIFI_IFACE_NAME));
+ }
+
+ /**
+ * Verifies that getSupportedBandsForStaFromWifiCond() calls underlying wificond.
+ */
+ @Test
+ public void testGetSupportedBands() throws Exception {
+ when(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ)).thenReturn(
+ new int[]{2412});
+ when(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ)).thenReturn(
+ new int[]{5160});
+ when(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_6_GHZ)).thenReturn(
+ new int[0]);
+ when(mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_60_GHZ)).thenReturn(
+ new int[0]);
+ when(mWifiVendorHal.getUsableChannels(WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ,
+ WifiAvailableChannel.OP_MODE_STA,
+ WifiAvailableChannel.FILTER_REGULATORY)).thenReturn(null);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE);
+ mWifiNative.switchClientInterfaceToConnectivityMode(WIFI_IFACE_NAME, TEST_WORKSOURCE);
+ verify(mWificondControl).getChannelsMhzForBand(WifiScanner.WIFI_BAND_24_GHZ);
+ verify(mWificondControl).getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ);
+ assertEquals(3, mWifiNative.getSupportedBandsForSta(WIFI_IFACE_NAME));
+ }
+
+ /**
* Verifies that isSoftApInstanceDiedHandlerSupported() calls underlying HostapdHal.
*/
@Test
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 a856e14de9..6378178a25 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -125,7 +125,6 @@ import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -251,6 +250,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
when(mResources.getBoolean(
eq(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)))
.thenReturn(false);
+ when(mResources.getInteger(R.integer.config_wifiNetworkSpecifierMaxPreferredChannels))
+ .thenReturn(5);
when(mPackageManager.getNameForUid(TEST_UID_1)).thenReturn(TEST_PACKAGE_NAME_1);
when(mPackageManager.getNameForUid(TEST_UID_2)).thenReturn(TEST_PACKAGE_NAME_2);
when(mPackageManager.getApplicationInfoAsUser(any(), anyInt(), any()))
@@ -270,6 +271,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
when(mActiveModeWarden.hasPrimaryClientModeManager()).thenReturn(true);
when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mPrimaryClientModeManager);
+ when(mPrimaryClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
doAnswer(invocation -> {
Object[] args = invocation.getArguments();
ActiveModeWarden.ExternalClientModeManagerRequestListener requestListener =
@@ -434,7 +436,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
.thenReturn(true);
doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
mLooper.dispatchAll();
@@ -448,7 +450,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
public void testHandleAcceptNetworkRequestFromWithInternetCapability() throws Exception {
mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mNetworkRequest.networkCapabilities.addCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET);
@@ -465,7 +467,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
public void testHandleAcceptNetworkRequestFromNonFgAppOrSvcWithSpecifier() throws Exception {
mockPackageImportance(TEST_PACKAGE_NAME_1, false, false);
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
mLooper.dispatchAll();
@@ -480,7 +482,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
public void testHandleAcceptNetworkRequestFromFgAppWithSpecifier() {
mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
}
@@ -495,7 +497,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID_1))
.thenReturn(true);
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
}
@@ -509,12 +511,12 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
mockPackageImportance(TEST_PACKAGE_NAME_2, true, true);
// Handle request 1.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Make request 2 which will be accepted because a fg app request can
// override a fg service request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
}
@@ -526,12 +528,12 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
public void testHandleAcceptNetworkRequestFromFgSvcWithSpecifierWithPendingRequestFromFgSvc() {
// Handle request 1.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Make request 2 which will be accepted because a fg service request can
// override an existing fg service request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
}
@@ -545,12 +547,12 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
mockPackageImportance(TEST_PACKAGE_NAME_2, true, true);
// Handle request 1.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Make request 2 which will be accepted because a fg app request can
// override an existing fg app request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
}
@@ -564,12 +566,12 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
// Handle request 1.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Make request 2 which will be rejected because a fg service request cannot
// override a fg app request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
mLooper.dispatchAll();
verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
@@ -588,7 +590,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
// Handle request 1.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Resend the request from a fg service (should be accepted since it is already being
@@ -617,7 +619,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Make request 2 which will be accepted because a fg app request can
// override an existing fg app request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
assertTrue(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
}
@@ -640,7 +642,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Make request 2 which will be rejected because a fg service request cannot
// override a fg app request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
assertFalse(mWifiNetworkFactory.acceptRequest(mNetworkRequest));
mLooper.dispatchAll();
verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
@@ -674,7 +676,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testHandleNetworkRequestWithSpecifier() {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify UI start.
@@ -683,7 +685,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Verify scan settings.
verify(mWifiScanner).startScan(mScanSettingsArgumentCaptor.capture(), any(), any(),
mWorkSourceArgumentCaptor.capture());
- validateScanSettings(null);
+ validateScanSettings(null, new int[0]);
verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
}
@@ -712,7 +714,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testHandleNetworkRequestWithSpecifierAndInternetCapability() throws Exception {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mNetworkRequest.networkCapabilities.addCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET);
@@ -726,7 +728,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testHandleNetworkRequestWithSpecifierForHiddenNetwork() {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify UI start.
@@ -737,7 +739,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
mWorkSourceArgumentCaptor.capture());
validateScanSettings(
((WifiNetworkSpecifier) mNetworkCapabilities.getNetworkSpecifier())
- .ssidPatternMatcher.getPath());
+ .ssidPatternMatcher.getPath(), new int[0]);
verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
}
@@ -751,25 +753,25 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
@Test
public void testHandleNetworkRequestWithSpecifierAfterPreviousHiddenNetworkRequest() {
// Hidden request 1.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify scan settings.
verify(mWifiScanner, times(1)).startScan(mScanSettingsArgumentCaptor.capture(), any(),
any(), mWorkSourceArgumentCaptor.capture());
validateScanSettings(
((WifiNetworkSpecifier) mNetworkCapabilities.getNetworkSpecifier())
- .ssidPatternMatcher.getPath());
+ .ssidPatternMatcher.getPath(), new int[0]);
// Release request 1.
mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
// Regular request 2.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify scan settings.
verify(mWifiScanner, times(2)).startScan(mScanSettingsArgumentCaptor.capture(), any(),
any(), mWorkSourceArgumentCaptor.capture());
- validateScanSettings(null);
+ validateScanSettings(null, new int[0]);
verify(mWifiMetrics, times(2)).incrementNetworkRequestApiNumRequest();
}
@@ -782,7 +784,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Make a generic request first to ensure that we re-enable auto-join after release.
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
// Make the network request with specifier.
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
@@ -802,7 +804,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testPeriodicScanNetworkRequestWithSpecifier() {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
verifyPeriodicScans(0,
@@ -818,7 +820,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testPeriodicScanCancelOnReleaseNetworkRequestWithSpecifier() {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
verifyPeriodicScans(0,
@@ -836,7 +838,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testPeriodicScanCancelOnUserSelectNetwork() throws Exception {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
@@ -863,7 +865,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testHandleCallbackRegistrationAndUnregistration() throws Exception {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
@@ -883,7 +885,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testHandleCallbackRegistrationWithNoActiveRequest() throws Exception {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
@@ -917,7 +919,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
validateUiStartParams(true);
@@ -958,7 +960,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
validateUiStartParams(true);
@@ -999,7 +1001,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
validateUiStartParams(false);
@@ -1041,7 +1043,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
validateUiStartParams(true);
@@ -1083,7 +1085,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
validateUiStartParams(false);
@@ -1126,7 +1128,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
validateUiStartParams(true);
@@ -1171,7 +1173,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
validateUiStartParams(true);
@@ -1209,7 +1211,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
validateUiStartParams(true);
@@ -1259,7 +1261,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
assertNotNull(networkRequestUserSelectionCallback);
// Now send another network request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Now trigger user selection to some network.
@@ -1328,7 +1330,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
// request network, trigger scan and get matched set.
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
@@ -1433,7 +1435,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
@@ -1481,7 +1483,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
@@ -1542,7 +1544,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
@@ -1603,7 +1605,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
@@ -2360,7 +2362,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
// Send second request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mLooper.dispatchAll();
@@ -2398,7 +2400,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testHandleNewNetworkRequestWithSpecifierWhenScanning() throws Exception {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Register callback.
@@ -2407,7 +2409,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
// Send second request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mLooper.dispatchAll();
@@ -2443,7 +2445,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
// Send second request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Ensure we don't request a new ClientModeManager.
@@ -2484,7 +2486,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
// Send second request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Ensure we don't request a new ClientModeManager.
@@ -2532,7 +2534,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
NetworkRequest oldRequest = new NetworkRequest(mNetworkRequest);
// Send second request.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_2, false, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Ensure we do request a new ClientModeManager.
@@ -2770,7 +2772,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testHandleNetworkRequestWithSpecifierWhenWifiOff() {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
// wifi off
when(mActiveModeWarden.hasPrimaryClientModeManager()).thenReturn(false);
@@ -2825,7 +2827,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testFullHandleNetworkRequestWithSpecifierWhenWifiOff() {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0]);
// wifi off
when(mActiveModeWarden.hasPrimaryClientModeManager()).thenReturn(false);
@@ -2865,7 +2867,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
MacAddress.BROADCAST_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch,
- WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1);
+ WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1,
+ new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
@@ -2908,7 +2911,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
MacAddress.BROADCAST_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
- TEST_UID_1, TEST_PACKAGE_NAME_1);
+ TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
@@ -2949,7 +2952,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createOpenNetwork(),
- TEST_UID_1, TEST_PACKAGE_NAME_1);
+ TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
@@ -2996,7 +2999,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
- TEST_UID_1, TEST_PACKAGE_NAME_1);
+ TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Connection does not happen yet since it is waiting for scan results.
@@ -3068,7 +3071,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
MacAddress.BROADCAST_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
- TEST_UID_1, TEST_PACKAGE_NAME_1);
+ TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
@@ -3112,7 +3115,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
MacAddress.BROADCAST_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
- TEST_UID_1, TEST_PACKAGE_NAME_1);
+ TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
when(mNetworkRequestMatchCallback.asBinder()).thenReturn(mAppBinder);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
@@ -3146,11 +3149,9 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
assertTrue(approvedAccessPointsMapToWrite.keySet().contains(TEST_PACKAGE_NAME_1));
Set<AccessPoint> approvedAccessPointsToWrite =
approvedAccessPointsMapToWrite.get(TEST_PACKAGE_NAME_1);
- Set<AccessPoint> expectedApprovedAccessPoints =
- new HashSet<AccessPoint>() {{
- add(new AccessPoint(TEST_SSID_1, MacAddress.fromString(TEST_BSSID_1),
+ Set<AccessPoint> expectedApprovedAccessPoints = Set.of(
+ new AccessPoint(TEST_SSID_1, MacAddress.fromString(TEST_BSSID_1),
WifiConfiguration.SECURITY_TYPE_PSK));
- }};
assertEquals(expectedApprovedAccessPoints, approvedAccessPointsToWrite);
// Ensure that the new data flag has been reset after read.
assertFalse(mDataSource.hasNewDataToSerialize());
@@ -3163,11 +3164,9 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
public void testNetworkSpecifierUserApprovalConfigStoreLoad()
throws Exception {
Map<String, Set<AccessPoint>> approvedAccessPointsMapToRead = new HashMap<>();
- Set<AccessPoint> approvedAccessPoints =
- new HashSet<AccessPoint>() {{
- add(new AccessPoint(TEST_SSID_1, MacAddress.fromString(TEST_BSSID_1),
+ Set<AccessPoint> approvedAccessPoints = Set.of(
+ new AccessPoint(TEST_SSID_1, MacAddress.fromString(TEST_BSSID_1),
WifiConfiguration.SECURITY_TYPE_PSK));
- }};
approvedAccessPointsMapToRead.put(TEST_PACKAGE_NAME_1, approvedAccessPoints);
mDataSource.fromDeserialized(approvedAccessPointsMapToRead);
@@ -3179,7 +3178,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
MacAddress.BROADCAST_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, WifiConfigurationTestUtil.createPskNetwork(),
- TEST_UID_1, TEST_PACKAGE_NAME_1);
+ TEST_UID_1, TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
mWifiNetworkFactory.addCallback(mNetworkRequestMatchCallback);
// Ensure we triggered a connect without issuing any scans.
@@ -3245,7 +3244,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
MacAddress.BROADCAST_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch,
- WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1);
+ WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1,
+ new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify we did not trigger the UI for the second request.
@@ -3306,7 +3306,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
MacAddress.BROADCAST_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch,
- WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1);
+ WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1,
+ new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify we did not trigger the UI for the second request.
@@ -3365,7 +3366,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
MacAddress.BROADCAST_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch,
- WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1);
+ WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1,
+ new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify we did not trigger the UI for the second request.
@@ -3402,7 +3404,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
validateUiStartParams(true);
@@ -3462,7 +3464,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, mSelectedNetwork, TEST_UID_2,
- TEST_PACKAGE_NAME_2);
+ TEST_PACKAGE_NAME_2, new int[0]);
mWifiNetworkFactory.needNetworkFor(new NetworkRequest(mNetworkRequest));
validateUiStartParams(true);
@@ -3529,7 +3531,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS);
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, mSelectedNetwork, TEST_UID_2,
- TEST_PACKAGE_NAME_2);
+ TEST_PACKAGE_NAME_2, new int[0]);
mWifiNetworkFactory.needNetworkFor(new NetworkRequest(mNetworkRequest));
validateUiStartParams(true);
@@ -3559,6 +3561,67 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
.getSpecificNetworkRequestUids(mSelectedNetwork, TEST_BSSID_1).size());
}
+ /**
+ * Validates a new network request with Car Mode Priority for same network which is already
+ * a saved network, the connection will be on primary STA and the should have the internet
+ * capabilities
+ */
+ @Test
+ public void testShareConnectedNetworkWithCarModePriorityAndSavedNetwork() throws Exception {
+ mockPackageImportance(TEST_PACKAGE_NAME_1, true, true);
+ when(mWifiPermissionsUtil.checkEnterCarModePrioritized(TEST_UID_1)).thenReturn(true);
+
+ // Connect to request 1
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+
+ sendNetworkRequestAndSetupForUserSelection(TEST_SSID_1, false);
+
+ INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
+ mNetworkRequestUserSelectionCallback.getValue();
+ assertNotNull(networkRequestUserSelectionCallback);
+
+ // Now trigger user selection to one of the network.
+ mSelectedNetwork = WifiConfigurationTestUtil.createPskNetwork();
+ mSelectedNetwork.SSID = "\"" + TEST_SSID_1 + "\"";
+ mSelectedNetwork.preSharedKey = TEST_WPA_PRESHARED_KEY;
+ when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
+ .thenReturn(List.of(mSelectedNetwork));
+ sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
+ mLooper.dispatchAll();
+
+ verify(mActiveModeWarden, never()).requestLocalOnlyClientModeManager(
+ any(), any(), any(), any(), anyBoolean());
+ verify(mActiveModeWarden, atLeastOnce()).getPrimaryClientModeManager();
+ if (SdkLevel.isAtLeastS()) {
+ verify(mPrimaryClientModeManager, atLeastOnce()).getConnectedWifiConfiguration();
+ verify(mPrimaryClientModeManager, atLeastOnce()).getConnectingWifiConfiguration();
+ verify(mPrimaryClientModeManager, atLeastOnce()).getConnectingBssid();
+ verify(mPrimaryClientModeManager, atLeastOnce()).getConnectedBssid();
+ }
+
+ // Cancel the periodic scan timer.
+ mInOrder.verify(mAlarmManager).cancel(mPeriodicScanListenerArgumentCaptor.getValue());
+ // Disable connectivity manager
+ verify(mWifiConnectivityManager, atLeastOnce()).setSpecificNetworkRequestInProgress(true);
+
+ // Increment the number of unique apps.
+ verify(mWifiMetrics).incrementNetworkRequestApiNumApps();
+
+ verify(mPrimaryClientModeManager, atLeastOnce()).disconnect();
+ verify(mConnectHelper, atLeastOnce()).connectToNetwork(
+ eq(mPrimaryClientModeManager),
+ eq(new NetworkUpdateResult(TEST_NETWORK_ID_1)),
+ mConnectListenerArgumentCaptor.capture(), anyInt(), any());
+ verify(mWifiMetrics, atLeastOnce()).incrementNetworkRequestApiNumConnectOnPrimaryIface();
+
+ // Start the connection timeout alarm.
+ mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+ eq((long) WifiNetworkFactory.NETWORK_CONNECTION_TIMEOUT_MS), any(),
+ mConnectionTimeoutAlarmListenerArgumentCaptor.capture(), any());
+ assertNotNull(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
+ assertTrue(mWifiNetworkFactory.shouldHaveInternetCapabilities());
+ }
+
private void sendNetworkRequestAndSetupForConnectionStatus() throws RemoteException {
sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
}
@@ -3651,7 +3714,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
attachWifiNetworkSpecifierAndAppInfo(
ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
- TEST_PACKAGE_NAME_1);
+ TEST_PACKAGE_NAME_1, new int[0]);
mWifiNetworkFactory.needNetworkFor(new NetworkRequest(mNetworkRequest));
validateUiStartParams(true);
@@ -3729,7 +3792,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
mInOrder.verifyNoMoreInteractions();
}
- private void attachDefaultWifiNetworkSpecifierAndAppInfo(int uid, boolean isHidden) {
+ private void attachDefaultWifiNetworkSpecifierAndAppInfo(int uid, boolean isHidden,
+ int[] channels) {
PatternMatcher ssidPatternMatch =
new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
Pair<MacAddress, MacAddress> bssidPatternMatch =
@@ -3749,17 +3813,17 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
fail();
}
attachWifiNetworkSpecifierAndAppInfo(ssidPatternMatch, bssidPatternMatch, wifiConfiguration,
- uid, packageName);
+ uid, packageName, channels);
}
private void attachWifiNetworkSpecifierAndAppInfo(
PatternMatcher ssidPatternMatch, Pair<MacAddress, MacAddress> bssidPatternMatch,
- WifiConfiguration wifiConfiguration, int uid, String packageName) {
+ WifiConfiguration wifiConfiguration, int uid, String packageName, int[] channels) {
mNetworkCapabilities.setRequestorUid(uid);
mNetworkCapabilities.setRequestorPackageName(packageName);
mNetworkCapabilities.setNetworkSpecifier(
new WifiNetworkSpecifier(ssidPatternMatch, bssidPatternMatch,
- ScanResult.UNSPECIFIED, wifiConfiguration));
+ ScanResult.UNSPECIFIED, wifiConfiguration, channels));
mNetworkRequest = new NetworkRequest.Builder()
.setCapabilities(mNetworkCapabilities)
.build();
@@ -3862,7 +3926,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
}
}
- private void validateScanSettings(@Nullable String hiddenSsid) {
+ private void validateScanSettings(@Nullable String hiddenSsid, int[] channels) {
ScanSettings scanSettings = mScanSettingsArgumentCaptor.getValue();
assertNotNull(scanSettings);
assertEquals(WifiScanner.WIFI_BAND_ALL, scanSettings.band);
@@ -3877,6 +3941,10 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
WorkSource workSource = mWorkSourceArgumentCaptor.getValue();
assertNotNull(workSource);
assertEquals(TEST_UID_1, workSource.getUid(0));
+ assertEquals(scanSettings.channels.length, channels.length);
+ for (int i = 0; i < channels.length; i++) {
+ assertEquals(channels[i], scanSettings.channels[i].frequency);
+ }
}
class WifiConfigMatcher implements ArgumentMatcher<WifiConfiguration> {
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 02be2e7c56..4626de802d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
@@ -70,6 +70,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
/**
* Unit tests for {@link com.android.server.wifi.WifiNetworkSelector}.
@@ -302,6 +303,8 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
private int mThresholdQualifiedRssi2G;
private int mThresholdQualifiedRssi5G;
private int mMinPacketRateActiveTraffic;
+ private int mLastMeteredSelectionWeightMinutes;
+ private int mLastUnmeteredSelectionWeightMinutes;
private int mSufficientDurationAfterUserSelection;
private CompatibilityScorer mCompatibilityScorer;
private ScoreCardBasedScorer mScoreCardBasedScorer;
@@ -336,6 +339,8 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
mThresholdQualifiedRssi5G = mScoringParams.getSufficientRssi(
ScanResult.BAND_5_GHZ_START_FREQ_MHZ);
mMinPacketRateActiveTraffic = mScoringParams.getActiveTrafficPacketsPerSecond();
+ mLastMeteredSelectionWeightMinutes = mScoringParams.getLastMeteredSelectionMinutes();
+ mLastUnmeteredSelectionWeightMinutes = mScoringParams.getLastUnmeteredSelectionMinutes();
}
private void setupWifiInfo() {
@@ -1307,6 +1312,110 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
}
/**
+ * Verify that WifiNetworkSelector does not override NetworkSelector's choice with
+ * the user connect choice when override is disabled
+ */
+ @Test
+ public void userConnectChoiceDoesNotOverrideWhenOverrideDisabled() {
+ String[] ssids = {"\"test1\"", "\"test2\""};
+ String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
+ int[] freqs = {2437, 5180};
+ String[] caps = {"[WPA2-PSK][ESS]", "[WPA2-PSK][ESS]"};
+ int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
+ int[] securities = {SECURITY_PSK, SECURITY_PSK};
+ ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
+ WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
+ freqs, caps, levels, securities, mWifiConfigManager, mClock);
+ List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+ WifiConfiguration[] wifiConfigs = scanDetailsAndConfigs.getWifiConfigs();
+ HashSet<String> blocklist = new HashSet<>();
+
+ // PlaceholderNominator always selects the first network in the list.
+ WifiConfiguration networkSelectorChoice = wifiConfigs[0];
+ networkSelectorChoice.getNetworkSelectionStatus()
+ .setSeenInLastQualifiedNetworkSelection(true);
+
+ // set user connect choice
+ WifiConfiguration userChoice = wifiConfigs[1];
+ userChoice.getNetworkSelectionStatus().setConnectChoice(null);
+ networkSelectorChoice.getNetworkSelectionStatus()
+ .setConnectChoice(userChoice.getProfileKey());
+
+ // Verify that the userChoice network is chosen when override is enabled by default
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blocklist,
+ Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo)),
+ false, true, true, Collections.emptySet(), false);
+ WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
+ WifiConfigurationTestUtil.assertConfigurationEqual(userChoice, candidate);
+
+
+ // Verify that the networkSelectorChoice is chosen when override is disabled
+ mWifiNetworkSelector.setUserConnectChoiceOverrideEnabled(false);
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blocklist,
+ Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo)),
+ false, true, true, Collections.emptySet(), false);
+ candidate = mWifiNetworkSelector.selectNetwork(candidates);
+ WifiConfigurationTestUtil.assertConfigurationEqual(networkSelectorChoice, candidate);
+ }
+
+ /**
+ * Tests last selection weight calculation returns 0.0 for the latest selected network
+ * when last selection weight is disabled
+ */
+ @Test
+ public void testLastSelectionWeightForLatestSelectedNetwork() {
+ String[] ssids = {"\"test1\"", "\"test2\""};
+ String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
+ int[] freqs = {2437, 5180};
+ String[] caps = {"[WPA2-PSK][ESS]", "[WPA2-PSK][ESS]"};
+ int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
+ int[] securities = {SECURITY_PSK, SECURITY_PSK};
+ ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
+ WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
+ freqs, caps, levels, securities, mWifiConfigManager, mClock);
+ List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+ WifiConfiguration[] wifiConfigs = scanDetailsAndConfigs.getWifiConfigs();
+ HashSet<String> blocklist = new HashSet<>();
+
+ // Set the latest selected network
+ WifiConfiguration latestSelection = wifiConfigs[0];
+ setupWifiConfigManager(latestSelection.networkId);
+ when(mWifiConfigManager.getLastSelectedTimeStamp())
+ .thenReturn(SystemClock.elapsedRealtime());
+
+ // Verify that the last selection weight for the latest selected network is greater than 0
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blocklist,
+ Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo)),
+ false, true, true, Collections.emptySet(), false);
+
+ assertFalse(candidates.isEmpty());
+ for (WifiCandidates.Candidate candidate: candidates) {
+ if (candidate.getNetworkConfigId() == latestSelection.networkId) {
+ assertTrue(candidate.getLastSelectionWeight() > 0.0);
+ }
+ }
+
+ // Disable last selection weight
+ mWifiNetworkSelector.setLastSelectionWeightEnabled(false);
+
+ // Verify that the last selection weight for the latest selected network is 0
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blocklist,
+ Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo)),
+ false, true, true, Collections.emptySet(), false);
+
+ assertFalse(candidates.isEmpty());
+ for (WifiCandidates.Candidate candidate: candidates) {
+ if (candidate.getNetworkConfigId() == latestSelection.networkId) {
+ assertTrue(candidate.getLastSelectionWeight() == 0.0);
+ }
+ }
+ }
+
+ /**
* Tests when multiple Nominators nominate the same candidate, any one of the nominator IDs is
* acceptable.
*/
@@ -1530,32 +1639,61 @@ public class WifiNetworkSelectorTest extends WifiBaseTest {
false);
}
- /**
- * New network selection is not performed if the currently connected network
- * was recently selected.
- */
- @Test
- public void networkIsSufficientWhenRecentlyUserSelected() {
- // Approximate mClock.getElapsedSinceBootMillis value mocked by testStayOrTryToSwitch
- long millisSinceBoot = SystemClock.elapsedRealtime()
- + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000;
+ private void verifyLastSelectedWeight(boolean isMetered) {
+ String[] ssids = {"\"test1\""};
+ String[] bssids = {"6c:f3:7f:ae:8c:f3"};
+ int[] freqs = {5180};
+ String[] caps = {"[WPA2-PSK][ESS]"};
+ int[] levels = {mThresholdQualifiedRssi5G + 5};
+ int[] securities = {SECURITY_PSK};
+
+ ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
+ WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
+ freqs, caps, levels, securities, mWifiConfigManager, mClock);
+ List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+ HashSet<String> blocklist = new HashSet<String>();
+ WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
+ if (isMetered) {
+ savedConfigs[0].meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
+ }
+ long startTimeMs = mClock.getElapsedSinceBootMillis();
+ long expectedStickyTimeMinutes = isMetered ? mLastMeteredSelectionWeightMinutes
+ : mLastUnmeteredSelectionWeightMinutes;
+ setupWifiConfigManager(savedConfigs[0].networkId); // Set last connected network
when(mWifiConfigManager.getLastSelectedTimeStamp())
- .thenReturn(millisSinceBoot
- - WAIT_JUST_A_MINUTE
- + 1000);
- setupWifiConfigManager(0); // testStayOrTryToSwitch first connects to network 0
- // Rssi after connected.
- when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
- // No streaming traffic.
- when(mWifiInfo.getSuccessfulTxPacketsPerSecond()).thenReturn(0.0);
- when(mWifiInfo.getSuccessfulRxPacketsPerSecond()).thenReturn(0.0);
+ .thenReturn(startTimeMs);
- testStayOrTryToSwitch(
- mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
- false /* not a 5G network */,
- false /* not open network */,
- // Should not try to switch.
- false);
+ // lastSelectionWeight should be greater than 0 before expectedStickyTimeMinutes passes
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(startTimeMs
+ + TimeUnit.MINUTES.toMillis(expectedStickyTimeMinutes) - 1);
+ List<WifiCandidates.Candidate> candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blocklist,
+ Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo)),
+ false, true, true, Collections.emptySet(), false);
+ //WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
+ assertEquals(1, candidates.size());
+ assertTrue(candidates.get(0).getLastSelectionWeight() > 0);
+
+ // lastSelectionWeight should be 0 after expectedStickyTimeMinutes passes
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(startTimeMs
+ + TimeUnit.MINUTES.toMillis(expectedStickyTimeMinutes));
+ candidates = mWifiNetworkSelector.getCandidatesFromScan(
+ scanDetails, blocklist,
+ Arrays.asList(new ClientModeManagerState(TEST_IFACE_NAME, false, true, mWifiInfo)),
+ false, true, true, Collections.emptySet(), false);
+ //WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(candidates);
+ assertEquals(1, candidates.size());
+ assertEquals(0, candidates.get(0).getLastSelectionWeight(), 0);
+ }
+
+ @Test
+ public void testLastSelectedWeight() {
+ verifyLastSelectedWeight(false);
+ }
+
+ @Test
+ public void testLastSelectedWeightMetered() {
+ verifyLastSelectedWeight(true);
}
/**
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 484ef4d49b..7d8eb15e98 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -80,7 +80,6 @@ import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
-import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
@@ -89,6 +88,7 @@ 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 com.android.dx.mockito.inline.extended.ExtendedMockito;
@@ -300,7 +300,8 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
when(mWifiKeyStore.updateNetworkKeys(any(), any())).thenReturn(true);
mWifiNetworkSuggestionsManager =
- new WifiNetworkSuggestionsManager(mContext, new Handler(mLooper.getLooper()),
+ new WifiNetworkSuggestionsManager(mContext,
+ new RunnerHandler(mLooper.getLooper(), 100, new LocalLog(128)),
mWifiInjector, mWifiPermissionsUtil, mWifiConfigManager, mWifiConfigStore,
mWifiMetrics, mWifiCarrierInfoManager, mWifiKeyStore,
mLruConnectionTracker, mClock);
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 c7c78f362e..35c066dab2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -21,6 +21,7 @@ import static android.Manifest.permission.MANAGE_WIFI_COUNTRY_CODE;
import static android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS;
import static android.Manifest.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS;
import static android.net.wifi.WifiAvailableChannel.FILTER_REGULATORY;
+import static android.net.wifi.WifiAvailableChannel.OP_MODE_SAP;
import static android.net.wifi.WifiAvailableChannel.OP_MODE_STA;
import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED;
import static android.net.wifi.WifiManager.ACTION_REMOVE_SUGGESTION_DISCONNECT;
@@ -126,6 +127,7 @@ import android.net.DhcpInfo;
import android.net.DhcpOption;
import android.net.DhcpResultsParcelable;
import android.net.MacAddress;
+import android.net.Network;
import android.net.NetworkStack;
import android.net.Uri;
import android.net.wifi.CoexUnsafeChannel;
@@ -569,10 +571,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
.thenReturn(Collections.emptyList());
when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
.thenReturn(true);
- // Defaulting apps to target SDK level that's prior to T. This is need for to test for
+ // Defaulting apps to target SDK level that's prior to T. This is needed to test for
// backward compatibility of API changes.
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
eq(Build.VERSION_CODES.TIRAMISU), anyInt())).thenReturn(true);
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(any(),
+ eq(Build.VERSION_CODES.UPSIDE_DOWN_CAKE),
+ anyInt())).thenReturn(true);
when(mWifiInjector.getWifiCarrierInfoManager()).thenReturn(mWifiCarrierInfoManager);
when(mWifiInjector.getOpenNetworkNotifier()).thenReturn(mOpenNetworkNotifier);
when(mClientSoftApCallback.asBinder()).thenReturn(mAppBinder);
@@ -1634,7 +1639,6 @@ public class WifiServiceImplTest extends WifiBaseTest {
SoftApConfiguration apConfig = createValidSoftApConfiguration();
assertTrue(mWifiServiceImpl.setSoftApConfiguration(apConfig, TEST_PACKAGE_NAME));
- mLooper.dispatchAll();
verify(mWifiApConfigStore).setApConfiguration(eq(apConfig));
verify(mActiveModeWarden).updateSoftApConfiguration(apConfig);
verify(mWifiPermissionsUtil).checkNetworkSettingsPermission(anyInt());
@@ -1649,7 +1653,6 @@ public class WifiServiceImplTest extends WifiBaseTest {
SoftApConfiguration apConfig = createValidSoftApConfiguration();
assertTrue(mWifiServiceImpl.setSoftApConfiguration(apConfig, TEST_PACKAGE_NAME));
- mLooper.dispatchAll();
verify(mWifiApConfigStore).setApConfiguration(eq(apConfig));
verify(mActiveModeWarden).updateSoftApConfiguration(apConfig);
verify(mWifiPermissionsUtil).checkConfigOverridePermission(anyInt());
@@ -2123,10 +2126,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testIsWifiBandSupported24gWithOverride() throws Exception {
when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
- mLooper.startAutoDispatch();
assertTrue(mWifiServiceImpl.is24GHzBandSupported());
- mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mWifiNative, never()).getChannelsForBand(anyInt());
+ verify(mActiveModeWarden, never()).isBandSupportedForSta(anyInt());
}
/**
@@ -2135,10 +2136,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testIsWifiBandSupported5gWithOverride() throws Exception {
when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
- mLooper.startAutoDispatch();
assertTrue(mWifiServiceImpl.is5GHzBandSupported());
- mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mWifiNative, never()).getChannelsForBand(anyInt());
+ verify(mActiveModeWarden, never()).isBandSupportedForSta(anyInt());
}
/**
@@ -2147,10 +2146,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testIsWifiBandSupported6gWithOverride() throws Exception {
when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true);
- mLooper.startAutoDispatch();
assertTrue(mWifiServiceImpl.is6GHzBandSupported());
- mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mWifiNative, never()).getChannelsForBand(anyInt());
+ verify(mActiveModeWarden, never()).isBandSupportedForSta(anyInt());
}
/**
@@ -2158,13 +2155,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported24gNoOverrideNoChannels() throws Exception {
- final int[] emptyArray = {};
when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(emptyArray);
- mLooper.startAutoDispatch();
+ when(mActiveModeWarden.isBandSupportedForSta(WIFI_BAND_24_GHZ)).thenReturn(false);
assertFalse(mWifiServiceImpl.is24GHzBandSupported());
- mLooper.stopAutoDispatch();
- verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ);
+ verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ);
}
/**
@@ -2172,13 +2166,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported5gNoOverrideNoChannels() throws Exception {
- final int[] emptyArray = {};
when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(emptyArray);
- mLooper.startAutoDispatch();
+ when(mActiveModeWarden.isBandSupportedForSta(WIFI_BAND_5_GHZ)).thenReturn(false);
assertFalse(mWifiServiceImpl.is5GHzBandSupported());
- mLooper.stopAutoDispatch();
- verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ);
+ verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ);
}
/**
@@ -2186,13 +2177,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported24gNoOverrideWithChannels() throws Exception {
- final int[] channelArray = {2412};
when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(channelArray);
- mLooper.startAutoDispatch();
+ when(mActiveModeWarden.isBandSupportedForSta(WIFI_BAND_24_GHZ)).thenReturn(true);
assertTrue(mWifiServiceImpl.is24GHzBandSupported());
- mLooper.stopAutoDispatch();
- verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ);
+ verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ);
}
/**
@@ -2200,13 +2188,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported5gNoOverrideWithChannels() throws Exception {
- final int[] channelArray = {5170};
when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(channelArray);
- mLooper.startAutoDispatch();
+ when(mActiveModeWarden.isBandSupportedForSta(WIFI_BAND_5_GHZ)).thenReturn(true);
assertTrue(mWifiServiceImpl.is5GHzBandSupported());
- mLooper.stopAutoDispatch();
- verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ);
+ verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ);
}
/**
@@ -2214,13 +2199,11 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported6gNoOverrideNoChannels() throws Exception {
- final int[] emptyArray = {};
when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(emptyArray);
- mLooper.startAutoDispatch();
+ when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ)).thenReturn(
+ false);
assertFalse(mWifiServiceImpl.is6GHzBandSupported());
- mLooper.stopAutoDispatch();
- verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ);
+ verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ);
}
/**
@@ -2228,13 +2211,11 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported6gNoOverrideWithChannels() throws Exception {
- final int[] channelArray = {6420};
when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(channelArray);
- mLooper.startAutoDispatch();
+ when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ)).thenReturn(
+ true);
assertTrue(mWifiServiceImpl.is6GHzBandSupported());
- mLooper.stopAutoDispatch();
- verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ);
+ verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ);
}
private void setup24GhzSupported() {
@@ -2246,8 +2227,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(false);
if (!isOnlyUnsupportedSoftAp) {
when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ))
- .thenReturn(new int[0]);
+ when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ))
+ .thenReturn(false);
}
}
@@ -2260,8 +2241,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mResources.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(false);
if (!isOnlyUnsupportedSoftAp) {
when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ))
- .thenReturn(new int[0]);
+ when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ))
+ .thenReturn(false);
}
}
@@ -2274,8 +2255,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mResources.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(false);
if (!isOnlyUnsupportedSoftAp) {
when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ))
- .thenReturn(new int[0]);
+ when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ))
+ .thenReturn(false);
}
}
@@ -2288,8 +2269,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mResources.getBoolean(R.bool.config_wifiSoftap60ghzSupported)).thenReturn(false);
if (!isOnlyUnsupportedSoftAp) {
when(mResources.getBoolean(R.bool.config_wifi60ghzSupport)).thenReturn(false);
- when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_60_GHZ))
- .thenReturn(new int[0]);
+ when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_60_GHZ))
+ .thenReturn(false);
}
}
@@ -2698,6 +2679,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME, TEST_FEATURE_ID));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mScanRequestProxy, never()).startScan(anyInt(), eq(SCAN_PACKAGE_NAME));
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_START_SCAN), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -2738,7 +2721,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testConnectedIdsAreHiddenFromAppWithoutPermission() throws Exception {
WifiInfo wifiInfo = setupForGetConnectionInfo();
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
anyString(), nullable(String.class), anyInt(), nullable(String.class));
@@ -2768,7 +2751,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testConnectedIdsAreHiddenOnSecurityException() throws Exception {
WifiInfo wifiInfo = setupForGetConnectionInfo();
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
anyString(), nullable(String.class), anyInt(), nullable(String.class));
@@ -2792,7 +2775,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testConnectedIdsAreVisibleFromPermittedApp() throws Exception {
WifiInfo wifiInfo = setupForGetConnectionInfo();
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mLooper.startAutoDispatch();
WifiInfo connectionInfo = parcelingRoundTrip(
@@ -2817,7 +2800,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
ConcreteClientModeManager secondaryCmm = mock(ConcreteClientModeManager.class);
when(secondaryCmm.getRequestorWs())
.thenReturn(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE));
- when(secondaryCmm.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(secondaryCmm.getConnectionInfo()).thenReturn(wifiInfo);
when(mActiveModeWarden.getClientModeManagersInRoles(
ROLE_CLIENT_LOCAL_ONLY, ROLE_CLIENT_SECONDARY_LONG_LIVED))
.thenReturn(Arrays.asList(secondaryCmm));
@@ -2847,12 +2830,12 @@ public class WifiServiceImplTest extends WifiBaseTest {
WorkSource ws = new WorkSource(Binder.getCallingUid(), TEST_PACKAGE);
ws.add(SETTINGS_WORKSOURCE);
when(secondaryCmm.getRequestorWs()).thenReturn(ws);
- when(secondaryCmm.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(secondaryCmm.getConnectionInfo()).thenReturn(wifiInfo);
when(mActiveModeWarden.getClientModeManagersInRoles(
ROLE_CLIENT_LOCAL_ONLY, ROLE_CLIENT_SECONDARY_LONG_LIVED))
.thenReturn(Arrays.asList(secondaryCmm));
ConcreteClientModeManager primaryCmm = mock(ConcreteClientModeManager.class);
- when(primaryCmm.syncRequestConnectionInfo()).thenReturn(new WifiInfo());
+ when(primaryCmm.getConnectionInfo()).thenReturn(new WifiInfo());
when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(primaryCmm);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(SETTINGS_WORKSOURCE.getUid(0)))
.thenReturn(true);
@@ -2876,7 +2859,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
assertEquals(WifiManager.UNKNOWN_SSID, connectionInfo.getSSID());
verify(mActiveModeWarden).getPrimaryClientModeManager();
- verify(primaryCmm).syncRequestConnectionInfo();
+ verify(primaryCmm).getConnectionInfo();
}
/**
@@ -2887,7 +2870,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testConnectedIdsFromPrimaryCmmAreVisibleFromAppNotRequestingSecondaryCmm()
throws Exception {
WifiInfo wifiInfo = setupForGetConnectionInfo();
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
ConcreteClientModeManager secondaryCmm = mock(ConcreteClientModeManager.class);
when(secondaryCmm.getRequestorWs())
.thenReturn(new WorkSource(Binder.getCallingUid(), TEST_PACKAGE_NAME_OTHER));
@@ -3173,12 +3156,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
new ArrayList<>(Arrays.asList(scanResults));
when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
WifiNetworkSuggestion mockSuggestion = mock(WifiNetworkSuggestion.class);
- List<WifiNetworkSuggestion> matchingSuggestions = new ArrayList<>() {{
- add(mockSuggestion);
- }};
- Map<WifiNetworkSuggestion, List<ScanResult>> result = new HashMap<>() {{
- put(mockSuggestion, scanResultList);
- }};
+ List<WifiNetworkSuggestion> matchingSuggestions = List.of(mockSuggestion);
+ Map<WifiNetworkSuggestion, List<ScanResult>> result = Map.of(
+ mockSuggestion, scanResultList);
when(mWifiNetworkSuggestionsManager.getMatchingScanResults(eq(matchingSuggestions),
eq(scanResultList))).thenReturn(result);
@@ -3206,12 +3186,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
List<ScanResult> scanResultList =
new ArrayList<>(Arrays.asList(scanResults));
WifiNetworkSuggestion mockSuggestion = mock(WifiNetworkSuggestion.class);
- List<WifiNetworkSuggestion> matchingSuggestions = new ArrayList<>() {{
- add(mockSuggestion);
- }};
- Map<WifiNetworkSuggestion, List<ScanResult>> result = new HashMap<>() {{
- put(mockSuggestion, scanResultList);
- }};
+ List<WifiNetworkSuggestion> matchingSuggestions = List.of(mockSuggestion);
+ Map<WifiNetworkSuggestion, List<ScanResult>> result = Map.of(
+ mockSuggestion, scanResultList);
+
when(mWifiNetworkSuggestionsManager.getMatchingScanResults(eq(matchingSuggestions),
eq(scanResultList))).thenReturn(result);
@@ -3242,12 +3220,10 @@ public class WifiServiceImplTest extends WifiBaseTest {
new ArrayList<>(Arrays.asList(scanResults));
when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
WifiNetworkSuggestion mockSuggestion = mock(WifiNetworkSuggestion.class);
- List<WifiNetworkSuggestion> matchingSuggestions = new ArrayList<>() {{
- add(mockSuggestion);
- }};
- Map<WifiNetworkSuggestion, List<ScanResult>> result = new HashMap<>() {{
- put(mockSuggestion, scanResultList);
- }};
+ List<WifiNetworkSuggestion> matchingSuggestions = List.of(mockSuggestion);
+ Map<WifiNetworkSuggestion, List<ScanResult>> result = Map.of(
+ mockSuggestion, scanResultList);
+
when(mWifiNetworkSuggestionsManager.getMatchingScanResults(eq(matchingSuggestions),
eq(scanResultList))).thenReturn(result);
@@ -4437,6 +4413,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mLohsCallback, never()).onHotspotStarted(any());
+ verify(mLastCallerInfoManager, atLeastOnce()).put(
+ eq(WifiManager.API_START_LOCAL_ONLY_HOTSPOT), anyInt(), anyInt(), anyInt(),
+ anyString(), eq(true));
}
/**
@@ -5156,6 +5135,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
any(ActionListenerWrapper.class), anyInt(), any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK),
anyInt());
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_CONNECT_CONFIG), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -5290,6 +5271,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), 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(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
@Test
@@ -5409,6 +5392,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
any());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK),
anyInt());
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_SAVE), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
@Test
@@ -5479,6 +5464,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.dispatchAll();
inOrder.verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt(), any());
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_FORGET), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
@Test
@@ -6672,6 +6659,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mConnectHelper).connectToNetwork(
eq(new NetworkUpdateResult(TEST_NETWORK_ID)), any(), anyInt(), any());
verify(mWifiMetrics).incrementNumEnableNetworkCalls();
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_ENABLE_NETWORK), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -7944,6 +7933,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
verify(mWifiConfigManager).allowAutojoin(anyInt(), anyBoolean());
verify(mWifiMetrics).logUserActionEvent(eq(UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON),
anyInt());
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_ALLOW_AUTOJOIN), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
@Test
@@ -8644,11 +8635,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
.enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
eq("WifiService"));
mWifiServiceImpl.setScanThrottleEnabled(true);
- mLooper.dispatchAll();
verify(mScanRequestProxy).setScanThrottleEnabled(true);
mWifiServiceImpl.setScanThrottleEnabled(false);
- mLooper.dispatchAll();
verify(mScanRequestProxy).setScanThrottleEnabled(false);
}
@@ -8659,16 +8648,13 @@ public class WifiServiceImplTest extends WifiBaseTest {
eq("WifiService"));
mWifiServiceImpl.setScanThrottleEnabled(true);
- mLooper.dispatchAll();
verify(mScanRequestProxy, never()).setScanThrottleEnabled(true);
}
@Test
public void testIsScanThrottleEnabled() {
when(mScanRequestProxy.isScanThrottleEnabled()).thenReturn(true);
- mLooper.startAutoDispatch();
assertTrue(mWifiServiceImpl.isScanThrottleEnabled());
- mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mScanRequestProxy).isScanThrottleEnabled();
}
@@ -8678,11 +8664,9 @@ public class WifiServiceImplTest extends WifiBaseTest {
.enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
eq("WifiService"));
mWifiServiceImpl.setAutoWakeupEnabled(true);
- mLooper.dispatchAll();
verify(mWakeupController).setEnabled(true);
mWifiServiceImpl.setAutoWakeupEnabled(false);
- mLooper.dispatchAll();
verify(mWakeupController).setEnabled(false);
}
@@ -8700,9 +8684,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testIsAutoWakeupEnabled() {
when(mWakeupController.isEnabled()).thenReturn(true);
- mLooper.startAutoDispatch();
assertTrue(mWifiServiceImpl.isAutoWakeupEnabled());
- mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWakeupController).isEnabled();
}
@@ -8903,6 +8885,33 @@ public class WifiServiceImplTest extends WifiBaseTest {
}
@Test
+ public void testSetCarrierNetworkOffloadEnabledWithoutPermissionThrowsException()
+ throws Exception {
+ try {
+ mWifiServiceImpl.setCarrierNetworkOffloadEnabled(10, true, true);
+ fail();
+ } catch (SecurityException e) { }
+ }
+
+ @Test
+ public void testSetCarrierNetworkOffloadEnabled() throws Exception {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.setCarrierNetworkOffloadEnabled(10, true, true);
+ verify(mWifiCarrierInfoManager).setCarrierNetworkOffloadEnabled(10, true, true);
+
+ mWifiServiceImpl.setCarrierNetworkOffloadEnabled(5, false, false);
+ verify(mWifiCarrierInfoManager).setCarrierNetworkOffloadEnabled(5, false, false);
+ }
+
+ @Test
+ public void testIsCarrierNetworkOffloadEnabled() throws Exception {
+ when(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(10, true)).thenReturn(true);
+ assertTrue(mWifiServiceImpl.isCarrierNetworkOffloadEnabled(10, true));
+ verify(mWifiCarrierInfoManager).isCarrierNetworkOffloadEnabled(10, true);
+ }
+
+ @Test
public void testSetEmergencyScanRequestWithoutPermissionThrowsException() throws Exception {
when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
.thenReturn(PackageManager.PERMISSION_DENIED);
@@ -9150,11 +9159,51 @@ public class WifiServiceImplTest extends WifiBaseTest {
doThrow(new SecurityException()).when(mWifiPermissionsUtil)
.checkCallersHardwareLocationPermission(anyInt());
try {
- mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA, FILTER_REGULATORY);
+ mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA, FILTER_REGULATORY,
+ TEST_PACKAGE_NAME, mExtras);
fail("expected SecurityException");
} catch (SecurityException expected) { }
}
+ @Test
+ public void testGetUsableChannelsThrowsSecurityExceptionOnMissingPermissionsAfterU() {
+ assumeTrue(SdkLevel.isAtLeastU());
+
+ // verify app targeting prior to Android U can call API with location permission
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(any(),
+ eq(Build.VERSION_CODES.UPSIDE_DOWN_CAKE),
+ anyInt())).thenReturn(true);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ when(mWifiPermissionsUtil.checkCallersHardwareLocationPermission(anyInt()))
+ .thenReturn(true);
+
+ mLooper.startAutoDispatch();
+ mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA, FILTER_REGULATORY,
+ TEST_PACKAGE_NAME, mExtras);
+
+ // Verify app targeting prior to Android U fails to call API without location permission
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA,
+ FILTER_REGULATORY, TEST_PACKAGE_NAME, mExtras));
+
+ // Verify app targeting Android U no longer need location.
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(any(),
+ eq(Build.VERSION_CODES.UPSIDE_DOWN_CAKE),
+ anyInt())).thenReturn(false);
+ mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA, FILTER_REGULATORY,
+ TEST_PACKAGE_NAME, mExtras);
+
+ // Verify app targeting Android U will fail without nearby permission
+ doThrow(new SecurityException())
+ .when(mWifiPermissionsUtil).enforceNearbyDevicesPermission(
+ any(), anyBoolean(), any());
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA,
+ FILTER_REGULATORY, TEST_PACKAGE_NAME, mExtras));
+ mLooper.stopAutoDispatch();
+ }
+
/**
* Verify the call to isValidBandForGetUsableChannels()
*/
@@ -9202,7 +9251,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiPermissionsUtil.checkCallersHardwareLocationPermission(anyInt()))
.thenReturn(true);
try {
- mWifiServiceImpl.getUsableChannels(WIFI_BAND_5_GHZ, OP_MODE_STA, FILTER_REGULATORY);
+ mWifiServiceImpl.getUsableChannels(WIFI_BAND_5_GHZ, OP_MODE_STA, FILTER_REGULATORY,
+ TEST_PACKAGE_NAME, mExtras);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
@@ -9218,12 +9268,43 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiPermissionsUtil.checkCallersHardwareLocationPermission(anyInt()))
.thenReturn(true);
mLooper.startAutoDispatch();
- mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA, FILTER_REGULATORY);
+ mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ, OP_MODE_STA, FILTER_REGULATORY,
+ TEST_PACKAGE_NAME, mExtras);
mLooper.stopAutoDispatch();
verify(mWifiNative).getUsableChannels(anyInt(), anyInt(), anyInt());
}
/**
+ * Verify the call to getUsableChannels() goes to cached SoftAp capabilities
+ */
+ @Test
+ public void testGetUsableChannelsForApRegulation() throws Exception {
+ mWifiServiceImpl.handleBootCompleted();
+ mLooper.dispatchAll();
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ when(mWifiPermissionsUtil.checkCallersHardwareLocationPermission(anyInt()))
+ .thenReturn(true);
+ // Country code update with HAL started
+ when(mWifiNative.isHalStarted()).thenReturn(true);
+ // Channel 9 - 2452Mhz
+ WifiAvailableChannel channels2g = new WifiAvailableChannel(2452,
+ WifiAvailableChannel.OP_MODE_SAP);
+ when(mWifiNative.isHalSupported()).thenReturn(true);
+ when(mWifiNative.isHalStarted()).thenReturn(true);
+ when(mWifiNative.getUsableChannels(eq(WifiScanner.WIFI_BAND_24_GHZ), anyInt(), anyInt()))
+ .thenReturn(new ArrayList<>(Arrays.asList(channels2g)));
+ mWifiServiceImpl.mCountryCodeTracker.onDriverCountryCodeChanged(TEST_COUNTRY_CODE);
+ mLooper.dispatchAll();
+ reset(mWifiNative);
+ List<WifiAvailableChannel> channels = mWifiServiceImpl.getUsableChannels(WIFI_BAND_24_GHZ,
+ OP_MODE_SAP, FILTER_REGULATORY, TEST_PACKAGE_NAME, mExtras);
+ assertEquals(1, channels.size());
+ assertEquals(channels2g, channels.get(0));
+ verify(mWifiNative, never()).getUsableChannels(eq(WifiScanner.WIFI_BAND_24_GHZ), anyInt(),
+ anyInt());
+ }
+
+ /**
* Verify that if the caller has NETWORK_SETTINGS permission, and the overlay
* config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW is set, then it can add an
* insecure Enterprise network, with Root CA certificate not set and/or domain name not set.
@@ -9486,7 +9567,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testGetPrivilegedConnectedNetworkNotConnected() {
trySetTargetSdkToT();
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(new WifiInfo());
+ when(mActiveModeWarden.getConnectionInfo()).thenReturn(new WifiInfo());
mLooper.startAutoDispatch();
assertNull(mWifiServiceImpl.getPrivilegedConnectedNetwork(
@@ -9509,7 +9590,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
testConfig.setRandomizedMacAddress(TEST_FACTORY_MAC_ADDR);
WifiInfo wifiInfo = new WifiInfo();
wifiInfo.setNetworkId(testConfig.networkId);
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mActiveModeWarden.getConnectionInfo()).thenReturn(wifiInfo);
when(mWifiConfigManager.getConfiguredNetworkWithPassword(testConfig.networkId)).thenReturn(
testConfig);
@@ -9664,8 +9745,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
.thenReturn(WifiManager.WIFI_FEATURE_PNO);
when(mWifiPermissionsUtil.checkRequestCompanionProfileAutomotiveProjectionPermission(
anyInt())).thenReturn(true);
- when(mWifiPermissionsUtil.checkCallersLocationPermission(
- any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
+ when(mWifiPermissionsUtil.checkCallersLocationPermissionInManifest(
+ anyInt(), anyBoolean())).thenReturn(true);
IPnoScanResultsCallback callback = mock(IPnoScanResultsCallback.class);
List<WifiSsid> ssids = new ArrayList<>();
ssids.add(WifiSsid.fromString("\"TEST_SSID_1\""));
@@ -9684,8 +9765,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mActiveModeWarden.getSupportedFeatureSet()).thenReturn(0L);
when(mWifiPermissionsUtil.checkRequestCompanionProfileAutomotiveProjectionPermission(
anyInt())).thenReturn(true);
- when(mWifiPermissionsUtil.checkCallersLocationPermission(
- any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
+ when(mWifiPermissionsUtil.checkCallersLocationPermissionInManifest(
+ anyInt(), anyBoolean())).thenReturn(true);
IPnoScanResultsCallback callback = mock(IPnoScanResultsCallback.class);
List<WifiSsid> ssids = new ArrayList<>();
ssids.add(WifiSsid.fromString("\"TEST_SSID_1\""));
@@ -10203,13 +10284,15 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(attributionSource.getUid()).thenReturn(Process.SYSTEM_UID);
when(attributionSource.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(TEST_SSID);
-
+ config.networkId = 1;
mWifiThreadRunner.prepareForAutoDispatch();
mLooper.startAutoDispatch();
mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution);
mLooper.stopAutoDispatch();
verify(mWifiConfigManager).addOrUpdateNetwork(config, Process.SYSTEM_UID,
TEST_PACKAGE_NAME, false);
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_UPDATE_NETWORK), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -10362,7 +10445,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mActiveModeWarden.getClientModeManagers()).thenReturn(
Collections.singletonList(mClientModeManager));
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST,
Arrays.asList(WifiSsid.fromUtf8Text("SSID")));
@@ -10390,7 +10473,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mActiveModeWarden.getClientModeManagers()).thenReturn(
Collections.singletonList(mClientModeManager));
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST,
Arrays.asList(WifiSsid.fromUtf8Text(TEST_SSID)));
@@ -10415,7 +10498,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mActiveModeWarden.getClientModeManagers()).thenReturn(
Collections.singletonList(mClientModeManager));
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST,
Arrays.asList(WifiSsid.fromUtf8Text("SSID")));
@@ -10444,7 +10527,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mActiveModeWarden.getClientModeManagers()).thenReturn(
Collections.singletonList(mClientModeManager));
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST,
Arrays.asList(WifiSsid.fromUtf8Text(TEST_SSID)));
@@ -10469,7 +10552,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mActiveModeWarden.getClientModeManagers()).thenReturn(
Collections.singletonList(mClientModeManager));
- when(mClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiServiceImpl.notifyMinimumRequiredWifiSecurityLevelChanged(
DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP);
@@ -10679,4 +10762,27 @@ public class WifiServiceImplTest extends WifiBaseTest {
assertEquals(-1, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME,
mAttribution));
}
+
+ /**
+ * Tests that {@link WifiServiceImpl#getCurrentNetwork} throws
+ * {@link SecurityException} if the caller doesn't have the necessary permissions.
+ */
+ @Test(expected = SecurityException.class)
+ public void testGetCurrentNetworkNoPermission() throws Exception {
+ doThrow(SecurityException.class)
+ .when(mContext).enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE), any());
+ mWifiServiceImpl.getCurrentNetwork();
+ }
+
+ /**
+ * Verifies that WifiServiceImpl#getCurrentNetwork() returns the current Wifi network.
+ */
+ @Test
+ public void testGetCurrentNetworkWithNetworkSettingsPermission() throws Exception {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ Network mockNetwork = mock(Network.class);
+ when(mActiveModeWarden.getCurrentNetwork()).thenReturn(mockNetwork);
+ assertEquals(mockNetwork, mWifiServiceImpl.getCurrentNetwork());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiSettingsStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiSettingsStoreTest.java
index a825882100..0f78f921af 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiSettingsStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiSettingsStoreTest.java
@@ -38,6 +38,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -52,6 +53,7 @@ import android.provider.Settings;
import androidx.test.filters.SmallTest;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.wifi.resources.R;
import org.junit.Before;
@@ -139,7 +141,8 @@ public class WifiSettingsStoreTest extends WifiBaseTest {
Settings.Global.WIFI_ON, WIFI_ENABLED_APM_OVERRIDE);
verify(mFrameworkFacade).setSecureIntegerSetting(
mContext, WIFI_APM_STATE, WIFI_REMAINS_ON_IN_APM);
- verify(mNotificationManager).notify(anyInt(), any(Notification.class));
+ verify(mNotificationManager).notify(eq(SystemMessage.NOTE_WIFI_APM_NOTIFICATION),
+ any(Notification.class));
verify(mFrameworkFacade).setSecureIntegerSetting(
mContext, APM_WIFI_ENABLED_NOTIFICATION, NOTIFICATION_SHOWN);
@@ -176,7 +179,8 @@ public class WifiSettingsStoreTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mFrameworkFacade).setIntegerSetting(mContentResolver,
Settings.Global.WIFI_ON, WIFI_ENABLED_APM_OVERRIDE);
- verify(mNotificationManager, never()).notify(anyInt(), any(Notification.class));
+ verify(mNotificationManager, never()).notify(eq(SystemMessage.NOTE_WIFI_APM_NOTIFICATION),
+ any(Notification.class));
verify(mFrameworkFacade, never()).setSecureIntegerSetting(
mContext, APM_WIFI_NOTIFICATION, NOTIFICATION_SHOWN);
@@ -187,7 +191,8 @@ public class WifiSettingsStoreTest extends WifiBaseTest {
mWifiSettingsStore.handleAirplaneModeToggled();
mLooper.dispatchAll();
- verify(mNotificationManager).notify(anyInt(), any(Notification.class));
+ verify(mNotificationManager).notify(eq(SystemMessage.NOTE_WIFI_APM_NOTIFICATION),
+ any(Notification.class));
verify(mFrameworkFacade).setSecureIntegerSetting(
mContext, APM_WIFI_NOTIFICATION, NOTIFICATION_SHOWN);
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 a522d0531a..f0767e20d1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
@@ -167,16 +167,12 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"get-ipreach-disconnect"});
verify(mWifiGlobals).getIpReachabilityDisconnectEnabled();
- mWifiShellCommand.getOutPrintWriter().toString().contains(
- "IPREACH_DISCONNECT state is true");
when(mWifiGlobals.getIpReachabilityDisconnectEnabled()).thenReturn(false);
mWifiShellCommand.exec(
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"get-ipreach-disconnect"});
verify(mWifiGlobals, times(2)).getIpReachabilityDisconnectEnabled();
- mWifiShellCommand.getOutPrintWriter().toString().contains(
- "IPREACH_DISCONNECT state is false");
}
@Test
@@ -219,8 +215,6 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"get-poll-rssi-interval-msecs"});
verify(mWifiGlobals).getPollRssiIntervalMillis();
- mWifiShellCommand.getOutPrintWriter().toString().contains(
- "WifiGlobals.getPollRssiIntervalMillis() = 5");
}
@Test
@@ -348,7 +342,6 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"network-suggestions-has-user-approved", TEST_PACKAGE});
verify(mWifiNetworkSuggestionsManager).hasUserApprovedForApp(TEST_PACKAGE);
- mWifiShellCommand.getOutPrintWriter().toString().contains("yes");
when(mWifiNetworkSuggestionsManager.hasUserApprovedForApp(TEST_PACKAGE))
.thenReturn(false);
@@ -356,7 +349,6 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"network-suggestions-has-user-approved", TEST_PACKAGE});
verify(mWifiNetworkSuggestionsManager, times(2)).hasUserApprovedForApp(TEST_PACKAGE);
- mWifiShellCommand.getOutPrintWriter().toString().contains("no");
}
@Test
@@ -405,7 +397,6 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"imsi-protection-exemption-has-user-approved-for-carrier", "5"});
verify(mWifiCarrierInfoManager).hasUserApprovedImsiPrivacyExemptionForCarrier(5);
- mWifiShellCommand.getOutPrintWriter().toString().contains("yes");
when(mWifiCarrierInfoManager.hasUserApprovedImsiPrivacyExemptionForCarrier(5))
.thenReturn(false);
@@ -413,7 +404,6 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"imsi-protection-exemption-has-user-approved-for-carrier", "5"});
verify(mWifiCarrierInfoManager, times(2)).hasUserApprovedImsiPrivacyExemptionForCarrier(5);
- mWifiShellCommand.getOutPrintWriter().toString().contains("no");
}
@Test
@@ -456,7 +446,6 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"network-requests-has-user-approved", TEST_PACKAGE});
verify(mWifiNetworkFactory).hasUserApprovedApp(TEST_PACKAGE);
- mWifiShellCommand.getOutPrintWriter().toString().contains("yes");
when(mWifiNetworkFactory.hasUserApprovedApp(TEST_PACKAGE))
.thenReturn(false);
@@ -464,7 +453,6 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"network-requests-has-user-approved", TEST_PACKAGE});
verify(mWifiNetworkFactory, times(2)).hasUserApprovedApp(TEST_PACKAGE);
- mWifiShellCommand.getOutPrintWriter().toString().contains("no");
}
@Test
@@ -738,7 +726,7 @@ public class WifiShellCommandTest extends WifiBaseTest {
verify(mWifiService).isScanAlwaysAvailable();
verify(mWifiService).getConnectionInfo(SHELL_PACKAGE_NAME, null);
- verify(mPrimaryClientModeManager, never()).syncRequestConnectionInfo();
+ verify(mPrimaryClientModeManager, never()).getConnectionInfo();
verify(mActiveModeWarden, never()).getClientModeManagers();
// rooted shell.
@@ -750,17 +738,17 @@ public class WifiShellCommandTest extends WifiBaseTest {
WifiInfo wifiInfo = new WifiInfo();
wifiInfo.setSupplicantState(SupplicantState.COMPLETED);
- when(mPrimaryClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
- when(additionalClientModeManager.syncRequestConnectionInfo()).thenReturn(wifiInfo);
+ when(mPrimaryClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
+ when(additionalClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiShellCommand.exec(
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"status"});
verify(mActiveModeWarden).getClientModeManagers();
- verify(mPrimaryClientModeManager).syncRequestConnectionInfo();
- verify(mPrimaryClientModeManager).syncGetCurrentNetwork();
- verify(additionalClientModeManager).syncRequestConnectionInfo();
- verify(additionalClientModeManager).syncGetCurrentNetwork();
+ verify(mPrimaryClientModeManager).getConnectionInfo();
+ verify(mPrimaryClientModeManager).getCurrentNetwork();
+ verify(additionalClientModeManager).getConnectionInfo();
+ verify(additionalClientModeManager).getCurrentNetwork();
}
@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 273fe7d156..47c423736d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -26,20 +26,14 @@ 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.ArgumentMatchers.argThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyByte;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.anyObject;
-import static org.mockito.Mockito.anyShort;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -53,55 +47,13 @@ import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.hardware.wifi.V1_0.IWifiApIface;
-import android.hardware.wifi.V1_0.IWifiChip;
-import android.hardware.wifi.V1_0.IWifiChipEventCallback;
-import android.hardware.wifi.V1_0.IWifiIface;
-import android.hardware.wifi.V1_0.IWifiStaIface;
-import android.hardware.wifi.V1_0.IWifiStaIfaceEventCallback;
-import android.hardware.wifi.V1_0.IfaceType;
-import android.hardware.wifi.V1_0.StaApfPacketFilterCapabilities;
-import android.hardware.wifi.V1_0.StaBackgroundScanCapabilities;
-import android.hardware.wifi.V1_0.StaBackgroundScanParameters;
-import android.hardware.wifi.V1_0.StaLinkLayerIfacePacketStats;
-import android.hardware.wifi.V1_0.StaLinkLayerIfaceStats;
-import android.hardware.wifi.V1_0.StaLinkLayerRadioStats;
-import android.hardware.wifi.V1_0.StaLinkLayerStats;
-import android.hardware.wifi.V1_0.StaRoamingCapabilities;
-import android.hardware.wifi.V1_0.StaRoamingConfig;
-import android.hardware.wifi.V1_0.StaRoamingState;
-import android.hardware.wifi.V1_0.StaScanData;
-import android.hardware.wifi.V1_0.StaScanDataFlagMask;
-import android.hardware.wifi.V1_0.StaScanResult;
-import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
-import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType;
-import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
-import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
-import android.hardware.wifi.V1_0.WifiDebugRingBufferVerboseLevel;
-import android.hardware.wifi.V1_0.WifiDebugRxPacketFate;
-import android.hardware.wifi.V1_0.WifiDebugRxPacketFateReport;
-import android.hardware.wifi.V1_0.WifiDebugTxPacketFate;
-import android.hardware.wifi.V1_0.WifiDebugTxPacketFateReport;
-import android.hardware.wifi.V1_0.WifiInformationElement;
-import android.hardware.wifi.V1_0.WifiStatus;
-import android.hardware.wifi.V1_0.WifiStatusCode;
-import android.hardware.wifi.V1_2.IWifiChipEventCallback.IfaceInfo;
-import android.hardware.wifi.V1_2.IWifiChipEventCallback.RadioModeInfo;
-import android.hardware.wifi.V1_3.WifiChannelStats;
-import android.hardware.wifi.V1_5.IWifiChip.MultiStaUseCase;
-import android.hardware.wifi.V1_5.StaLinkLayerIfaceContentionTimeStats;
-import android.hardware.wifi.V1_5.StaPeerInfo;
-import android.hardware.wifi.V1_5.StaRateStat;
-import android.hardware.wifi.V1_5.WifiUsableChannel;
import android.net.InetAddresses;
import android.net.KeepalivePacketData;
import android.net.MacAddress;
import android.net.NattKeepalivePacketData;
import android.net.apf.ApfCapabilities;
-import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
-import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
@@ -110,25 +62,21 @@ import android.os.RemoteException;
import android.os.WorkSource;
import android.os.test.TestLooper;
import android.system.OsConstants;
-import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
-import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
-import com.android.server.wifi.WifiLinkLayerStats.ChannelStats;
-import com.android.server.wifi.WifiLinkLayerStats.RadioStat;
-import com.android.server.wifi.WifiNative.RoamingCapabilities;
-import com.android.server.wifi.WifiNative.RxFateReport;
-import com.android.server.wifi.WifiNative.TxFateReport;
+import com.android.server.wifi.hal.WifiApIface;
+import com.android.server.wifi.hal.WifiChip;
+import com.android.server.wifi.hal.WifiHal;
+import com.android.server.wifi.hal.WifiStaIface;
import com.android.server.wifi.util.NativeUtil;
import com.android.wifi.resources.R;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
@@ -147,18 +95,12 @@ import java.util.Set;
*/
@SmallTest
public class WifiVendorHalTest extends WifiBaseTest {
-
private static final String TEST_IFACE_NAME = "wlan0";
private static final String TEST_IFACE_NAME_1 = "wlan1";
private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("ee:33:a2:94:10:92");
- private static final int[] TEST_FREQUENCIES =
- {2412, 2417, 2422, 2427, 2432, 2437};
private static final WorkSource TEST_WORKSOURCE = new WorkSource();
private WifiVendorHal mWifiVendorHal;
- private WifiStatus mWifiStatusSuccess;
- private WifiStatus mWifiStatusFailure;
- private WifiStatus mWifiStatusBusy;
private WifiLog mWifiLog;
private TestLooper mLooper;
private Handler mHandler;
@@ -173,35 +115,13 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Mock
private WifiVendorHal.HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
@Mock
- private IWifiApIface mIWifiApIface;
- @Mock
- private android.hardware.wifi.V1_4.IWifiApIface mIWifiApIfaceV14;
- @Mock
- private android.hardware.wifi.V1_5.IWifiApIface mIWifiApIfaceV15;
- @Mock
- private IWifiChip mIWifiChip;
- @Mock
- private android.hardware.wifi.V1_1.IWifiChip mIWifiChipV11;
- @Mock
- private android.hardware.wifi.V1_2.IWifiChip mIWifiChipV12;
- @Mock
- private android.hardware.wifi.V1_3.IWifiChip mIWifiChipV13;
+ private WifiApIface mWifiApIface;
@Mock
- private android.hardware.wifi.V1_4.IWifiChip mIWifiChipV14;
+ private WifiChip mWifiChip;
@Mock
- private android.hardware.wifi.V1_5.IWifiChip mIWifiChipV15;
- @Mock
- private IWifiStaIface mIWifiStaIface;
- @Mock
- private android.hardware.wifi.V1_2.IWifiStaIface mIWifiStaIfaceV12;
- @Mock
- private android.hardware.wifi.V1_3.IWifiStaIface mIWifiStaIfaceV13;
- @Mock
- private android.hardware.wifi.V1_5.IWifiStaIface mIWifiStaIfaceV15;
- private IWifiStaIfaceEventCallback mIWifiStaIfaceEventCallback;
- private IWifiChipEventCallback mIWifiChipEventCallback;
- private android.hardware.wifi.V1_2.IWifiChipEventCallback mIWifiChipEventCallbackV12;
- private android.hardware.wifi.V1_4.IWifiChipEventCallback mIWifiChipEventCallbackV14;
+ private WifiStaIface mWifiStaIface;
+ private WifiStaIface.Callback mWifiStaIfaceEventCallback;
+ private WifiChip.Callback mWifiChipEventCallback;
@Mock
private WifiNative.VendorHalDeathEventHandler mVendorHalDeathHandler;
@Mock
@@ -213,144 +133,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Mock
private SsidTranslator mSsidTranslator;
- /**
- * Spy used to return the V1_1 IWifiChip mock object to simulate the 1.1 HAL running on the
- * device.
- */
- private class WifiVendorHalSpyV1_1 extends WifiVendorHal {
- WifiVendorHalSpyV1_1(Context context, HalDeviceManager halDeviceManager, Handler handler,
- WifiGlobals wifiGlobals,
- @NonNull SsidTranslator ssidTranslator) {
- super(context, halDeviceManager, handler, wifiGlobals, ssidTranslator);
- }
-
- @Override
- protected android.hardware.wifi.V1_1.IWifiChip getWifiChipForV1_1Mockable() {
- return mIWifiChipV11;
- }
-
- @Override
- protected android.hardware.wifi.V1_2.IWifiChip getWifiChipForV1_2Mockable() {
- return null;
- }
-
- @Override
- protected android.hardware.wifi.V1_3.IWifiChip getWifiChipForV1_3Mockable() {
- return null;
- }
-
- @Override
- protected android.hardware.wifi.V1_4.IWifiChip getWifiChipForV1_4Mockable() {
- return null;
- }
-
- @Override
- protected android.hardware.wifi.V1_2.IWifiStaIface getWifiStaIfaceForV1_2Mockable(
- String ifaceName) {
- return null;
- }
-
- @Override
- protected android.hardware.wifi.V1_3.IWifiStaIface getWifiStaIfaceForV1_3Mockable(
- String ifaceName) {
- return null;
- }
-
- @Override
- protected android.hardware.wifi.V1_5.IWifiStaIface getWifiStaIfaceForV1_5Mockable(
- String ifaceName) {
- return null;
- }
- }
-
- /**
- * Spy used to return the V1_2 IWifiChip and IWifiStaIface mock objects to simulate
- * the 1.2 HAL running on the device.
- */
- private class WifiVendorHalSpyV1_2 extends WifiVendorHalSpyV1_1 {
- WifiVendorHalSpyV1_2(Context context, HalDeviceManager halDeviceManager, Handler handler,
- WifiGlobals wifiGlobals) {
- super(context, halDeviceManager, handler, wifiGlobals, mSsidTranslator);
- }
-
- @Override
- protected android.hardware.wifi.V1_2.IWifiChip getWifiChipForV1_2Mockable() {
- return mIWifiChipV12;
- }
-
- @Override
- protected android.hardware.wifi.V1_2.IWifiStaIface getWifiStaIfaceForV1_2Mockable(
- String ifaceName) {
- return mIWifiStaIfaceV12;
- }
- }
-
- /**
- * Spy used to return the V1_3 IWifiChip and V1_3 IWifiStaIface mock objects to simulate
- * the 1.3 HAL running on the device.
- */
- private class WifiVendorHalSpyV1_3 extends WifiVendorHalSpyV1_2 {
- WifiVendorHalSpyV1_3(Context context, HalDeviceManager halDeviceManager, Handler handler,
- WifiGlobals wifiGlobals) {
- super(context, halDeviceManager, handler, wifiGlobals);
- }
-
- @Override
- protected android.hardware.wifi.V1_3.IWifiChip getWifiChipForV1_3Mockable() {
- return mIWifiChipV13;
- }
-
- @Override
- protected android.hardware.wifi.V1_3.IWifiStaIface getWifiStaIfaceForV1_3Mockable(
- String ifaceName) {
- return mIWifiStaIfaceV13;
- }
- }
-
- /**
- * Spy used to return the V1_4 IWifiChip and V1_4 IWifiStaIface mock objects to simulate
- * the 1.4 HAL running on the device.
- */
- private class WifiVendorHalSpyV1_4 extends WifiVendorHalSpyV1_3 {
- WifiVendorHalSpyV1_4(Context context, HalDeviceManager halDeviceManager, Handler handler,
- WifiGlobals wifiGlobals) {
- super(context, halDeviceManager, handler, wifiGlobals);
- }
-
- @Override
- protected android.hardware.wifi.V1_4.IWifiChip getWifiChipForV1_4Mockable() {
- return mIWifiChipV14;
- }
- }
-
- /**
- * Spy used to return the V1_5 IWifiChip and V1_5 IWifiStaIface mock objects to simulate
- * the 1.5 HAL running on the device.
- */
- private class WifiVendorHalSpyV1_5 extends WifiVendorHalSpyV1_4 {
- WifiVendorHalSpyV1_5(Context context, HalDeviceManager halDeviceManager, Handler handler,
- WifiGlobals wifiGlobals) {
- super(context, halDeviceManager, handler, wifiGlobals);
- }
-
- @Override
- protected android.hardware.wifi.V1_5.IWifiChip getWifiChipForV1_5Mockable() {
- return mIWifiChipV15;
- }
-
- @Override
- protected android.hardware.wifi.V1_5.IWifiStaIface getWifiStaIfaceForV1_5Mockable(
- String ifaceName) {
- return mIWifiStaIfaceV15;
- }
- }
-
- /**
- * Identity function to supply a type to its argument, which is a lambda
- */
- static Answer<WifiStatus> answerWifiStatus(Answer<WifiStatus> statusLambda) {
- return (statusLambda);
- }
+ private ArgumentCaptor<List> mListCaptor = ArgumentCaptor.forClass(List.class);
/**
* Sets up for unit test
@@ -361,15 +144,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
mWifiLog = new FakeWifiLog();
mLooper = new TestLooper();
mHandler = new Handler(mLooper.getLooper());
- mWifiStatusSuccess = new WifiStatus();
- mWifiStatusSuccess.code = WifiStatusCode.SUCCESS;
- mWifiStatusFailure = new WifiStatus();
- mWifiStatusFailure.code = WifiStatusCode.ERROR_UNKNOWN;
- mWifiStatusFailure.description = "I don't even know what a Mock Turtle is.";
- mWifiStatusBusy = new WifiStatus();
- mWifiStatusBusy.code = WifiStatusCode.ERROR_BUSY;
- mWifiStatusBusy.description = "Don't bother me, kid";
- when(mIWifiStaIface.enableLinkLayerStatsCollection(false)).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.enableLinkLayerStatsCollection(false)).thenReturn(true);
// Setup the HalDeviceManager mock's start/stop behaviour. This can be overridden in
// individual tests, if needed.
@@ -392,59 +167,32 @@ public class WifiVendorHalTest extends WifiBaseTest {
}
}).when(mHalDeviceManager).stop();
when(mHalDeviceManager.createStaIface(any(), any(), any()))
- .thenReturn(mIWifiStaIface);
+ .thenReturn(mWifiStaIface);
when(mHalDeviceManager.createApIface(anyLong(), any(), any(), any(), anyBoolean(),
eq(mSoftApManager)))
- .thenReturn(mIWifiApIface);
+ .thenReturn(mWifiApIface);
when(mHalDeviceManager.removeIface(any())).thenReturn(true);
- when(mHalDeviceManager.getChip(any(IWifiIface.class)))
- .thenReturn(mIWifiChip);
+ when(mHalDeviceManager.getChip(any(WifiHal.WifiInterface.class)))
+ .thenReturn(mWifiChip);
when(mHalDeviceManager.isSupported()).thenReturn(true);
- when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class)))
- .thenReturn(mWifiStatusSuccess);
- mIWifiStaIfaceEventCallback = null;
- when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class)))
- .thenAnswer(answerWifiStatus((invocation) -> {
- Object[] args = invocation.getArguments();
- mIWifiStaIfaceEventCallback = (IWifiStaIfaceEventCallback) args[0];
- return (mWifiStatusSuccess);
- }));
- when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class)))
- .thenAnswer(answerWifiStatus((invocation) -> {
- Object[] args = invocation.getArguments();
- mIWifiChipEventCallback = (IWifiChipEventCallback) args[0];
- return (mWifiStatusSuccess);
- }));
- when(mIWifiChipV12.registerEventCallback_1_2(
- any(android.hardware.wifi.V1_2.IWifiChipEventCallback.class)))
- .thenAnswer(answerWifiStatus((invocation) -> {
- Object[] args = invocation.getArguments();
- mIWifiChipEventCallbackV12 =
- (android.hardware.wifi.V1_2.IWifiChipEventCallback) args[0];
- return (mWifiStatusSuccess);
- }));
-
- when(mIWifiChipV14.registerEventCallback_1_4(
- any(android.hardware.wifi.V1_4.IWifiChipEventCallback.class)))
- .thenAnswer(answerWifiStatus((invocation) -> {
- Object[] args = invocation.getArguments();
- mIWifiChipEventCallbackV14 =
- (android.hardware.wifi.V1_4.IWifiChipEventCallback) args[0];
- return (mWifiStatusSuccess);
- }));
+ when(mWifiChip.registerCallback(any(WifiChip.Callback.class)))
+ .thenReturn(true);
+ mWifiStaIfaceEventCallback = null;
doAnswer(new AnswerWithArguments() {
- public void answer(IWifiIface.getNameCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, TEST_IFACE_NAME);
+ public boolean answer(WifiStaIface.Callback callback) {
+ mWifiStaIfaceEventCallback = callback;
+ return true;
}
- }).when(mIWifiStaIface).getName(any(IWifiIface.getNameCallback.class));
+ }).when(mWifiStaIface).registerFrameworkCallback(any(WifiStaIface.Callback.class));
doAnswer(new AnswerWithArguments() {
- public void answer(IWifiIface.getNameCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, TEST_IFACE_NAME);
+ public boolean answer(WifiChip.Callback callback) {
+ mWifiChipEventCallback = callback;
+ return true;
}
- }).when(mIWifiApIface).getName(any(IWifiIface.getNameCallback.class));
+ }).when(mWifiChip).registerCallback(any(WifiChip.Callback.class));
+ when(mWifiStaIface.getName()).thenReturn(TEST_IFACE_NAME);
+ when(mWifiApIface.getName()).thenReturn(TEST_IFACE_NAME);
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled))
@@ -493,11 +241,11 @@ public class WifiVendorHalTest extends WifiBaseTest {
verify(mHalDeviceManager).start();
verify(mHalDeviceManager).createStaIface(any(), any(), any());
- verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
+ verify(mHalDeviceManager).getChip(eq(mWifiStaIface));
verify(mHalDeviceManager).isReady();
verify(mHalDeviceManager).isStarted();
- verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
- verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
+ verify(mWifiStaIface).registerFrameworkCallback(any(WifiStaIface.Callback.class));
+ verify(mWifiChip).registerCallback(any(WifiChip.Callback.class));
verify(mHalDeviceManager, never()).createApIface(
anyLong(), any(), any(), any(), anyBoolean(), eq(mSoftApManager));
@@ -524,9 +272,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
verify(mHalDeviceManager, never()).createStaIface(any(), any(), any());
verify(mHalDeviceManager, never()).createApIface(
anyLong(), any(), any(), any(), anyBoolean(), eq(mSoftApManager));
- verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
- verify(mIWifiStaIface, never())
- .registerEventCallback(any(IWifiStaIfaceEventCallback.class));
+ verify(mHalDeviceManager, never()).getChip(any(WifiHal.WifiInterface.class));
+ verify(mWifiStaIface, never())
+ .registerFrameworkCallback(any(WifiStaIface.Callback.class));
}
/**
@@ -545,9 +293,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
verify(mHalDeviceManager, never()).createApIface(
anyLong(), any(), any(), any(), anyBoolean(), eq(mSoftApManager));
- verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
- verify(mIWifiStaIface, never())
- .registerEventCallback(any(IWifiStaIfaceEventCallback.class));
+ verify(mHalDeviceManager, never()).getChip(any(WifiHal.WifiInterface.class));
+ verify(mWifiStaIface, never())
+ .registerFrameworkCallback(any(WifiStaIface.Callback.class));
}
/**
@@ -556,15 +304,15 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testStartHalFailureInChipGetInStaMode() throws Exception {
- when(mHalDeviceManager.getChip(any(IWifiIface.class))).thenReturn(null);
+ when(mHalDeviceManager.getChip(any(WifiHal.WifiInterface.class))).thenReturn(null);
assertFalse(mWifiVendorHal.startVendorHalSta());
assertFalse(mWifiVendorHal.isHalStarted());
verify(mHalDeviceManager).start();
verify(mHalDeviceManager).createStaIface(any(), any(), any());
- verify(mHalDeviceManager).getChip(any(IWifiIface.class));
+ verify(mHalDeviceManager).getChip(any(WifiHal.WifiInterface.class));
verify(mHalDeviceManager).stop();
- verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
+ verify(mWifiStaIface).registerFrameworkCallback(any(WifiStaIface.Callback.class));
verify(mHalDeviceManager, never()).createApIface(
anyLong(), any(), any(), any(), anyBoolean(), eq(mSoftApManager));
@@ -576,17 +324,17 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testStartHalFailureInStaIfaceCallbackRegistration() throws Exception {
- when(mIWifiStaIface.registerEventCallback(any(IWifiStaIfaceEventCallback.class)))
- .thenReturn(mWifiStatusFailure);
+ when(mWifiStaIface.registerFrameworkCallback(any(WifiStaIface.Callback.class)))
+ .thenReturn(false);
assertFalse(mWifiVendorHal.startVendorHalSta());
assertFalse(mWifiVendorHal.isHalStarted());
verify(mHalDeviceManager).start();
verify(mHalDeviceManager).createStaIface(any(), any(), any());
verify(mHalDeviceManager).stop();
- verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
+ verify(mWifiStaIface).registerFrameworkCallback(any(WifiStaIface.Callback.class));
- verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
+ verify(mHalDeviceManager, never()).getChip(any(WifiHal.WifiInterface.class));
verify(mHalDeviceManager, never()).createApIface(
anyLong(), any(), any(), any(), anyBoolean(), eq(mSoftApManager));
}
@@ -597,17 +345,17 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testStartHalFailureInChipCallbackRegistration() throws Exception {
- when(mIWifiChip.registerEventCallback(any(IWifiChipEventCallback.class)))
- .thenReturn(mWifiStatusFailure);
+ when(mWifiChip.registerCallback(any(WifiChip.Callback.class)))
+ .thenReturn(false);
assertFalse(mWifiVendorHal.startVendorHalSta());
assertFalse(mWifiVendorHal.isHalStarted());
verify(mHalDeviceManager).start();
verify(mHalDeviceManager).createStaIface(any(), any(), any());
- verify(mHalDeviceManager).getChip(any(IWifiIface.class));
+ verify(mHalDeviceManager).getChip(any(WifiHal.WifiInterface.class));
verify(mHalDeviceManager).stop();
- verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
- verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
+ verify(mWifiStaIface).registerFrameworkCallback(any(WifiStaIface.Callback.class));
+ verify(mWifiChip).registerCallback(any(WifiChip.Callback.class));
verify(mHalDeviceManager, never()).createApIface(
anyLong(), any(), any(), any(), anyBoolean(), eq(mSoftApManager));
@@ -628,7 +376,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
verify(mHalDeviceManager).start();
verify(mHalDeviceManager).stop();
verify(mHalDeviceManager).createStaIface(any(), any(), any());
- verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
+ verify(mHalDeviceManager).getChip(eq(mWifiStaIface));
verify(mHalDeviceManager, times(2)).isReady();
verify(mHalDeviceManager, times(2)).isStarted();
@@ -655,7 +403,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
verify(mHalDeviceManager).stop();
verify(mHalDeviceManager).createApIface(
anyLong(), any(), any(), any(), anyBoolean(), eq(mSoftApManager));
- verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
+ verify(mHalDeviceManager).getChip(eq(mWifiApIface));
verify(mHalDeviceManager, times(2)).isReady();
verify(mHalDeviceManager, times(2)).isStarted();
@@ -678,11 +426,11 @@ public class WifiVendorHalTest extends WifiBaseTest {
verify(mHalDeviceManager).start();
verify(mHalDeviceManager).createStaIface(internalListenerCaptor.capture(),
any(), eq(TEST_WORKSOURCE));
- verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
+ verify(mHalDeviceManager).getChip(eq(mWifiStaIface));
verify(mHalDeviceManager).isReady();
verify(mHalDeviceManager).isStarted();
- verify(mIWifiStaIface).registerEventCallback(any(IWifiStaIfaceEventCallback.class));
- verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
+ verify(mWifiStaIface).registerFrameworkCallback(any(WifiStaIface.Callback.class));
+ verify(mWifiChip).registerCallback(any(WifiChip.Callback.class));
// Now trigger the interface destroyed callback from HalDeviceManager and ensure the
// external listener is invoked and iface removed from internal database.
@@ -713,10 +461,10 @@ public class WifiVendorHalTest extends WifiBaseTest {
verify(mHalDeviceManager).createApIface(anyLong(),
internalListenerCaptor.capture(), any(), eq(TEST_WORKSOURCE), eq(false),
eq(mSoftApManager));
- verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
+ verify(mHalDeviceManager).getChip(eq(mWifiApIface));
verify(mHalDeviceManager).isReady();
verify(mHalDeviceManager).isStarted();
- verify(mIWifiChip).registerEventCallback(any(IWifiChipEventCallback.class));
+ verify(mWifiChip).registerCallback(any(WifiChip.Callback.class));
// Now trigger the interface destroyed callback from HalDeviceManager and ensure the
// external listener is invoked and iface removed from internal database.
@@ -753,19 +501,6 @@ public class WifiVendorHalTest extends WifiBaseTest {
}
/**
- * Test that boolResult logs a false result
- */
- @Test
- public void testBoolResultFalse() {
- mWifiLog = spy(mWifiLog);
- mWifiVendorHal.mLog = mWifiLog;
- mWifiVendorHal.mVerboseLog = mWifiLog;
- assertFalse(mWifiVendorHal.getBgScanCapabilities(
- TEST_IFACE_NAME, new WifiNative.ScanCapabilities()));
- verify(mWifiLog).err("% returns %");
- }
-
- /**
* Test that getBgScanCapabilities is hooked up to the HAL correctly
*
* A call before the vendor HAL is started should return a non-null result with version 0
@@ -774,19 +509,12 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testGetBgScanCapabilities() throws Exception {
- StaBackgroundScanCapabilities capabilities = new StaBackgroundScanCapabilities();
- capabilities.maxCacheSize = 12;
- capabilities.maxBuckets = 34;
- capabilities.maxApCachePerScan = 56;
- capabilities.maxReportingThreshold = 78;
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiStaIface.getBackgroundScanCapabilitiesCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, capabilities);
- }
- }).when(mIWifiStaIface).getBackgroundScanCapabilities(any(
- IWifiStaIface.getBackgroundScanCapabilitiesCallback.class));
+ WifiNative.ScanCapabilities capabilities = new WifiNative.ScanCapabilities();
+ capabilities.max_scan_cache_size = 12;
+ capabilities.max_scan_buckets = 34;
+ capabilities.max_ap_cache_per_scan = 56;
+ capabilities.max_scan_reporting_threshold = 78;
+ when(mWifiStaIface.getBackgroundScanCapabilities()).thenReturn(capabilities);
WifiNative.ScanCapabilities result = new WifiNative.ScanCapabilities();
@@ -804,96 +532,29 @@ public class WifiVendorHalTest extends WifiBaseTest {
}
/**
- * Test translation to WifiManager.WIFI_FEATURE_*
- *
- * Just do a spot-check with a few feature bits here; since the code is table-
- * driven we don't have to work hard to exercise all of it.
- */
- @Test
- public void testStaIfaceFeatureMaskTranslation() {
- int caps = (
- IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
- | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
- );
- long expected = (
- WifiManager.WIFI_FEATURE_SCANNER
- | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS);
- assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromStaCapabilities(caps));
- }
-
- /**
- * Test translation to WifiManager.WIFI_FEATURE_*
- *
- * Just do a spot-check with a few feature bits here; since the code is table-
- * driven we don't have to work hard to exercise all of it.
- */
- @Test
- public void testChipFeatureMaskTranslation() {
- int caps = (
- android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT
- | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
- | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2AP_RTT
- );
- long expected = (
- WifiManager.WIFI_FEATURE_TX_POWER_LIMIT
- | WifiManager.WIFI_FEATURE_D2D_RTT
- | WifiManager.WIFI_FEATURE_D2AP_RTT
- );
- assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromChipCapabilities(caps));
- }
-
- /**
- * Test translation to WifiManager.WIFI_FEATURE_* for V1.3
- *
- * Test the added features in V1.3
+ * Test get supported features. Tests whether we coalesce information from different sources
+ * (IWifiStaIface, IWifiChip and HalDeviceManager) into the bitmask of supported features
+ * correctly.
*/
@Test
- public void testChipFeatureMaskTranslation_1_3() {
- int caps = (
- android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.SET_LATENCY_MODE
- | android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
- );
- long expected = (
- WifiManager.WIFI_FEATURE_LOW_LATENCY
- | WifiManager.WIFI_FEATURE_D2D_RTT
- );
- assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromChipCapabilities_1_3(caps));
- }
-
- private void testGetSupportedFeaturesCommon(
- int staIfaceHidlCaps, int chipHidlCaps, long expectedFeatureSet) throws Exception {
- assertTrue(mWifiVendorHal.startVendorHalSta());
+ public void testGetSupportedFeatures() throws Exception {
+ long staIfaceCaps =
+ WifiManager.WIFI_FEATURE_SCANNER | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS;
+ long chipCaps = WifiManager.WIFI_FEATURE_TX_POWER_LIMIT;
+ WifiChip.Response<Long> chipCapsResponse = new WifiChip.Response<>(chipCaps);
+ chipCapsResponse.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
+ when(mWifiStaIface.getCapabilities()).thenReturn(staIfaceCaps);
+ when(mWifiChip.getCapabilitiesAfterIfacesExist()).thenReturn(chipCapsResponse);
Set<Integer> halDeviceManagerSupportedIfaces = new HashSet<Integer>() {{
- add(IfaceType.STA);
- add(IfaceType.P2P);
+ add(WifiChip.IFACE_TYPE_STA);
+ add(WifiChip.IFACE_TYPE_P2P);
}};
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiStaIface.getCapabilitiesCallback cb) throws RemoteException {
- cb.onValues(mWifiStatusSuccess, staIfaceHidlCaps);
- }
- }).when(mIWifiStaIface).getCapabilities(any(IWifiStaIface.getCapabilitiesCallback.class));
-
when(mHalDeviceManager.getSupportedIfaceTypes())
.thenReturn(halDeviceManagerSupportedIfaces);
-
- assertEquals(expectedFeatureSet, mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME));
- }
- /**
- * Test get supported features. Tests whether we coalesce information from different sources
- * (IWifiStaIface, IWifiChip and HalDeviceManager) into the bitmask of supported features
- * correctly.
- */
- @Test
- public void testGetSupportedFeatures() throws Exception {
- int staIfaceHidlCaps = (
- IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
- | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
- );
- int chipHidlCaps =
- android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.SET_TX_POWER_LIMIT;
when(mWifiGlobals.isWpa3SaeH2eSupported()).thenReturn(true);
+ when(mHalDeviceManager.is24g5gDbsSupported(any())).thenReturn(true);
+
long expectedFeatureSet = (
WifiManager.WIFI_FEATURE_SCANNER
| WifiManager.WIFI_FEATURE_LINK_LAYER_STATS
@@ -901,92 +562,10 @@ public class WifiVendorHalTest extends WifiBaseTest {
| WifiManager.WIFI_FEATURE_INFRA
| WifiManager.WIFI_FEATURE_P2P
| WifiManager.WIFI_FEATURE_SAE_H2E
+ | WifiManager.WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS
);
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiChip.getCapabilitiesCallback cb) throws RemoteException {
- cb.onValues(mWifiStatusSuccess, chipHidlCaps);
- }
- }).when(mIWifiChip).getCapabilities(any(IWifiChip.getCapabilitiesCallback.class));
-
- mWifiVendorHal = new WifiVendorHalSpyV1_1(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals, mSsidTranslator);
- testGetSupportedFeaturesCommon(staIfaceHidlCaps, chipHidlCaps, expectedFeatureSet);
- }
-
- /**
- * Test get supported features. Tests whether we coalesce information from different sources
- * (IWifiStaIface, IWifiChip and HalDeviceManager) into the bitmask of supported features
- * correctly.
- */
- @Test
- public void testGetSupportedFeaturesForHalV1_3() throws Exception {
- assertTrue(mWifiVendorHal.startVendorHalSta());
-
- int staIfaceHidlCaps = (
- IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
- | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
- );
- int chipHidlCaps =
- android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.SET_LATENCY_MODE
- | android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.P2P_RAND_MAC;
- long expectedFeatureSet = (
- WifiManager.WIFI_FEATURE_SCANNER
- | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS
- | WifiManager.WIFI_FEATURE_LOW_LATENCY
- | WifiManager.WIFI_FEATURE_P2P_RAND_MAC
- | WifiManager.WIFI_FEATURE_INFRA
- | WifiManager.WIFI_FEATURE_P2P
- );
-
- doAnswer(new AnswerWithArguments() {
- public void answer(
- android.hardware.wifi.V1_3.IWifiChip.getCapabilities_1_3Callback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, chipHidlCaps);
- }
- }).when(mIWifiChipV13).getCapabilities_1_3(
- any(android.hardware.wifi.V1_3.IWifiChip.getCapabilities_1_3Callback.class));
-
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- testGetSupportedFeaturesCommon(staIfaceHidlCaps, chipHidlCaps, expectedFeatureSet);
- }
-
- /**
- * Test get supported features. Tests whether we coalesce information from different sources
- * (IWifiStaIface, IWifiChip and HalDeviceManager) into the bitmask of supported features
- * correctly.
- */
- @Test
- public void testGetSupportedFeaturesForHalV1_5() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
-
- int staIfaceHidlCaps = (
- IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
- | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
- );
- int chipHidlCaps = android.hardware.wifi.V1_5.IWifiChip.ChipCapabilityMask.WIGIG;
- long expectedFeatureSet = (
- WifiManager.WIFI_FEATURE_SCANNER
- | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS
- | WifiManager.WIFI_FEATURE_INFRA_60G
- | WifiManager.WIFI_FEATURE_INFRA
- | WifiManager.WIFI_FEATURE_P2P
- );
-
- doAnswer(new AnswerWithArguments() {
- public void answer(
- android.hardware.wifi.V1_5.IWifiChip.getCapabilities_1_5Callback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, chipHidlCaps);
- }
- }).when(mIWifiChipV15).getCapabilities_1_5(
- any(android.hardware.wifi.V1_5.IWifiChip.getCapabilities_1_5Callback.class));
-
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- testGetSupportedFeaturesCommon(staIfaceHidlCaps, chipHidlCaps, expectedFeatureSet);
+ assertEquals(expectedFeatureSet, mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME));
}
/**
@@ -1016,56 +595,10 @@ public class WifiVendorHalTest extends WifiBaseTest {
| WifiManager.WIFI_FEATURE_P2P
| WifiManager.WIFI_FEATURE_AWARE
);
-
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
assertEquals(expectedFeatureSet, mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME));
}
/**
- * Test |getFactoryMacAddress| gets called when the hal version is V1_3
- * @throws Exception
- */
- @Test
- public void testGetStaFactoryMacWithHalV1_3() throws Exception {
- doAnswer(new AnswerWithArguments() {
- public void answer(
- android.hardware.wifi.V1_3.IWifiStaIface.getFactoryMacAddressCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, MacAddress.BROADCAST_ADDRESS.toByteArray());
- }
- }).when(mIWifiStaIfaceV13).getFactoryMacAddress(any(
- android.hardware.wifi.V1_3.IWifiStaIface.getFactoryMacAddressCallback.class));
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- assertEquals(MacAddress.BROADCAST_ADDRESS.toString(),
- mWifiVendorHal.getStaFactoryMacAddress(TEST_IFACE_NAME).toString());
- verify(mIWifiStaIfaceV13).getFactoryMacAddress(any());
- }
-
- /**
- * Test getLinkLayerStats_1_3 gets called when the hal version is V1_3.
- */
- @Test
- public void testLinkLayerStatsCorrectVersionWithHalV1_3() throws Exception {
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME);
- verify(mIWifiStaIfaceV13).getLinkLayerStats_1_3(any());
- }
-
- /**
- * Test getLinkLayerStats_1_5 gets called when the hal version is V1_5.
- */
- @Test
- public void testLinkLayerStatsCorrectVersionWithHalV1_5() throws Exception {
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME);
- verify(mIWifiStaIfaceV15).getLinkLayerStats_1_5(any());
- }
-
- /**
* Test that link layer stats are not enabled and harmless in AP mode
*
* Start the HAL in AP mode
@@ -1075,7 +608,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testLinkLayerStatsNotEnabledAndHarmlessInApMode() throws Exception {
- doNothing().when(mIWifiStaIface).getLinkLayerStats(any());
+ when(mWifiStaIface.getLinkLayerStats()).thenReturn(null);
assertTrue(mWifiVendorHal.startVendorHal());
assertNotNull(mWifiVendorHal.createApIface(null, null,
@@ -1085,548 +618,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
verify(mHalDeviceManager).start();
- verify(mIWifiStaIface, never()).enableLinkLayerStatsCollection(false);
- verify(mIWifiStaIface, never()).getLinkLayerStats(any());
- }
-
- /**
- * Test that the link layer stats fields are populated correctly.
- *
- * This is done by filling Hal LinkLayerStats (V1_0) with random values, converting it to
- * WifiLinkLayerStats and then asserting the values in the original structure are equal to the
- * values in the converted structure.
- */
- @Test
- public void testLinkLayerStatsAssignment() throws Exception {
- Random r = new Random(1775968256);
- StaLinkLayerStats stats = new StaLinkLayerStats();
- randomizePacketStats(r, stats.iface.wmeBePktStats);
- randomizePacketStats(r, stats.iface.wmeBkPktStats);
- randomizePacketStats(r, stats.iface.wmeViPktStats);
- randomizePacketStats(r, stats.iface.wmeVoPktStats);
- randomizeRadioStats(r, stats.radios);
- stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL;
-
- WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats(stats);
-
- verifyIFaceStats(stats.iface, converted);
- verifyRadioStats(stats.radios, converted);
- assertEquals(stats.timeStampInMs, converted.timeStampInMs);
- assertEquals(WifiLinkLayerStats.V1_0, converted.version);
- }
-
- /**
- * Test that the link layer stats V1_3 fields are populated correctly.
- *
- * This is done by filling Hal LinkLayerStats (V1_3) with random values, converting it to
- * WifiLinkLayerStats and then asserting the values in the original structure are equal to the
- * values in the converted structure.
- */
- @Test
- public void testLinkLayerStatsAssignment_1_3() throws Exception {
- Random r = new Random(1775968256);
- android.hardware.wifi.V1_3.StaLinkLayerStats stats =
- new android.hardware.wifi.V1_3.StaLinkLayerStats();
- randomizePacketStats(r, stats.iface.wmeBePktStats);
- randomizePacketStats(r, stats.iface.wmeBkPktStats);
- randomizePacketStats(r, stats.iface.wmeViPktStats);
- randomizePacketStats(r, stats.iface.wmeVoPktStats);
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat =
- new android.hardware.wifi.V1_3.StaLinkLayerRadioStats();
- randomizeRadioStats_1_3(r, rstat);
- stats.radios.add(rstat);
- stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL;
-
- WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_3(stats);
-
- verifyIFaceStats(stats.iface, converted);
- verifyRadioStats_1_3(stats.radios.get(0), converted);
- assertEquals(stats.timeStampInMs, converted.timeStampInMs);
- assertEquals(WifiLinkLayerStats.V1_3, converted.version);
- assertEquals(1, converted.numRadios);
- }
-
- /**
- * Test that the link layer stats V1_5 fields are populated correctly.
- *
- * This is done by filling Hal LinkLayerStats (V1_5) with random values, converting it to
- * WifiLinkLayerStats and then asserting the values in the original structure are equal to the
- * values in the converted structure.
- */
- @Test
- public void testLinkLayerStatsAssignment_1_5() throws Exception {
- Random r = new Random(1775968256);
- android.hardware.wifi.V1_5.StaLinkLayerStats stats =
- new android.hardware.wifi.V1_5.StaLinkLayerStats();
- randomizePacketStats(r, stats.iface.V1_0.wmeBePktStats);
- randomizePacketStats(r, stats.iface.V1_0.wmeBkPktStats);
- randomizePacketStats(r, stats.iface.V1_0.wmeViPktStats);
- randomizePacketStats(r, stats.iface.V1_0.wmeVoPktStats);
- android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat =
- new android.hardware.wifi.V1_5.StaLinkLayerRadioStats();
- randomizeRadioStats_1_5(r, rstat);
- stats.radios.add(rstat);
- stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL;
- randomizeContentionTimeStats(r, stats.iface.wmeBeContentionTimeStats);
- randomizeContentionTimeStats(r, stats.iface.wmeBkContentionTimeStats);
- randomizeContentionTimeStats(r, stats.iface.wmeViContentionTimeStats);
- randomizeContentionTimeStats(r, stats.iface.wmeVoContentionTimeStats);
- randomizePeerInfoStats(r, stats.iface.peers);
-
- WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_5(stats);
-
- verifyIFaceStats(stats.iface.V1_0, converted);
- verifyIFaceStats_1_5(stats.iface, converted);
- verifyPerRadioStats(stats.radios, converted);
- verifyRadioStats_1_5(stats.radios.get(0), converted);
- assertEquals(stats.timeStampInMs, converted.timeStampInMs);
- assertEquals(WifiLinkLayerStats.V1_5, converted.version);
- assertEquals(1, converted.numRadios);
- }
-
- /**
- * Test that the link layer stats V1_3 fields are aggregated correctly for two radios.
- *
- * This is done by filling multiple Hal LinkLayerStats (V1_3) with random values,
- * converting it to WifiLinkLayerStats and then asserting the sum of values from HAL structure
- * are equal to the values in the converted structure.
- */
- @Test
- public void testTwoRadioStatsAggregation_1_3() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled))
- .thenReturn(true);
- Random r = new Random(245786856);
- android.hardware.wifi.V1_3.StaLinkLayerStats stats =
- new android.hardware.wifi.V1_3.StaLinkLayerStats();
- // Fill stats in two radios
- for (int i = 0; i < 2; i++) {
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat =
- new android.hardware.wifi.V1_3.StaLinkLayerRadioStats();
- randomizeRadioStats_1_3(r, rstat);
- stats.radios.add(rstat);
- }
-
- WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_3(stats);
- verifyTwoRadioStatsAggregation_1_3(stats.radios, converted);
- assertEquals(2, converted.numRadios);
- }
-
- /**
- * Test that the link layer stats V1_3 fields are not aggregated on setting
- * config_wifiLinkLayerAllRadiosStatsAggregationEnabled to false(Default value).
- *
- * This is done by filling multiple Hal LinkLayerStats (V1_3) with random values,
- * converting it to WifiLinkLayerStats and then asserting the values from radio 0
- * are equal to the values in the converted structure.
- */
- @Test
- public void testRadioStatsAggregationDisabled_1_3() throws Exception {
- Random r = new Random(245786856);
- android.hardware.wifi.V1_3.StaLinkLayerStats stats =
- new android.hardware.wifi.V1_3.StaLinkLayerStats();
- // Fill stats in two radios
- for (int i = 0; i < 2; i++) {
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat =
- new android.hardware.wifi.V1_3.StaLinkLayerRadioStats();
- randomizeRadioStats_1_3(r, rstat);
- stats.radios.add(rstat);
- }
-
- WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_3(stats);
- verifyRadioStats_1_3(stats.radios.get(0), converted);
- assertEquals(1, converted.numRadios);
- }
-
- /**
- * Test that the link layer stats V1_5 fields are aggregated correctly for two radios.
- *
- * This is done by filling multiple Hal LinkLayerStats (V1_5) with random values,
- * converting it to WifiLinkLayerStats and then asserting the sum of values from HAL structure
- * are equal to the values in the converted structure.
- */
- @Test
- public void testTwoRadioStatsAggregation_1_5() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled))
- .thenReturn(true);
- Random r = new Random(245786856);
- android.hardware.wifi.V1_5.StaLinkLayerStats stats =
- new android.hardware.wifi.V1_5.StaLinkLayerStats();
- // Fill stats in two radios
- for (int i = 0; i < 2; i++) {
- android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat =
- new android.hardware.wifi.V1_5.StaLinkLayerRadioStats();
- randomizeRadioStats_1_5(r, rstat);
- stats.radios.add(rstat);
- }
-
- WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_5(stats);
- verifyPerRadioStats(stats.radios, converted);
- verifyTwoRadioStatsAggregation_1_5(stats.radios, converted);
- assertEquals(2, converted.numRadios);
- }
-
- /**
- * Test that the link layer stats V1_5 fields are not aggregated on setting
- * config_wifiLinkLayerAllRadiosStatsAggregationEnabled to false(Default value).
- *
- * This is done by filling multiple Hal LinkLayerStats (V1_5) with random values,
- * converting it to WifiLinkLayerStats and then asserting the values from radio 0
- * are equal to the values in the converted structure.
- */
- @Test
- public void testRadioStatsAggregationDisabled_1_5() throws Exception {
- Random r = new Random(245786856);
- android.hardware.wifi.V1_5.StaLinkLayerStats stats =
- new android.hardware.wifi.V1_5.StaLinkLayerStats();
- // Fill stats in two radios
- for (int i = 0; i < 2; i++) {
- android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat =
- new android.hardware.wifi.V1_5.StaLinkLayerRadioStats();
- randomizeRadioStats_1_5(r, rstat);
- stats.radios.add(rstat);
- }
-
- WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats_1_5(stats);
- verifyPerRadioStats(stats.radios, converted);
- verifyRadioStats_1_5(stats.radios.get(0), converted);
- assertEquals(1, converted.numRadios);
- }
-
- private void verifyIFaceStats(StaLinkLayerIfaceStats iface,
- WifiLinkLayerStats wifiLinkLayerStats) {
- assertEquals(iface.beaconRx, wifiLinkLayerStats.beacon_rx);
- assertEquals(iface.avgRssiMgmt, wifiLinkLayerStats.rssi_mgmt);
-
- assertEquals(iface.wmeBePktStats.rxMpdu, wifiLinkLayerStats.rxmpdu_be);
- assertEquals(iface.wmeBePktStats.txMpdu, wifiLinkLayerStats.txmpdu_be);
- assertEquals(iface.wmeBePktStats.lostMpdu, wifiLinkLayerStats.lostmpdu_be);
- assertEquals(iface.wmeBePktStats.retries, wifiLinkLayerStats.retries_be);
-
- assertEquals(iface.wmeBkPktStats.rxMpdu, wifiLinkLayerStats.rxmpdu_bk);
- assertEquals(iface.wmeBkPktStats.txMpdu, wifiLinkLayerStats.txmpdu_bk);
- assertEquals(iface.wmeBkPktStats.lostMpdu, wifiLinkLayerStats.lostmpdu_bk);
- assertEquals(iface.wmeBkPktStats.retries, wifiLinkLayerStats.retries_bk);
-
- assertEquals(iface.wmeViPktStats.rxMpdu, wifiLinkLayerStats.rxmpdu_vi);
- assertEquals(iface.wmeViPktStats.txMpdu, wifiLinkLayerStats.txmpdu_vi);
- assertEquals(iface.wmeViPktStats.lostMpdu, wifiLinkLayerStats.lostmpdu_vi);
- assertEquals(iface.wmeViPktStats.retries, wifiLinkLayerStats.retries_vi);
-
- assertEquals(iface.wmeVoPktStats.rxMpdu, wifiLinkLayerStats.rxmpdu_vo);
- assertEquals(iface.wmeVoPktStats.txMpdu, wifiLinkLayerStats.txmpdu_vo);
- assertEquals(iface.wmeVoPktStats.lostMpdu, wifiLinkLayerStats.lostmpdu_vo);
- assertEquals(iface.wmeVoPktStats.retries, wifiLinkLayerStats.retries_vo);
- }
-
- private void verifyIFaceStats_1_5(android.hardware.wifi.V1_5.StaLinkLayerIfaceStats iface,
- WifiLinkLayerStats wifiLinkLayerStats) {
- assertEquals(iface.wmeBeContentionTimeStats.contentionTimeMinInUsec,
- wifiLinkLayerStats.contentionTimeMinBeInUsec);
- assertEquals(iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec,
- wifiLinkLayerStats.contentionTimeMaxBeInUsec);
- assertEquals(iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec,
- wifiLinkLayerStats.contentionTimeAvgBeInUsec);
- assertEquals(iface.wmeBeContentionTimeStats.contentionNumSamples,
- wifiLinkLayerStats.contentionNumSamplesBe);
-
- assertEquals(iface.wmeBkContentionTimeStats.contentionTimeMinInUsec,
- wifiLinkLayerStats.contentionTimeMinBkInUsec);
- assertEquals(iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec,
- wifiLinkLayerStats.contentionTimeMaxBkInUsec);
- assertEquals(iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec,
- wifiLinkLayerStats.contentionTimeAvgBkInUsec);
- assertEquals(iface.wmeBkContentionTimeStats.contentionNumSamples,
- wifiLinkLayerStats.contentionNumSamplesBk);
-
- assertEquals(iface.wmeViContentionTimeStats.contentionTimeMinInUsec,
- wifiLinkLayerStats.contentionTimeMinViInUsec);
- assertEquals(iface.wmeViContentionTimeStats.contentionTimeMaxInUsec,
- wifiLinkLayerStats.contentionTimeMaxViInUsec);
- assertEquals(iface.wmeViContentionTimeStats.contentionTimeAvgInUsec,
- wifiLinkLayerStats.contentionTimeAvgViInUsec);
- assertEquals(iface.wmeViContentionTimeStats.contentionNumSamples,
- wifiLinkLayerStats.contentionNumSamplesVi);
-
- assertEquals(iface.wmeVoContentionTimeStats.contentionTimeMinInUsec,
- wifiLinkLayerStats.contentionTimeMinVoInUsec);
- assertEquals(iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec,
- wifiLinkLayerStats.contentionTimeMaxVoInUsec);
- assertEquals(iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec,
- wifiLinkLayerStats.contentionTimeAvgVoInUsec);
- assertEquals(iface.wmeVoContentionTimeStats.contentionNumSamples,
- wifiLinkLayerStats.contentionNumSamplesVo);
-
- for (int i = 0; i < iface.peers.size(); i++) {
- assertEquals(iface.peers.get(i).staCount, wifiLinkLayerStats.peerInfo[i].staCount);
- assertEquals(iface.peers.get(i).chanUtil, wifiLinkLayerStats.peerInfo[i].chanUtil);
- for (int j = 0; j < iface.peers.get(i).rateStats.size(); j++) {
- assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.preamble,
- wifiLinkLayerStats.peerInfo[i].rateStats[j].preamble);
- assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.nss,
- wifiLinkLayerStats.peerInfo[i].rateStats[j].nss);
- assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.bw,
- wifiLinkLayerStats.peerInfo[i].rateStats[j].bw);
- assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.rateMcsIdx,
- wifiLinkLayerStats.peerInfo[i].rateStats[j].rateMcsIdx);
- assertEquals(iface.peers.get(i).rateStats.get(j).rateInfo.bitRateInKbps,
- wifiLinkLayerStats.peerInfo[i].rateStats[j].bitRateInKbps);
- assertEquals(iface.peers.get(i).rateStats.get(j).txMpdu,
- wifiLinkLayerStats.peerInfo[i].rateStats[j].txMpdu);
- assertEquals(iface.peers.get(i).rateStats.get(j).rxMpdu,
- wifiLinkLayerStats.peerInfo[i].rateStats[j].rxMpdu);
- assertEquals(iface.peers.get(i).rateStats.get(j).mpduLost,
- wifiLinkLayerStats.peerInfo[i].rateStats[j].mpduLost);
- assertEquals(iface.peers.get(i).rateStats.get(j).retries,
- wifiLinkLayerStats.peerInfo[i].rateStats[j].retries);
- }
- }
- }
-
- private void verifyRadioStats(List<StaLinkLayerRadioStats> radios,
- WifiLinkLayerStats wifiLinkLayerStats) {
- StaLinkLayerRadioStats radio = radios.get(0);
- assertEquals(radio.onTimeInMs, wifiLinkLayerStats.on_time);
- assertEquals(radio.txTimeInMs, wifiLinkLayerStats.tx_time);
- assertEquals(radio.rxTimeInMs, wifiLinkLayerStats.rx_time);
- assertEquals(radio.onTimeInMsForScan, wifiLinkLayerStats.on_time_scan);
- assertEquals(radio.txTimeInMsPerLevel.size(),
- wifiLinkLayerStats.tx_time_per_level.length);
- for (int i = 0; i < radio.txTimeInMsPerLevel.size(); i++) {
- assertEquals((int) radio.txTimeInMsPerLevel.get(i),
- wifiLinkLayerStats.tx_time_per_level[i]);
- }
- }
-
- private void verifyRadioStats_1_3(
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio,
- WifiLinkLayerStats wifiLinkLayerStats) {
- assertEquals(radio.V1_0.onTimeInMs, wifiLinkLayerStats.on_time);
- assertEquals(radio.V1_0.txTimeInMs, wifiLinkLayerStats.tx_time);
- assertEquals(radio.V1_0.rxTimeInMs, wifiLinkLayerStats.rx_time);
- assertEquals(radio.V1_0.onTimeInMsForScan, wifiLinkLayerStats.on_time_scan);
- assertEquals(radio.V1_0.txTimeInMsPerLevel.size(),
- wifiLinkLayerStats.tx_time_per_level.length);
- for (int i = 0; i < radio.V1_0.txTimeInMsPerLevel.size(); i++) {
- assertEquals((int) radio.V1_0.txTimeInMsPerLevel.get(i),
- wifiLinkLayerStats.tx_time_per_level[i]);
- }
- assertEquals(radio.onTimeInMsForNanScan, wifiLinkLayerStats.on_time_nan_scan);
- assertEquals(radio.onTimeInMsForBgScan, wifiLinkLayerStats.on_time_background_scan);
- assertEquals(radio.onTimeInMsForRoamScan, wifiLinkLayerStats.on_time_roam_scan);
- assertEquals(radio.onTimeInMsForPnoScan, wifiLinkLayerStats.on_time_pno_scan);
- assertEquals(radio.onTimeInMsForHs20Scan, wifiLinkLayerStats.on_time_hs20_scan);
- assertEquals(radio.channelStats.size(),
- wifiLinkLayerStats.channelStatsMap.size());
- for (int j = 0; j < radio.channelStats.size(); j++) {
- WifiChannelStats channelStats = radio.channelStats.get(j);
- ChannelStats retrievedChannelStats =
- wifiLinkLayerStats.channelStatsMap.get(channelStats.channel.centerFreq);
- assertNotNull(retrievedChannelStats);
- assertEquals(channelStats.channel.centerFreq, retrievedChannelStats.frequency);
- assertEquals(channelStats.onTimeInMs, retrievedChannelStats.radioOnTimeMs);
- assertEquals(channelStats.ccaBusyTimeInMs, retrievedChannelStats.ccaBusyTimeMs);
- }
- }
-
- private void verifyPerRadioStats(List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios,
- WifiLinkLayerStats wifiLinkLayerStats) {
- assertEquals(radios.size(),
- wifiLinkLayerStats.radioStats.length);
- for (int i = 0; i < radios.size(); i++) {
- android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio = radios.get(i);
- RadioStat radioStat = wifiLinkLayerStats.radioStats[i];
- assertEquals(radio.radioId, radioStat.radio_id);
- assertEquals(radio.V1_3.V1_0.onTimeInMs, radioStat.on_time);
- assertEquals(radio.V1_3.V1_0.txTimeInMs, radioStat.tx_time);
- assertEquals(radio.V1_3.V1_0.rxTimeInMs, radioStat.rx_time);
- assertEquals(radio.V1_3.V1_0.onTimeInMsForScan, radioStat.on_time_scan);
- assertEquals(radio.V1_3.onTimeInMsForNanScan, radioStat.on_time_nan_scan);
- assertEquals(radio.V1_3.onTimeInMsForBgScan, radioStat.on_time_background_scan);
- assertEquals(radio.V1_3.onTimeInMsForRoamScan, radioStat.on_time_roam_scan);
- assertEquals(radio.V1_3.onTimeInMsForPnoScan, radioStat.on_time_pno_scan);
- assertEquals(radio.V1_3.onTimeInMsForHs20Scan, radioStat.on_time_hs20_scan);
-
- assertEquals(radio.V1_3.channelStats.size(),
- radioStat.channelStatsMap.size());
- for (int j = 0; j < radio.V1_3.channelStats.size(); j++) {
- WifiChannelStats channelStats = radio.V1_3.channelStats.get(j);
- ChannelStats retrievedChannelStats =
- radioStat.channelStatsMap.get(channelStats.channel.centerFreq);
- assertNotNull(retrievedChannelStats);
- assertEquals(channelStats.channel.centerFreq, retrievedChannelStats.frequency);
- assertEquals(channelStats.onTimeInMs, retrievedChannelStats.radioOnTimeMs);
- assertEquals(channelStats.ccaBusyTimeInMs, retrievedChannelStats.ccaBusyTimeMs);
- }
- }
-
- }
-
- private void verifyRadioStats_1_5(
- android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio,
- WifiLinkLayerStats wifiLinkLayerStats) {
- verifyRadioStats_1_3(radio.V1_3, wifiLinkLayerStats);
- }
-
- private void verifyTwoRadioStatsAggregation(
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio0,
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio1,
- WifiLinkLayerStats wifiLinkLayerStats) {
- assertEquals(radio0.V1_0.onTimeInMs + radio1.V1_0.onTimeInMs,
- wifiLinkLayerStats.on_time);
- assertEquals(radio0.V1_0.txTimeInMs + radio1.V1_0.txTimeInMs,
- wifiLinkLayerStats.tx_time);
- assertEquals(radio0.V1_0.rxTimeInMs + radio1.V1_0.rxTimeInMs,
- wifiLinkLayerStats.rx_time);
- assertEquals(radio0.V1_0.onTimeInMsForScan + radio1.V1_0.onTimeInMsForScan,
- wifiLinkLayerStats.on_time_scan);
- assertEquals(radio0.V1_0.txTimeInMsPerLevel.size(),
- radio1.V1_0.txTimeInMsPerLevel.size());
- assertEquals(radio0.V1_0.txTimeInMsPerLevel.size(),
- wifiLinkLayerStats.tx_time_per_level.length);
- for (int i = 0; i < radio0.V1_0.txTimeInMsPerLevel.size(); i++) {
- assertEquals((int) radio0.V1_0.txTimeInMsPerLevel.get(i)
- + (int) radio1.V1_0.txTimeInMsPerLevel.get(i),
- wifiLinkLayerStats.tx_time_per_level[i]);
- }
- assertEquals(radio0.onTimeInMsForNanScan + radio1.onTimeInMsForNanScan,
- wifiLinkLayerStats.on_time_nan_scan);
- assertEquals(radio0.onTimeInMsForBgScan + radio1.onTimeInMsForBgScan,
- wifiLinkLayerStats.on_time_background_scan);
- assertEquals(radio0.onTimeInMsForRoamScan + radio1.onTimeInMsForRoamScan,
- wifiLinkLayerStats.on_time_roam_scan);
- assertEquals(radio0.onTimeInMsForPnoScan + radio1.onTimeInMsForPnoScan,
- wifiLinkLayerStats.on_time_pno_scan);
- assertEquals(radio0.onTimeInMsForHs20Scan + radio1.onTimeInMsForHs20Scan,
- wifiLinkLayerStats.on_time_hs20_scan);
- assertEquals(radio0.channelStats.size(), radio1.channelStats.size());
- assertEquals(radio0.channelStats.size(),
- wifiLinkLayerStats.channelStatsMap.size());
- for (int j = 0; j < radio0.channelStats.size(); j++) {
- WifiChannelStats radio0ChannelStats = radio0.channelStats.get(j);
- WifiChannelStats radio1ChannelStats = radio1.channelStats.get(j);
- ChannelStats retrievedChannelStats =
- wifiLinkLayerStats.channelStatsMap.get(radio0ChannelStats.channel.centerFreq);
- assertNotNull(retrievedChannelStats);
- assertEquals(radio0ChannelStats.channel.centerFreq, retrievedChannelStats.frequency);
- assertEquals(radio1ChannelStats.channel.centerFreq, retrievedChannelStats.frequency);
- assertEquals(radio0ChannelStats.onTimeInMs + radio1ChannelStats.onTimeInMs,
- retrievedChannelStats.radioOnTimeMs);
- assertEquals(radio0ChannelStats.ccaBusyTimeInMs
- + radio1ChannelStats.ccaBusyTimeInMs, retrievedChannelStats.ccaBusyTimeMs);
- }
- }
-
- private void verifyTwoRadioStatsAggregation_1_3(
- List<android.hardware.wifi.V1_3.StaLinkLayerRadioStats> radios,
- WifiLinkLayerStats wifiLinkLayerStats) {
- assertEquals(2, radios.size());
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio0 = radios.get(0);
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats radio1 = radios.get(1);
- verifyTwoRadioStatsAggregation(radio0, radio1, wifiLinkLayerStats);
- }
-
- private void verifyTwoRadioStatsAggregation_1_5(
- List<android.hardware.wifi.V1_5.StaLinkLayerRadioStats> radios,
- WifiLinkLayerStats wifiLinkLayerStats) {
- assertEquals(2, radios.size());
- android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio0 = radios.get(0);
- android.hardware.wifi.V1_5.StaLinkLayerRadioStats radio1 = radios.get(1);
- verifyTwoRadioStatsAggregation(radio0.V1_3, radio1.V1_3, wifiLinkLayerStats);
- }
-
- /**
- * Populate packet stats with non-negative random values
- */
- private static void randomizePacketStats(Random r, StaLinkLayerIfacePacketStats pstats) {
- pstats.rxMpdu = r.nextLong() & 0xFFFFFFFFFFL; // more than 32 bits
- pstats.txMpdu = r.nextLong() & 0xFFFFFFFFFFL;
- pstats.lostMpdu = r.nextLong() & 0xFFFFFFFFFFL;
- pstats.retries = r.nextLong() & 0xFFFFFFFFFFL;
- }
-
- /**
- * Populate contention time stats with non-negative random values
- */
- private static void randomizeContentionTimeStats(Random r,
- StaLinkLayerIfaceContentionTimeStats cstats) {
- cstats.contentionTimeMinInUsec = r.nextInt() & 0x7FFFFFFF;
- cstats.contentionTimeMaxInUsec = r.nextInt() & 0x7FFFFFFF;
- cstats.contentionTimeAvgInUsec = r.nextInt() & 0x7FFFFFFF;
- cstats.contentionNumSamples = r.nextInt() & 0x7FFFFFFF;
- }
-
- /**
- * Populate peer info stats with non-negative random values
- */
- private static void randomizePeerInfoStats(Random r, ArrayList<StaPeerInfo> pstats) {
- StaPeerInfo pstat = new StaPeerInfo();
- pstat.staCount = 2;
- pstat.chanUtil = 90;
- pstat.rateStats = new ArrayList<StaRateStat>();
- StaRateStat rateStat = new StaRateStat();
- rateStat.rateInfo.preamble = r.nextInt() & 0x7FFFFFFF;
- rateStat.rateInfo.nss = r.nextInt() & 0x7FFFFFFF;
- rateStat.rateInfo.bw = r.nextInt() & 0x7FFFFFFF;
- rateStat.rateInfo.rateMcsIdx = 9;
- rateStat.rateInfo.bitRateInKbps = 101;
- rateStat.txMpdu = r.nextInt() & 0x7FFFFFFF;
- rateStat.rxMpdu = r.nextInt() & 0x7FFFFFFF;
- rateStat.mpduLost = r.nextInt() & 0x7FFFFFFF;
- rateStat.retries = r.nextInt() & 0x7FFFFFFF;
- pstat.rateStats.add(rateStat);
- pstats.add(pstat);
- }
-
- /**
- * Populate radio stats with non-negative random values
- */
- private static void randomizeRadioStats(Random r, ArrayList<StaLinkLayerRadioStats> rstats) {
- StaLinkLayerRadioStats rstat = new StaLinkLayerRadioStats();
- rstat.onTimeInMs = r.nextInt() & 0xFFFFFF;
- rstat.txTimeInMs = r.nextInt() & 0xFFFFFF;
- for (int i = 0; i < 4; i++) {
- Integer v = r.nextInt() & 0xFFFFFF;
- rstat.txTimeInMsPerLevel.add(v);
- }
- rstat.rxTimeInMs = r.nextInt() & 0xFFFFFF;
- rstat.onTimeInMsForScan = r.nextInt() & 0xFFFFFF;
- rstats.add(rstat);
- }
-
- /**
- * Populate radio stats V1_3 with non-negative random values
- */
- private static void randomizeRadioStats_1_3(Random r,
- android.hardware.wifi.V1_3.StaLinkLayerRadioStats rstat) {
- rstat.V1_0.onTimeInMs = r.nextInt() & 0xFFFFFF;
- rstat.V1_0.txTimeInMs = r.nextInt() & 0xFFFFFF;
- for (int j = 0; j < 4; j++) {
- Integer v = r.nextInt() & 0xFFFFFF;
- rstat.V1_0.txTimeInMsPerLevel.add(v);
- }
- rstat.V1_0.rxTimeInMs = r.nextInt() & 0xFFFFFF;
- rstat.V1_0.onTimeInMsForScan = r.nextInt() & 0xFFFFFF;
- rstat.onTimeInMsForNanScan = r.nextInt() & 0xFFFFFF;
- rstat.onTimeInMsForBgScan = r.nextInt() & 0xFFFFFF;
- rstat.onTimeInMsForRoamScan = r.nextInt() & 0xFFFFFF;
- rstat.onTimeInMsForPnoScan = r.nextInt() & 0xFFFFFF;
- rstat.onTimeInMsForHs20Scan = r.nextInt() & 0xFFFFFF;
- for (int k = 0; k < TEST_FREQUENCIES.length; k++) {
- WifiChannelStats channelStats = new WifiChannelStats();
- channelStats.channel.centerFreq = TEST_FREQUENCIES[k];
- channelStats.onTimeInMs = r.nextInt() & 0xFFFFFF;
- channelStats.ccaBusyTimeInMs = r.nextInt() & 0xFFFFFF;
- rstat.channelStats.add(channelStats);
- }
- }
-
- /**
- * Populate radio stats V1_5 with non-negative random values
- */
- private static void randomizeRadioStats_1_5(Random r,
- android.hardware.wifi.V1_5.StaLinkLayerRadioStats rstat) {
- rstat.radioId = r.nextInt() & 0xFFFFFF;
- randomizeRadioStats_1_3(r, rstat.V1_3);
+ verify(mWifiStaIface, never()).enableLinkLayerStatsCollection(false);
+ verify(mWifiStaIface, never()).getLinkLayerStats();
}
/**
@@ -1638,15 +631,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
public void testVersionGetters() throws Exception {
String firmwareVersion = "fuzzy";
String driverVersion = "dizzy";
- IWifiChip.ChipDebugInfo chipDebugInfo = new IWifiChip.ChipDebugInfo();
- chipDebugInfo.firmwareDescription = firmwareVersion;
- chipDebugInfo.driverDescription = driverVersion;
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiChip.requestChipDebugInfoCallback cb) throws RemoteException {
- cb.onValues(mWifiStatusSuccess, chipDebugInfo);
- }
- }).when(mIWifiChip).requestChipDebugInfo(any(IWifiChip.requestChipDebugInfoCallback.class));
+ WifiChip.ChipDebugInfo chipDebugInfo =
+ new WifiChip.ChipDebugInfo(driverVersion, firmwareVersion);
+ when(mWifiChip.requestChipDebugInfo()).thenReturn(chipDebugInfo);
assertNull(mWifiVendorHal.getFirmwareVersion());
assertNull(mWifiVendorHal.getDriverVersion());
@@ -1657,41 +644,6 @@ public class WifiVendorHalTest extends WifiBaseTest {
assertEquals(driverVersion, mWifiVendorHal.getDriverVersion());
}
- /**
- * For checkRoundTripIntTranslation lambdas
- */
- interface IntForInt {
- int translate(int value);
- }
-
- /**
- * Checks that translation from x to y and back again is the identity function
- *
- * @param xFromY reverse translator
- * @param yFromX forward translator
- * @param xLimit non-inclusive upper bound on x (lower bound is zero)
- */
- private void checkRoundTripIntTranslation(
- IntForInt xFromY, IntForInt yFromX, int xFirst, int xLimit) throws Exception {
- int ex = 0;
- for (int i = xFirst; i < xLimit; i++) {
- assertEquals(i, xFromY.translate(yFromX.translate(i)));
- }
- try {
- yFromX.translate(xLimit);
- assertTrue("expected an exception here", false);
- } catch (IllegalArgumentException e) {
- ex++;
- }
- try {
- xFromY.translate(yFromX.translate(xLimit - 1) + 1);
- assertTrue("expected an exception here", false);
- } catch (IllegalArgumentException e) {
- ex++;
- }
- assertEquals(2, ex);
- }
-
@Test
public void testStartSendingOffloadedPacket() throws Exception {
byte[] srcMac = NativeUtil.macAddressToByteArray("4007b2088c81");
@@ -1704,30 +656,30 @@ public class WifiVendorHalTest extends WifiBaseTest {
KeepalivePacketData kap =
NattKeepalivePacketData.nattKeepalivePacket(src, 63000, dst, 4500);
- when(mIWifiStaIface.startSendingKeepAlivePackets(
- anyInt(), any(), anyShort(), any(), any(), anyInt()
- )).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.startSendingKeepAlivePackets(
+ anyInt(), any(), anyInt(), any(), any(), anyInt()
+ )).thenReturn(true);
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(0 == mWifiVendorHal.startSendingOffloadedPacket(
+ assertEquals(0, mWifiVendorHal.startSendingOffloadedPacket(
TEST_IFACE_NAME, slot, srcMac, dstMac, kap.getPacket(),
OsConstants.ETH_P_IPV6, millis));
- verify(mIWifiStaIface).startSendingKeepAlivePackets(
- eq(slot), any(), anyShort(), any(), any(), eq(millis));
+ verify(mWifiStaIface).startSendingKeepAlivePackets(
+ eq(slot), any(), anyInt(), any(), any(), eq(millis));
}
@Test
public void testStopSendingOffloadedPacket() throws Exception {
int slot = 13;
- when(mIWifiStaIface.stopSendingKeepAlivePackets(anyInt())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.stopSendingKeepAlivePackets(anyInt())).thenReturn(true);
assertTrue(mWifiVendorHal.startVendorHalSta());
assertTrue(0 == mWifiVendorHal.stopSendingOffloadedPacket(
TEST_IFACE_NAME, slot));
- verify(mIWifiStaIface).stopSendingKeepAlivePackets(eq(slot));
+ verify(mWifiStaIface).stopSendingKeepAlivePackets(eq(slot));
}
/**
@@ -1736,10 +688,10 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testRssiMonitoring() throws Exception {
- when(mIWifiStaIface.startRssiMonitoring(anyInt(), anyInt(), anyInt()))
- .thenReturn(mWifiStatusSuccess);
- when(mIWifiStaIface.stopRssiMonitoring(anyInt()))
- .thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.startRssiMonitoring(anyInt(), anyInt(), anyInt()))
+ .thenReturn(true);
+ when(mWifiStaIface.stopRssiMonitoring(anyInt()))
+ .thenReturn(true);
ArrayList<Byte> breach = new ArrayList<>(10);
byte hi = -21;
@@ -1758,7 +710,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler));
int theCmdId = mWifiVendorHal.sRssiMonCmdId;
breach.clear();
- mIWifiStaIfaceEventCallback.onRssiThresholdBreached(theCmdId, new byte[6], lower);
+ mWifiStaIfaceEventCallback.onRssiThresholdBreached(theCmdId, new byte[6], lower);
assertEquals(breach.get(0), lower);
assertEquals(0, mWifiVendorHal.stopRssiMonitoring(TEST_IFACE_NAME));
assertEquals(0, mWifiVendorHal.startRssiMonitoring(TEST_IFACE_NAME, hi, lo, handler));
@@ -1784,18 +736,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
int myVersion = 33;
int myMaxSize = 1234;
- StaApfPacketFilterCapabilities capabilities = new StaApfPacketFilterCapabilities();
- capabilities.version = myVersion;
- capabilities.maxLength = myMaxSize;
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiStaIface.getApfPacketFilterCapabilitiesCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, capabilities);
- }
- }).when(mIWifiStaIface).getApfPacketFilterCapabilities(any(
- IWifiStaIface.getApfPacketFilterCapabilitiesCallback.class));
-
+ ApfCapabilities capabilities =
+ new ApfCapabilities(myVersion, myMaxSize, android.system.OsConstants.ARPHRD_ETHER);
+ when(mWifiStaIface.getApfPacketFilterCapabilities()).thenReturn(capabilities);
assertEquals(0, mWifiVendorHal.getApfCapabilities(TEST_IFACE_NAME)
.apfVersionSupported);
@@ -1816,17 +759,11 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testInstallApf() throws Exception {
byte[] filter = new byte[] {19, 53, 10};
-
- ArrayList<Byte> expected = new ArrayList<>(3);
- for (byte b : filter) expected.add(b);
-
- when(mIWifiStaIface.installApfPacketFilter(anyInt(), any(ArrayList.class)))
- .thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.installApfPacketFilter(any(byte[].class))).thenReturn(true);
assertTrue(mWifiVendorHal.startVendorHalSta());
assertTrue(mWifiVendorHal.installPacketFilter(TEST_IFACE_NAME, filter));
-
- verify(mIWifiStaIface).installApfPacketFilter(eq(0), eq(expected));
+ verify(mWifiStaIface).installApfPacketFilter(eq(filter));
}
/**
@@ -1834,69 +771,14 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testReadApf() throws Exception {
- // Expose the 1.2 IWifiStaIface.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
-
byte[] program = new byte[] {65, 66, 67};
- ArrayList<Byte> expected = new ArrayList<>(3);
- for (byte b : program) expected.add(b);
-
- doAnswer(new AnswerWithArguments() {
- public void answer(
- android.hardware.wifi.V1_2.IWifiStaIface.readApfPacketFilterDataCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, expected);
- }
- }).when(mIWifiStaIfaceV12).readApfPacketFilterData(any(
- android.hardware.wifi.V1_2.IWifiStaIface.readApfPacketFilterDataCallback.class));
+ when(mWifiStaIface.readApfPacketFilterData()).thenReturn(program);
assertTrue(mWifiVendorHal.startVendorHalSta());
assertArrayEquals(program, mWifiVendorHal.readPacketFilter(TEST_IFACE_NAME));
}
/**
- * Test that the country code is set in AP mode (when it should be).
- */
- @Test
- public void testSetApCountryCode() throws Exception {
- byte[] expected = new byte[]{(byte) 'C', (byte) 'A'};
-
- when(mIWifiApIface.setCountryCode(any()))
- .thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHal());
- assertNotNull(mWifiVendorHal.createApIface(null, null,
- SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
-
- assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, null));
- assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, ""));
- assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "A"));
- // Only one expected to succeed
- assertTrue(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "CA"));
- assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "ZZZ"));
-
- verify(mIWifiApIface).setCountryCode(eq(expected));
- }
-
- /**
- * Test that RemoteException is caught and logged.
- */
- @Test
- public void testRemoteExceptionIsHandled() throws Exception {
- mWifiLog = spy(mWifiLog);
- mWifiVendorHal.mVerboseLog = mWifiLog;
- when(mIWifiApIface.setCountryCode(any()))
- .thenThrow(new RemoteException("oops"));
- assertTrue(mWifiVendorHal.startVendorHal());
- assertNotNull(mWifiVendorHal.createApIface(null, null,
- SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
- assertFalse(mWifiVendorHal.setApCountryCode(TEST_IFACE_NAME, "CA"));
- assertTrue(mWifiVendorHal.isHalStarted());
- verify(mWifiLog).err("% RemoteException in HIDL call %");
- }
-
- /**
* Test that startLoggingToDebugRingBuffer is plumbed to chip
*
* A call before the vendor hal is started should just return false.
@@ -1904,15 +786,15 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testStartLoggingRingBuffer() throws Exception {
- when(mIWifiChip.startLoggingToDebugRingBuffer(
+ when(mWifiChip.startLoggingToDebugRingBuffer(
any(String.class), anyInt(), anyInt(), anyInt()
- )).thenReturn(mWifiStatusSuccess);
+ )).thenReturn(true);
assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
assertTrue(mWifiVendorHal.startVendorHalSta());
assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
- verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
+ verify(mWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
}
/**
@@ -1920,9 +802,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testStartLoggingRingBufferOnAp() throws Exception {
- when(mIWifiChip.startLoggingToDebugRingBuffer(
+ when(mWifiChip.startLoggingToDebugRingBuffer(
any(String.class), anyInt(), anyInt(), anyInt()
- )).thenReturn(mWifiStatusSuccess);
+ )).thenReturn(true);
assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
assertTrue(mWifiVendorHal.startVendorHal());
@@ -1930,53 +812,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
- verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
- }
-
- /**
- * Test that getRingBufferStatus gets and translates its stuff correctly
- */
- @Test
- public void testRingBufferStatus() throws Exception {
- WifiDebugRingBufferStatus one = new WifiDebugRingBufferStatus();
- one.ringName = "One";
- one.flags = WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES;
- one.ringId = 5607371;
- one.sizeInBytes = 54321;
- one.freeSizeInBytes = 42;
- one.verboseLevel = WifiDebugRingBufferVerboseLevel.VERBOSE;
- String oneExpect = "name: One flag: 1 ringBufferId: 5607371 ringBufferByteSize: 54321"
- + " verboseLevel: 2 writtenBytes: 0 readBytes: 0 writtenRecords: 0";
-
- WifiDebugRingBufferStatus two = new WifiDebugRingBufferStatus();
- two.ringName = "Two";
- two.flags = WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES
- | WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES;
- two.ringId = 4512470;
- two.sizeInBytes = 300;
- two.freeSizeInBytes = 42;
- two.verboseLevel = WifiDebugRingBufferVerboseLevel.DEFAULT;
-
- ArrayList<WifiDebugRingBufferStatus> halBufferStatus = new ArrayList<>(2);
- halBufferStatus.add(one);
- halBufferStatus.add(two);
-
- WifiNative.RingBufferStatus[] actual;
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiChip.getDebugRingBuffersStatusCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, halBufferStatus);
- }
- }).when(mIWifiChip).getDebugRingBuffersStatus(any(
- IWifiChip.getDebugRingBuffersStatusCallback.class));
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- actual = mWifiVendorHal.getRingBufferStatus();
-
- assertEquals(halBufferStatus.size(), actual.length);
- assertEquals(oneExpect, actual[0].toString());
- assertEquals(two.ringId, actual[1].ringBufferId);
+ verify(mWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
}
/**
@@ -1986,8 +822,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testForceRingBufferDump() throws Exception {
- when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Gunk"))).thenReturn(mWifiStatusSuccess);
- when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Glop"))).thenReturn(mWifiStatusFailure);
+ when(mWifiChip.forceDumpToDebugRingBuffer(eq("Gunk"))).thenReturn(true);
+ when(mWifiChip.forceDumpToDebugRingBuffer(eq("Glop"))).thenReturn(false);
assertFalse(mWifiVendorHal.getRingBufferData("Gunk")); // hal not started
@@ -1996,8 +832,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
assertTrue(mWifiVendorHal.getRingBufferData("Gunk")); // mocked call succeeds
assertFalse(mWifiVendorHal.getRingBufferData("Glop")); // mocked call fails
- verify(mIWifiChip).forceDumpToDebugRingBuffer("Gunk");
- verify(mIWifiChip).forceDumpToDebugRingBuffer("Glop");
+ verify(mWifiChip).forceDumpToDebugRingBuffer("Gunk");
+ verify(mWifiChip).forceDumpToDebugRingBuffer("Glop");
}
/**
@@ -2007,15 +843,13 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testFlushRingBufferToFile() throws Exception {
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV13.flushRingBufferToFile()).thenReturn(mWifiStatusSuccess);
+ when(mWifiChip.flushRingBufferToFile()).thenReturn(true);
assertFalse(mWifiVendorHal.flushRingBufferData());
assertTrue(mWifiVendorHal.startVendorHalSta());
assertTrue(mWifiVendorHal.flushRingBufferData());
- verify(mIWifiChipV13).flushRingBufferToFile();
+ verify(mWifiChip).flushRingBufferToFile();
}
/**
@@ -2025,14 +859,14 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testStartPktFateMonitoring() throws Exception {
- when(mIWifiStaIface.startDebugPacketFateMonitoring()).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.startDebugPacketFateMonitoring()).thenReturn(true);
assertFalse(mWifiVendorHal.startPktFateMonitoring(TEST_IFACE_NAME));
- verify(mIWifiStaIface, never()).startDebugPacketFateMonitoring();
+ verify(mWifiStaIface, never()).startDebugPacketFateMonitoring();
assertTrue(mWifiVendorHal.startVendorHalSta());
assertTrue(mWifiVendorHal.startPktFateMonitoring(TEST_IFACE_NAME));
- verify(mIWifiStaIface).startDebugPacketFateMonitoring();
+ verify(mWifiStaIface).startDebugPacketFateMonitoring();
}
/**
@@ -2044,78 +878,26 @@ public class WifiVendorHalTest extends WifiBaseTest {
public void testGetTxPktFates() throws Exception {
byte[] frameContentBytes = new byte[30];
new Random().nextBytes(frameContentBytes);
- WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport();
- fateReport.fate = WifiDebugTxPacketFate.DRV_QUEUED;
- fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
- fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II;
- fateReport.frameInfo.frameContent.addAll(
- NativeUtil.byteArrayToArrayList(frameContentBytes));
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) {
- cb.onValues(mWifiStatusSuccess, new ArrayList<>(Arrays.asList(fateReport)));
- }
- }).when(mIWifiStaIface)
- .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
+ byte fate = WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED;
+ long driverTimestampUsec = new Random().nextLong();
+ byte frameType = WifiLoggerHal.FRAME_TYPE_ETHERNET_II;
+ WifiNative.TxFateReport fateReport = new WifiNative.TxFateReport(
+ fate, driverTimestampUsec, frameType, frameContentBytes);
+ when(mWifiStaIface.getDebugTxPacketFates()).thenReturn(Arrays.asList(fateReport));
assertEquals(0, mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME).size());
- verify(mIWifiStaIface, never())
- .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
+ verify(mWifiStaIface, never()).getDebugTxPacketFates();
assertTrue(mWifiVendorHal.startVendorHalSta());
- List<TxFateReport> retrievedFates = mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME);
+ List<WifiNative.TxFateReport> retrievedFates =
+ mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME);
assertEquals(1, retrievedFates.size());
- TxFateReport retrievedFate = retrievedFates.get(0);
- verify(mIWifiStaIface)
- .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
- assertEquals(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, retrievedFate.mFate);
- assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
- assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFate.mFrameType);
- assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes);
- }
-
- /**
- * Tests the retrieval of tx packet fates when the number of fates retrieved exceeds the
- * maximum number of packet fates fetched ({@link WifiLoggerHal#MAX_FATE_LOG_LEN}).
- *
- * Try once before hal start, and once after.
- */
- @Test
- public void testGetTxPktFatesExceedsInputArrayLength() throws Exception {
- byte[] frameContentBytes = new byte[30];
- new Random().nextBytes(frameContentBytes);
- WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport();
- fateReport.fate = WifiDebugTxPacketFate.FW_DROP_OTHER;
- fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
- fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211;
- fateReport.frameInfo.frameContent.addAll(
- NativeUtil.byteArrayToArrayList(frameContentBytes));
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) {
- cb.onValues(mWifiStatusSuccess, new ArrayList<>(
- // create twice as many as the max size
- Collections.nCopies(WifiLoggerHal.MAX_FATE_LOG_LEN * 2, fateReport)));
- }
- }).when(mIWifiStaIface)
- .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
-
- assertEquals(0, mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME).size());
- verify(mIWifiStaIface, never())
- .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
-
- List<TxFateReport> retrievedFates = mWifiVendorHal.getTxPktFates(TEST_IFACE_NAME);
- // assert that at most WifiLoggerHal.MAX_FATE_LOG_LEN is retrieved
- assertEquals(WifiLoggerHal.MAX_FATE_LOG_LEN, retrievedFates.size());
- TxFateReport retrievedFate = retrievedFates.get(0);
- verify(mIWifiStaIface)
- .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
- assertEquals(WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, retrievedFate.mFate);
- assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
- assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFate.mFrameType);
+ WifiNative.TxFateReport retrievedFate = retrievedFates.get(0);
+ verify(mWifiStaIface).getDebugTxPacketFates();
+ assertEquals(fate, retrievedFate.mFate);
+ assertEquals(driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
+ assertEquals(frameType, retrievedFate.mFrameType);
assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes);
}
@@ -2128,77 +910,26 @@ public class WifiVendorHalTest extends WifiBaseTest {
public void testGetRxPktFates() throws Exception {
byte[] frameContentBytes = new byte[30];
new Random().nextBytes(frameContentBytes);
- WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport();
- fateReport.fate = WifiDebugRxPacketFate.SUCCESS;
- fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
- fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II;
- fateReport.frameInfo.frameContent.addAll(
- NativeUtil.byteArrayToArrayList(frameContentBytes));
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) {
- cb.onValues(mWifiStatusSuccess, new ArrayList<>(Arrays.asList(fateReport)));
- }
- }).when(mIWifiStaIface)
- .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
+ byte fate = WifiLoggerHal.RX_PKT_FATE_SUCCESS;
+ long driverTimestampUsec = new Random().nextLong();
+ byte frameType = WifiLoggerHal.FRAME_TYPE_ETHERNET_II;
+ WifiNative.RxFateReport fateReport = new WifiNative.RxFateReport(
+ fate, driverTimestampUsec, frameType, frameContentBytes);
+ when(mWifiStaIface.getDebugRxPacketFates()).thenReturn(Arrays.asList(fateReport));
assertEquals(0, mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME).size());
- verify(mIWifiStaIface, never())
- .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
+ verify(mWifiStaIface, never()).getDebugRxPacketFates();
assertTrue(mWifiVendorHal.startVendorHalSta());
- List<RxFateReport> retrievedFates = mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME);
+ List<WifiNative.RxFateReport> retrievedFates =
+ mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME);
assertEquals(1, retrievedFates.size());
- RxFateReport retrievedFate = retrievedFates.get(0);
- verify(mIWifiStaIface)
- .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
- assertEquals(WifiLoggerHal.RX_PKT_FATE_SUCCESS, retrievedFate.mFate);
- assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
- assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFate.mFrameType);
- assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes);
- }
-
- /**
- * Tests the retrieval of rx packet fates when the number of fates retrieved exceeds the
- * input array.
- *
- * Try once before hal start, and once after.
- */
- @Test
- public void testGetRxPktFatesExceedsInputArrayLength() throws Exception {
- byte[] frameContentBytes = new byte[30];
- new Random().nextBytes(frameContentBytes);
- WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport();
- fateReport.fate = WifiDebugRxPacketFate.FW_DROP_FILTER;
- fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
- fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211;
- fateReport.frameInfo.frameContent.addAll(
- NativeUtil.byteArrayToArrayList(frameContentBytes));
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) {
- cb.onValues(mWifiStatusSuccess, new ArrayList<>(
- // create twice as many as the max size
- Collections.nCopies(WifiLoggerHal.MAX_FATE_LOG_LEN * 2, fateReport)));
- }
- }).when(mIWifiStaIface)
- .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
-
- assertEquals(0, mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME).size());
- verify(mIWifiStaIface, never())
- .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
-
- List<RxFateReport> retrievedFates = mWifiVendorHal.getRxPktFates(TEST_IFACE_NAME);
- assertEquals(WifiLoggerHal.MAX_FATE_LOG_LEN, retrievedFates.size());
- verify(mIWifiStaIface)
- .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
- RxFateReport retrievedFate = retrievedFates.get(0);
- assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, retrievedFate.mFate);
- assertEquals(fateReport.frameInfo.driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
- assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFate.mFrameType);
+ WifiNative.RxFateReport retrievedFate = retrievedFates.get(0);
+ verify(mWifiStaIface).getDebugRxPacketFates();
+ assertEquals(fate, retrievedFate.mFate);
+ assertEquals(driverTimestampUsec, retrievedFate.mDriverTimestampUSec);
+ assertEquals(frameType, retrievedFate.mFrameType);
assertArrayEquals(frameContentBytes, retrievedFate.mFrameBytes);
}
@@ -2207,17 +938,17 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testEnableDisableNdOffload() throws Exception {
- when(mIWifiStaIface.enableNdOffload(anyBoolean())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.enableNdOffload(anyBoolean())).thenReturn(true);
assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, true));
- verify(mIWifiStaIface, never()).enableNdOffload(anyBoolean());
+ verify(mWifiStaIface, never()).enableNdOffload(anyBoolean());
assertTrue(mWifiVendorHal.startVendorHalSta());
assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, true));
- verify(mIWifiStaIface).enableNdOffload(eq(true));
+ verify(mWifiStaIface).enableNdOffload(eq(true));
assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, false));
- verify(mIWifiStaIface).enableNdOffload(eq(false));
+ verify(mWifiStaIface).enableNdOffload(eq(false));
}
/**
@@ -2225,80 +956,12 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testEnableNdOffloadFailure() throws Exception {
- when(mIWifiStaIface.enableNdOffload(eq(true))).thenReturn(mWifiStatusFailure);
+ when(mWifiStaIface.enableNdOffload(eq(true))).thenReturn(false);
assertTrue(mWifiVendorHal.startVendorHalSta());
assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(TEST_IFACE_NAME, true));
- verify(mIWifiStaIface).enableNdOffload(eq(true));
- }
-
- /**
- * Helper class for mocking getRoamingCapabilities callback
- */
- private class GetRoamingCapabilitiesAnswer extends AnswerWithArguments {
- private final WifiStatus mStatus;
- private final StaRoamingCapabilities mCaps;
-
- GetRoamingCapabilitiesAnswer(WifiStatus status, StaRoamingCapabilities caps) {
- mStatus = status;
- mCaps = caps;
- }
-
- public void answer(IWifiStaIface.getRoamingCapabilitiesCallback cb) {
- cb.onValues(mStatus, mCaps);
- }
- }
-
- /**
- * Tests retrieval of firmware roaming capabilities
- */
- @Test
- public void testFirmwareRoamingCapabilityRetrieval() throws Exception {
- assertTrue(mWifiVendorHal.startVendorHalSta());
- for (int i = 0; i < 4; i++) {
- int blocklistSize = i + 10;
- int allowlistSize = i * 3;
- StaRoamingCapabilities caps = new StaRoamingCapabilities();
- caps.maxBlacklistSize = blocklistSize;
- caps.maxWhitelistSize = allowlistSize;
- doAnswer(new GetRoamingCapabilitiesAnswer(mWifiStatusSuccess, caps))
- .when(mIWifiStaIface).getRoamingCapabilities(
- any(IWifiStaIface.getRoamingCapabilitiesCallback.class));
- RoamingCapabilities roamCap = mWifiVendorHal.getRoamingCapabilities(TEST_IFACE_NAME);
- assertNotNull(roamCap);
- assertEquals(blocklistSize, roamCap.maxBlocklistSize);
- assertEquals(allowlistSize, roamCap.maxAllowlistSize);
- }
- }
-
- /**
- * Tests unsuccessful retrieval of firmware roaming capabilities
- */
- @Test
- public void testUnsuccessfulFirmwareRoamingCapabilityRetrieval() throws Exception {
- assertTrue(mWifiVendorHal.startVendorHalSta());
- StaRoamingCapabilities caps = new StaRoamingCapabilities();
- caps.maxBlacklistSize = 43;
- caps.maxWhitelistSize = 18;
-
- // hal returns a failure status
- doAnswer(new GetRoamingCapabilitiesAnswer(mWifiStatusFailure, null))
- .when(mIWifiStaIface).getRoamingCapabilities(
- any(IWifiStaIface.getRoamingCapabilitiesCallback.class));
- assertNull(mWifiVendorHal.getRoamingCapabilities(TEST_IFACE_NAME));
-
- // hal returns failure status, but supplies caps anyway
- doAnswer(new GetRoamingCapabilitiesAnswer(mWifiStatusFailure, caps))
- .when(mIWifiStaIface).getRoamingCapabilities(
- any(IWifiStaIface.getRoamingCapabilitiesCallback.class));
- assertNull(mWifiVendorHal.getRoamingCapabilities(TEST_IFACE_NAME));
-
- // lost connection
- doThrow(new RemoteException())
- .when(mIWifiStaIface).getRoamingCapabilities(
- any(IWifiStaIface.getRoamingCapabilitiesCallback.class));
- assertNull(mWifiVendorHal.getRoamingCapabilities(TEST_IFACE_NAME));
+ verify(mWifiStaIface).enableNdOffload(eq(true));
}
/**
@@ -2307,8 +970,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testEnableFirmwareRoamingSuccess() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
- when(mIWifiStaIface.setRoamingState(eq(StaRoamingState.ENABLED)))
- .thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.setRoamingState(eq(WifiNative.ENABLE_FIRMWARE_ROAMING)))
+ .thenReturn(WifiNative.SET_FIRMWARE_ROAMING_SUCCESS);
assertEquals(WifiNative.SET_FIRMWARE_ROAMING_SUCCESS,
mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
WifiNative.ENABLE_FIRMWARE_ROAMING));
@@ -2320,34 +983,21 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testDisbleFirmwareRoamingSuccess() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
- when(mIWifiStaIface.setRoamingState(eq(StaRoamingState.DISABLED)))
- .thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.setRoamingState(eq(WifiNative.DISABLE_FIRMWARE_ROAMING)))
+ .thenReturn(WifiNative.SET_FIRMWARE_ROAMING_SUCCESS);
assertEquals(WifiNative.SET_FIRMWARE_ROAMING_SUCCESS,
mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
WifiNative.DISABLE_FIRMWARE_ROAMING));
}
/**
- * Tests enableFirmwareRoaming failure case - invalid argument
- */
- @Test
- public void testEnableFirmwareRoamingFailureInvalidArgument() throws Exception {
- final int badState = WifiNative.DISABLE_FIRMWARE_ROAMING
- + WifiNative.ENABLE_FIRMWARE_ROAMING + 1;
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertEquals(WifiNative.SET_FIRMWARE_ROAMING_FAILURE,
- mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME, badState));
- verify(mIWifiStaIface, never()).setRoamingState(anyByte());
- }
-
- /**
* Tests enableFirmwareRoaming failure case - busy
*/
@Test
public void testEnableFirmwareRoamingFailureBusy() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
- when(mIWifiStaIface.setRoamingState(anyByte()))
- .thenReturn(mWifiStatusBusy);
+ when(mWifiStaIface.setRoamingState(anyInt()))
+ .thenReturn(WifiNative.SET_FIRMWARE_ROAMING_BUSY);
assertEquals(WifiNative.SET_FIRMWARE_ROAMING_BUSY,
mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
WifiNative.ENABLE_FIRMWARE_ROAMING));
@@ -2359,20 +1009,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testEnableFirmwareRoamingFailure() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
- when(mIWifiStaIface.setRoamingState(anyByte()))
- .thenReturn(mWifiStatusFailure);
- assertEquals(WifiNative.SET_FIRMWARE_ROAMING_FAILURE,
- mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
- WifiNative.ENABLE_FIRMWARE_ROAMING));
- }
-
- /**
- * Tests enableFirmwareRoaming remote exception failure case
- */
- @Test
- public void testEnableFirmwareRoamingException() throws Exception {
- assertTrue(mWifiVendorHal.startVendorHalSta());
- doThrow(new RemoteException()).when(mIWifiStaIface).setRoamingState(anyByte());
+ when(mWifiStaIface.setRoamingState(anyInt()))
+ .thenReturn(WifiNative.SET_FIRMWARE_ROAMING_FAILURE);
assertEquals(WifiNative.SET_FIRMWARE_ROAMING_FAILURE,
mWifiVendorHal.enableFirmwareRoaming(TEST_IFACE_NAME,
WifiNative.ENABLE_FIRMWARE_ROAMING));
@@ -2390,9 +1028,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
roamingConfig.allowlistSsids = new ArrayList();
roamingConfig.allowlistSsids.add("\"xyzzy\"");
roamingConfig.allowlistSsids.add("\"\u0F00 \u05D0\"");
- when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.configureRoaming(any(), any())).thenReturn(true);
assertTrue(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
- verify(mIWifiStaIface).configureRoaming(any());
+ verify(mWifiStaIface).configureRoaming(any(), any());
}
/**
@@ -2404,22 +1042,18 @@ public class WifiVendorHalTest extends WifiBaseTest {
WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
roamingConfig.allowlistSsids = new ArrayList();
roamingConfig.allowlistSsids.add("\"xyzzy\"");
- when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.configureRoaming(any(), any())).thenReturn(true);
assertTrue(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
- ArgumentCaptor<StaRoamingConfig> staRoamingConfigCaptor = ArgumentCaptor.forClass(
- StaRoamingConfig.class);
- verify(mIWifiStaIface).configureRoaming(staRoamingConfigCaptor.capture());
+ verify(mWifiStaIface).configureRoaming(any(), mListCaptor.capture());
byte[] allowlistSsidsPadded = new byte[32];
allowlistSsidsPadded[0] = (byte) 0x78;
allowlistSsidsPadded[1] = (byte) 0x79;
allowlistSsidsPadded[2] = (byte) 0x7a;
allowlistSsidsPadded[3] = (byte) 0x7a;
allowlistSsidsPadded[4] = (byte) 0x79;
- assertArrayEquals(staRoamingConfigCaptor.getValue().ssidWhitelist.get(0),
- allowlistSsidsPadded);
+ assertArrayEquals((byte[]) mListCaptor.getValue().get(0), allowlistSsidsPadded);
allowlistSsidsPadded[5] = (byte) 0x79;
- assertFalse(Arrays.equals(staRoamingConfigCaptor.getValue().ssidWhitelist.get(0),
- allowlistSsidsPadded));
+ assertFalse(Arrays.equals((byte[]) mListCaptor.getValue().get(0), allowlistSsidsPadded));
}
/**
@@ -2429,9 +1063,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
public void testConfigureRoamingResetSuccess() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
- when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.configureRoaming(any(), any())).thenReturn(true);
assertTrue(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
- verify(mIWifiStaIface).configureRoaming(any());
+ verify(mWifiStaIface).configureRoaming(any(), any());
}
/**
@@ -2441,21 +1075,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
public void testConfigureRoamingFailure() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
- when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusFailure);
- assertFalse(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
- verify(mIWifiStaIface).configureRoaming(any());
- }
-
- /**
- * Tests configureRoaming failure due to remote exception
- */
- @Test
- public void testConfigureRoamingRemoteException() throws Exception {
- assertTrue(mWifiVendorHal.startVendorHalSta());
- WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
- doThrow(new RemoteException()).when(mIWifiStaIface).configureRoaming(any());
+ when(mWifiStaIface.configureRoaming(any(), any())).thenReturn(false);
assertFalse(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
- verify(mIWifiStaIface).configureRoaming(any());
+ verify(mWifiStaIface).configureRoaming(any(), any());
}
/**
@@ -2467,9 +1089,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
WifiNative.RoamingConfig roamingConfig = new WifiNative.RoamingConfig();
roamingConfig.blocklistBssids = new ArrayList();
roamingConfig.blocklistBssids.add("12:34:56:78:zz:zz");
- when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.configureRoaming(any(), any())).thenReturn(true);
assertFalse(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
- verify(mIWifiStaIface, never()).configureRoaming(any());
+ verify(mWifiStaIface, never()).configureRoaming(any(), any());
}
/**
@@ -2482,61 +1104,11 @@ public class WifiVendorHalTest extends WifiBaseTest {
roamingConfig.allowlistSsids = new ArrayList();
// Add an SSID that is too long (> 32 bytes) due to the multi-byte utf-8 characters
roamingConfig.allowlistSsids.add("\"123456789012345678901234567890\u0F00\u05D0\"");
- when(mIWifiStaIface.configureRoaming(any())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.configureRoaming(any(), any())).thenReturn(true);
assertTrue(mWifiVendorHal.configureRoaming(TEST_IFACE_NAME, roamingConfig));
- ArgumentCaptor<StaRoamingConfig> staRoamingConfigCaptor = ArgumentCaptor.forClass(
- StaRoamingConfig.class);
- verify(mIWifiStaIface).configureRoaming(staRoamingConfigCaptor.capture());
+ verify(mWifiStaIface).configureRoaming(any(), mListCaptor.capture());
verify(mSsidTranslator).getAllPossibleOriginalSsids(any());
- assertTrue(staRoamingConfigCaptor.getValue().ssidWhitelist.isEmpty());
- }
-
- /**
- * Tests the retrieval of wlan wake reason stats.
- */
- @Test
- public void testGetWlanWakeReasonCount() throws Exception {
- WifiDebugHostWakeReasonStats stats = new WifiDebugHostWakeReasonStats();
- Random rand = new Random();
- stats.totalCmdEventWakeCnt = rand.nextInt();
- stats.totalDriverFwLocalWakeCnt = rand.nextInt();
- stats.totalRxPacketWakeCnt = rand.nextInt();
- stats.rxPktWakeDetails.rxUnicastCnt = rand.nextInt();
- stats.rxPktWakeDetails.rxMulticastCnt = rand.nextInt();
- stats.rxIcmpPkWakeDetails.icmpPkt = rand.nextInt();
- stats.rxIcmpPkWakeDetails.icmp6Pkt = rand.nextInt();
- stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt = rand.nextInt();
- stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt = rand.nextInt();
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) {
- cb.onValues(mWifiStatusSuccess, stats);
- }
- }).when(mIWifiChip).getDebugHostWakeReasonStats(
- any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
-
- assertNull(mWifiVendorHal.getWlanWakeReasonCount());
- verify(mIWifiChip, never())
- .getDebugHostWakeReasonStats(
- any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
-
- WlanWakeReasonAndCounts retrievedStats = mWifiVendorHal.getWlanWakeReasonCount();
- verify(mIWifiChip).getDebugHostWakeReasonStats(
- any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
- assertNotNull(retrievedStats);
- assertEquals(stats.totalCmdEventWakeCnt, retrievedStats.totalCmdEventWake);
- assertEquals(stats.totalDriverFwLocalWakeCnt, retrievedStats.totalDriverFwLocalWake);
- assertEquals(stats.totalRxPacketWakeCnt, retrievedStats.totalRxDataWake);
- assertEquals(stats.rxPktWakeDetails.rxUnicastCnt, retrievedStats.rxUnicast);
- assertEquals(stats.rxPktWakeDetails.rxMulticastCnt, retrievedStats.rxMulticast);
- assertEquals(stats.rxIcmpPkWakeDetails.icmpPkt, retrievedStats.icmp);
- assertEquals(stats.rxIcmpPkWakeDetails.icmp6Pkt, retrievedStats.icmp6);
- assertEquals(stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt,
- retrievedStats.ipv4RxMulticast);
- assertEquals(stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt,
- retrievedStats.ipv6Multicast);
+ assertTrue(mListCaptor.getValue().isEmpty());
}
/**
@@ -2544,12 +1116,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testGetWlanWakeReasonCountFailure() throws Exception {
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) {
- cb.onValues(mWifiStatusFailure, new WifiDebugHostWakeReasonStats());
- }
- }).when(mIWifiChip).getDebugHostWakeReasonStats(
- any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
+ when(mWifiChip.getDebugHostWakeReasonStats()).thenReturn(null);
// This should work in both AP & STA mode.
assertTrue(mWifiVendorHal.startVendorHal());
@@ -2557,8 +1124,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
assertNull(mWifiVendorHal.getWlanWakeReasonCount());
- verify(mIWifiChip).getDebugHostWakeReasonStats(
- any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
+ verify(mWifiChip).getDebugHostWakeReasonStats();
}
/**
@@ -2567,15 +1133,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testGetFwMemoryDump() throws Exception {
byte [] sample = NativeUtil.hexStringToByteArray("268c7a3fbfa4661c0bdd6a36");
- ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample);
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiChip.requestFirmwareDebugDumpCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, halBlob);
- }
- }).when(mIWifiChip).requestFirmwareDebugDump(any(
- IWifiChip.requestFirmwareDebugDumpCallback.class));
+ when(mWifiChip.requestFirmwareDebugDump()).thenReturn(sample);
assertTrue(mWifiVendorHal.startVendorHalSta());
assertArrayEquals(sample, mWifiVendorHal.getFwMemoryDump());
@@ -2589,15 +1147,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testGetDriverStateDump() throws Exception {
byte [] sample = NativeUtil.hexStringToByteArray("e83ff543cf80083e6459d20f");
- ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample);
-
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiChip.requestDriverDebugDumpCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, halBlob);
- }
- }).when(mIWifiChip).requestDriverDebugDump(any(
- IWifiChip.requestDriverDebugDumpCallback.class));
+ when(mWifiChip.requestDriverDebugDump()).thenReturn(sample);
assertTrue(mWifiVendorHal.startVendorHal());
assertNotNull(mWifiVendorHal.createApIface(null, null,
@@ -2611,12 +1161,12 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testBgScanFailureCallback() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiStaIfaceEventCallback);
+ assertNotNull(mWifiStaIfaceEventCallback);
WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
startBgScan(eventHandler);
- mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId);
+ mWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId);
verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_FAILED);
}
@@ -2626,12 +1176,12 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testBgScanFailureCallbackWithInvalidCmdId() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiStaIfaceEventCallback);
+ assertNotNull(mWifiStaIfaceEventCallback);
WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
startBgScan(eventHandler);
- mIWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId + 1);
+ mWifiStaIfaceEventCallback.onBackgroundScanFailure(mWifiVendorHal.mScan.cmdId + 1);
verify(eventHandler, never()).onScanStatus(WifiNative.WIFI_SCAN_FAILED);
}
@@ -2641,21 +1191,21 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testBgScanFullScanResults() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiStaIfaceEventCallback);
+ assertNotNull(mWifiStaIfaceEventCallback);
WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
startBgScan(eventHandler);
WifiSsid ssid = WifiSsid.fromUtf8Text("This is an SSID");
MacAddress bssid = MacAddress.fromString("aa:bb:cc:dd:ee:ff");
- Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult(ssid, bssid);
- mIWifiStaIfaceEventCallback.onBackgroundFullScanResult(
- mWifiVendorHal.mScan.cmdId, 5, result.first);
+ ScanResult result = createFrameworkBgScanResult(ssid, bssid);
+ mWifiStaIfaceEventCallback.onBackgroundFullScanResult(
+ mWifiVendorHal.mScan.cmdId, 5, result);
ArgumentCaptor<ScanResult> scanResultCaptor = ArgumentCaptor.forClass(ScanResult.class);
verify(eventHandler).onFullScanResult(scanResultCaptor.capture(), eq(5));
- assertScanResultEqual(result.second, scanResultCaptor.getValue());
+ assertScanResultEqual(result, scanResultCaptor.getValue());
}
/**
@@ -2664,19 +1214,18 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testBgScanScanResults() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiStaIfaceEventCallback);
+ assertNotNull(mWifiStaIfaceEventCallback);
WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
startBgScan(eventHandler);
- Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>> data =
- createHidlAndFrameworkBgScanDatas();
- mIWifiStaIfaceEventCallback.onBackgroundScanResults(
- mWifiVendorHal.mScan.cmdId, data.first);
+ WifiScanner.ScanData[] data = createFrameworkBgScanDatas();
+ mWifiStaIfaceEventCallback.onBackgroundScanResults(
+ mWifiVendorHal.mScan.cmdId, data);
verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
assertScanDatasEqual(
- data.second, Arrays.asList(mWifiVendorHal.mScan.latestScanResults));
+ Arrays.asList(data), Arrays.asList(mWifiVendorHal.mScan.latestScanResults));
}
/**
@@ -2684,16 +1233,16 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testBgScanReplacement() throws Exception {
- when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(true);
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiStaIfaceEventCallback);
+ assertNotNull(mWifiStaIfaceEventCallback);
WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
startBgScan(eventHandler);
int cmdId1 = mWifiVendorHal.mScan.cmdId;
startBgScan(eventHandler);
assertNotEquals(mWifiVendorHal.mScan.cmdId, cmdId1);
- verify(mIWifiStaIface, times(2)).startBackgroundScan(anyInt(), any());
- verify(mIWifiStaIface).stopBackgroundScan(cmdId1);
+ verify(mWifiStaIface, times(2)).startBackgroundScan(anyInt(), any());
+ verify(mWifiStaIface).stopBackgroundScan(cmdId1);
}
/**
@@ -2701,9 +1250,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testBgScanStop() throws Exception {
- when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(true);
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiStaIfaceEventCallback);
+ assertNotNull(mWifiStaIfaceEventCallback);
WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
startBgScan(eventHandler);
@@ -2711,7 +1260,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
mWifiVendorHal.stopBgScan(TEST_IFACE_NAME);
mWifiVendorHal.stopBgScan(TEST_IFACE_NAME); // second call should not do anything
- verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once
+ verify(mWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once
}
/**
@@ -2719,9 +1268,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testBgScanPauseAndRestart() throws Exception {
- when(mIWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.stopBackgroundScan(anyInt())).thenReturn(true);
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiStaIfaceEventCallback);
+ assertNotNull(mWifiStaIfaceEventCallback);
WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
startBgScan(eventHandler);
@@ -2729,8 +1278,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
mWifiVendorHal.pauseBgScan(TEST_IFACE_NAME);
mWifiVendorHal.restartBgScan(TEST_IFACE_NAME);
- verify(mIWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once
- verify(mIWifiStaIface, times(2)).startBackgroundScan(eq(cmdId), any());
+ verify(mWifiStaIface).stopBackgroundScan(cmdId); // Should be called just once
+ verify(mWifiStaIface, times(2)).startBackgroundScan(eq(cmdId), any());
}
/**
@@ -2738,23 +1287,23 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testSetLogHandler() throws Exception {
- when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
+ when(mWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(true);
WifiNative.WifiLoggerEventHandler eventHandler =
mock(WifiNative.WifiLoggerEventHandler.class);
assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler));
- verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
+ verify(mWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
assertTrue(mWifiVendorHal.startVendorHalSta());
assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler));
- verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
- reset(mIWifiChip);
+ verify(mWifiChip).enableDebugErrorAlerts(eq(true));
+ reset(mWifiChip);
// Second call should fail.
assertFalse(mWifiVendorHal.setLoggingEventHandler(eventHandler));
- verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
+ verify(mWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
}
/**
@@ -2762,12 +1311,12 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testResetLogHandler() throws Exception {
- when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
- when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
+ when(mWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(true);
+ when(mWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(true);
assertFalse(mWifiVendorHal.resetLogHandler());
- verify(mIWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
- verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer();
+ verify(mWifiChip, never()).enableDebugErrorAlerts(anyBoolean());
+ verify(mWifiChip, never()).stopLoggingToDebugRingBuffer();
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2775,9 +1324,9 @@ public class WifiVendorHalTest extends WifiBaseTest {
assertTrue(mWifiVendorHal.setLoggingEventHandler(
mock(WifiNative.WifiLoggerEventHandler.class)));
assertTrue(mWifiVendorHal.resetLogHandler());
- verify(mIWifiChip).enableDebugErrorAlerts(eq(false));
- verify(mIWifiChip).stopLoggingToDebugRingBuffer();
- reset(mIWifiChip);
+ verify(mWifiChip).enableDebugErrorAlerts(eq(false));
+ verify(mWifiChip).stopLoggingToDebugRingBuffer();
+ reset(mWifiChip);
}
/**
@@ -2785,8 +1334,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testResetLogHandlerAfterHalStop() throws Exception {
- when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
- when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
+ when(mWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(true);
+ when(mWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(true);
// Start in STA mode.
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2794,15 +1343,15 @@ public class WifiVendorHalTest extends WifiBaseTest {
// Now set the log handler, succeeds.
assertTrue(mWifiVendorHal.setLoggingEventHandler(
mock(WifiNative.WifiLoggerEventHandler.class)));
- verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
+ verify(mWifiChip).enableDebugErrorAlerts(eq(true));
// Stop
mWifiVendorHal.stopVendorHal();
// Reset the log handler after stop, not HAL methods invoked.
assertFalse(mWifiVendorHal.resetLogHandler());
- verify(mIWifiChip, never()).enableDebugErrorAlerts(eq(false));
- verify(mIWifiChip, never()).stopLoggingToDebugRingBuffer();
+ verify(mWifiChip, never()).enableDebugErrorAlerts(eq(false));
+ verify(mWifiChip, never()).stopLoggingToDebugRingBuffer();
// Start in STA mode again.
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2810,7 +1359,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
// Now set the log handler again, should succeed.
assertTrue(mWifiVendorHal.setLoggingEventHandler(
mock(WifiNative.WifiLoggerEventHandler.class)));
- verify(mIWifiChip, times(2)).enableDebugErrorAlerts(eq(true));
+ verify(mWifiChip, times(2)).enableDebugErrorAlerts(eq(true));
}
/**
@@ -2819,9 +1368,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testAlertCallback() throws Exception {
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiChipEventCallback);
-
- testAlertCallbackUsingProvidedCallback(mIWifiChipEventCallback);
+ assertNotNull(mWifiChipEventCallback);
+ testAlertCallbackUsingProvidedCallback(mWifiChipEventCallback);
}
/**
@@ -2829,29 +1377,29 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testRingBufferDataCallback() throws Exception {
- when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
- when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
+ when(mWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(true);
+ when(mWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(true);
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiChipEventCallback);
+ assertNotNull(mWifiChipEventCallback);
byte[] errorData = new byte[45];
new Random().nextBytes(errorData);
- // Randomly raise the HIDL callback before we register for the log callback.
+ // Randomly raise the callback before we register for the log callback.
// This should be safely ignored. (Not trigger NPE.)
- mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
- new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
+ mWifiChipEventCallback.onDebugRingBufferDataAvailable(
+ new WifiNative.RingBufferStatus(), errorData);
mLooper.dispatchAll();
WifiNative.WifiLoggerEventHandler eventHandler =
mock(WifiNative.WifiLoggerEventHandler.class);
assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler));
- verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
+ verify(mWifiChip).enableDebugErrorAlerts(eq(true));
- // Now raise the HIDL callback, this should be properly handled.
- mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
- new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
+ // Now raise the callback, this should be properly handled.
+ mWifiChipEventCallback.onDebugRingBufferDataAvailable(
+ new WifiNative.RingBufferStatus(), errorData);
mLooper.dispatchAll();
verify(eventHandler).onRingBufferData(
any(WifiNative.RingBufferStatus.class), eq(errorData));
@@ -2859,8 +1407,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
// Now stop the logging and invoke the callback. This should be ignored.
reset(eventHandler);
assertTrue(mWifiVendorHal.resetLogHandler());
- mIWifiChipEventCallback.onDebugRingBufferDataAvailable(
- new WifiDebugRingBufferStatus(), NativeUtil.byteArrayToArrayList(errorData));
+ mWifiChipEventCallback.onDebugRingBufferDataAvailable(
+ new WifiNative.RingBufferStatus(), errorData);
mLooper.dispatchAll();
verify(eventHandler, never()).onRingBufferData(anyObject(), anyObject());
}
@@ -2880,436 +1428,11 @@ public class WifiVendorHalTest extends WifiBaseTest {
}
/**
- * Test the selectTxPowerScenario HIDL method invocation for 1.0 interface.
- * This should return failure since SAR is not supported for this interface version.
- */
- @Test
- public void testSelectTxPowerScenario_1_0() throws RemoteException {
- // Create a SAR info record
- SarInfo sarInfo = new SarInfo();
- sarInfo.isVoiceCall = true;
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- // Should fail because we exposed the 1.0 IWifiChip.
- assertFalse(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the selectTxPowerScenario HIDL method invocation for 1.1 interface.
- * This should return success.
- */
- @Test
- public void testSelectTxPowerScenario_1_1() throws RemoteException {
- // Create a SAR info record
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = false;
-
- sarInfo.isVoiceCall = true;
-
- // Now expose the 1.1 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_1(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals, mSsidTranslator);
- when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV11).selectTxPowerScenario(
- eq(android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL));
- verify(mIWifiChipV11, never()).resetTxPowerScenario();
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the selectTxPowerScenario HIDL method invocation for 1.2 interface.
- * This should return success.
- */
- @Test
- public void testSelectTxPowerScenario_1_2() throws RemoteException {
- // Create a SAR info record
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = false;
-
- sarInfo.isVoiceCall = true;
-
- // Now expose the 1.2 IWifiChip
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV12).selectTxPowerScenario_1_2(
- eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.VOICE_CALL));
- verify(mIWifiChipV12, never()).resetTxPowerScenario();
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the resetTxPowerScenario HIDL method invocation for 1.0 interface.
- * This should return failure since it does not supprt SAR.
- */
- @Test
- public void testResetTxPowerScenario_1_0() throws RemoteException {
- // Create a SAR info record
- SarInfo sarInfo = new SarInfo();
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- // Should fail because we exposed the 1.0 IWifiChip.
- assertFalse(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV11, never()).resetTxPowerScenario();
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the resetTxPowerScenario HIDL method invocation for 1.1 interface.
- * This should return success.
- */
- @Test
- public void testResetTxPowerScenario_1_1() throws RemoteException {
- // Create a SAR info record
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = false;
-
- // Now expose the 1.1 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_1(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals, mSsidTranslator);
- when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV11).resetTxPowerScenario();
- verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test resetting SAR scenario when not needed, should return true without invoking
- * the HAL method.
- * This is using HAL 1.1 interface.
- */
- @Test
- public void testResetTxPowerScenario_not_needed_1_1() throws RemoteException {
- InOrder inOrder = inOrder(mIWifiChipV11);
-
- // Create a SAR info record (no SAP support)
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = false;
-
- // Now expose the 1.1 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_1(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals, mSsidTranslator);
- when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
-
- /* Calling reset once */
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- inOrder.verify(mIWifiChipV11).resetTxPowerScenario();
- inOrder.verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
- sarInfo.reportingSuccessful();
-
- /* Calling reset second time */
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- inOrder.verify(mIWifiChipV11, never()).resetTxPowerScenario();
- inOrder.verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt());
-
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the new resetTxPowerScenario HIDL method invocation for 1.2 interface.
- * This should return success.
- */
- @Test
- public void testResetTxPowerScenario_1_2() throws RemoteException {
- // Create a SAR info record (no SAP support)
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = false;
-
- // Now expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV12).resetTxPowerScenario();
- verify(mIWifiChipV12, never()).selectTxPowerScenario_1_2(anyInt());
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test resetting SAR scenario when not needed, should return true without invoking
- * the HAL method.
- * This is using HAL 1.2 interface.
- */
- @Test
- public void testResetTxPowerScenario_not_needed_1_2() throws RemoteException {
- InOrder inOrder = inOrder(mIWifiChipV12);
-
- // Create a SAR info record (no SAP support)
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = false;
-
- // Now expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
-
- /* Calling reset once */
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- inOrder.verify(mIWifiChipV12).resetTxPowerScenario();
- inOrder.verify(mIWifiChipV12, never()).selectTxPowerScenario(anyInt());
- sarInfo.reportingSuccessful();
-
- /* Calling reset second time */
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- inOrder.verify(mIWifiChipV12, never()).resetTxPowerScenario();
- inOrder.verify(mIWifiChipV12, never()).selectTxPowerScenario(anyInt());
-
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the selectTxPowerScenario HIDL method invocation with SAP and voice call support.
- * When SAP is enabled, should result in SAP with near body scenario
- * Using IWifiChip 1.2 interface
- */
- @Test
- public void testSapScenarios_SelectTxPowerV1_2() throws RemoteException {
- // Create a SAR info record (with SAP support)
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = true;
- sarInfo.isWifiSapEnabled = true;
-
- // Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
-
- // ON_BODY_CELL_ON
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV12).selectTxPowerScenario_1_2(
- eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_BODY_CELL_ON));
- verify(mIWifiChipV12, never()).resetTxPowerScenario();
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the selectTxPowerScenario HIDL method invocation with SAP and voice call support.
- * When a voice call is ongoing, should result in cell with near head scenario
- * Using IWifiChip 1.2 interface
- */
- @Test
- public void testVoiceCallScenarios_SelectTxPowerV1_2() throws RemoteException {
- // Create a SAR info record (with SAP support)
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = true;
-
- sarInfo.isVoiceCall = true;
-
- // Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
-
- // ON_HEAD_CELL_ON
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV12).selectTxPowerScenario_1_2(
- eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_HEAD_CELL_ON));
- verify(mIWifiChipV12, never()).resetTxPowerScenario();
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the selectTxPowerScenario HIDL method invocation with SAP and voice call support.
- * When earpiece is active, should result in cell with near head scenario
- * Using IWifiChip 1.2 interface
- */
- @Test
- public void testEarPieceScenarios_SelectTxPowerV1_2() throws RemoteException {
- // Create a SAR info record (with SAP support)
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = true;
-
- sarInfo.isEarPieceActive = true;
-
- // Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
-
- // ON_HEAD_CELL_ON
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV12).selectTxPowerScenario_1_2(
- eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_HEAD_CELL_ON));
- verify(mIWifiChipV12, never()).resetTxPowerScenario();
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test setting SAR scenario when not needed, should return true without invoking
- * the HAL method.
- * This is using HAL 1.2 interface.
- */
- @Test
- public void testSetTxPowerScenario_not_needed_1_2() throws RemoteException {
- InOrder inOrder = inOrder(mIWifiChipV12);
-
- // Create a SAR info record (no SAP support)
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = true;
-
- // Now expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
-
- /* Calling set once */
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- inOrder.verify(mIWifiChipV12).resetTxPowerScenario();
- sarInfo.reportingSuccessful();
-
- /* Calling set second time */
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- inOrder.verify(mIWifiChipV12, never()).resetTxPowerScenario();
- inOrder.verify(mIWifiChipV12, never()).selectTxPowerScenario(anyInt());
-
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the selectTxPowerScenario HIDL method invocation with IWifiChip 1.2 interface.
- * The following inputs:
- * - SAP is enabled
- * - No voice call
- */
- @Test
- public void testSelectTxPowerScenario_1_2_sap() throws RemoteException {
- // Create a SAR info record (with SAP support)
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = true;
-
- sarInfo.isWifiSapEnabled = true;
- sarInfo.isVoiceCall = false;
-
- // Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV12).selectTxPowerScenario_1_2(
- eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_BODY_CELL_ON));
-
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the selectTxPowerScenario HIDL method invocation with IWifiChip 1.2 interface.
- * The following inputs:
- * - SAP is enabled
- * - voice call is enabled
- */
- @Test
- public void testSelectTxPowerScenario_1_2_head_sap_call() throws RemoteException {
- // Create a SAR info record (with SAP support)
- SarInfo sarInfo = new SarInfo();
- sarInfo.sarVoiceCallSupported = true;
- sarInfo.sarSapSupported = true;
-
- sarInfo.isWifiSapEnabled = true;
- sarInfo.isVoiceCall = true;
-
- // Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertTrue(mWifiVendorHal.selectTxPowerScenario(sarInfo));
- verify(mIWifiChipV12).selectTxPowerScenario_1_2(
- eq(android.hardware.wifi.V1_2.IWifiChip.TxPowerScenario.ON_HEAD_CELL_ON));
-
- mWifiVendorHal.stopVendorHal();
- }
-
- /**
- * Test the setLowLatencyMode HIDL method invocation with IWifiChip 1.2 interface.
- * Function should return false
- */
- @Test
- public void testSetLowLatencyMode_1_2() throws RemoteException {
- // Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- assertFalse(mWifiVendorHal.setLowLatencyMode(true));
- assertFalse(mWifiVendorHal.setLowLatencyMode(false));
- }
-
- /**
- * Test the setLowLatencyMode HIDL method invocation with IWifiChip 1.3 interface
- */
- @Test
- public void testSetLowLatencyMode_1_3_enabled() throws RemoteException {
- int mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.LOW;
-
- // Expose the 1.3 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV13.setLatencyMode(anyInt())).thenReturn(mWifiStatusSuccess);
- assertTrue(mWifiVendorHal.setLowLatencyMode(true));
- verify(mIWifiChipV13).setLatencyMode(eq(mode));
- }
-
- /**
- * Test the setLowLatencyMode HIDL method invocation with IWifiChip 1.3 interface
- */
- @Test
- public void testSetLowLatencyMode_1_3_disabled() throws RemoteException {
- int mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.NORMAL;
-
- // Expose the 1.3 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV13.setLatencyMode(anyInt())).thenReturn(mWifiStatusSuccess);
- assertTrue(mWifiVendorHal.setLowLatencyMode(false));
- verify(mIWifiChipV13).setLatencyMode(eq(mode));
- }
-
- /**
* Test the STA Iface creation failure due to iface name retrieval failure.
*/
@Test
public void testCreateStaIfaceFailureInIfaceName() throws RemoteException {
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiIface.getNameCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusFailure, "wlan0");
- }
- }).when(mIWifiStaIface).getName(any(IWifiIface.getNameCallback.class));
-
+ when(mWifiStaIface.getName()).thenReturn(null);
assertTrue(mWifiVendorHal.startVendorHal());
assertNull(mWifiVendorHal.createStaIface(null, TEST_WORKSOURCE));
verify(mHalDeviceManager).createStaIface(any(), any(), eq(TEST_WORKSOURCE));
@@ -3320,13 +1443,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testCreateApIfaceFailureInIfaceName() throws RemoteException {
- doAnswer(new AnswerWithArguments() {
- public void answer(IWifiIface.getNameCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusFailure, "wlan0");
- }
- }).when(mIWifiApIface).getName(any(IWifiIface.getNameCallback.class));
-
+ when(mWifiApIface.getName()).thenReturn(null);
assertTrue(mWifiVendorHal.startVendorHal());
assertNull(mWifiVendorHal.createApIface(
null, TEST_WORKSOURCE, SoftApConfiguration.BAND_2GHZ, false, mSoftApManager));
@@ -3344,7 +1461,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
verify(mHalDeviceManager).createStaIface(any(), any(), eq(TEST_WORKSOURCE));
assertEquals(TEST_IFACE_NAME, ifaceName);
assertTrue(mWifiVendorHal.removeStaIface(ifaceName));
- verify(mHalDeviceManager).removeIface(eq(mIWifiStaIface));
+ verify(mHalDeviceManager).removeIface(eq(mWifiStaIface));
}
/**
@@ -3359,297 +1476,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
anyLong(), any(), any(), eq(TEST_WORKSOURCE), eq(false), eq(mSoftApManager));
assertEquals(TEST_IFACE_NAME, ifaceName);
assertTrue(mWifiVendorHal.removeApIface(ifaceName));
- verify(mHalDeviceManager).removeIface(eq(mIWifiApIface));
- }
-
- /**
- * Test removeIfaceInstanceFromBridgedApIface
- */
- @Test
- public void testRemoveIfaceInstanceFromBridgedApIface() throws RemoteException {
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV15.removeIfaceInstanceFromBridgedApIface(any(), any()))
- .thenReturn(mWifiStatusSuccess);
- assertTrue(mWifiVendorHal.removeIfaceInstanceFromBridgedApIface(any(), any()));
- }
-
- /**
- * Test setCoexUnsafeChannels
- */
- @Test
- public void testSetCoexUnsafeChannels() throws RemoteException {
- assumeTrue(SdkLevel.isAtLeastS());
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV15.setCoexUnsafeChannels(any(), anyInt()))
- .thenReturn(mWifiStatusSuccess);
- final List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>();
- unsafeChannels.add(new CoexUnsafeChannel(WifiScanner.WIFI_BAND_24_GHZ, 6));
- unsafeChannels.add(new CoexUnsafeChannel(WifiScanner.WIFI_BAND_5_GHZ, 36));
- final int restrictions = WifiManager.COEX_RESTRICTION_WIFI_DIRECT
- | WifiManager.COEX_RESTRICTION_WIFI_AWARE | WifiManager.COEX_RESTRICTION_SOFTAP;
- assertTrue(mWifiVendorHal.setCoexUnsafeChannels(unsafeChannels, restrictions));
- }
-
- /**
- * Test the callback handling for the 1.2 HAL.
- */
- @Test
- public void testAlertCallbackUsing_1_2_EventCallback() throws Exception {
- // Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
-
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiChipEventCallbackV12);
-
- testAlertCallbackUsingProvidedCallback(mIWifiChipEventCallbackV12);
- }
-
- /**
- * Verifies setMacAddress() success.
- */
- @Test
- public void testSetStaMacAddressSuccess() throws Exception {
- // Expose the 1.2 IWifiStaIface.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
- when(mIWifiStaIfaceV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.setStaMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
- verify(mIWifiStaIfaceV12).setMacAddress(macByteArray);
- }
-
- /**
- * Verifies setMacAddress() can handle failure status.
- */
- @Test
- public void testSetStaMacAddressFailDueToStatusFailure() throws Exception {
- // Expose the 1.2 IWifiStaIface.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
- when(mIWifiStaIfaceV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusFailure);
-
- assertFalse(mWifiVendorHal.setStaMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
- verify(mIWifiStaIfaceV12).setMacAddress(macByteArray);
- }
-
- /**
- * Verifies setMacAddress() can handle RemoteException.
- */
- @Test
- public void testSetStaMacAddressFailDueToRemoteException() throws Exception {
- // Expose the 1.2 IWifiStaIface.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
- doThrow(new RemoteException()).when(mIWifiStaIfaceV12).setMacAddress(macByteArray);
-
- assertFalse(mWifiVendorHal.setStaMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
- verify(mIWifiStaIfaceV12).setMacAddress(macByteArray);
- }
-
- /**
- * Verifies setMacAddress() success.
- */
- @Test
- public void testSetApMacAddressSuccess() throws Exception {
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_4Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV14);
- byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
- when(mIWifiApIfaceV14.setMacAddress(macByteArray)).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.setApMacAddress(TEST_IFACE_NAME_1, TEST_MAC_ADDRESS));
- verify(mIWifiApIfaceV14).setMacAddress(macByteArray);
- }
-
- /**
- * Verifies setMacAddress() can handle failure status.
- */
- @Test
- public void testSetApMacAddressFailDueToStatusFailure() throws Exception {
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_4Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV14);
- byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
- when(mIWifiApIfaceV14.setMacAddress(macByteArray)).thenReturn(mWifiStatusFailure);
-
- assertFalse(mWifiVendorHal.setApMacAddress(TEST_IFACE_NAME_1, TEST_MAC_ADDRESS));
- verify(mIWifiApIfaceV14).setMacAddress(macByteArray);
- }
-
- /**
- * Verifies setMacAddress() can handle RemoteException.
- */
- @Test
- public void testSetApMacAddressFailDueToRemoteException() throws Exception {
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_4Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV14);
- byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
- doThrow(new RemoteException()).when(mIWifiApIfaceV14).setMacAddress(macByteArray);
-
- assertFalse(mWifiVendorHal.setApMacAddress(TEST_IFACE_NAME_1, TEST_MAC_ADDRESS));
- verify(mIWifiApIfaceV14).setMacAddress(macByteArray);
- }
-
- /**
- * Verifies setMacAddress() does not crash with older HALs.
- */
- @Test
- public void testSetMacAddressDoesNotCrashOnOlderHal() throws Exception {
- byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
- assertFalse(mWifiVendorHal.setStaMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
- assertFalse(mWifiVendorHal.setApMacAddress(TEST_IFACE_NAME, TEST_MAC_ADDRESS));
- }
-
- /**
- * Verifies resetApMacToFactoryMacAddress resetToFactoryMacAddress() success.
- */
- @Test
- public void testResetApMacToFactoryMacAddressSuccess() throws Exception {
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV15);
- when(mIWifiApIfaceV15.resetToFactoryMacAddress()).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.resetApMacToFactoryMacAddress(TEST_IFACE_NAME_1));
- verify(mIWifiApIfaceV15).resetToFactoryMacAddress();
- }
-
- /**
- * Verifies resetApMacToFactoryMacAddress() can handle failure status.
- */
- @Test
- public void testResetApMacToFactoryMacAddressFailDueToStatusFailure() throws Exception {
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV15);
- when(mIWifiApIfaceV15.resetToFactoryMacAddress()).thenReturn(mWifiStatusFailure);
-
- assertFalse(mWifiVendorHal.resetApMacToFactoryMacAddress(TEST_IFACE_NAME_1));
- verify(mIWifiApIfaceV15).resetToFactoryMacAddress();
- }
-
- /**
- * Verifies resetApMacToFactoryMacAddress() can handle RemoteException.
- */
- @Test
- public void testResetApMacToFactoryMacAddressFailDueToRemoteException() throws Exception {
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV15);
- doThrow(new RemoteException()).when(mIWifiApIfaceV15).resetToFactoryMacAddress();
- assertFalse(mWifiVendorHal.resetApMacToFactoryMacAddress(TEST_IFACE_NAME_1));
- verify(mIWifiApIfaceV15).resetToFactoryMacAddress();
- }
-
- /**
- * Verifies resetApMacToFactoryMacAddress() does not crash with older HALs.
- */
- @Test
- public void testResetApMacToFactoryMacAddressDoesNotCrashOnOlderHal() throws Exception {
- assertFalse(mWifiVendorHal.resetApMacToFactoryMacAddress(TEST_IFACE_NAME));
- }
-
- /**
- * Verifies getBridgedApInstances() success.
- */
- @Test
- public void testGetBridgedApInstancesSuccess() throws Exception {
- doAnswer(new AnswerWithArguments() {
- public void answer(
- android.hardware.wifi.V1_5.IWifiApIface.getBridgedInstancesCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess,
- new ArrayList<String>() {{ add(TEST_IFACE_NAME_1); }});
- }
- }).when(mIWifiApIfaceV15).getBridgedInstances(any(
- android.hardware.wifi.V1_5.IWifiApIface.getBridgedInstancesCallback.class));
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV15);
-
- assertNotNull(mWifiVendorHal.getBridgedApInstances(TEST_IFACE_NAME_1));
- verify(mIWifiApIfaceV15).getBridgedInstances(any());
- }
-
- /**
- * Verifies getBridgedApInstances() can handle failure status.
- */
- @Test
- public void testGetBridgedApInstancesFailDueToStatusFailure() throws Exception {
- doAnswer(new AnswerWithArguments() {
- public void answer(
- android.hardware.wifi.V1_5.IWifiApIface.getBridgedInstancesCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusFailure, null);
- }
- }).when(mIWifiApIfaceV15).getBridgedInstances(any(
- android.hardware.wifi.V1_5.IWifiApIface.getBridgedInstancesCallback.class));
-
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV15);
- assertNull(mWifiVendorHal.getBridgedApInstances(TEST_IFACE_NAME_1));
- verify(mIWifiApIfaceV15).getBridgedInstances(any());
- }
-
- /**
- * Verifies getBridgedApInstances() can handle RemoteException.
- */
- @Test
- public void testGetBridgedApInstancesFailDueToRemoteException() throws Exception {
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_5Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV15);
- doThrow(new RemoteException()).when(mIWifiApIfaceV15).getBridgedInstances(any());
- assertNull(mWifiVendorHal.getBridgedApInstances(TEST_IFACE_NAME_1));
- verify(mIWifiApIfaceV15).getBridgedInstances(any());
- }
-
- /**
- * Verifies getBridgedApInstances() does not crash with older HALs.
- */
- @Test
- public void testGetBridgedApInstancesNotCrashOnOlderHal() throws Exception {
- assertNull(mWifiVendorHal.getBridgedApInstances(TEST_IFACE_NAME));
- }
-
- /**
- * Verifies isSetMacAddressSupported().
- */
- @Test
- public void testIsApSetMacAddressSupportedWhenV1_4Support() throws Exception {
- mWifiVendorHal = spy(mWifiVendorHal);
- when(mWifiVendorHal.getWifiApIfaceForV1_4Mockable(TEST_IFACE_NAME_1))
- .thenReturn(mIWifiApIfaceV14);
-
- assertTrue(mWifiVendorHal.isApSetMacAddressSupported(TEST_IFACE_NAME_1));
- }
-
- /**
- * Verifies isSetMacAddressSupported().
- */
- @Test
- public void testIsStaSetMacAddressSupportedWhenV1_2Support() throws Exception {
- // Expose the 1.2 IWifiStaIface.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- assertTrue(mWifiVendorHal.isStaSetMacAddressSupported(TEST_IFACE_NAME));
- }
-
- /**
- * Verifies isSetMacAddressSupported() does not crash with older HALs.
- */
- @Test
- public void testIsSetMacAddressSupportedOnOlderHal() throws Exception {
- assertFalse(mWifiVendorHal.isStaSetMacAddressSupported(TEST_IFACE_NAME));
- assertFalse(mWifiVendorHal.isApSetMacAddressSupported(TEST_IFACE_NAME));
+ verify(mHalDeviceManager).removeIface(eq(mWifiApIface));
}
/**
@@ -3659,62 +1486,19 @@ public class WifiVendorHalTest extends WifiBaseTest {
public void testRadioModeChangeCallbackToDbsMode() throws Exception {
startHalInStaModeAndRegisterRadioModeChangeCallback();
- RadioModeInfo radioModeInfo0 = new RadioModeInfo();
- radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
- RadioModeInfo radioModeInfo1 = new RadioModeInfo();
- radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_24_GHZ;
-
- IfaceInfo ifaceInfo0 = new IfaceInfo();
- ifaceInfo0.name = TEST_IFACE_NAME;
- ifaceInfo0.channel = 34;
- IfaceInfo ifaceInfo1 = new IfaceInfo();
- ifaceInfo1.name = TEST_IFACE_NAME_1;
- ifaceInfo1.channel = 1;
-
- radioModeInfo0.ifaceInfos.add(ifaceInfo0);
- radioModeInfo1.ifaceInfos.add(ifaceInfo1);
+ WifiChip.IfaceInfo ifaceInfo0 = new WifiChip.IfaceInfo(TEST_IFACE_NAME, 34);
+ WifiChip.IfaceInfo ifaceInfo1 = new WifiChip.IfaceInfo(TEST_IFACE_NAME_1, 1);
- ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
- radioModeInfos.add(radioModeInfo0);
- radioModeInfos.add(radioModeInfo1);
+ WifiChip.RadioModeInfo radioModeInfo0 = new WifiChip.RadioModeInfo(
+ 0, WifiScanner.WIFI_BAND_5_GHZ, Arrays.asList(ifaceInfo0));
+ WifiChip.RadioModeInfo radioModeInfo1 = new WifiChip.RadioModeInfo(
+ 1, WifiScanner.WIFI_BAND_24_GHZ, Arrays.asList(ifaceInfo1));
- mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
- mLooper.dispatchAll();
- verify(mVendorHalRadioModeChangeHandler).onDbs();
-
- verifyNoMoreInteractions(mVendorHalRadioModeChangeHandler);
- }
-
- /**
- * Verifies radio mode change callback to indicate DBS mode using V1.4 callback.
- */
- @Test
- public void testRadioModeChangeCallbackToDbsModeV14() throws Exception {
- startHalInStaModeAndRegisterRadioModeChangeCallback14();
-
- android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo radioModeInfo0 =
- new android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo();
- radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_6_GHZ;
- android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo radioModeInfo1 =
- new android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo();
- radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_24_GHZ;
-
- IfaceInfo ifaceInfo0 = new IfaceInfo();
- ifaceInfo0.name = TEST_IFACE_NAME;
- ifaceInfo0.channel = 34;
- IfaceInfo ifaceInfo1 = new IfaceInfo();
- ifaceInfo1.name = TEST_IFACE_NAME_1;
- ifaceInfo1.channel = 1;
-
- radioModeInfo0.ifaceInfos.add(ifaceInfo0);
- radioModeInfo1.ifaceInfos.add(ifaceInfo1);
-
- ArrayList<android.hardware.wifi.V1_4.IWifiChipEventCallback.RadioModeInfo> radioModeInfos =
- new ArrayList<>();
+ ArrayList<WifiChip.RadioModeInfo> radioModeInfos = new ArrayList<>();
radioModeInfos.add(radioModeInfo0);
radioModeInfos.add(radioModeInfo1);
- mIWifiChipEventCallbackV14.onRadioModeChange_1_4(radioModeInfos);
+ mWifiChipEventCallback.onRadioModeChange(radioModeInfos);
mLooper.dispatchAll();
verify(mVendorHalRadioModeChangeHandler).onDbs();
@@ -3728,26 +1512,19 @@ public class WifiVendorHalTest extends WifiBaseTest {
public void testRadioModeChangeCallbackToSbsMode() throws Exception {
startHalInStaModeAndRegisterRadioModeChangeCallback();
- RadioModeInfo radioModeInfo0 = new RadioModeInfo();
- radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
- RadioModeInfo radioModeInfo1 = new RadioModeInfo();
- radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
-
- IfaceInfo ifaceInfo0 = new IfaceInfo();
- ifaceInfo0.name = TEST_IFACE_NAME;
- ifaceInfo0.channel = 34;
- IfaceInfo ifaceInfo1 = new IfaceInfo();
- ifaceInfo1.name = TEST_IFACE_NAME_1;
- ifaceInfo1.channel = 36;
+ WifiChip.IfaceInfo ifaceInfo0 = new WifiChip.IfaceInfo(TEST_IFACE_NAME, 34);
+ WifiChip.IfaceInfo ifaceInfo1 = new WifiChip.IfaceInfo(TEST_IFACE_NAME_1, 36);
- radioModeInfo0.ifaceInfos.add(ifaceInfo0);
- radioModeInfo1.ifaceInfos.add(ifaceInfo1);
+ WifiChip.RadioModeInfo radioModeInfo0 = new WifiChip.RadioModeInfo(
+ 0, WifiScanner.WIFI_BAND_5_GHZ, Arrays.asList(ifaceInfo0));
+ WifiChip.RadioModeInfo radioModeInfo1 = new WifiChip.RadioModeInfo(
+ 1, WifiScanner.WIFI_BAND_5_GHZ, Arrays.asList(ifaceInfo1));
- ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
+ ArrayList<WifiChip.RadioModeInfo> radioModeInfos = new ArrayList<>();
radioModeInfos.add(radioModeInfo0);
radioModeInfos.add(radioModeInfo1);
- mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
+ mWifiChipEventCallback.onRadioModeChange(radioModeInfos);
mLooper.dispatchAll();
verify(mVendorHalRadioModeChangeHandler).onSbs(WifiScanner.WIFI_BAND_5_GHZ);
@@ -3761,23 +1538,15 @@ public class WifiVendorHalTest extends WifiBaseTest {
public void testRadioModeChangeCallbackToSccMode() throws Exception {
startHalInStaModeAndRegisterRadioModeChangeCallback();
- RadioModeInfo radioModeInfo0 = new RadioModeInfo();
- radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
-
- IfaceInfo ifaceInfo0 = new IfaceInfo();
- ifaceInfo0.name = TEST_IFACE_NAME;
- ifaceInfo0.channel = 34;
- IfaceInfo ifaceInfo1 = new IfaceInfo();
- ifaceInfo1.name = TEST_IFACE_NAME_1;
- ifaceInfo1.channel = 34;
+ WifiChip.IfaceInfo ifaceInfo0 = new WifiChip.IfaceInfo(TEST_IFACE_NAME, 34);
+ WifiChip.IfaceInfo ifaceInfo1 = new WifiChip.IfaceInfo(TEST_IFACE_NAME_1, 34);
+ WifiChip.RadioModeInfo radioModeInfo0 = new WifiChip.RadioModeInfo(
+ 0, WifiScanner.WIFI_BAND_5_GHZ, Arrays.asList(ifaceInfo0, ifaceInfo1));
- radioModeInfo0.ifaceInfos.add(ifaceInfo0);
- radioModeInfo0.ifaceInfos.add(ifaceInfo1);
-
- ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
+ ArrayList<WifiChip.RadioModeInfo> radioModeInfos = new ArrayList<>();
radioModeInfos.add(radioModeInfo0);
- mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
+ mWifiChipEventCallback.onRadioModeChange(radioModeInfos);
mLooper.dispatchAll();
verify(mVendorHalRadioModeChangeHandler).onScc(WifiScanner.WIFI_BAND_5_GHZ);
@@ -3791,23 +1560,16 @@ public class WifiVendorHalTest extends WifiBaseTest {
public void testRadioModeChangeCallbackToMccMode() throws Exception {
startHalInStaModeAndRegisterRadioModeChangeCallback();
- RadioModeInfo radioModeInfo0 = new RadioModeInfo();
- radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_BOTH;
-
- IfaceInfo ifaceInfo0 = new IfaceInfo();
- ifaceInfo0.name = TEST_IFACE_NAME;
- ifaceInfo0.channel = 1;
- IfaceInfo ifaceInfo1 = new IfaceInfo();
- ifaceInfo1.name = TEST_IFACE_NAME_1;
- ifaceInfo1.channel = 36;
+ WifiChip.IfaceInfo ifaceInfo0 = new WifiChip.IfaceInfo(TEST_IFACE_NAME, 1);
+ WifiChip.IfaceInfo ifaceInfo1 = new WifiChip.IfaceInfo(TEST_IFACE_NAME_1, 36);
- radioModeInfo0.ifaceInfos.add(ifaceInfo0);
- radioModeInfo0.ifaceInfos.add(ifaceInfo1);
+ WifiChip.RadioModeInfo radioModeInfo0 = new WifiChip.RadioModeInfo(
+ 0, WifiScanner.WIFI_BAND_BOTH, Arrays.asList(ifaceInfo0, ifaceInfo1));
- ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
+ ArrayList<WifiChip.RadioModeInfo> radioModeInfos = new ArrayList<>();
radioModeInfos.add(radioModeInfo0);
- mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
+ mWifiChipEventCallback.onRadioModeChange(radioModeInfos);
mLooper.dispatchAll();
verify(mVendorHalRadioModeChangeHandler).onMcc(WifiScanner.WIFI_BAND_BOTH);
@@ -3822,23 +1584,18 @@ public class WifiVendorHalTest extends WifiBaseTest {
throws Exception {
startHalInStaModeAndRegisterRadioModeChangeCallback();
- RadioModeInfo radioModeInfo0 = new RadioModeInfo();
- radioModeInfo0.bandInfo = WifiScanner.WIFI_BAND_24_GHZ;
- RadioModeInfo radioModeInfo1 = new RadioModeInfo();
- radioModeInfo1.bandInfo = WifiScanner.WIFI_BAND_5_GHZ;
-
- IfaceInfo ifaceInfo0 = new IfaceInfo();
- ifaceInfo0.name = TEST_IFACE_NAME;
- ifaceInfo0.channel = 34;
+ WifiChip.IfaceInfo ifaceInfo0 = new WifiChip.IfaceInfo(TEST_IFACE_NAME, 34);
- radioModeInfo0.ifaceInfos.add(ifaceInfo0);
- radioModeInfo1.ifaceInfos.add(ifaceInfo0);
+ WifiChip.RadioModeInfo radioModeInfo0 = new WifiChip.RadioModeInfo(
+ 0, WifiScanner.WIFI_BAND_24_GHZ, Arrays.asList(ifaceInfo0));
+ WifiChip.RadioModeInfo radioModeInfo1 = new WifiChip.RadioModeInfo(
+ 1, WifiScanner.WIFI_BAND_5_GHZ, Arrays.asList(ifaceInfo0));
- ArrayList<RadioModeInfo> radioModeInfos = new ArrayList<>();
+ ArrayList<WifiChip.RadioModeInfo> radioModeInfos = new ArrayList<>();
radioModeInfos.add(radioModeInfo0);
radioModeInfos.add(radioModeInfo1);
- mIWifiChipEventCallbackV12.onRadioModeChange(radioModeInfos);
+ mWifiChipEventCallback.onRadioModeChange(radioModeInfos);
mLooper.dispatchAll();
// Ignored....
@@ -3859,111 +1616,60 @@ public class WifiVendorHalTest extends WifiBaseTest {
@Test
public void testIsStaApConcurrencySupported() {
when(mHalDeviceManager.canDeviceSupportCreateTypeCombo(
- argThat(ifaceCombo -> ifaceCombo.get(IfaceType.STA) == 1
- && ifaceCombo.get(IfaceType.AP) == 1))).thenReturn(true);
+ argThat(ifaceCombo -> ifaceCombo.get(WifiChip.IFACE_TYPE_STA) == 1
+ && ifaceCombo.get(WifiChip.IFACE_TYPE_AP) == 1))).thenReturn(true);
assertTrue(mWifiVendorHal.isStaApConcurrencySupported());
}
@Test
public void testIsStaStaConcurrencySupported() {
when(mHalDeviceManager.canDeviceSupportCreateTypeCombo(
- argThat(ifaceCombo -> ifaceCombo.get(IfaceType.STA) == 2))).thenReturn(true);
+ argThat(ifaceCombo -> ifaceCombo.get(WifiChip.IFACE_TYPE_STA) == 2)))
+ .thenReturn(true);
assertTrue(mWifiVendorHal.isStaStaConcurrencySupported());
}
- @Test
- public void testSetMultiStaPrimaryConnection() throws Exception {
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV15.setMultiStaPrimaryConnection(any())).thenReturn(mWifiStatusSuccess);
- assertTrue(mWifiVendorHal.setMultiStaPrimaryConnection(TEST_IFACE_NAME));
- verify(mIWifiChipV15).setMultiStaPrimaryConnection(TEST_IFACE_NAME);
- }
-
- @Test
- public void testSetMultiStaUseCase() throws Exception {
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV15.setMultiStaUseCase(MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY))
- .thenReturn(mWifiStatusSuccess);
- when(mIWifiChipV15.setMultiStaUseCase(MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED))
- .thenReturn(mWifiStatusFailure);
-
- assertTrue(mWifiVendorHal.setMultiStaUseCase(WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY));
- verify(mIWifiChipV15).setMultiStaUseCase(MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY);
-
- assertFalse(mWifiVendorHal.setMultiStaUseCase(WifiNative.DUAL_STA_NON_TRANSIENT_UNBIASED));
- verify(mIWifiChipV15).setMultiStaUseCase(MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED);
-
- // illegal value.
- assertFalse(mWifiVendorHal.setMultiStaUseCase(5));
- }
-
private void startHalInStaModeAndRegisterRadioModeChangeCallback() {
- // Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
mWifiVendorHal.registerRadioModeChangeHandler(mVendorHalRadioModeChangeHandler);
assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiChipEventCallbackV12);
+ assertNotNull(mWifiChipEventCallback);
}
- private void startHalInStaModeAndRegisterRadioModeChangeCallback14() {
- // Expose the 1.4 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_4(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- mWifiVendorHal.registerRadioModeChangeHandler(mVendorHalRadioModeChangeHandler);
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiChipEventCallbackV14);
- }
-
- private void startHalInStaModeAndRegisterRadioModeChangeCallback15() {
- // Expose the 1.5 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- mWifiVendorHal.registerRadioModeChangeHandler(mVendorHalRadioModeChangeHandler);
- assertTrue(mWifiVendorHal.startVendorHalSta());
- assertNotNull(mIWifiChipEventCallbackV14);
- }
-
- private void testAlertCallbackUsingProvidedCallback(IWifiChipEventCallback chipCallback)
+ private void testAlertCallbackUsingProvidedCallback(WifiChip.Callback chipCallback)
throws Exception {
- when(mIWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(mWifiStatusSuccess);
- when(mIWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(mWifiStatusSuccess);
+ when(mWifiChip.enableDebugErrorAlerts(anyBoolean())).thenReturn(true);
+ when(mWifiChip.stopLoggingToDebugRingBuffer()).thenReturn(true);
int errorCode = 5;
byte[] errorData = new byte[45];
new Random().nextBytes(errorData);
- // Randomly raise the HIDL callback before we register for the log callback.
+ // Randomly raise the callback before we register for the log callback.
// This should be safely ignored. (Not trigger NPE.)
- chipCallback.onDebugErrorAlert(
- errorCode, NativeUtil.byteArrayToArrayList(errorData));
+ chipCallback.onDebugErrorAlert(errorCode, errorData);
mLooper.dispatchAll();
WifiNative.WifiLoggerEventHandler eventHandler =
mock(WifiNative.WifiLoggerEventHandler.class);
assertTrue(mWifiVendorHal.setLoggingEventHandler(eventHandler));
- verify(mIWifiChip).enableDebugErrorAlerts(eq(true));
+ verify(mWifiChip).enableDebugErrorAlerts(eq(true));
- // Now raise the HIDL callback, this should be properly handled.
- chipCallback.onDebugErrorAlert(
- errorCode, NativeUtil.byteArrayToArrayList(errorData));
+ // Now raise the callback, this should be properly handled.
+ chipCallback.onDebugErrorAlert(errorCode, errorData);
mLooper.dispatchAll();
verify(eventHandler).onWifiAlert(eq(errorCode), eq(errorData));
// Now stop the logging and invoke the callback. This should be ignored.
reset(eventHandler);
assertTrue(mWifiVendorHal.resetLogHandler());
- chipCallback.onDebugErrorAlert(
- errorCode, NativeUtil.byteArrayToArrayList(errorData));
+ chipCallback.onDebugErrorAlert(errorCode, errorData);
mLooper.dispatchAll();
verify(eventHandler, never()).onWifiAlert(anyInt(), anyObject());
}
private void startBgScan(WifiNative.ScanEventHandler eventHandler) throws Exception {
- when(mIWifiStaIface.startBackgroundScan(
- anyInt(), any(StaBackgroundScanParameters.class))).thenReturn(mWifiStatusSuccess);
+ when(mWifiStaIface.startBackgroundScan(
+ anyInt(), any(WifiStaIface.StaBackgroundScanParameters.class))).thenReturn(true);
WifiNative.ScanSettings settings = new WifiNative.ScanSettings();
settings.num_buckets = 1;
WifiNative.BucketSettings bucketSettings = new WifiNative.BucketSettings();
@@ -3974,61 +1680,34 @@ public class WifiVendorHalTest extends WifiBaseTest {
assertTrue(mWifiVendorHal.startBgScan(TEST_IFACE_NAME, settings, eventHandler));
}
- // Create a pair of HIDL scan result and its corresponding framework scan result for
- // comparison.
- private Pair<StaScanResult, ScanResult> createHidlAndFrameworkBgScanResult(
+ private ScanResult createFrameworkBgScanResult(
@NonNull WifiSsid ssid, @NonNull MacAddress bssid) {
- StaScanResult staScanResult = new StaScanResult();
- staScanResult.ssid.addAll(NativeUtil.byteArrayToArrayList(ssid.getBytes()));
- staScanResult.bssid = bssid.toByteArray();
- staScanResult.frequency = 2432;
- staScanResult.rssi = -45;
- staScanResult.timeStampInUs = 5;
- WifiInformationElement ie1 = new WifiInformationElement();
- byte[] ie1_data = new byte[56];
- new Random().nextBytes(ie1_data);
- ie1.id = 1;
- ie1.data.addAll(NativeUtil.byteArrayToArrayList(ie1_data));
- staScanResult.informationElements.add(ie1);
-
- // Now create the corresponding Scan result structure.
ScanResult scanResult = new ScanResult();
scanResult.setWifiSsid(getTranslatedSsid(ssid));
scanResult.BSSID = bssid.toString();
- scanResult.frequency = staScanResult.frequency;
- scanResult.level = staScanResult.rssi;
- scanResult.timestamp = staScanResult.timeStampInUs;
-
- return Pair.create(staScanResult, scanResult);
+ scanResult.frequency = 2432;
+ scanResult.level = -45;
+ scanResult.timestamp = 5;
+ return scanResult;
}
- // Create a pair of HIDL scan datas and its corresponding framework scan datas for
- // comparison.
- private Pair<ArrayList<StaScanData>, ArrayList<WifiScanner.ScanData>>
- createHidlAndFrameworkBgScanDatas() {
- ArrayList<StaScanData> staScanDatas = new ArrayList<>();
- StaScanData staScanData = new StaScanData();
-
+ private WifiScanner.ScanData[] createFrameworkBgScanDatas() {
byte[] ssidBytes = new byte[8];
byte[] bssidBytes = new byte[6];
Random random = new Random();
random.nextBytes(ssidBytes);
random.nextBytes(bssidBytes);
- Pair<StaScanResult, ScanResult> result = createHidlAndFrameworkBgScanResult(
+ ScanResult result = createFrameworkBgScanResult(
WifiSsid.fromBytes(ssidBytes), MacAddress.fromBytes(bssidBytes));
- staScanData.results.add(result.first);
- staScanData.bucketsScanned = 5;
- staScanData.flags = StaScanDataFlagMask.INTERRUPTED;
- staScanDatas.add(staScanData);
- ArrayList<WifiScanner.ScanData> scanDatas = new ArrayList<>();
+ WifiScanner.ScanData[] scanDatas = new WifiScanner.ScanData[1];
ScanResult[] scanResults = new ScanResult[1];
- scanResults[0] = result.second;
+ scanResults[0] = result;
WifiScanner.ScanData scanData =
new WifiScanner.ScanData(mWifiVendorHal.mScan.cmdId, 1,
- staScanData.bucketsScanned, WifiScanner.WIFI_BAND_UNSPECIFIED, scanResults);
- scanDatas.add(scanData);
- return Pair.create(staScanDatas, scanDatas);
+ 5, WifiScanner.WIFI_BAND_UNSPECIFIED, scanResults);
+ scanDatas[0] = scanData;
+ return scanDatas;
}
private void assertScanResultEqual(ScanResult expected, ScanResult actual) {
@@ -4061,60 +1740,4 @@ public class WifiVendorHalTest extends WifiBaseTest {
assertScanDataEqual(expected.get(i), actual.get(i));
}
}
-
- /**
- * Test setCountryCode gets called when the hal version is V1_5.
- */
- @Test
- public void testSetCountryCodeWithHalV1_5() throws Exception {
- byte[] expected = new byte[]{(byte) 'U', (byte) 'S'};
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiChipV15.setCountryCode(any())).thenReturn(mWifiStatusSuccess);
-
- // Invalid cases
- assertFalse(mWifiVendorHal.setChipCountryCode(null));
- assertFalse(mWifiVendorHal.setChipCountryCode(""));
- assertFalse(mWifiVendorHal.setChipCountryCode("A"));
- verify(mIWifiChipV15, never()).setCountryCode(any());
-
- //valid country code
- assertTrue(mWifiVendorHal.setChipCountryCode("US"));
- verify(mIWifiChipV15).setCountryCode(eq(expected));
- }
-
- @Test
- public void testSetScanMode() throws Exception {
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- when(mIWifiStaIfaceV15.setScanMode(anyBoolean())).thenReturn(mWifiStatusSuccess);
-
- assertTrue(mWifiVendorHal.setScanMode(TEST_IFACE_NAME, true));
- verify(mIWifiStaIfaceV15).setScanMode(true);
-
- assertTrue(mWifiVendorHal.setScanMode(TEST_IFACE_NAME, false));
- verify(mIWifiStaIfaceV15).setScanMode(false);
- }
-
- @Test
- public void testGetUsableChannels() throws Exception {
- assertTrue(mWifiVendorHal.startVendorHalSta());
- mWifiVendorHal = new WifiVendorHalSpyV1_5(mContext, mHalDeviceManager, mHandler,
- mWifiGlobals);
- ArrayList<WifiUsableChannel> channels = new ArrayList<>();
- doAnswer(new AnswerWithArguments() {
- public void answer(int band, int mode, int filter,
- android.hardware.wifi.V1_5.IWifiChip.getUsableChannelsCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, channels);
- }
- }).when(mIWifiChipV15).getUsableChannels(anyInt(), anyInt(), anyInt(),
- any(android.hardware.wifi.V1_5.IWifiChip.getUsableChannelsCallback.class));
- mWifiVendorHal.getUsableChannels(
- WifiScanner.WIFI_BAND_24_GHZ,
- WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI,
- WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE);
- verify(mIWifiChipV15).getUsableChannels(anyInt(), anyInt(), anyInt(),
- any(android.hardware.wifi.V1_5.IWifiChip.getUsableChannelsCallback.class));
- }
}
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 24be263fcb..e9488c628e 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
@@ -16,7 +16,6 @@
package com.android.server.wifi.aware;
-import static android.hardware.wifi.V1_0.NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED;
import static android.net.wifi.ScanResult.CHANNEL_WIDTH_80MHZ;
import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
@@ -46,7 +45,6 @@ import android.app.test.TestAlarmManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.hardware.wifi.V1_0.NanStatusType;
import android.net.ConnectivityManager;
import android.net.MacAddress;
import android.net.NetworkCapabilities;
@@ -95,6 +93,8 @@ import com.android.server.wifi.MockResources;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.aware.WifiAwareDataPathStateManager.WifiAwareNetworkAgent;
+import com.android.server.wifi.hal.WifiNanIface.NanDataPathChannelCfg;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
import com.android.server.wifi.util.NetdWrapper;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
@@ -550,7 +550,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB);
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(),
eq(requestorId + i),
- eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
+ eq(NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
eq(interfaceName),
eq(false), any(), any(), any());
@@ -573,7 +573,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
}
inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
agentBinders[i] = agentCaptor.getValue();
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.SUCCESS),
eq(false), anyLong());
inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
WifiAwareNetworkInfo netInfo =
@@ -669,7 +669,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
// (3) verify the start NDP HAL request
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
- eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
+ eq(NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
eq(sAwareInterfacePrefix + "0"), eq(true), any(), any(),
any());
@@ -707,7 +707,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.SUCCESS),
eq(true), anyLong());
inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
WifiAwareNetworkInfo netInfo =
@@ -823,8 +823,8 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
if (i < numNdis) {
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
- eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
- ifNameCaptor.capture(), eq(true), any(), any(),
+ eq(NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED), anyInt(),
+ eq(peerDiscoveryMac), ifNameCaptor.capture(), eq(true), any(), any(),
any());
interfaces.add(ifNameCaptor.getValue());
@@ -840,7 +840,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.SUCCESS),
eq(true), anyLong());
inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
WifiAwareNetworkInfo netInfo =
@@ -914,7 +914,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB);
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
- eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
+ eq(NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
ifNameCaptor.capture(), eq(true), any(), any(), any());
interfaces.add(ifNameCaptor.getValue());
@@ -934,7 +934,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
first = false;
}
inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.SUCCESS),
eq(true), anyLong());
inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
WifiAwareNetworkInfo netInfo =
@@ -1009,8 +1009,9 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
if (i < numNdis) {
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
- eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
- ifNameCaptor.capture(), eq(true), any(), any(), any());
+ eq(NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED), anyInt(),
+ eq(peerDiscoveryMac), ifNameCaptor.capture(), eq(true), any(), any(),
+ any());
interfaces.add(ifNameCaptor.getValue());
mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i);
@@ -1025,7 +1026,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.SUCCESS),
eq(true), anyLong());
inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
WifiAwareNetworkInfo netInfo =
@@ -1106,7 +1107,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB);
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
- eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
+ eq(NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
ifNameCaptor.capture(), eq(true), any(), any(),
any());
interfaces.add(ifNameCaptor.getValue());
@@ -1125,7 +1126,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
first = false;
}
inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.SUCCESS),
eq(true), anyLong());
inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
WifiAwareNetworkInfo netInfo =
@@ -1732,13 +1733,13 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt());
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(),
eq(useDirect ? 0 : requestorId),
- eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
+ eq(NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
eq(sAwareInterfacePrefix + "0"),
eq(useDirect), any(), any(),
any());
if (immediateHalFailure) {
// short-circuit the rest of this test
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.INTERNAL_FAILURE),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.INTERNAL_FAILURE),
eq(useDirect), anyLong());
verifyRequestDeclaredUnfullfillable(nr);
verifyNoMoreInteractions(mMockNative, mAwareMetricsMock);
@@ -1809,7 +1810,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
} else {
inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
networkAgent = agentCaptor.getValue();
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.SUCCESS),
eq(useDirect), anyLong());
inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
WifiAwareNetworkInfo netInfo =
@@ -1835,7 +1836,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
mMockLooper.dispatchAll();
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.INTERNAL_FAILURE),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.INTERNAL_FAILURE),
eq(useDirect), anyLong());
}
@@ -1936,7 +1937,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString());
inOrder.verify(mMockNetdWrapper).enableIpv6(anyString());
inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture());
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.SUCCESS),
eq(useDirect), anyLong());
inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
WifiAwareNetworkInfo netInfo =
@@ -1961,7 +1962,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
mMockLooper.dispatchAll();
inOrderM.verify(mAwareMetricsMock).recordNdpStatus(
- eq(NanStatusType.INTERNAL_FAILURE), eq(useDirect), anyLong());
+ eq(NanStatusCode.INTERNAL_FAILURE), eq(useDirect), anyLong());
}
// (4) end data-path (unless didn't get confirmation)
@@ -2167,7 +2168,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(Process.myUid()), any());
inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(Process.myUid(),
- NanStatusType.SUCCESS, doPublish);
+ NanStatusCode.SUCCESS, doPublish);
mDut.onMessageReceivedNotification(pubSubId, requestorId, peerDiscoveryMac,
someMsg.getBytes());
@@ -2448,7 +2449,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
assertEquals(-1, netInfo.getTransportProtocol());
assertEquals(1, mDut.mDataPathMgr.getNumOfNdps());
}
- inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS),
+ inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusCode.SUCCESS),
eq(false), anyLong());
inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any());
assertEquals(successNdpIds.size(), mDut.mDataPathMgr.getNumOfNdps());
@@ -2460,7 +2461,7 @@ public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
inOrderM.verify(mAwareMetricsMock).recordNdpStatus(
- eq(NanStatusType.INTERNAL_FAILURE), eq(false), anyLong());
+ eq(NanStatusCode.INTERNAL_FAILURE), eq(false), anyLong());
mDut.onDataPathEndNotification(ndpId);
mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
verify(mMockCm, never()).declareNetworkRequestUnfulfillable(any());
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java
index 38bacade31..62c11dceb1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java
@@ -27,7 +27,6 @@ import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
import android.content.Context;
-import android.hardware.wifi.V1_0.NanStatusType;
import android.net.wifi.aware.WifiAwareNetworkSpecifier;
import android.util.LocalLog;
import android.util.Log;
@@ -38,6 +37,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.util.MetricsUtils;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -283,8 +283,8 @@ public class WifiAwareMetricsTest extends WifiBaseTest {
mDut.recordAttachSession(uid2, false, clients);
// a few failures
- mDut.recordAttachStatus(NanStatusType.INTERNAL_FAILURE);
- mDut.recordAttachStatus(NanStatusType.INTERNAL_FAILURE);
+ mDut.recordAttachStatus(NanStatusCode.INTERNAL_FAILURE);
+ mDut.recordAttachStatus(NanStatusCode.INTERNAL_FAILURE);
mDut.recordAttachStatus(-5); // invalid
// verify
@@ -335,49 +335,49 @@ public class WifiAwareMetricsTest extends WifiBaseTest {
client1.addSession(new WifiAwareDiscoverySessionState(null, 100, (byte) 0, null, true,
false, mClock.getElapsedSinceBootMillis(), false, 0, mLocalLog));
mDut.recordDiscoverySession(uid1, clients);
- mDut.recordDiscoveryStatus(uid1, NanStatusType.SUCCESS, true);
+ mDut.recordDiscoveryStatus(uid1, NanStatusCode.SUCCESS, true);
// uid1: publish session 2
client1.addSession(new WifiAwareDiscoverySessionState(null, 101, (byte) 0, null, true,
false, mClock.getElapsedSinceBootMillis(), false, 0, mLocalLog));
mDut.recordDiscoverySession(uid1, clients);
- mDut.recordDiscoveryStatus(uid1, NanStatusType.SUCCESS, true);
+ mDut.recordDiscoveryStatus(uid1, NanStatusCode.SUCCESS, true);
// uid3: publish session 3 with ranging
client3.addSession(new WifiAwareDiscoverySessionState(null, 111, (byte) 0, null, true,
true, mClock.getElapsedSinceBootMillis(), false, 0, mLocalLog));
mDut.recordDiscoverySessionWithRanging(uid3, false, -1, -1, clients);
- mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, true);
+ mDut.recordDiscoveryStatus(uid3, NanStatusCode.SUCCESS, true);
// uid2: subscribe session 1
client2.addSession(new WifiAwareDiscoverySessionState(null, 102, (byte) 0, null, false,
false, mClock.getElapsedSinceBootMillis(), false, 0, mLocalLog));
mDut.recordDiscoverySession(uid2, clients);
- mDut.recordDiscoveryStatus(uid2, NanStatusType.SUCCESS, false);
+ mDut.recordDiscoveryStatus(uid2, NanStatusCode.SUCCESS, false);
// uid2: publish session 2
client2.addSession(new WifiAwareDiscoverySessionState(null, 103, (byte) 0, null, true,
false, mClock.getElapsedSinceBootMillis(), false, 0, mLocalLog));
mDut.recordDiscoverySession(uid2, clients);
- mDut.recordDiscoveryStatus(uid2, NanStatusType.SUCCESS, false);
+ mDut.recordDiscoveryStatus(uid2, NanStatusCode.SUCCESS, false);
// uid3: subscribe session 3 with ranging: min
client3.addSession(new WifiAwareDiscoverySessionState(null, 112, (byte) 0, null, false,
true, mClock.getElapsedSinceBootMillis(), false, 0, mLocalLog));
mDut.recordDiscoverySessionWithRanging(uid3, true, 10, -1, clients);
- mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, false);
+ mDut.recordDiscoveryStatus(uid3, NanStatusCode.SUCCESS, false);
// uid3: subscribe session 3 with ranging: max
client3.addSession(new WifiAwareDiscoverySessionState(null, 113, (byte) 0, null, false,
true, mClock.getElapsedSinceBootMillis(), false, 0, mLocalLog));
mDut.recordDiscoverySessionWithRanging(uid3, true, -1, 50, clients);
- mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, false);
+ mDut.recordDiscoveryStatus(uid3, NanStatusCode.SUCCESS, false);
// uid3: subscribe session 3 with ranging: minmax
client3.addSession(new WifiAwareDiscoverySessionState(null, 114, (byte) 0, null, false,
true, mClock.getElapsedSinceBootMillis(), false, 0, mLocalLog));
mDut.recordDiscoverySessionWithRanging(uid3, true, 0, 110, clients);
- mDut.recordDiscoveryStatus(uid3, NanStatusType.SUCCESS, false);
+ mDut.recordDiscoveryStatus(uid3, NanStatusCode.SUCCESS, false);
// uid1: delete session 1
setTime(10);
@@ -397,9 +397,9 @@ public class WifiAwareMetricsTest extends WifiBaseTest {
false, mClock.getElapsedSinceBootMillis(), false, 0, mLocalLog));
// a few failures
- mDut.recordDiscoveryStatus(uid1, NanStatusType.INTERNAL_FAILURE, true);
- mDut.recordDiscoveryStatus(uid2, NanStatusType.INTERNAL_FAILURE, false);
- mDut.recordDiscoveryStatus(uid2, NanStatusType.NO_RESOURCES_AVAILABLE, false);
+ mDut.recordDiscoveryStatus(uid1, NanStatusCode.INTERNAL_FAILURE, true);
+ mDut.recordDiscoveryStatus(uid2, NanStatusCode.INTERNAL_FAILURE, false);
+ mDut.recordDiscoveryStatus(uid2, NanStatusCode.NO_RESOURCES_AVAILABLE, false);
mDut.recordAttachStatus(-5); // invalid
// verify
@@ -486,28 +486,28 @@ public class WifiAwareMetricsTest extends WifiBaseTest {
addNetworkInfoToCache(networkRequestCache, 10, uid1, package1, ndi0, null);
mDut.recordNdpCreation(uid1, package1, networkRequestCache);
setTime(7); // 2ms creation time
- mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 5);
+ mDut.recordNdpStatus(NanStatusCode.SUCCESS, false, 5);
// uid2: ndp (non-secure) on ndi0
WifiAwareNetworkSpecifier ns = addNetworkInfoToCache(networkRequestCache, 11, uid2,
package2, ndi0, null);
mDut.recordNdpCreation(uid2, package2, networkRequestCache);
setTime(10); // 3 ms creation time
- mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 7);
+ mDut.recordNdpStatus(NanStatusCode.SUCCESS, false, 7);
// uid2: ndp (secure) on ndi1 (OOB)
addNetworkInfoToCache(networkRequestCache, 12, uid2, package2, ndi1,
"passphrase of some kind");
mDut.recordNdpCreation(uid2, package2, networkRequestCache);
setTime(25); // 15 ms creation time
- mDut.recordNdpStatus(NanStatusType.SUCCESS, true, 10);
+ mDut.recordNdpStatus(NanStatusCode.SUCCESS, true, 10);
// uid2: ndp (secure) on ndi0 (OOB)
addNetworkInfoToCache(networkRequestCache, 13, uid2, package2, ndi0,
"super secret password");
mDut.recordNdpCreation(uid2, package2, networkRequestCache);
setTime(36); // 11 ms creation time
- mDut.recordNdpStatus(NanStatusType.SUCCESS, true, 25);
+ mDut.recordNdpStatus(NanStatusCode.SUCCESS, true, 25);
// uid2: delete the first NDP
networkRequestCache.remove(ns);
@@ -516,12 +516,12 @@ public class WifiAwareMetricsTest extends WifiBaseTest {
addNetworkInfoToCache(networkRequestCache, 14, uid2, package2, ndi0, null);
mDut.recordNdpCreation(uid2, package2, networkRequestCache);
setTime(37); // 1 ms creation time!
- mDut.recordNdpStatus(NanStatusType.SUCCESS, false, 36);
+ mDut.recordNdpStatus(NanStatusCode.SUCCESS, false, 36);
// a few error codes
- mDut.recordNdpStatus(NanStatusType.INTERNAL_FAILURE, false, 0);
- mDut.recordNdpStatus(NanStatusType.INTERNAL_FAILURE, false, 0);
- mDut.recordNdpStatus(NanStatusType.NO_RESOURCES_AVAILABLE, false, 0);
+ mDut.recordNdpStatus(NanStatusCode.INTERNAL_FAILURE, false, 0);
+ mDut.recordNdpStatus(NanStatusCode.INTERNAL_FAILURE, false, 0);
+ mDut.recordNdpStatus(NanStatusCode.NO_RESOURCES_AVAILABLE, false, 0);
// and some durations
setTime(150);
@@ -611,13 +611,13 @@ public class WifiAwareMetricsTest extends WifiBaseTest {
public void testNanStatusTypeHistogram() {
SparseIntArray statusHistogram = new SparseIntArray();
- addNanHalStatusToHistogram(NanStatusType.SUCCESS, statusHistogram);
+ addNanHalStatusToHistogram(NanStatusCode.SUCCESS, statusHistogram);
addNanHalStatusToHistogram(-1, statusHistogram);
- addNanHalStatusToHistogram(NanStatusType.ALREADY_ENABLED, statusHistogram);
- addNanHalStatusToHistogram(NanStatusType.SUCCESS, statusHistogram);
- addNanHalStatusToHistogram(NanStatusType.INTERNAL_FAILURE, statusHistogram);
- addNanHalStatusToHistogram(NanStatusType.SUCCESS, statusHistogram);
- addNanHalStatusToHistogram(NanStatusType.INTERNAL_FAILURE, statusHistogram);
+ addNanHalStatusToHistogram(NanStatusCode.ALREADY_ENABLED, statusHistogram);
+ addNanHalStatusToHistogram(NanStatusCode.SUCCESS, statusHistogram);
+ addNanHalStatusToHistogram(NanStatusCode.INTERNAL_FAILURE, statusHistogram);
+ addNanHalStatusToHistogram(NanStatusCode.SUCCESS, statusHistogram);
+ addNanHalStatusToHistogram(NanStatusCode.INTERNAL_FAILURE, statusHistogram);
addNanHalStatusToHistogram(55, statusHistogram);
addNanHalStatusToHistogram(65, statusHistogram);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java
index c4263a48c9..7d7ea7be41 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java
@@ -16,43 +16,24 @@
package com.android.server.wifi.aware;
-import static android.hardware.wifi.V1_0.NanCipherSuiteType.SHARED_KEY_128_MASK;
-import static android.hardware.wifi.V1_0.NanCipherSuiteType.SHARED_KEY_256_MASK;
-import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
-import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
-
import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyShort;
-import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.hardware.wifi.V1_0.IWifiNanIface;
-import android.hardware.wifi.V1_0.NanBandIndex;
-import android.hardware.wifi.V1_0.NanConfigRequest;
-import android.hardware.wifi.V1_0.NanDataPathSecurityType;
-import android.hardware.wifi.V1_0.NanEnableRequest;
-import android.hardware.wifi.V1_0.NanPublishRequest;
-import android.hardware.wifi.V1_0.NanRangingIndication;
-import android.hardware.wifi.V1_0.NanSubscribeRequest;
-import android.hardware.wifi.V1_0.WifiStatus;
-import android.hardware.wifi.V1_0.WifiStatusCode;
-import android.hardware.wifi.V1_2.NanConfigRequestSupplemental;
-import android.net.MacAddress;
-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.RemoteException;
-import android.util.Pair;
-
import androidx.test.filters.SmallTest;
import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.hal.WifiNanIface;
import org.junit.Before;
import org.junit.Rule;
@@ -63,7 +44,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.PrintWriter;
-import java.util.ArrayList;
/**
@@ -72,8 +52,7 @@ import java.util.ArrayList;
@SmallTest
public class WifiAwareNativeApiTest extends WifiBaseTest {
@Mock WifiAwareNativeManager mWifiAwareNativeManagerMock;
- @Mock IWifiNanIface mIWifiNanIfaceMock;
- @Mock android.hardware.wifi.V1_2.IWifiNanIface mIWifiNanIface12Mock;
+ @Mock WifiNanIface mWifiNanIfaceMock;
@Rule public ErrorCollector collector = new ErrorCollector();
@@ -81,16 +60,9 @@ public class WifiAwareNativeApiTest extends WifiBaseTest {
MockableWifiAwareNativeApi(WifiAwareNativeManager wifiAwareNativeManager) {
super(wifiAwareNativeManager);
}
-
- @Override
- public android.hardware.wifi.V1_2.IWifiNanIface mockableCastTo_1_2(IWifiNanIface iface) {
- return mIsInterface12 ? mIWifiNanIface12Mock : null;
- }
}
private MockableWifiAwareNativeApi mDut;
- private boolean mIsInterface12;
- private static final Capabilities CAP = new Capabilities();
/**
* Initializes mocks.
@@ -98,28 +70,8 @@ public class WifiAwareNativeApiTest extends WifiBaseTest {
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
-
- when(mWifiAwareNativeManagerMock.getWifiNanIface()).thenReturn(mIWifiNanIfaceMock);
-
- WifiStatus status = new WifiStatus();
- status.code = WifiStatusCode.SUCCESS;
- when(mIWifiNanIfaceMock.enableRequest(anyShort(), any())).thenReturn(status);
- when(mIWifiNanIfaceMock.configRequest(anyShort(), any())).thenReturn(status);
- when(mIWifiNanIfaceMock.startPublishRequest(anyShort(), any())).thenReturn(status);
- when(mIWifiNanIfaceMock.startSubscribeRequest(anyShort(), any())).thenReturn(status);
- when(mIWifiNanIfaceMock.initiateDataPathRequest(anyShort(), any())).thenReturn(status);
- when(mIWifiNanIfaceMock.respondToDataPathIndicationRequest(anyShort(), any())).thenReturn(
- status);
- when(mIWifiNanIface12Mock.enableRequest_1_2(anyShort(), any(), any())).thenReturn(status);
- when(mIWifiNanIface12Mock.configRequest_1_2(anyShort(), any(), any())).thenReturn(status);
- when(mIWifiNanIface12Mock.startPublishRequest(anyShort(), any())).thenReturn(status);
- when(mIWifiNanIface12Mock.startSubscribeRequest(anyShort(), any())).thenReturn(status);
-
- mIsInterface12 = false;
-
+ when(mWifiAwareNativeManagerMock.getWifiNanIface()).thenReturn(mWifiNanIfaceMock);
mDut = new MockableWifiAwareNativeApi(mWifiAwareNativeManagerMock);
- CAP.supportedCipherSuites = WIFI_AWARE_CIPHER_SUITE_NCS_SK_128
- | WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
}
/**
@@ -149,444 +101,76 @@ public class WifiAwareNativeApiTest extends WifiBaseTest {
}
/**
- * Validate that the configuration parameters used to manage power state behavior is
- * using default values at the default power state.
+ * Validate disable Aware will pass to the NAN interface, and trigger releaseAware.
+ * @throws Exception
*/
@Test
- public void testEnableAndConfigPowerSettingsDefaults() throws RemoteException {
- byte default5 = 1;
- byte default24 = 1;
-
- Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
- validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), true,
- true, true, false, false);
-
- collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("validDiscoveryWindowIntervalVal-24", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-5", default5,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .discoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-24", default24,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .discoveryWindowIntervalVal));
+ public void testDisableConfigRequest() throws Exception {
+ when(mWifiNanIfaceMock.disable(anyShort())).thenReturn(true);
+ assertTrue(mDut.disable((short) 10));
+ verify(mWifiNanIfaceMock).disable((short) 10);
}
/**
- * Validate that the configuration parameters used to manage power state behavior is
- * using the specified non-interactive values when in that power state.
+ * Validate that power configuration params set in the DUT are properly converted to
+ * {@link WifiNanIface.PowerParameters}.
*/
@Test
- public void testEnableAndConfigPowerSettingsNoneInteractive() throws RemoteException {
- byte interactive5 = 2;
- byte interactive24 = 3;
+ public void testConversionToPowerParams() {
+ ArgumentCaptor<WifiNanIface.PowerParameters> powerParamsCaptor = ArgumentCaptor.forClass(
+ WifiNanIface.PowerParameters.class);
+ when(mWifiNanIfaceMock.enableAndConfigure(anyShort(), any(), anyBoolean(),
+ anyBoolean(), anyBoolean(), anyBoolean(), anyInt(), anyInt(), any()))
+ .thenReturn(true);
- setPowerConfigurationParams(interactive5, interactive24, (byte) -1, (byte) -1);
- Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
- validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), false,
- false, false, false, false);
+ // Call enableAndConfigure without changing the config.
+ mDut.enableAndConfigure((short) 1, null, true, true,
+ false, true /* isIdle */, true, true, 1);
+ verify(mWifiNanIfaceMock).enableAndConfigure(anyShort(), any(), anyBoolean(),
+ anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
+ eq(1800), // PARAM_MAC_RANDOM_INTERVAL_SEC_DEFAULT
+ powerParamsCaptor.capture());
- collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-5", interactive5,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .discoveryWindowIntervalVal));
- collector.checkThat("validDiscoveryWindowIntervalVal-24", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-24", interactive24,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .discoveryWindowIntervalVal));
- }
+ // Expect the default power parameters.
+ WifiNanIface.PowerParameters powerParams = powerParamsCaptor.getValue();
+ assertEquals(powerParams.discoveryWindow24Ghz, 4); // PARAM_DW_24GHZ_IDLE
+ assertEquals(powerParams.discoveryWindow5Ghz, 0); // PARAM_DW_5GHZ_IDLE
+ assertEquals(powerParams.discoveryWindow6Ghz, 0); // PARAM_DW_6GHZ_IDLE
+ assertEquals(powerParams.discoveryBeaconIntervalMs,
+ 0); // PARAM_DISCOVERY_BEACON_INTERVAL_MS_IDLE
+ assertEquals(powerParams.numberOfSpatialStreamsInDiscovery,
+ 0); // PARAM_NUM_SS_IN_DISCOVERY_IDLE
+ assertFalse(powerParams.enableDiscoveryWindowEarlyTermination);
- /**
- * Validate that the configuration parameters used to manage power state behavior is
- * using the specified idle (doze) values when in that power state.
- */
- @Test
- public void testEnableAndConfigPowerSettingsIdle() throws RemoteException {
+ // Set custom power configuration params.
byte idle5 = 2;
byte idle24 = -1;
-
- setPowerConfigurationParams((byte) -1, (byte) -1, idle5, idle24);
- Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
- validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), false,
- true, false, true, false);
-
- collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-5", idle5,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .discoveryWindowIntervalVal));
- collector.checkThat("validDiscoveryWindowIntervalVal-24", false,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .validDiscoveryWindowIntervalVal));
- }
-
- /**
- * Validate that the configuration parameters used to manage power state behavior is
- * using default values at the default power state.
- *
- * Using HAL 1.2: additional power configurations.
- */
- @Test
- public void testEnableAndConfigPowerSettingsDefaults_1_2() throws RemoteException {
- byte default5 = 1;
- byte default24 = 1;
-
- Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
- validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), true,
- true, true, false, true);
-
- collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("validDiscoveryWindowIntervalVal-24", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-5", default5,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .discoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-24", default24,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .discoveryWindowIntervalVal));
-
- collector.checkThat("discoveryBeaconIntervalMs", 0,
- equalTo(configs.second.discoveryBeaconIntervalMs));
- collector.checkThat("numberOfSpatialStreamsInDiscovery", 0,
- equalTo(configs.second.numberOfSpatialStreamsInDiscovery));
- collector.checkThat("enableDiscoveryWindowEarlyTermination", false,
- equalTo(configs.second.enableDiscoveryWindowEarlyTermination));
- }
-
- /**
- * Validate that the configuration parameters used to manage power state behavior is
- * using the specified non-interactive values when in that power state.
- *
- * Using HAL 1.2: additional power configurations.
- */
- @Test
- public void testEnableAndConfigPowerSettingsNoneInteractive_1_2() throws RemoteException {
- byte interactive5 = 2;
- byte interactive24 = 3;
-
- setPowerConfigurationParams(interactive5, interactive24, (byte) -1, (byte) -1);
- Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
- validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), false,
- false, false, false, true);
-
- collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-5", interactive5,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .discoveryWindowIntervalVal));
- collector.checkThat("validDiscoveryWindowIntervalVal-24", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-24", interactive24,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .discoveryWindowIntervalVal));
-
- // Note: still defaults (i.e. disabled) - will be tweaked for low power
- collector.checkThat("discoveryBeaconIntervalMs", 0,
- equalTo(configs.second.discoveryBeaconIntervalMs));
- collector.checkThat("numberOfSpatialStreamsInDiscovery", 0,
- equalTo(configs.second.numberOfSpatialStreamsInDiscovery));
- collector.checkThat("enableDiscoveryWindowEarlyTermination", false,
- equalTo(configs.second.enableDiscoveryWindowEarlyTermination));
- }
-
- /**
- * Validate that the configuration parameters used to manage power state behavior is
- * using the specified idle (doze) values when in that power state.
- *
- * Using HAL 1.2: additional power configurations.
- */
- @Test
- public void testEnableAndConfigPowerSettingsIdle_1_2() throws RemoteException {
- byte idle5 = 2;
- byte idle24 = -1;
-
- setPowerConfigurationParams((byte) -1, (byte) -1, idle5, idle24);
- Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
- validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), false,
- true, false, true, true);
-
- collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .validDiscoveryWindowIntervalVal));
- collector.checkThat("discoveryWindowIntervalVal-5", idle5,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
- .discoveryWindowIntervalVal));
- collector.checkThat("validDiscoveryWindowIntervalVal-24", false,
- equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
- .validDiscoveryWindowIntervalVal));
-
- // Note: still defaults (i.e. disabled) - will be tweaked for low power
- collector.checkThat("discoveryBeaconIntervalMs", 0,
- equalTo(configs.second.discoveryBeaconIntervalMs));
- collector.checkThat("numberOfSpatialStreamsInDiscovery", 0,
- equalTo(configs.second.numberOfSpatialStreamsInDiscovery));
- collector.checkThat("enableDiscoveryWindowEarlyTermination", false,
- equalTo(configs.second.enableDiscoveryWindowEarlyTermination));
- }
-
- @Test
- public void testDiscoveryRangingSettings() throws RemoteException {
- short tid = 666;
- byte pid = 34;
- int minDistanceMm = 100;
- int maxDistanceMm = 555;
- // TODO: b/69428593 remove once HAL is converted from CM to MM
- short minDistanceCm = (short) (minDistanceMm / 10);
- short maxDistanceCm = (short) (maxDistanceMm / 10);
-
- ArgumentCaptor<NanPublishRequest> pubCaptor = ArgumentCaptor.forClass(
- NanPublishRequest.class);
- ArgumentCaptor<NanSubscribeRequest> subCaptor = ArgumentCaptor.forClass(
- NanSubscribeRequest.class);
-
- PublishConfig pubDefault = new PublishConfig.Builder().setServiceName("XXX").build();
- PublishConfig pubWithRanging = new PublishConfig.Builder().setServiceName(
- "XXX").setRangingEnabled(true).build();
- SubscribeConfig subDefault = new SubscribeConfig.Builder().setServiceName("XXX").build();
- SubscribeConfig subWithMin = new SubscribeConfig.Builder().setServiceName(
- "XXX").setMinDistanceMm(minDistanceMm).build();
- SubscribeConfig subWithMax = new SubscribeConfig.Builder().setServiceName(
- "XXX").setMaxDistanceMm(maxDistanceMm).build();
- SubscribeConfig subWithMinMax = new SubscribeConfig.Builder().setServiceName(
- "XXX").setMinDistanceMm(minDistanceMm).setMaxDistanceMm(maxDistanceMm).build();
-
- mDut.publish(tid, pid, pubDefault);
- mDut.publish(tid, pid, pubWithRanging);
- mDut.subscribe(tid, pid, subDefault);
- mDut.subscribe(tid, pid, subWithMin);
- mDut.subscribe(tid, pid, subWithMax);
- mDut.subscribe(tid, pid, subWithMinMax);
-
- verify(mIWifiNanIfaceMock, times(2)).startPublishRequest(eq(tid), pubCaptor.capture());
- verify(mIWifiNanIfaceMock, times(4)).startSubscribeRequest(eq(tid), subCaptor.capture());
-
- NanPublishRequest halPubReq;
- NanSubscribeRequest halSubReq;
-
- // pubDefault
- halPubReq = pubCaptor.getAllValues().get(0);
- collector.checkThat("pubDefault.baseConfigs.sessionId", pid,
- equalTo(halPubReq.baseConfigs.sessionId));
- collector.checkThat("pubDefault.baseConfigs.rangingRequired", false,
- equalTo(halPubReq.baseConfigs.rangingRequired));
-
- // pubWithRanging
- halPubReq = pubCaptor.getAllValues().get(1);
- collector.checkThat("pubWithRanging.baseConfigs.sessionId", pid,
- equalTo(halPubReq.baseConfigs.sessionId));
- collector.checkThat("pubWithRanging.baseConfigs.rangingRequired", true,
- equalTo(halPubReq.baseConfigs.rangingRequired));
-
- // subDefault
- halSubReq = subCaptor.getAllValues().get(0);
- collector.checkThat("subDefault.baseConfigs.sessionId", pid,
- equalTo(halSubReq.baseConfigs.sessionId));
- collector.checkThat("subDefault.baseConfigs.rangingRequired", false,
- equalTo(halSubReq.baseConfigs.rangingRequired));
-
- // subWithMin
- halSubReq = subCaptor.getAllValues().get(1);
- collector.checkThat("subWithMin.baseConfigs.sessionId", pid,
- equalTo(halSubReq.baseConfigs.sessionId));
- collector.checkThat("subWithMin.baseConfigs.rangingRequired", true,
- equalTo(halSubReq.baseConfigs.rangingRequired));
- collector.checkThat("subWithMin.baseConfigs.configRangingIndications",
- NanRangingIndication.EGRESS_MET_MASK,
- equalTo(halSubReq.baseConfigs.configRangingIndications));
- collector.checkThat("subWithMin.baseConfigs.distanceEgressCm", minDistanceCm,
- equalTo(halSubReq.baseConfigs.distanceEgressCm));
-
- // subWithMax
- halSubReq = subCaptor.getAllValues().get(2);
- collector.checkThat("subWithMax.baseConfigs.sessionId", pid,
- equalTo(halSubReq.baseConfigs.sessionId));
- collector.checkThat("subWithMax.baseConfigs.rangingRequired", true,
- equalTo(halSubReq.baseConfigs.rangingRequired));
- collector.checkThat("subWithMax.baseConfigs.configRangingIndications",
- NanRangingIndication.INGRESS_MET_MASK,
- equalTo(halSubReq.baseConfigs.configRangingIndications));
- collector.checkThat("subWithMin.baseConfigs.distanceIngressCm", maxDistanceCm,
- equalTo(halSubReq.baseConfigs.distanceIngressCm));
-
- // subWithMinMax
- halSubReq = subCaptor.getAllValues().get(3);
- collector.checkThat("subWithMinMax.baseConfigs.sessionId", pid,
- equalTo(halSubReq.baseConfigs.sessionId));
- collector.checkThat("subWithMinMax.baseConfigs.rangingRequired", true,
- equalTo(halSubReq.baseConfigs.rangingRequired));
- collector.checkThat("subWithMinMax.baseConfigs.configRangingIndications",
- NanRangingIndication.INGRESS_MET_MASK | NanRangingIndication.EGRESS_MET_MASK,
- equalTo(halSubReq.baseConfigs.configRangingIndications));
- collector.checkThat("subWithMin.baseConfigs.distanceEgressCm", minDistanceCm,
- equalTo(halSubReq.baseConfigs.distanceEgressCm));
- collector.checkThat("subWithMin.baseConfigs.distanceIngressCm", maxDistanceCm,
- equalTo(halSubReq.baseConfigs.distanceIngressCm));
- }
-
- /**
- * Validate the initiation of NDP for an open link.
- */
- @Test
- public void testInitiateDataPathOpen() throws Exception {
- validateInitiateDataPath(
- /* usePmk */ false,
- /* usePassphrase */ false,
- /* isOutOfBand */ false,
- /* publicCipherSuites */ 0,
- /* halCipherSuite */ 0);
- }
-
- /**
- * Validate the initiation of NDP for an PMK protected link with in-band discovery.
- */
- @Test
- public void testInitiateDataPathPmkInBand() throws Exception {
- validateInitiateDataPath(
- /* usePmk */ true,
- /* usePassphrase */ false,
- /* isOutOfBand */ false,
- /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
- /* halCipherSuite */ SHARED_KEY_256_MASK);
-
- }
-
- /**
- * Validate the initiation of NDP for an Passphrase protected link with in-band discovery.
- */
- @Test
- public void testInitiateDataPathPassphraseInBand() throws Exception {
- validateInitiateDataPath(
- /* usePmk */ false,
- /* usePassphrase */ true,
- /* isOutOfBand */ false,
- /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
- /* halCipherSuite */ SHARED_KEY_128_MASK);
- }
-
- /**
- * Validate the initiation of NDP for an PMK protected link with out-of-band discovery.
- */
- @Test
- public void testInitiateDataPathPmkOutOfBand() throws Exception {
- validateInitiateDataPath(
- /* usePmk */ true,
- /* usePassphrase */ false,
- /* isOutOfBand */ true,
- /* supportedCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
- /* expectedCipherSuite */ SHARED_KEY_128_MASK);
- }
-
- /**
- * Validate the response to an NDP request for an open link.
- */
- @Test
- public void testRespondToDataPathRequestOpenInBand() throws Exception {
- validateRespondToDataPathRequest(
- /* usePmk */ false,
- /* usePassphrase */ false,
- /* accept */ true,
- /* isOutOfBand */ false,
- /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
- /* halCipherSuite */ SHARED_KEY_256_MASK);
- }
-
- /**
- * Validate the response to an NDP request for a PMK-protected link with in-band discovery.
- */
- @Test
- public void testRespondToDataPathRequestPmkInBand() throws Exception {
- validateRespondToDataPathRequest(
- /* usePmk */ true,
- /* usePassphrase */ false,
- /* accept */ true,
- /* isOutOfBand */ false,
- /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
- /* halCipherSuite */ SHARED_KEY_128_MASK);
- }
-
- /**
- * Validate the response to an NDP request for a Passphrase-protected link with in-band
- * discovery.
- */
- @Test
- public void testRespondToDataPathRequestPassphraseInBand() throws Exception {
- validateRespondToDataPathRequest(
- /* usePmk */ false,
- /* usePassphrase */ true,
- /* accept */ true,
- /* isOutOfBand */ false,
- /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
- /* halCipherSuite */ SHARED_KEY_256_MASK);
- }
-
- /**
- * Validate the response to an NDP request for a PMK-protected link with out-of-band discovery.
- */
- @Test
- public void testRespondToDataPathRequestPmkOutOfBand() throws Exception {
- validateRespondToDataPathRequest(
- /* usePmk */ true,
- /* usePassphrase */ false,
- /* accept */ true,
- /* isOutOfBand */ true,
- /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
- /* halCipherSuite */ SHARED_KEY_128_MASK);
- }
-
- /**
- * Validate the response to an NDP request - when request is rejected.
- */
- @Test
- public void testRespondToDataPathRequestReject() throws Exception {
- validateRespondToDataPathRequest(
- /* usePmk */ true,
- /* usePassphrase */ false,
- /* accept */ false,
- /* isOutOfBand */ true,
- /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
- /* halCipherSuite */ 0);
- }
-
- /**
- * Validate disable Aware will pass to the NAN interface, and trigger releaseAware.
- * @throws Exception
- */
- @Test
- public void testDisableConfigRequest() throws Exception {
- WifiStatus status = new WifiStatus();
- status.code = WifiStatusCode.SUCCESS;
- when(mIWifiNanIfaceMock.disableRequest(anyShort())).thenReturn(status);
- assertTrue(mDut.disable((short) 10));
- verify(mIWifiNanIfaceMock).disableRequest((short) 10);
- }
-
- // utilities
-
- private void setPowerConfigurationParams(byte interactive5, byte interactive24, byte idle5,
- byte idle24) {
- setSettablePowerParam(WifiAwareNativeApi.POWER_PARAM_INACTIVE_KEY,
- WifiAwareNativeApi.PARAM_DW_5GHZ, Integer.toString(interactive5), true);
- setSettablePowerParam(WifiAwareNativeApi.POWER_PARAM_INACTIVE_KEY,
- WifiAwareNativeApi.PARAM_DW_24GHZ, Integer.toString(interactive24), true);
setSettablePowerParam(WifiAwareNativeApi.POWER_PARAM_IDLE_KEY,
WifiAwareNativeApi.PARAM_DW_5GHZ, Integer.toString(idle5), true);
setSettablePowerParam(WifiAwareNativeApi.POWER_PARAM_IDLE_KEY,
WifiAwareNativeApi.PARAM_DW_24GHZ, Integer.toString(idle24), true);
+
+ mDut.enableAndConfigure((short) 1, null, true, true,
+ false, true /* isIdle */, true, true, 1);
+ verify(mWifiNanIfaceMock, times(2)).enableAndConfigure(anyShort(), any(), anyBoolean(),
+ anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
+ eq(1800), // PARAM_MAC_RANDOM_INTERVAL_SEC_DEFAULT
+ powerParamsCaptor.capture());
+
+ // Expect the updated power parameters.
+ powerParams = powerParamsCaptor.getValue();
+ assertEquals(powerParams.discoveryWindow24Ghz, idle24);
+ assertEquals(powerParams.discoveryWindow5Ghz, idle5);
+ assertEquals(powerParams.discoveryWindow6Ghz, 0); // PARAM_DW_6GHZ_IDLE
+ assertEquals(powerParams.discoveryBeaconIntervalMs,
+ 0); // PARAM_DISCOVERY_BEACON_INTERVAL_MS_IDLE
+ assertEquals(powerParams.numberOfSpatialStreamsInDiscovery,
+ 0); // PARAM_NUM_SS_IN_DISCOVERY_IDLE
+ assertFalse(powerParams.enableDiscoveryWindowEarlyTermination);
}
+ // utilities
+
private void setSettablePowerParam(String mode, String name, String value,
boolean expectSuccess) {
PrintWriter pwMock = mock(PrintWriter.class);
@@ -607,217 +191,4 @@ public class WifiAwareNativeApiTest extends WifiBaseTest {
collector.checkThat(mDut.onCommand(parentShellMock), equalTo(expectSuccess ? 0 : -1));
}
-
- private Pair<NanConfigRequest, NanConfigRequestSupplemental> validateEnableAndConfigure(
- short transactionId, ConfigRequest configRequest, boolean notifyIdentityChange,
- boolean initialConfiguration, boolean isInteractive, boolean isIdle, boolean isHal12)
- throws RemoteException {
- mIsInterface12 = isHal12;
-
- mDut.enableAndConfigure(transactionId, configRequest, notifyIdentityChange,
- initialConfiguration, isInteractive, isIdle, false, false, 2437);
-
- ArgumentCaptor<NanEnableRequest> enableReqCaptor = ArgumentCaptor.forClass(
- NanEnableRequest.class);
- ArgumentCaptor<NanConfigRequest> configReqCaptor = ArgumentCaptor.forClass(
- NanConfigRequest.class);
- ArgumentCaptor<NanConfigRequestSupplemental> configSuppCaptor = ArgumentCaptor.forClass(
- NanConfigRequestSupplemental.class);
- NanConfigRequest config;
- NanConfigRequestSupplemental configSupp = null;
-
- if (initialConfiguration) {
- if (isHal12) {
- verify(mIWifiNanIface12Mock).enableRequest_1_2(eq(transactionId),
- enableReqCaptor.capture(), configSuppCaptor.capture());
- configSupp = configSuppCaptor.getValue();
- } else {
- verify(mIWifiNanIfaceMock).enableRequest(eq(transactionId),
- enableReqCaptor.capture());
- }
- config = enableReqCaptor.getValue().configParams;
- } else {
- if (isHal12) {
- verify(mIWifiNanIface12Mock).configRequest_1_2(eq(transactionId),
- configReqCaptor.capture(), configSuppCaptor.capture());
- configSupp = configSuppCaptor.getValue();
- } else {
- verify(mIWifiNanIfaceMock).configRequest(eq(transactionId),
- configReqCaptor.capture());
- }
- config = configReqCaptor.getValue();
- }
-
- collector.checkThat("disableDiscoveryAddressChangeIndication", !notifyIdentityChange,
- equalTo(config.disableDiscoveryAddressChangeIndication));
- collector.checkThat("disableStartedClusterIndication", !notifyIdentityChange,
- equalTo(config.disableStartedClusterIndication));
- collector.checkThat("disableJoinedClusterIndication", !notifyIdentityChange,
- equalTo(config.disableJoinedClusterIndication));
-
- return new Pair<>(config, configSupp);
- }
-
- private void validateInitiateDataPath(boolean usePmk, boolean usePassphrase,
- boolean isOutOfBand, int publicCipherSuites, int halCipherSuite)
- throws Exception {
- short tid = 44;
- int peerId = 555;
- int channelRequestType =
- android.hardware.wifi.V1_0.NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED;
- int channel = 2146;
- byte[] peer = MacAddress.fromString("00:01:02:03:04:05").toByteArray();
- String interfaceName = "aware_data5";
- final byte[] pmk = "01234567890123456789012345678901".getBytes();
- String passphrase = "blahblah";
- final byte[] appInfo = "Out-of-band info".getBytes();
-
- ArgumentCaptor<android.hardware.wifi.V1_0.NanInitiateDataPathRequest> captor =
- ArgumentCaptor.forClass(
- android.hardware.wifi.V1_0.NanInitiateDataPathRequest.class);
- WifiAwareDataPathSecurityConfig securityConfig = null;
- if (usePassphrase) {
- securityConfig = new WifiAwareDataPathSecurityConfig
- .Builder(publicCipherSuites)
- .setPskPassphrase(passphrase)
- .build();
- } else if (usePmk) {
- securityConfig = new WifiAwareDataPathSecurityConfig
- .Builder(publicCipherSuites)
- .setPmk(pmk)
- .build();
- }
-
- mDut.initiateDataPath(tid, peerId, channelRequestType, channel, peer, interfaceName,
- isOutOfBand, appInfo, CAP, securityConfig);
-
- verify(mIWifiNanIfaceMock).initiateDataPathRequest(eq(tid), captor.capture());
-
- android.hardware.wifi.V1_0.NanInitiateDataPathRequest nidpr = captor.getValue();
- collector.checkThat("peerId", peerId, equalTo(nidpr.peerId));
- collector.checkThat("peerDiscMacAddr", peer, equalTo(nidpr.peerDiscMacAddr));
- collector.checkThat("channelRequestType", channelRequestType,
- equalTo(nidpr.channelRequestType));
- collector.checkThat("channel", channel, equalTo(nidpr.channel));
- collector.checkThat("ifaceName", interfaceName, equalTo(nidpr.ifaceName));
-
- if (usePmk) {
- collector.checkThat("securityConfig.securityType",
- NanDataPathSecurityType.PMK,
- equalTo(nidpr.securityConfig.securityType));
- collector.checkThat("securityConfig.cipherType", halCipherSuite,
- equalTo(nidpr.securityConfig.cipherType));
- collector.checkThat("securityConfig.pmk", pmk, equalTo(nidpr.securityConfig.pmk));
- collector.checkThat("securityConfig.passphrase.length", 0,
- equalTo(nidpr.securityConfig.passphrase.size()));
- }
-
- if (usePassphrase) {
- collector.checkThat("securityConfig.securityType",
- NanDataPathSecurityType.PASSPHRASE,
- equalTo(nidpr.securityConfig.securityType));
- collector.checkThat("securityConfig.cipherType", halCipherSuite,
- equalTo(nidpr.securityConfig.cipherType));
- collector.checkThat("securityConfig.passphrase", passphrase.getBytes(),
- equalTo(convertArrayListToNativeByteArray(nidpr.securityConfig.passphrase)));
- }
-
- collector.checkThat("appInfo", appInfo,
- equalTo(convertArrayListToNativeByteArray(nidpr.appInfo)));
-
- if ((usePmk || usePassphrase) && isOutOfBand) {
- collector.checkThat("serviceNameOutOfBand",
- WifiAwareNativeApi.SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(),
- equalTo(convertArrayListToNativeByteArray(nidpr.serviceNameOutOfBand)));
- } else {
- collector.checkThat("serviceNameOutOfBand.length", 0,
- equalTo(nidpr.serviceNameOutOfBand.size()));
- }
- }
-
- private void validateRespondToDataPathRequest(boolean usePmk, boolean usePassphrase,
- boolean accept, boolean isOutOfBand, int publicCipherSuites, int halCipherSuite)
- throws Exception {
- short tid = 33;
- int ndpId = 44;
- String interfaceName = "aware_whatever22";
- final byte[] pmk = "01234567890123456789012345678901".getBytes();
- String passphrase = "blahblah";
- final byte[] appInfo = "Out-of-band info".getBytes();
-
- ArgumentCaptor<android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest> captor =
- ArgumentCaptor.forClass(
- android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest.class);
- WifiAwareDataPathSecurityConfig securityConfig = null;
- if (usePassphrase) {
- securityConfig = new WifiAwareDataPathSecurityConfig
- .Builder(publicCipherSuites)
- .setPskPassphrase(passphrase)
- .build();
- } else if (usePmk) {
- securityConfig = new WifiAwareDataPathSecurityConfig
- .Builder(publicCipherSuites)
- .setPmk(pmk)
- .build();
- }
-
- mDut.respondToDataPathRequest(tid, accept, ndpId, interfaceName,
- appInfo, isOutOfBand, CAP, securityConfig);
-
- verify(mIWifiNanIfaceMock).respondToDataPathIndicationRequest(eq(tid), captor.capture());
-
- android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest nrtdpir =
- captor.getValue();
- collector.checkThat("acceptRequest", accept, equalTo(nrtdpir.acceptRequest));
- collector.checkThat("ndpInstanceId", ndpId, equalTo(nrtdpir.ndpInstanceId));
- collector.checkThat("ifaceName", interfaceName, equalTo(nrtdpir.ifaceName));
-
- if (accept) {
- if (usePmk) {
- collector.checkThat("securityConfig.securityType",
- NanDataPathSecurityType.PMK,
- equalTo(nrtdpir.securityConfig.securityType));
- collector.checkThat("securityConfig.cipherType", halCipherSuite,
- equalTo(nrtdpir.securityConfig.cipherType));
- collector.checkThat("securityConfig.pmk", pmk, equalTo(nrtdpir.securityConfig.pmk));
- collector.checkThat("securityConfig.passphrase.length", 0,
- equalTo(nrtdpir.securityConfig.passphrase.size()));
- }
-
- if (usePassphrase) {
- collector.checkThat("securityConfig.securityType",
- NanDataPathSecurityType.PASSPHRASE,
- equalTo(nrtdpir.securityConfig.securityType));
- collector.checkThat("securityConfig.cipherType", halCipherSuite,
- equalTo(nrtdpir.securityConfig.cipherType));
- collector.checkThat("securityConfig.passphrase", passphrase.getBytes(),
- equalTo(convertArrayListToNativeByteArray(
- nrtdpir.securityConfig.passphrase)));
- }
-
- collector.checkThat("appInfo", appInfo,
- equalTo(convertArrayListToNativeByteArray(nrtdpir.appInfo)));
-
- if ((usePmk || usePassphrase) && isOutOfBand) {
- collector.checkThat("serviceNameOutOfBand",
- WifiAwareNativeApi.SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(),
- equalTo(convertArrayListToNativeByteArray(nrtdpir.serviceNameOutOfBand)));
- } else {
- collector.checkThat("serviceNameOutOfBand.length", 0,
- equalTo(nrtdpir.serviceNameOutOfBand.size()));
- }
- }
- }
-
- private byte[] convertArrayListToNativeByteArray(ArrayList<Byte> from) {
- if (from == null) {
- return null;
- }
-
- byte[] to = new byte[from.size()];
- for (int i = 0; i < from.size(); ++i) {
- to[i] = from.get(i);
- }
- return to;
- }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeManagerTest.java
index 8c9fdf8b24..3aa410c0f2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeManagerTest.java
@@ -19,13 +19,13 @@ package com.android.server.wifi.aware;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import android.hardware.wifi.V1_0.IWifiNanIface;
import android.hardware.wifi.V1_0.WifiStatus;
import android.hardware.wifi.V1_0.WifiStatusCode;
import android.os.Handler;
@@ -35,6 +35,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.hal.WifiNanIface;
import org.junit.Before;
import org.junit.Rule;
@@ -56,10 +57,7 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
@Mock private WifiAwareStateManager mWifiAwareStateManagerMock;
@Mock private HalDeviceManager mHalDeviceManager;
@Mock private WifiAwareNativeCallback mWifiAwareNativeCallback;
- @Mock private IWifiNanIface mWifiNanIfaceMock;
- @Mock android.hardware.wifi.V1_2.IWifiNanIface mIWifiNanIface12Mock;
- @Mock android.hardware.wifi.V1_5.IWifiNanIface mIWifiNanIface15Mock;
- @Mock android.hardware.wifi.V1_6.IWifiNanIface mIWifiNanIface16Mock;
+ @Mock private WifiNanIface mWifiNanIfaceMock;
@Mock private Handler mHandlerMock;
private ArgumentCaptor<HalDeviceManager.ManagerStatusListener> mManagerStatusListenerCaptor =
ArgumentCaptor.forClass(HalDeviceManager.ManagerStatusListener.class);
@@ -77,21 +75,6 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
WifiAwareNativeCallback wifiAwareNativeCallback) {
super(awareStateManager, halDeviceManager, wifiAwareNativeCallback);
}
-
- @Override
- public android.hardware.wifi.V1_2.IWifiNanIface mockableCastTo_1_2(IWifiNanIface iface) {
- return (iface == mIWifiNanIface12Mock) ? mIWifiNanIface12Mock : null;
- }
-
- @Override
- public android.hardware.wifi.V1_5.IWifiNanIface mockableCastTo_1_5(IWifiNanIface iface) {
- return (iface == mIWifiNanIface15Mock) ? mIWifiNanIface15Mock : null;
- }
-
- @Override
- public android.hardware.wifi.V1_6.IWifiNanIface mockableCastTo_1_6(IWifiNanIface iface) {
- return (iface == mIWifiNanIface16Mock) ? mIWifiNanIface16Mock : null;
- }
}
@Before
@@ -101,15 +84,13 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
mStatusOk = new WifiStatus();
mStatusOk.code = WifiStatusCode.SUCCESS;
- when(mWifiNanIfaceMock.registerEventCallback(any())).thenReturn(mStatusOk);
- when(mIWifiNanIface15Mock.registerEventCallback_1_5(any())).thenReturn(mStatusOk);
+ when(mWifiNanIfaceMock.registerFrameworkCallback(any())).thenReturn(true);
mDut = new MockableWifiAwareNativeManager(mWifiAwareStateManagerMock,
mHalDeviceManager, mWifiAwareNativeCallback);
mDut.start(mHandlerMock);
- mInOrder = inOrder(mWifiAwareStateManagerMock, mHalDeviceManager, mWifiNanIfaceMock,
- mIWifiNanIface15Mock);
+ mInOrder = inOrder(mWifiAwareStateManagerMock, mHalDeviceManager, mWifiNanIfaceMock);
// validate (and capture) that register manage status callback
mInOrder.verify(mHalDeviceManager).initialize();
@@ -133,7 +114,8 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
// configure HalDeviceManager as ready/wifi started (and to return an interface if
// requested)
when(mHalDeviceManager.isStarted()).thenReturn(true);
- when(mHalDeviceManager.createNanIface(any(), any(), any())).thenReturn(mWifiNanIfaceMock);
+ when(mHalDeviceManager.createNanIface(any(), any(), any()))
+ .thenReturn(mWifiNanIfaceMock);
// 1. onStatusChange (ready/started)
mManagerStatusListenerCaptor.getValue().onStatusChanged();
@@ -151,8 +133,7 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
mInOrder.verify(mWifiAwareStateManagerMock).tryToGetAwareCapability();
mInOrder.verify(mHalDeviceManager, never()).createNanIface(any(), any(), any());
- verifyNoMoreInteractions(mWifiAwareStateManagerMock, mWifiNanIfaceMock,
- mIWifiNanIface15Mock);
+ verifyNoMoreInteractions(mWifiAwareStateManagerMock, mWifiNanIfaceMock);
assertNull("Interface non-null!", mDut.getWifiNanIface());
}
@@ -165,7 +146,8 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
// configure HalDeviceManager as ready/wifi started (and to return an interface if
// requested)
when(mHalDeviceManager.isStarted()).thenReturn(true);
- when(mHalDeviceManager.createNanIface(any(), any(), any())).thenReturn(mWifiNanIfaceMock);
+ when(mHalDeviceManager.createNanIface(any(), any(), any()))
+ .thenReturn(mWifiNanIfaceMock);
// 1. onStatusChange (ready/started)
mManagerStatusListenerCaptor.getValue().onStatusChanged();
@@ -176,7 +158,8 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
mDut.tryToGetAware(TEST_WS);
mInOrder.verify(mHalDeviceManager).createNanIface(mDestroyedListenerCaptor.capture(),
any(), eq(TEST_WS));
- mInOrder.verify(mWifiNanIfaceMock).registerEventCallback(any());
+ mInOrder.verify(mWifiNanIfaceMock).registerFrameworkCallback(any());
+ mInOrder.verify(mWifiNanIfaceMock).enableVerboseLogging(anyBoolean());
assertEquals("Interface mismatch", mWifiNanIfaceMock, mDut.getWifiNanIface());
// 3. release (interface released)
@@ -190,7 +173,8 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
mDut.tryToGetAware(TEST_WS);
mInOrder.verify(mHalDeviceManager).createNanIface(mDestroyedListenerCaptor.capture(),
any(), eq(TEST_WS));
- mInOrder.verify(mWifiNanIfaceMock).registerEventCallback(any());
+ mInOrder.verify(mWifiNanIfaceMock).registerFrameworkCallback(any());
+ mInOrder.verify(mWifiNanIfaceMock).enableVerboseLogging(anyBoolean());
assertEquals("Interface mismatch", mWifiNanIfaceMock, mDut.getWifiNanIface());
// 5. request (nop - already have interface)
@@ -210,8 +194,7 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
mInOrder.verify(mHalDeviceManager, never()).createNanIface(any(), any(), any());
mInOrder.verify(mHalDeviceManager, never()).removeIface(any());
- verifyNoMoreInteractions(mWifiAwareStateManagerMock, mWifiNanIfaceMock,
- mIWifiNanIface15Mock);
+ verifyNoMoreInteractions(mWifiAwareStateManagerMock, mWifiNanIfaceMock);
}
/**
@@ -222,7 +205,8 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
// configure HalDeviceManager as ready/wifi started (and to return an interface if
// requested)
when(mHalDeviceManager.isStarted()).thenReturn(true);
- when(mHalDeviceManager.createNanIface(any(), any(), any())).thenReturn(mWifiNanIfaceMock);
+ when(mHalDeviceManager.createNanIface(any(), any(), any()))
+ .thenReturn(mWifiNanIfaceMock);
// 1. onStatusChange (ready/started)
mManagerStatusListenerCaptor.getValue().onStatusChanged();
@@ -233,7 +217,8 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
mDut.tryToGetAware(TEST_WS);
mInOrder.verify(mHalDeviceManager).createNanIface(mDestroyedListenerCaptor.capture(),
any(), eq(TEST_WS));
- mInOrder.verify(mWifiNanIfaceMock).registerEventCallback(any());
+ mInOrder.verify(mWifiNanIfaceMock).registerFrameworkCallback(any());
+ mInOrder.verify(mWifiNanIfaceMock).enableVerboseLogging(anyBoolean());
assertEquals("Interface mismatch", mWifiNanIfaceMock, mDut.getWifiNanIface());
// 3. interface gets destroyed
@@ -247,32 +232,6 @@ public class WifiAwareNativeManagerTest extends WifiBaseTest {
mInOrder.verify(mHalDeviceManager, never()).createNanIface(any(), any(), any());
mInOrder.verify(mHalDeviceManager, never()).removeIface(any());
- verifyNoMoreInteractions(mWifiAwareStateManagerMock, mWifiNanIfaceMock,
- mIWifiNanIface15Mock);
- }
-
- /**
- * Test the basic control flow for HAL 1.5 - validate that the correct event registration
- * occurs.
- */
- @Test
- public void testBasicFlowHal15() throws Exception {
- // configure HalDeviceManager as ready/wifi started (and to return an interface if
- // requested)
- when(mHalDeviceManager.isStarted()).thenReturn(true);
- when(mHalDeviceManager.createNanIface(any(), any(), any()))
- .thenReturn(mIWifiNanIface15Mock);
-
- // 1. onStatusChange (ready/started)
- mManagerStatusListenerCaptor.getValue().onStatusChanged();
- mInOrder.verify(mWifiAwareStateManagerMock).tryToGetAwareCapability();
- assertNull("Interface non-null!", mDut.getWifiNanIface());
-
- // 2. request (interface obtained)
- mDut.tryToGetAware(TEST_WS);
- mInOrder.verify(mHalDeviceManager).createNanIface(mDestroyedListenerCaptor.capture(),
- any(), eq(TEST_WS));
- mInOrder.verify(mIWifiNanIface15Mock).registerEventCallback_1_5(any());
- assertEquals("Interface mismatch", mIWifiNanIface15Mock, mDut.getWifiNanIface());
+ verifyNoMoreInteractions(mWifiAwareStateManagerMock, mWifiNanIfaceMock);
}
}
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 4ddf8d78af..67759ce3c8 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
@@ -57,8 +57,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.hardware.wifi.V1_0.NanRangingIndication;
-import android.hardware.wifi.V1_0.NanStatusType;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.wifi.WifiAvailableChannel;
@@ -103,6 +101,8 @@ import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WifiThreadRunner;
+import com.android.server.wifi.hal.WifiNanIface.NanRangingIndication;
+import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
import com.android.server.wifi.util.NetdWrapper;
import com.android.server.wifi.util.WaitingState;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -473,7 +473,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mMockLooper.dispatchAll();
inOrder.verify(mMockAwareDataPathStatemanager).deleteAllInterfaces();
inOrder.verify(mMockNative).disable(transactionId.capture());
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
assertFalse(mDut.isDeviceAttached());
@@ -509,7 +509,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
validateCorrectAwareStatusChangeBroadcast(inOrder);
inOrder.verify(mMockNative).disable(transactionId.capture());
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
// (3) try connecting and validate that get failure callback (though app should be aware of
// non-availability through state change broadcast and/or query API)
@@ -574,7 +574,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrderM.verify(mAwareMetricsMock).recordDisableAware();
inOrderM.verify(mAwareMetricsMock).recordDisableUsage();
validateInternalClientInfoCleanedUp(clientId);
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
inOrderM.verify(mAwareMetricsMock).recordDisableAware();
assertFalse(mDut.isDeviceAttached());
@@ -584,7 +584,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
configRequest, false, mExtras);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onConnectFail(anyInt());
- inOrderM.verify(mAwareMetricsMock).recordAttachStatus(NanStatusType.INTERNAL_FAILURE);
+ inOrderM.verify(mAwareMetricsMock).recordAttachStatus(NanStatusCode.INTERNAL_FAILURE);
assertFalse(mDut.isDeviceAttached());
// (5) disable usage again and validate that not much happens
@@ -648,8 +648,9 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNativeManager).tryToGetAware(new WorkSource(uid, callingPackage));
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
eq(false), eq(true), eq(true), eq(false), eq(false), eq(false), anyInt());
+
inOrder.verify(mMockNativeManager).releaseAware();
- inOrder.verify(mockCallback).onConnectFail(NanStatusType.INTERNAL_FAILURE);
+ inOrder.verify(mockCallback).onConnectFail(NanStatusCode.INTERNAL_FAILURE);
validateInternalClientInfoCleanedUp(clientId);
verifyNoMoreInteractions(mMockNative, mockCallback);
@@ -670,7 +671,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final int pid = 2000;
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
- final int reason = NanStatusType.INTERNAL_FAILURE;
+ final int reason = NanStatusCode.INTERNAL_FAILURE;
final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
final byte[] someMac2 = HexEncoding.decode("060708090A0B".toCharArray(), false);
@@ -795,9 +796,9 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNative).publish(anyShort(), eq((byte) 0), eq(publishConfig));
assertTrue(mAlarmManager.dispatch(WifiAwareStateManager.HAL_COMMAND_TIMEOUT_TAG));
mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid,
- NanStatusType.INTERNAL_FAILURE, true);
+ NanStatusCode.INTERNAL_FAILURE, true);
validateInternalNoSessions(clientId);
// (3) publish + success
@@ -809,7 +810,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(uid), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, true);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, true);
verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback, mAwareMetricsMock);
}
@@ -825,7 +826,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final int pid = 2000;
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
- final int reasonFail = NanStatusType.INTERNAL_FAILURE;
+ final int reasonFail = NanStatusCode.INTERNAL_FAILURE;
ConfigRequest configRequest = new ConfigRequest.Builder().build();
PublishConfig publishConfig = new PublishConfig.Builder().build();
@@ -896,7 +897,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final int pid = 2000;
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
- final int reasonTerminate = NanStatusType.SUCCESS;
+ final int reasonTerminate = NanStatusCode.SUCCESS;
final byte publishId = 15;
ConfigRequest configRequest = new ConfigRequest.Builder().build();
@@ -939,7 +940,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(uid), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, true);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, true);
validateCorrectAwareResourcesChangeBroadcast(inOrder);
assertEquals(1, mDut.getAvailableAwareResources().getAvailablePublishSessionsCount());
assertEquals(2, mDut.getAvailableAwareResources().getAvailableSubscribeSessionsCount());
@@ -981,7 +982,6 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final int pid = 2000;
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
- final int reasonTerminate = NanStatusType.SUCCESS;
final byte publishId = 15;
ConfigRequest configRequest = new ConfigRequest.Builder().build();
@@ -1025,7 +1025,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(uid), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, true);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, true);
validateCorrectAwareResourcesChangeBroadcast(inOrder);
assertEquals(1, mDut.getAvailableAwareResources().getAvailablePublishSessionsCount());
assertEquals(2, mDut.getAvailableAwareResources().getAvailableSubscribeSessionsCount());
@@ -1067,7 +1067,6 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final int pid = 2000;
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
- final int reasonTerminate = NanStatusType.SUCCESS;
final byte subscribeId = 15;
ConfigRequest configRequest = new ConfigRequest.Builder().build();
@@ -1111,7 +1110,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(uid), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, false);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, false);
validateCorrectAwareResourcesChangeBroadcast(inOrder);
assertEquals(2, mDut.getAvailableAwareResources().getAvailablePublishSessionsCount());
assertEquals(1, mDut.getAvailableAwareResources().getAvailableSubscribeSessionsCount());
@@ -1156,7 +1155,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
final byte publishId = 15;
- final int reasonFail = NanStatusType.INTERNAL_FAILURE;
+ final int reasonFail = NanStatusCode.INTERNAL_FAILURE;
ConfigRequest configRequest = new ConfigRequest.Builder().build();
PublishConfig publishConfig = new PublishConfig.Builder().setRangingEnabled(true).build();
@@ -1198,7 +1197,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySessionWithRanging(eq(uid), eq(false),
eq(-1), eq(-1), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, true);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, true);
mMockLooper.dispatchAll();
// Verify reconfigure aware to enable ranging.
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
@@ -1228,7 +1227,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionConfigSuccess();
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, true);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, true);
// (7) another update + immediate failure
when(mMockNative.publish(anyShort(), anyByte(), any())).thenReturn(false);
@@ -1248,11 +1247,11 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId),
eq(publishConfig));
mDut.onSessionConfigFailResponse(transactionId.getValue(), true,
- NanStatusType.INVALID_SESSION_ID);
+ NanStatusCode.INVALID_SESSION_ID);
mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusType.INVALID_SESSION_ID);
+ inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusCode.INVALID_SESSION_ID);
inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid,
- NanStatusType.INVALID_SESSION_ID, true);
+ NanStatusCode.INVALID_SESSION_ID, true);
// Verify reconfigure aware to disable ranging.
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
@@ -1330,10 +1329,10 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNative).disable(transactionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(uid), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, true);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, true);
inOrderM.verify(mAwareMetricsMock).recordAttachSessionDuration(anyLong());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySessionDuration(anyLong(), eq(true));
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
inOrderM.verify(mAwareMetricsMock).recordDisableAware();
verify(mMockNativeManager, times(2)).releaseAware();
@@ -1355,7 +1354,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final int pid = 2000;
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
- final int reasonFail = NanStatusType.INTERNAL_FAILURE;
+ final int reasonFail = NanStatusCode.INTERNAL_FAILURE;
ConfigRequest configRequest = new ConfigRequest.Builder().build();
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
@@ -1426,7 +1425,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final int pid = 2000;
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
- final int reasonTerminate = NanStatusType.SUCCESS;
+ final int reasonTerminate = NanStatusCode.SUCCESS;
final byte subscribeId = 15;
ConfigRequest configRequest = new ConfigRequest.Builder().build();
@@ -1468,7 +1467,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(uid), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, false);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, false);
validateCorrectAwareResourcesChangeBroadcast(inOrder);
assertEquals(2, mDut.getAvailableAwareResources().getAvailablePublishSessionsCount());
assertEquals(1, mDut.getAvailableAwareResources().getAvailableSubscribeSessionsCount());
@@ -1512,7 +1511,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
final byte subscribeId = 15;
- final int reasonFail = NanStatusType.INTERNAL_FAILURE;
+ final int reasonFail = NanStatusCode.INTERNAL_FAILURE;
final int rangeMax = 10;
ConfigRequest configRequest = new ConfigRequest.Builder().build();
@@ -1556,7 +1555,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySessionWithRanging(eq(uid), eq(true),
eq(-1), eq(rangeMax), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, false);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, false);
// Verify reconfigure aware to enable ranging.
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
@@ -1586,7 +1585,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onSessionConfigSuccess();
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, false);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, false);
// (7) another update + immediate failure
when(mMockNative.subscribe(anyShort(), anyByte(), any()))
@@ -1678,7 +1677,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String callingFeature = "com.google.someFeature";
final String serviceName = "some-service-name";
final String ssi = "some much longer and more arbitrary data";
- final int reasonFail = NanStatusType.INTERNAL_FAILURE;
+ final int reasonFail = NanStatusCode.INTERNAL_FAILURE;
final byte subscribeId = 15;
final int requestorId = 22;
final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
@@ -1736,7 +1735,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySessionWithRanging(eq(uid), eq(true),
eq(rangeMin), eq(rangeMax), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, false);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, false);
// Verify reconfigure aware to enable ranging.
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
@@ -1829,7 +1828,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String msgToPeer2 = "hey there 0506...";
final int msgToPeerId1 = 546;
final int msgToPeerId2 = 9654;
- final int reason = NanStatusType.INTERNAL_FAILURE;
+ final int reason = NanStatusCode.INTERNAL_FAILURE;
ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
.setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
@@ -2070,7 +2069,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
ssi.getBytes(), messageId, 0);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
- NanStatusType.INTERNAL_FAILURE);
+ NanStatusCode.INTERNAL_FAILURE);
validateInternalSendMessageQueuesCleanedUp(messageId);
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
@@ -2160,10 +2159,10 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId + 2));
short transactionId3 = transactionId.getValue();
- mDut.onMessageSendQueuedFailResponse(transactionId3, NanStatusType.INTERNAL_FAILURE);
+ mDut.onMessageSendQueuedFailResponse(transactionId3, NanStatusCode.INTERNAL_FAILURE);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMessageSendFail(messageId + 2,
- NanStatusType.INTERNAL_FAILURE);
+ NanStatusCode.INTERNAL_FAILURE);
validateInternalSendMessageQueuesCleanedUp(messageId + 2);
// (5) send a message and get an immediate failure (configure first)
@@ -2177,14 +2176,14 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId + 3));
short transactionId4 = transactionId.getValue();
inOrder.verify(mockSessionCallback).onMessageSendFail(messageId + 3,
- NanStatusType.INTERNAL_FAILURE);
+ NanStatusCode.INTERNAL_FAILURE);
validateInternalSendMessageQueuesCleanedUp(messageId + 3);
// (6) message send timeout
assertTrue(mAlarmManager.dispatch(WifiAwareStateManager.HAL_SEND_MESSAGE_TIMEOUT_TAG));
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
- NanStatusType.INTERNAL_FAILURE);
+ NanStatusCode.INTERNAL_FAILURE);
validateInternalSendMessageQueuesCleanedUp(messageId);
// (7) firmware response (unlikely - but good to check)
@@ -2193,7 +2192,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// bogus: these didn't even go to firmware or weren't queued
mDut.onMessageSendSuccessNotification(transactionId3);
- mDut.onMessageSendFailNotification(transactionId4, NanStatusType.INTERNAL_FAILURE);
+ mDut.onMessageSendFailNotification(transactionId4, NanStatusCode.INTERNAL_FAILURE);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId + 1);
@@ -2271,7 +2270,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (4) loop and fail until reach retryCount
for (int i = 0; i < retryCount; ++i) {
- mDut.onMessageSendFailNotification(transactionId.getValue(), NanStatusType.NO_OTA_ACK);
+ mDut.onMessageSendFailNotification(transactionId.getValue(), NanStatusCode.NO_OTA_ACK);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
@@ -2358,7 +2357,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (4) loop and fail until reach retryCount+1
for (int i = 0; i < retryCount + 1; ++i) {
- mDut.onMessageSendFailNotification(transactionId.getValue(), NanStatusType.NO_OTA_ACK);
+ mDut.onMessageSendFailNotification(transactionId.getValue(), NanStatusCode.NO_OTA_ACK);
mMockLooper.dispatchAll();
if (i != retryCount) {
@@ -2370,7 +2369,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
}
inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
- NanStatusType.NO_OTA_ACK);
+ NanStatusCode.NO_OTA_ACK);
validateInternalSendMessageQueuesCleanedUp(messageId);
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
@@ -2596,7 +2595,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback, times(numOfReject * 2))
.onMessageSendFail(messageIdCaptorFail.capture(),
- eq(NanStatusType.INTERNAL_FAILURE));
+ eq(NanStatusCode.INTERNAL_FAILURE));
// (4) Transmit messages
int successNum = 0;
@@ -2761,9 +2760,9 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
verify(mockSessionCallback, times(numOfSuccesses)).onMessageSendSuccess(anyInt());
verify(mockSessionCallback, times(numOfFailuresInternalFailure)).onMessageSendFail(anyInt(),
- eq(NanStatusType.INTERNAL_FAILURE));
+ eq(NanStatusCode.INTERNAL_FAILURE));
verify(mockSessionCallback, times(numOfFailuresNoOta)).onMessageSendFail(anyInt(),
- eq(NanStatusType.NO_OTA_ACK));
+ eq(NanStatusCode.NO_OTA_ACK));
verifyNoMoreInteractions(mockCallback, mockSessionCallback);
}
@@ -2924,7 +2923,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
}
if (mFailQueueCommandLater != null && mFailQueueCommandLater.contains(messageId)) {
- mDut.onMessageSendQueuedFailResponse(transactionId, NanStatusType.INTERNAL_FAILURE);
+ mDut.onMessageSendQueuedFailResponse(transactionId, NanStatusCode.INTERNAL_FAILURE);
} else {
if (mQueue.size() <= mMaxQueueDepth) {
mQueue.addLast(transactionId);
@@ -2932,7 +2931,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mDut.onMessageSendQueuedSuccessResponse(transactionId);
} else {
mDut.onMessageSendQueuedFailResponse(transactionId,
- NanStatusType.FOLLOWUP_TX_QUEUE_FULL);
+ NanStatusCode.FOLLOWUP_TX_QUEUE_FULL);
}
}
@@ -2953,7 +2952,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
if (mRetryLimit != null && mRetryLimit.containsKey(mid)) {
int numRetries = mRetryLimit.get(mid);
if (numRetries == -1) {
- mDut.onMessageSendFailNotification(tid, NanStatusType.INTERNAL_FAILURE);
+ mDut.onMessageSendFailNotification(tid, NanStatusCode.INTERNAL_FAILURE);
} else {
int currentRetries = mTriesUsedByMid.get(mid);
if (currentRetries > numRetries) {
@@ -2961,7 +2960,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
} else if (currentRetries == numRetries) {
mDut.onMessageSendSuccessNotification(tid);
} else {
- mDut.onMessageSendFailNotification(tid, NanStatusType.NO_OTA_ACK);
+ mDut.onMessageSendFailNotification(tid, NanStatusCode.NO_OTA_ACK);
}
mTriesUsedByMid.put(mid, currentRetries + 1);
}
@@ -3055,7 +3054,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mDut.connect(clientId2, uid, pid, callingPackage, callingFeature, mockCallback2,
configRequest2, false, mExtras);
mMockLooper.dispatchAll();
- inOrder.verify(mockCallback2).onConnectFail(NanStatusType.INTERNAL_FAILURE);
+ inOrder.verify(mockCallback2).onConnectFail(NanStatusCode.INTERNAL_FAILURE);
validateInternalClientInfoCleanedUp(clientId2);
// (3) config3 (compatible with config1)
@@ -3249,14 +3248,14 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNative).disable(transactionId.capture());
validateInternalClientInfoCleanedUp(clientId);
assertFalse(mDut.isDeviceAttached());
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
verify(mMockNativeManager, times(2)).releaseAware();
// (5) trying to publish on the same client: NOP
mDut.publish(clientId, publishConfig, mockSessionCallback);
mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
// (6) got some callback on original publishId - should be ignored
mDut.onSessionTerminatedNotification(publishId, 0, true);
@@ -3433,10 +3432,10 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
eq(false), eq(true), eq(true), eq(false), eq(false), eq(false), anyInt());
short transactionIdConfig = transactionId.getValue();
- mDut.onConfigFailedResponse(transactionIdConfig, NanStatusType.INTERNAL_FAILURE);
+ mDut.onConfigFailedResponse(transactionIdConfig, NanStatusCode.INTERNAL_FAILURE);
mMockLooper.dispatchAll();
inOrder.verify(mMockNativeManager).releaseAware();
- inOrder.verify(mockCallback).onConnectFail(NanStatusType.INTERNAL_FAILURE);
+ inOrder.verify(mockCallback).onConnectFail(NanStatusCode.INTERNAL_FAILURE);
verifyNoMoreInteractions(mMockNative, mockCallback);
@@ -3491,7 +3490,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (3) update-subscribe -> failure
mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
}
@@ -3547,7 +3546,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
// (3) update-publish -> error
mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusType.INTERNAL_FAILURE);
+ inOrder.verify(mockSessionCallback).onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE);
verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
}
@@ -3722,7 +3721,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
validateCorrectAwareStatusChangeBroadcast(inOrder);
inOrder.verify(mMockNative).disable(transactionId.capture());
assertFalse(mDut.isDeviceAttached());
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
inOrder.verify(mMockNativeManager).releaseAware();
@@ -3795,7 +3794,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockCallback).onAttachTerminate();
validateCorrectAwareStatusChangeBroadcast(inOrder);
inOrder.verify(mMockNative).disable(transactionId.capture());
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
assertFalse(mDut.isDeviceAttached());
collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
@@ -3930,7 +3929,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockCallback).onAttachTerminate();
validateCorrectAwareStatusChangeBroadcast(inOrder);
inOrder.verify(mMockNative).disable(transactionId.capture());
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
inOrder.verify(mMockNativeManager).releaseAware();
assertFalse(mDut.isDeviceAttached());
@@ -3991,7 +3990,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockCallback).onConnectSuccess(clientId);
// (2) Aware down notification from native
- mDut.onAwareDownNotification(NanStatusType.UNSUPPORTED_CONCURRENCY_NAN_DISABLED);
+ mDut.onAwareDownNotification(NanStatusCode.UNSUPPORTED_CONCURRENCY_NAN_DISABLED);
mMockLooper.dispatchAll();
inOrder.verify(mockCallback).onAttachTerminate();
collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
@@ -4026,7 +4025,6 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String callingFeature = "com.google.someFeature";
final String serviceName = "some-service-name";
final String ssi = "some much longer and more arbitrary data";
- final int reasonFail = NanStatusType.INTERNAL_FAILURE;
final byte subscribeId = 15;
final int requestorId = 22;
final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
@@ -4084,7 +4082,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySessionWithRanging(eq(uid), eq(true),
eq(rangeMin), eq(rangeMax), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, false);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, false);
// Verify reconfigure aware to enable ranging.
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
@@ -4227,7 +4225,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mMockAwareDataPathStatemanager).deleteAllInterfaces();
inOrder.verify(mMockNative).disable(transactionId.capture());
assertFalse(mDut.isDeviceAttached());
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
inOrderM.verify(mAwareMetricsMock).recordAttachSessionDuration(anyLong());
inOrderM.verify(mAwareMetricsMock).recordDisableAware();
@@ -4304,7 +4302,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrderM.verify(mAwareMetricsMock).recordDisableAware();
inOrderM.verify(mAwareMetricsMock).recordDisableUsage();
validateInternalClientInfoCleanedUp(clientId);
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
inOrderM.verify(mAwareMetricsMock).recordEnableUsage();
inOrderM.verify(mAwareMetricsMock).recordDisableAware();
@@ -4332,7 +4330,6 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String callingPackage = "com.google.somePackage";
final String callingFeature = "com.google.someFeature";
final byte publishId = 15;
- final int reasonFail = NanStatusType.INTERNAL_FAILURE;
ConfigRequest configRequest = new ConfigRequest.Builder().build();
PublishConfig publishConfig = new PublishConfig.Builder().setRangingEnabled(true).build();
@@ -4374,7 +4371,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySessionWithRanging(eq(uid), eq(false),
eq(-1), eq(-1), any());
- inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusType.SUCCESS, true);
+ inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(uid, NanStatusCode.SUCCESS, true);
mMockLooper.dispatchAll();
// Verify reconfigure aware to enable ranging.
inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
@@ -4384,11 +4381,11 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
mDut.disconnect(clientId);
mMockLooper.dispatchAll();
- inOrder.verify(mockSessionCallback).onSessionTerminated(NanStatusType.SUCCESS);
+ inOrder.verify(mockSessionCallback).onSessionTerminated(NanStatusCode.SUCCESS);
inOrder.verify(mMockNative).stopPublish(anyShort(), eq(publishId));
inOrder.verify(mockCallback).onAttachTerminate();
inOrder.verify(mMockNative).disable(transactionId.capture());
- mDut.onDisableResponse(transactionId.getValue(), NanStatusType.SUCCESS);
+ mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
inOrderM.verify(mAwareMetricsMock).recordAttachSessionDuration(anyLong());
inOrderM.verify(mAwareMetricsMock).recordDiscoverySessionDuration(anyLong(), eq(true));
@@ -4460,7 +4457,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
verify(mMockNative).enableAndConfigure(anyShort(), eq(configRequest), eq(false),
eq(true), eq(true), eq(false), eq(false), eq(false), anyInt());
} else {
- verify(mockCallback).onConnectFail(NanStatusType.NO_RESOURCES_AVAILABLE);
+ verify(mockCallback).onConnectFail(NanStatusCode.NO_RESOURCES_AVAILABLE);
}
}
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
new file mode 100644
index 0000000000..abd1b1cc40
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/HalTestUtils.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.when;
+
+import java.util.function.Supplier;
+
+public class HalTestUtils {
+ /**
+ * Check that we get the expected return value when the specified method is called.
+ *
+ * @param calledMethod Method to call on mDut.
+ * @param mockedMethod Method called by mDut to retrieve the value.
+ * @param value Value that the mockedMethod should return.
+ */
+ public static <T> void verifyReturnValue(Supplier<T> calledMethod, T mockedMethod, T value) {
+ when(mockedMethod).thenReturn(value);
+ T retrievedValue = calledMethod.get();
+ assertEquals(value, retrievedValue);
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiApIfaceTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiApIfaceTest.java
new file mode 100644
index 0000000000..d4f9c3aec4
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiApIfaceTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+
+import static org.mockito.ArgumentMatchers.any;
+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.MacAddress;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class WifiApIfaceTest {
+ // HAL mocks
+ @Mock android.hardware.wifi.V1_0.IWifiApIface mIWifiApIfaceHidlMock;
+ @Mock android.hardware.wifi.IWifiApIface mIWifiApIfaceAidlMock;
+
+ // Framework HIDL/AIDL implementation mocks
+ @Mock WifiApIfaceHidlImpl mWifiApIfaceHidlImplMock;
+ @Mock WifiApIfaceAidlImpl mWifiApIfaceAidlImplMock;
+
+ private WifiApIface mDut;
+
+ private class WifiApIfaceSpy extends WifiApIface {
+ WifiApIfaceSpy(android.hardware.wifi.V1_0.IWifiApIface apIface) {
+ super(apIface);
+ }
+
+ WifiApIfaceSpy(android.hardware.wifi.IWifiApIface apIface) {
+ super(apIface);
+ }
+
+ @Override
+ protected WifiApIfaceHidlImpl createWifiApIfaceHidlImplMockable(
+ android.hardware.wifi.V1_0.IWifiApIface apIface) {
+ return mWifiApIfaceHidlImplMock;
+ }
+
+ @Override
+ protected WifiApIfaceAidlImpl createWifiApIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiApIface apIface) {
+ return mWifiApIfaceAidlImplMock;
+ }
+ }
+
+ private class NullWifiApIfaceSpy extends WifiApIface {
+ NullWifiApIfaceSpy() {
+ super(mIWifiApIfaceAidlMock);
+ }
+
+ @Override
+ protected WifiApIfaceAidlImpl createWifiApIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiApIface apIface) {
+ return null;
+ }
+ }
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mDut = new WifiApIfaceSpy(mIWifiApIfaceAidlMock);
+ }
+
+ /**
+ * Test that we can initialize using the HIDL implementation.
+ */
+ @Test
+ public void testInitWithHidlImpl() {
+ mDut = new WifiApIfaceSpy(mIWifiApIfaceHidlMock);
+ mDut.getName();
+ verify(mWifiApIfaceHidlImplMock).getName();
+ verify(mWifiApIfaceAidlImplMock, never()).getName();
+ }
+
+ /**
+ * Test the case where the creation of the xIDL implementation
+ * fails, so mWifiApIface is null.
+ */
+ @Test
+ public void testInitFailureCase() {
+ mDut = new NullWifiApIfaceSpy();
+ assertNull(mDut.getName());
+ verify(mWifiApIfaceHidlImplMock, never()).getName();
+ verify(mWifiApIfaceAidlImplMock, never()).getName();
+ }
+
+ @Test
+ public void testGetName() {
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.getName(),
+ mWifiApIfaceAidlImplMock.getName(),
+ "wlan0");
+ verify(mWifiApIfaceAidlImplMock).getName();
+ }
+
+ @Test
+ public void testSetCountryCode() {
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.setCountryCode("MX"),
+ mWifiApIfaceAidlImplMock.setCountryCode(any()),
+ true);
+ verify(mWifiApIfaceAidlImplMock).setCountryCode(any());
+ }
+
+ /**
+ * Test that setCountryCode rejects invalid country codes.
+ */
+ @Test
+ public void testSetCountryCodeInvalidInput() {
+ when(mWifiApIfaceAidlImplMock.setCountryCode(any())).thenReturn(true);
+ assertFalse(mDut.setCountryCode(null));
+ assertFalse(mDut.setCountryCode(""));
+ assertFalse(mDut.setCountryCode("A"));
+ assertFalse(mDut.setCountryCode("ABC"));
+ verify(mWifiApIfaceAidlImplMock, never()).setCountryCode(any());
+ }
+
+ @Test
+ public void testSetMacAddress() {
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.setMacAddress(mock(MacAddress.class)),
+ mWifiApIfaceAidlImplMock.setMacAddress(any()),
+ true);
+ verify(mWifiApIfaceAidlImplMock).setMacAddress(any());
+ }
+
+ /**
+ * Test that setMacAddress rejects a null MacAddress.
+ */
+ @Test
+ public void testSetMacAddressInvalidInput() {
+ when(mWifiApIfaceAidlImplMock.setMacAddress(any())).thenReturn(true);
+ assertFalse(mDut.setMacAddress(null));
+ verify(mWifiApIfaceAidlImplMock, never()).setMacAddress(any());
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipTest.java
new file mode 100644
index 0000000000..7d9eb3e943
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static junit.framework.Assert.assertFalse;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.content.Context;
+
+import com.android.server.wifi.SsidTranslator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class WifiChipTest {
+ // HAL mocks
+ @Mock android.hardware.wifi.V1_0.IWifiChip mIWifiChipHidlMock;
+ @Mock android.hardware.wifi.IWifiChip mIWifiChipAidlMock;
+
+ // Framework HIDL/AIDL implementation mocks
+ @Mock WifiChipHidlImpl mWifiChipHidlImplMock;
+ @Mock WifiChipAidlImpl mWifiChipAidlImplMock;
+
+ @Mock Context mContextMock;
+ @Mock SsidTranslator mSsidTranslatorMock;
+
+ private WifiChip mDut;
+
+ private class WifiChipSpy extends WifiChip {
+ WifiChipSpy(android.hardware.wifi.V1_0.IWifiChip chip) {
+ super(chip, mContextMock, mSsidTranslatorMock);
+ }
+
+ WifiChipSpy(android.hardware.wifi.IWifiChip chip) {
+ super(chip, mContextMock, mSsidTranslatorMock);
+ }
+
+ @Override
+ protected WifiChipHidlImpl createWifiChipHidlImplMockable(
+ @NonNull android.hardware.wifi.V1_0.IWifiChip chip,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ return mWifiChipHidlImplMock;
+ }
+
+ @Override
+ protected WifiChipAidlImpl createWifiChipAidlImplMockable(
+ @NonNull android.hardware.wifi.IWifiChip chip,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ return mWifiChipAidlImplMock;
+ }
+ }
+
+ private class NullWifiChipSpy extends WifiChip {
+ NullWifiChipSpy() {
+ super(mIWifiChipAidlMock, mContextMock, mSsidTranslatorMock);
+ }
+
+ @Override
+ protected WifiChipAidlImpl createWifiChipAidlImplMockable(
+ @NonNull android.hardware.wifi.IWifiChip chip,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ return null;
+ }
+ }
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mDut = new WifiChipSpy(mIWifiChipAidlMock);
+ }
+
+ /**
+ * Test that we can initialize using the HIDL implementation.
+ */
+ @Test
+ public void testInitWithHidlImpl() {
+ mDut = new WifiChipSpy(mIWifiChipHidlMock);
+ mDut.configureChip(1);
+ verify(mWifiChipHidlImplMock).configureChip(eq(1));
+ verify(mWifiChipAidlImplMock, never()).configureChip(anyInt());
+ }
+
+ /**
+ * Test the case where the creation of the xIDL implementation
+ * fails, so mWifiChip is null.
+ */
+ @Test
+ public void testInitFailureCase() {
+ mDut = new NullWifiChipSpy();
+ assertFalse(mDut.configureChip(1));
+ verify(mWifiChipHidlImplMock, never()).configureChip(anyInt());
+ verify(mWifiChipAidlImplMock, never()).configureChip(anyInt());
+ }
+
+ @Test
+ public void testConfigureChip() {
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.configureChip(1),
+ mWifiChipAidlImplMock.configureChip(anyInt()),
+ true);
+ verify(mWifiChipAidlImplMock).configureChip(eq(1));
+ }
+
+ @Test
+ public void testSetCountryCode() {
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.setCountryCode("MX"),
+ mWifiChipAidlImplMock.setCountryCode(any()),
+ true);
+ verify(mWifiChipAidlImplMock).setCountryCode(any());
+ }
+
+ /**
+ * Test that setCountryCode rejects invalid country codes.
+ */
+ @Test
+ public void testSetCountryCodeInvalidInput() {
+ when(mWifiChipAidlImplMock.setCountryCode(any())).thenReturn(true);
+ assertFalse(mDut.setCountryCode(null));
+ assertFalse(mDut.setCountryCode(""));
+ assertFalse(mDut.setCountryCode("A"));
+ assertFalse(mDut.setCountryCode("ABC"));
+ verify(mWifiChipAidlImplMock, never()).setCountryCode(any());
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiHalTest.java
new file mode 100644
index 0000000000..71ef5f3b7f
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiHalTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static junit.framework.Assert.assertNull;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.annotation.NonNull;
+import android.content.Context;
+
+import com.android.server.wifi.SsidTranslator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class WifiHalTest {
+ // Framework HIDL/AIDL implementation mocks
+ @Mock WifiHalHidlImpl mWifiHalHidlImplMock;
+ @Mock WifiHalAidlImpl mWifiHalAidlImplMock;
+
+ @Mock Context mContextMock;
+ @Mock SsidTranslator mSsidTranslatorMock;
+
+ private WifiHal mDut;
+
+ private class WifiHalAidlSpy extends WifiHal {
+ WifiHalAidlSpy() {
+ super(mContextMock, mSsidTranslatorMock);
+ }
+
+ @Override
+ protected IWifiHal createWifiHalMockable(@NonNull Context context,
+ @NonNull SsidTranslator ssidTranslator) {
+ return mWifiHalAidlImplMock;
+ }
+ }
+
+ private class WifiHalHidlSpy extends WifiHal {
+ WifiHalHidlSpy() {
+ super(mContextMock, mSsidTranslatorMock);
+ }
+
+ @Override
+ protected IWifiHal createWifiHalMockable(@NonNull Context context,
+ @NonNull SsidTranslator ssidTranslator) {
+ return mWifiHalHidlImplMock;
+ }
+ }
+
+ private class WifiHalNullSpy extends WifiHal {
+ WifiHalNullSpy() {
+ super(mContextMock, mSsidTranslatorMock);
+ }
+
+ @Override
+ protected IWifiHal createWifiHalMockable(@NonNull Context context,
+ @NonNull SsidTranslator ssidTranslator) {
+ return null;
+ }
+ }
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ /**
+ * Test that we can initialize using the HIDL implementation.
+ */
+ @Test
+ public void testInitWithHidlImpl() {
+ mDut = new WifiHalHidlSpy();
+ mDut.getChip(1);
+ verify(mWifiHalHidlImplMock).getChip(eq(1));
+ verify(mWifiHalAidlImplMock, never()).getChip(anyInt());
+ }
+
+ /**
+ * Test the case where the creation of the xIDL implementation
+ * fails, so mWifi is null.
+ */
+ @Test
+ public void testInitFailureCase() {
+ mDut = new WifiHalNullSpy();
+ assertNull(mDut.getChip(1));
+ verify(mWifiHalHidlImplMock, never()).getChip(anyInt());
+ verify(mWifiHalAidlImplMock, never()).getChip(anyInt());
+ }
+
+ @Test
+ public void testGetChip() {
+ mDut = new WifiHalAidlSpy();
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.getChip(1),
+ mWifiHalAidlImplMock.getChip(anyInt()),
+ mock(WifiChip.class));
+ verify(mWifiHalAidlImplMock).getChip(eq(1));
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceHidlImplTest.java
new file mode 100644
index 0000000000..5757cdfcb9
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceHidlImplTest.java
@@ -0,0 +1,756 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static android.hardware.wifi.V1_0.NanCipherSuiteType.SHARED_KEY_128_MASK;
+import static android.hardware.wifi.V1_0.NanCipherSuiteType.SHARED_KEY_256_MASK;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.wifi.V1_0.IWifiNanIface;
+import android.hardware.wifi.V1_0.NanBandIndex;
+import android.hardware.wifi.V1_0.NanConfigRequest;
+import android.hardware.wifi.V1_0.NanDataPathSecurityType;
+import android.hardware.wifi.V1_0.NanEnableRequest;
+import android.hardware.wifi.V1_0.NanPublishRequest;
+import android.hardware.wifi.V1_0.NanRangingIndication;
+import android.hardware.wifi.V1_0.NanSubscribeRequest;
+import android.hardware.wifi.V1_0.WifiStatus;
+import android.hardware.wifi.V1_0.WifiStatusCode;
+import android.hardware.wifi.V1_2.NanConfigRequestSupplemental;
+import android.net.MacAddress;
+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.RemoteException;
+import android.util.Pair;
+
+import com.android.server.wifi.aware.Capabilities;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ErrorCollector;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+public class WifiNanIfaceHidlImplTest {
+ @Mock IWifiNanIface mIWifiNanIface;
+ @Mock android.hardware.wifi.V1_2.IWifiNanIface mIWifiNanIface12Mock;
+
+ @Rule public ErrorCollector collector = new ErrorCollector();
+
+ private class MockableWifiNanIface extends WifiNanIfaceHidlImpl {
+ MockableWifiNanIface(IWifiNanIface wifiNanIface) {
+ super(wifiNanIface);
+ }
+
+ @Override
+ public android.hardware.wifi.V1_2.IWifiNanIface mockableCastTo_1_2() {
+ return mIsInterface12 ? mIWifiNanIface12Mock : null;
+ }
+ }
+
+ private boolean mIsInterface12;
+ private MockableWifiNanIface mDut;
+ private static final Capabilities CAP = new Capabilities();
+
+ /**
+ * Initializes mocks.
+ */
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ WifiStatus status = new WifiStatus();
+ status.code = WifiStatusCode.SUCCESS;
+ when(mIWifiNanIface.enableRequest(anyShort(), any())).thenReturn(status);
+ when(mIWifiNanIface.configRequest(anyShort(), any())).thenReturn(status);
+ when(mIWifiNanIface.startPublishRequest(anyShort(), any())).thenReturn(status);
+ when(mIWifiNanIface.startSubscribeRequest(anyShort(), any())).thenReturn(status);
+ when(mIWifiNanIface.initiateDataPathRequest(anyShort(), any())).thenReturn(status);
+ when(mIWifiNanIface.respondToDataPathIndicationRequest(anyShort(), any())).thenReturn(
+ status);
+ when(mIWifiNanIface12Mock.enableRequest_1_2(anyShort(), any(), any())).thenReturn(status);
+ when(mIWifiNanIface12Mock.configRequest_1_2(anyShort(), any(), any())).thenReturn(status);
+ when(mIWifiNanIface12Mock.startPublishRequest(anyShort(), any())).thenReturn(status);
+ when(mIWifiNanIface12Mock.startSubscribeRequest(anyShort(), any())).thenReturn(status);
+
+ mIsInterface12 = false;
+
+ mDut = new MockableWifiNanIface(mIWifiNanIface);
+ CAP.supportedCipherSuites = WIFI_AWARE_CIPHER_SUITE_NCS_SK_128
+ | WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
+ }
+
+ @Test
+ public void testDiscoveryRangingSettings() throws RemoteException {
+ short tid = 250;
+ byte pid = 34;
+ int minDistanceMm = 100;
+ int maxDistanceMm = 555;
+ short minDistanceCm = (short) (minDistanceMm / 10);
+ short maxDistanceCm = (short) (maxDistanceMm / 10);
+
+ ArgumentCaptor<NanPublishRequest> pubCaptor = ArgumentCaptor.forClass(
+ NanPublishRequest.class);
+ ArgumentCaptor<NanSubscribeRequest> subCaptor = ArgumentCaptor.forClass(
+ NanSubscribeRequest.class);
+
+ PublishConfig pubDefault = new PublishConfig.Builder().setServiceName("XXX").build();
+ PublishConfig pubWithRanging = new PublishConfig.Builder().setServiceName(
+ "XXX").setRangingEnabled(true).build();
+ SubscribeConfig subDefault = new SubscribeConfig.Builder().setServiceName("XXX").build();
+ SubscribeConfig subWithMin = new SubscribeConfig.Builder().setServiceName(
+ "XXX").setMinDistanceMm(minDistanceMm).build();
+ SubscribeConfig subWithMax = new SubscribeConfig.Builder().setServiceName(
+ "XXX").setMaxDistanceMm(maxDistanceMm).build();
+ SubscribeConfig subWithMinMax = new SubscribeConfig.Builder().setServiceName(
+ "XXX").setMinDistanceMm(minDistanceMm).setMaxDistanceMm(maxDistanceMm).build();
+
+ mDut.publish(tid, pid, pubDefault);
+ mDut.publish(tid, pid, pubWithRanging);
+ mDut.subscribe(tid, pid, subDefault);
+ mDut.subscribe(tid, pid, subWithMin);
+ mDut.subscribe(tid, pid, subWithMax);
+ mDut.subscribe(tid, pid, subWithMinMax);
+
+ verify(mIWifiNanIface, times(2)).startPublishRequest(eq(tid), pubCaptor.capture());
+ verify(mIWifiNanIface, times(4)).startSubscribeRequest(eq(tid), subCaptor.capture());
+
+ NanPublishRequest halPubReq;
+ NanSubscribeRequest halSubReq;
+
+ // pubDefault
+ halPubReq = pubCaptor.getAllValues().get(0);
+ collector.checkThat("pubDefault.baseConfigs.sessionId", pid,
+ equalTo(halPubReq.baseConfigs.sessionId));
+ collector.checkThat("pubDefault.baseConfigs.rangingRequired", false,
+ equalTo(halPubReq.baseConfigs.rangingRequired));
+
+ // pubWithRanging
+ halPubReq = pubCaptor.getAllValues().get(1);
+ collector.checkThat("pubWithRanging.baseConfigs.sessionId", pid,
+ equalTo(halPubReq.baseConfigs.sessionId));
+ collector.checkThat("pubWithRanging.baseConfigs.rangingRequired", true,
+ equalTo(halPubReq.baseConfigs.rangingRequired));
+
+ // subDefault
+ halSubReq = subCaptor.getAllValues().get(0);
+ collector.checkThat("subDefault.baseConfigs.sessionId", pid,
+ equalTo(halSubReq.baseConfigs.sessionId));
+ collector.checkThat("subDefault.baseConfigs.rangingRequired", false,
+ equalTo(halSubReq.baseConfigs.rangingRequired));
+
+ // subWithMin
+ halSubReq = subCaptor.getAllValues().get(1);
+ collector.checkThat("subWithMin.baseConfigs.sessionId", pid,
+ equalTo(halSubReq.baseConfigs.sessionId));
+ collector.checkThat("subWithMin.baseConfigs.rangingRequired", true,
+ equalTo(halSubReq.baseConfigs.rangingRequired));
+ collector.checkThat("subWithMin.baseConfigs.configRangingIndications",
+ NanRangingIndication.EGRESS_MET_MASK,
+ equalTo(halSubReq.baseConfigs.configRangingIndications));
+ collector.checkThat("subWithMin.baseConfigs.distanceEgressCm", minDistanceCm,
+ equalTo(halSubReq.baseConfigs.distanceEgressCm));
+
+ // subWithMax
+ halSubReq = subCaptor.getAllValues().get(2);
+ collector.checkThat("subWithMax.baseConfigs.sessionId", pid,
+ equalTo(halSubReq.baseConfigs.sessionId));
+ collector.checkThat("subWithMax.baseConfigs.rangingRequired", true,
+ equalTo(halSubReq.baseConfigs.rangingRequired));
+ collector.checkThat("subWithMax.baseConfigs.configRangingIndications",
+ NanRangingIndication.INGRESS_MET_MASK,
+ equalTo(halSubReq.baseConfigs.configRangingIndications));
+ collector.checkThat("subWithMin.baseConfigs.distanceIngressCm", maxDistanceCm,
+ equalTo(halSubReq.baseConfigs.distanceIngressCm));
+
+ // subWithMinMax
+ halSubReq = subCaptor.getAllValues().get(3);
+ collector.checkThat("subWithMinMax.baseConfigs.sessionId", pid,
+ equalTo(halSubReq.baseConfigs.sessionId));
+ collector.checkThat("subWithMinMax.baseConfigs.rangingRequired", true,
+ equalTo(halSubReq.baseConfigs.rangingRequired));
+ collector.checkThat("subWithMinMax.baseConfigs.configRangingIndications",
+ NanRangingIndication.INGRESS_MET_MASK | NanRangingIndication.EGRESS_MET_MASK,
+ equalTo(halSubReq.baseConfigs.configRangingIndications));
+ collector.checkThat("subWithMin.baseConfigs.distanceEgressCm", minDistanceCm,
+ equalTo(halSubReq.baseConfigs.distanceEgressCm));
+ collector.checkThat("subWithMin.baseConfigs.distanceIngressCm", maxDistanceCm,
+ equalTo(halSubReq.baseConfigs.distanceIngressCm));
+ }
+
+ /**
+ * Validate that the configuration parameters used to manage power state behavior are
+ * using default values at the default power state.
+ */
+ @Test
+ public void testEnableAndConfigPowerSettingsDefaults() throws RemoteException {
+ byte default24 = 1;
+ byte default5 = 1;
+
+ Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
+ validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), true,
+ true, true, false, default24, default5, false);
+
+ collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("validDiscoveryWindowIntervalVal-24", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-5", default5,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-24", default24,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .discoveryWindowIntervalVal));
+ }
+
+ /**
+ * Validate that the configuration parameters used to manage power state behavior are
+ * using the specified non-interactive values when in that power state.
+ */
+ @Test
+ public void testEnableAndConfigPowerSettingsNoneInteractive() throws RemoteException {
+ byte interactive24 = 3;
+ byte interactive5 = 2;
+
+ Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
+ validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), false,
+ false, false, false, interactive24, interactive5, false);
+
+ collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-5", interactive5,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal));
+ collector.checkThat("validDiscoveryWindowIntervalVal-24", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-24", interactive24,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .discoveryWindowIntervalVal));
+ }
+
+ /**
+ * Validate that the configuration parameters used to manage power state behavior are
+ * using the specified idle (doze) values when in that power state.
+ */
+ @Test
+ public void testEnableAndConfigPowerSettingsIdle() throws RemoteException {
+ byte idle24 = -1;
+ byte idle5 = 2;
+
+ Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
+ validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), false,
+ true, false, true, idle24, idle5, false);
+
+ collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-5", idle5,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal));
+ collector.checkThat("validDiscoveryWindowIntervalVal-24", false,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal));
+ }
+
+ /**
+ * Validate that the configuration parameters used to manage power state behavior are
+ * using default values at the default power state.
+ *
+ * Using HAL 1.2: additional power configurations.
+ */
+ @Test
+ public void testEnableAndConfigPowerSettingsDefaults_1_2() throws RemoteException {
+ byte default24 = 1;
+ byte default5 = 1;
+
+ Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
+ validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), true,
+ true, true, false, default24, default5, true);
+
+ collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("validDiscoveryWindowIntervalVal-24", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-5", default5,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-24", default24,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .discoveryWindowIntervalVal));
+
+ collector.checkThat("discoveryBeaconIntervalMs", 0,
+ equalTo(configs.second.discoveryBeaconIntervalMs));
+ collector.checkThat("numberOfSpatialStreamsInDiscovery", 0,
+ equalTo(configs.second.numberOfSpatialStreamsInDiscovery));
+ collector.checkThat("enableDiscoveryWindowEarlyTermination", false,
+ equalTo(configs.second.enableDiscoveryWindowEarlyTermination));
+ }
+
+ /**
+ * Validate that the configuration parameters used to manage power state behavior are
+ * using the specified non-interactive values when in that power state.
+ *
+ * Using HAL 1.2: additional power configurations.
+ */
+ @Test
+ public void testEnableAndConfigPowerSettingsNoneInteractive_1_2() throws RemoteException {
+ byte interactive24 = 3;
+ byte interactive5 = 2;
+
+ Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
+ validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), false,
+ false, false, false, interactive24, interactive5, true);
+
+ collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-5", interactive5,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal));
+ collector.checkThat("validDiscoveryWindowIntervalVal-24", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-24", interactive24,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .discoveryWindowIntervalVal));
+
+ // Note: still defaults (i.e. disabled) - will be tweaked for low power
+ collector.checkThat("discoveryBeaconIntervalMs", 0,
+ equalTo(configs.second.discoveryBeaconIntervalMs));
+ collector.checkThat("numberOfSpatialStreamsInDiscovery", 0,
+ equalTo(configs.second.numberOfSpatialStreamsInDiscovery));
+ collector.checkThat("enableDiscoveryWindowEarlyTermination", false,
+ equalTo(configs.second.enableDiscoveryWindowEarlyTermination));
+ }
+
+ /**
+ * Validate that the configuration parameters used to manage power state behavior are
+ * using the specified idle (doze) values when in that power state.
+ *
+ * Using HAL 1.2: additional power configurations.
+ */
+ @Test
+ public void testEnableAndConfigPowerSettingsIdle_1_2() throws RemoteException {
+ byte idle24 = -1;
+ byte idle5 = 2;
+
+ Pair<NanConfigRequest, NanConfigRequestSupplemental> configs =
+ validateEnableAndConfigure((short) 10, new ConfigRequest.Builder().build(), false,
+ true, false, true, idle24, idle5, true);
+
+ collector.checkThat("validDiscoveryWindowIntervalVal-5", true,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal));
+ collector.checkThat("discoveryWindowIntervalVal-5", idle5,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal));
+ collector.checkThat("validDiscoveryWindowIntervalVal-24", false,
+ equalTo(configs.first.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal));
+
+ // Note: still defaults (i.e. disabled) - will be tweaked for low power
+ collector.checkThat("discoveryBeaconIntervalMs", 0,
+ equalTo(configs.second.discoveryBeaconIntervalMs));
+ collector.checkThat("numberOfSpatialStreamsInDiscovery", 0,
+ equalTo(configs.second.numberOfSpatialStreamsInDiscovery));
+ collector.checkThat("enableDiscoveryWindowEarlyTermination", false,
+ equalTo(configs.second.enableDiscoveryWindowEarlyTermination));
+ }
+
+ /**
+ * Validate the initiation of NDP for an open link.
+ */
+ @Test
+ public void testInitiateDataPathOpen() throws Exception {
+ validateInitiateDataPath(
+ /* usePmk */ false,
+ /* usePassphrase */ false,
+ /* isOutOfBand */ false,
+ /* publicCipherSuites */ 0,
+ /* halCipherSuite */ 0);
+ }
+
+ /**
+ * Validate the initiation of NDP for an PMK protected link with in-band discovery.
+ */
+ @Test
+ public void testInitiateDataPathPmkInBand() throws Exception {
+ validateInitiateDataPath(
+ /* usePmk */ true,
+ /* usePassphrase */ false,
+ /* isOutOfBand */ false,
+ /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
+ /* halCipherSuite */ SHARED_KEY_256_MASK);
+
+ }
+
+ /**
+ * Validate the initiation of NDP for an Passphrase protected link with in-band discovery.
+ */
+ @Test
+ public void testInitiateDataPathPassphraseInBand() throws Exception {
+ validateInitiateDataPath(
+ /* usePmk */ false,
+ /* usePassphrase */ true,
+ /* isOutOfBand */ false,
+ /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
+ /* halCipherSuite */ SHARED_KEY_128_MASK);
+ }
+
+ /**
+ * Validate the initiation of NDP for an PMK protected link with out-of-band discovery.
+ */
+ @Test
+ public void testInitiateDataPathPmkOutOfBand() throws Exception {
+ validateInitiateDataPath(
+ /* usePmk */ true,
+ /* usePassphrase */ false,
+ /* isOutOfBand */ true,
+ /* supportedCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
+ /* expectedCipherSuite */ SHARED_KEY_128_MASK);
+ }
+
+ /**
+ * Validate the response to an NDP request for an open link.
+ */
+ @Test
+ public void testRespondToDataPathRequestOpenInBand() throws Exception {
+ validateRespondToDataPathRequest(
+ /* usePmk */ false,
+ /* usePassphrase */ false,
+ /* accept */ true,
+ /* isOutOfBand */ false,
+ /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
+ /* halCipherSuite */ SHARED_KEY_256_MASK);
+ }
+
+ /**
+ * Validate the response to an NDP request for a PMK-protected link with in-band discovery.
+ */
+ @Test
+ public void testRespondToDataPathRequestPmkInBand() throws Exception {
+ validateRespondToDataPathRequest(
+ /* usePmk */ true,
+ /* usePassphrase */ false,
+ /* accept */ true,
+ /* isOutOfBand */ false,
+ /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
+ /* halCipherSuite */ SHARED_KEY_128_MASK);
+ }
+
+ /**
+ * Validate the response to an NDP request for a Passphrase-protected link with in-band
+ * discovery.
+ */
+ @Test
+ public void testRespondToDataPathRequestPassphraseInBand() throws Exception {
+ validateRespondToDataPathRequest(
+ /* usePmk */ false,
+ /* usePassphrase */ true,
+ /* accept */ true,
+ /* isOutOfBand */ false,
+ /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_256,
+ /* halCipherSuite */ SHARED_KEY_256_MASK);
+ }
+
+ /**
+ * Validate the response to an NDP request for a PMK-protected link with out-of-band discovery.
+ */
+ @Test
+ public void testRespondToDataPathRequestPmkOutOfBand() throws Exception {
+ validateRespondToDataPathRequest(
+ /* usePmk */ true,
+ /* usePassphrase */ false,
+ /* accept */ true,
+ /* isOutOfBand */ true,
+ /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
+ /* halCipherSuite */ SHARED_KEY_128_MASK);
+ }
+
+ /**
+ * Validate the response to an NDP request - when request is rejected.
+ */
+ @Test
+ public void testRespondToDataPathRequestReject() throws Exception {
+ validateRespondToDataPathRequest(
+ /* usePmk */ true,
+ /* usePassphrase */ false,
+ /* accept */ false,
+ /* isOutOfBand */ true,
+ /* publicCipherSuites */ WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
+ /* halCipherSuite */ 0);
+ }
+
+
+ // utilities
+
+ private Pair<NanConfigRequest, NanConfigRequestSupplemental> validateEnableAndConfigure(
+ short transactionId, ConfigRequest configRequest, boolean notifyIdentityChange,
+ boolean initialConfiguration, boolean isInteractive, boolean isIdle,
+ int discoveryWindow24Ghz, int discoveryWindow5Ghz, boolean isHal12)
+ throws RemoteException {
+ mIsInterface12 = isHal12;
+
+ mDut.enableAndConfigure(transactionId, configRequest, notifyIdentityChange,
+ initialConfiguration, false, false, 2437,
+ 1800 /* PARAM_MAC_RANDOM_INTERVAL_SEC_DEFAULT */,
+ getPowerParams(isInteractive, isIdle, discoveryWindow24Ghz, discoveryWindow5Ghz));
+
+ ArgumentCaptor<NanEnableRequest> enableReqCaptor = ArgumentCaptor.forClass(
+ NanEnableRequest.class);
+ ArgumentCaptor<NanConfigRequest> configReqCaptor = ArgumentCaptor.forClass(
+ NanConfigRequest.class);
+ ArgumentCaptor<NanConfigRequestSupplemental> configSuppCaptor = ArgumentCaptor.forClass(
+ NanConfigRequestSupplemental.class);
+ NanConfigRequest config;
+ NanConfigRequestSupplemental configSupp = null;
+
+ if (initialConfiguration) {
+ if (isHal12) {
+ verify(mIWifiNanIface12Mock).enableRequest_1_2(eq(transactionId),
+ enableReqCaptor.capture(), configSuppCaptor.capture());
+ configSupp = configSuppCaptor.getValue();
+ } else {
+ verify(mIWifiNanIface).enableRequest(eq(transactionId),
+ enableReqCaptor.capture());
+ }
+ config = enableReqCaptor.getValue().configParams;
+ } else {
+ if (isHal12) {
+ verify(mIWifiNanIface12Mock).configRequest_1_2(eq(transactionId),
+ configReqCaptor.capture(), configSuppCaptor.capture());
+ configSupp = configSuppCaptor.getValue();
+ } else {
+ verify(mIWifiNanIface).configRequest(eq(transactionId),
+ configReqCaptor.capture());
+ }
+ config = configReqCaptor.getValue();
+ }
+
+ collector.checkThat("disableDiscoveryAddressChangeIndication", !notifyIdentityChange,
+ equalTo(config.disableDiscoveryAddressChangeIndication));
+ collector.checkThat("disableStartedClusterIndication", !notifyIdentityChange,
+ equalTo(config.disableStartedClusterIndication));
+ collector.checkThat("disableJoinedClusterIndication", !notifyIdentityChange,
+ equalTo(config.disableJoinedClusterIndication));
+
+ return new Pair<>(config, configSupp);
+ }
+
+ private WifiNanIface.PowerParameters getPowerParams(boolean isInteractive, boolean isIdle,
+ int discoveryWindow24Ghz, int discoveryWindow5Ghz) {
+ WifiNanIface.PowerParameters params = new WifiNanIface.PowerParameters();
+ params.discoveryBeaconIntervalMs = 0; // PARAM_DISCOVERY_BEACON_INTERVAL_MS_DEFAULT
+ params.enableDiscoveryWindowEarlyTermination = false; // PARAM_ENABLE_DW_EARLY_TERM_DEFAULT
+ params.numberOfSpatialStreamsInDiscovery = 0; // PARAM_NUM_SS_IN_DISCOVERY_DEFAULT
+ if (isInteractive && !isIdle) {
+ params.discoveryWindow24Ghz = 1; // PARAM_DW_24GHZ_DEFAULT
+ params.discoveryWindow5Ghz = 1; // PARAM_DW_5GHZ_DEFAULT
+ params.discoveryWindow6Ghz = 1; // PARAM_DW_6GHZ_DEFAULT
+ } else {
+ params.discoveryWindow24Ghz = discoveryWindow24Ghz;
+ params.discoveryWindow5Ghz = discoveryWindow5Ghz;
+ params.discoveryWindow6Ghz = 0;
+ }
+ return params;
+ }
+
+ private void validateInitiateDataPath(boolean usePmk, boolean usePassphrase,
+ boolean isOutOfBand, int publicCipherSuites, int halCipherSuite)
+ throws Exception {
+ short tid = 44;
+ int peerId = 555;
+ int channelRequestType =
+ android.hardware.wifi.V1_0.NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED;
+ int channel = 2146;
+ MacAddress peer = MacAddress.fromString("00:01:02:03:04:05");
+ String interfaceName = "aware_data5";
+ final byte[] pmk = "01234567890123456789012345678901".getBytes();
+ String passphrase = "blahblah";
+ final byte[] appInfo = "Out-of-band info".getBytes();
+
+ ArgumentCaptor<android.hardware.wifi.V1_0.NanInitiateDataPathRequest> captor =
+ ArgumentCaptor.forClass(
+ android.hardware.wifi.V1_0.NanInitiateDataPathRequest.class);
+ WifiAwareDataPathSecurityConfig securityConfig = null;
+ if (usePassphrase) {
+ securityConfig = new WifiAwareDataPathSecurityConfig
+ .Builder(publicCipherSuites)
+ .setPskPassphrase(passphrase)
+ .build();
+ } else if (usePmk) {
+ securityConfig = new WifiAwareDataPathSecurityConfig
+ .Builder(publicCipherSuites)
+ .setPmk(pmk)
+ .build();
+ }
+
+ mDut.initiateDataPath(tid, peerId, channelRequestType, channel, peer, interfaceName,
+ isOutOfBand, appInfo, CAP, securityConfig);
+
+ verify(mIWifiNanIface).initiateDataPathRequest(eq(tid), captor.capture());
+
+ android.hardware.wifi.V1_0.NanInitiateDataPathRequest nidpr = captor.getValue();
+ collector.checkThat("peerId", peerId, equalTo(nidpr.peerId));
+ collector.checkThat("peerDiscMacAddr", peer.toByteArray(),
+ equalTo(nidpr.peerDiscMacAddr));
+ collector.checkThat("channelRequestType", channelRequestType,
+ equalTo(nidpr.channelRequestType));
+ collector.checkThat("channel", channel, equalTo(nidpr.channel));
+ collector.checkThat("ifaceName", interfaceName, equalTo(nidpr.ifaceName));
+
+ if (usePmk) {
+ collector.checkThat("securityConfig.securityType",
+ NanDataPathSecurityType.PMK,
+ equalTo(nidpr.securityConfig.securityType));
+ collector.checkThat("securityConfig.cipherType", halCipherSuite,
+ equalTo(nidpr.securityConfig.cipherType));
+ collector.checkThat("securityConfig.pmk", pmk, equalTo(nidpr.securityConfig.pmk));
+ collector.checkThat("securityConfig.passphrase.length", 0,
+ equalTo(nidpr.securityConfig.passphrase.size()));
+ }
+
+ if (usePassphrase) {
+ collector.checkThat("securityConfig.securityType",
+ NanDataPathSecurityType.PASSPHRASE,
+ equalTo(nidpr.securityConfig.securityType));
+ collector.checkThat("securityConfig.cipherType", halCipherSuite,
+ equalTo(nidpr.securityConfig.cipherType));
+ collector.checkThat("securityConfig.passphrase", passphrase.getBytes(),
+ equalTo(convertArrayListToNativeByteArray(nidpr.securityConfig.passphrase)));
+ }
+
+ collector.checkThat("appInfo", appInfo,
+ equalTo(convertArrayListToNativeByteArray(nidpr.appInfo)));
+
+ if ((usePmk || usePassphrase) && isOutOfBand) {
+ collector.checkThat("serviceNameOutOfBand",
+ WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(),
+ equalTo(convertArrayListToNativeByteArray(nidpr.serviceNameOutOfBand)));
+ } else {
+ collector.checkThat("serviceNameOutOfBand.length", 0,
+ equalTo(nidpr.serviceNameOutOfBand.size()));
+ }
+ }
+
+ private void validateRespondToDataPathRequest(boolean usePmk, boolean usePassphrase,
+ boolean accept, boolean isOutOfBand, int publicCipherSuites, int halCipherSuite)
+ throws Exception {
+ short tid = 33;
+ int ndpId = 44;
+ String interfaceName = "aware_whatever22";
+ final byte[] pmk = "01234567890123456789012345678901".getBytes();
+ String passphrase = "blahblah";
+ final byte[] appInfo = "Out-of-band info".getBytes();
+
+ ArgumentCaptor<android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest> captor =
+ ArgumentCaptor.forClass(
+ android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest.class);
+ WifiAwareDataPathSecurityConfig securityConfig = null;
+ if (usePassphrase) {
+ securityConfig = new WifiAwareDataPathSecurityConfig
+ .Builder(publicCipherSuites)
+ .setPskPassphrase(passphrase)
+ .build();
+ } else if (usePmk) {
+ securityConfig = new WifiAwareDataPathSecurityConfig
+ .Builder(publicCipherSuites)
+ .setPmk(pmk)
+ .build();
+ }
+
+ mDut.respondToDataPathRequest(tid, accept, ndpId, interfaceName,
+ appInfo, isOutOfBand, CAP, securityConfig);
+
+ verify(mIWifiNanIface).respondToDataPathIndicationRequest(eq(tid), captor.capture());
+
+ android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest nrtdpir =
+ captor.getValue();
+ collector.checkThat("acceptRequest", accept, equalTo(nrtdpir.acceptRequest));
+ collector.checkThat("ndpInstanceId", ndpId, equalTo(nrtdpir.ndpInstanceId));
+ collector.checkThat("ifaceName", interfaceName, equalTo(nrtdpir.ifaceName));
+
+ if (accept) {
+ if (usePmk) {
+ collector.checkThat("securityConfig.securityType",
+ NanDataPathSecurityType.PMK,
+ equalTo(nrtdpir.securityConfig.securityType));
+ collector.checkThat("securityConfig.cipherType", halCipherSuite,
+ equalTo(nrtdpir.securityConfig.cipherType));
+ collector.checkThat("securityConfig.pmk", pmk, equalTo(nrtdpir.securityConfig.pmk));
+ collector.checkThat("securityConfig.passphrase.length", 0,
+ equalTo(nrtdpir.securityConfig.passphrase.size()));
+ }
+
+ if (usePassphrase) {
+ collector.checkThat("securityConfig.securityType",
+ NanDataPathSecurityType.PASSPHRASE,
+ equalTo(nrtdpir.securityConfig.securityType));
+ collector.checkThat("securityConfig.cipherType", halCipherSuite,
+ equalTo(nrtdpir.securityConfig.cipherType));
+ collector.checkThat("securityConfig.passphrase", passphrase.getBytes(),
+ equalTo(convertArrayListToNativeByteArray(
+ nrtdpir.securityConfig.passphrase)));
+ }
+
+ collector.checkThat("appInfo", appInfo,
+ equalTo(convertArrayListToNativeByteArray(nrtdpir.appInfo)));
+
+ if ((usePmk || usePassphrase) && isOutOfBand) {
+ collector.checkThat("serviceNameOutOfBand",
+ WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(),
+ equalTo(convertArrayListToNativeByteArray(nrtdpir.serviceNameOutOfBand)));
+ } else {
+ collector.checkThat("serviceNameOutOfBand.length", 0,
+ equalTo(nrtdpir.serviceNameOutOfBand.size()));
+ }
+ }
+ }
+
+ private byte[] convertArrayListToNativeByteArray(ArrayList<Byte> from) {
+ if (from == null) {
+ return null;
+ }
+
+ byte[] to = new byte[from.size()];
+ for (int i = 0; i < from.size(); ++i) {
+ to[i] = from.get(i);
+ }
+ return to;
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceTest.java
new file mode 100644
index 0000000000..9a315d74ce
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static junit.framework.Assert.assertNull;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class WifiNanIfaceTest {
+ // HAL mocks
+ @Mock android.hardware.wifi.V1_0.IWifiNanIface mIWifiNanIfaceHidlMock;
+ @Mock android.hardware.wifi.IWifiNanIface mIWifiNanIfaceAidlMock;
+
+ // Framework HIDL/AIDL implementation mocks
+ @Mock WifiNanIfaceHidlImpl mWifiNanIfaceHidlImplMock;
+ @Mock WifiNanIfaceAidlImpl mWifiNanIfaceAidlImplMock;
+
+ private WifiNanIface mDut;
+
+ private class WifiNanIfaceSpy extends WifiNanIface {
+ WifiNanIfaceSpy(android.hardware.wifi.V1_0.IWifiNanIface nanIface) {
+ super(nanIface);
+ }
+
+ WifiNanIfaceSpy(android.hardware.wifi.IWifiNanIface nanIface) {
+ super(nanIface);
+ }
+
+ @Override
+ protected WifiNanIfaceHidlImpl createWifiNanIfaceHidlImplMockable(
+ android.hardware.wifi.V1_0.IWifiNanIface nanIface) {
+ return mWifiNanIfaceHidlImplMock;
+ }
+
+ @Override
+ protected WifiNanIfaceAidlImpl createWifiNanIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiNanIface nanIface) {
+ return mWifiNanIfaceAidlImplMock;
+ }
+ }
+
+ private class NullWifiNanIfaceSpy extends WifiNanIface {
+ NullWifiNanIfaceSpy() {
+ super(mIWifiNanIfaceAidlMock);
+ }
+
+ @Override
+ protected WifiNanIfaceAidlImpl createWifiNanIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiNanIface nanIface) {
+ return null;
+ }
+ }
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mDut = new WifiNanIfaceSpy(mIWifiNanIfaceAidlMock);
+ }
+
+ /**
+ * Test that we can initialize using the HIDL implementation.
+ */
+ @Test
+ public void testInitWithHidlImpl() {
+ mDut = new WifiNanIfaceSpy(mIWifiNanIfaceHidlMock);
+ mDut.getName();
+ verify(mWifiNanIfaceHidlImplMock).getName();
+ verify(mWifiNanIfaceAidlImplMock, never()).getName();
+ }
+
+ /**
+ * Test the case where the creation of the xIDL implementation
+ * fails, so mWifiNanIface is null.
+ */
+ @Test
+ public void testInitFailureCase() {
+ mDut = new NullWifiNanIfaceSpy();
+ assertNull(mDut.getName());
+ verify(mWifiNanIfaceHidlImplMock, never()).getName();
+ verify(mWifiNanIfaceAidlImplMock, never()).getName();
+ }
+
+ @Test
+ public void testGetName() {
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.getName(),
+ mWifiNanIfaceAidlImplMock.getName(),
+ "wlan0");
+ verify(mWifiNanIfaceAidlImplMock).getName();
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiP2pIfaceTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiP2pIfaceTest.java
new file mode 100644
index 0000000000..76b7606d88
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiP2pIfaceTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static junit.framework.Assert.assertNull;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class WifiP2pIfaceTest {
+ // HAL mocks
+ @Mock android.hardware.wifi.V1_0.IWifiP2pIface mIWifiP2pIfaceHidlMock;
+ @Mock android.hardware.wifi.IWifiP2pIface mIWifiP2pIfaceAidlMock;
+
+ // Framework HIDL/AIDL implementation mocks
+ @Mock WifiP2pIfaceHidlImpl mWifiP2pIfaceHidlImplMock;
+ @Mock WifiP2pIfaceAidlImpl mWifiP2pIfaceAidlImplMock;
+
+ private WifiP2pIface mDut;
+
+ private class WifiP2pIfaceSpy extends WifiP2pIface {
+ WifiP2pIfaceSpy(android.hardware.wifi.V1_0.IWifiP2pIface p2pIface) {
+ super(p2pIface);
+ }
+
+ WifiP2pIfaceSpy(android.hardware.wifi.IWifiP2pIface p2pIface) {
+ super(p2pIface);
+ }
+
+ @Override
+ protected WifiP2pIfaceHidlImpl createWifiP2pIfaceHidlImplMockable(
+ android.hardware.wifi.V1_0.IWifiP2pIface p2pIface) {
+ return mWifiP2pIfaceHidlImplMock;
+ }
+
+ @Override
+ protected WifiP2pIfaceAidlImpl createWifiP2pIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiP2pIface p2pIface) {
+ return mWifiP2pIfaceAidlImplMock;
+ }
+ }
+
+ private class NullWifiP2pIfaceSpy extends WifiP2pIface {
+ NullWifiP2pIfaceSpy() {
+ super(mIWifiP2pIfaceAidlMock);
+ }
+
+ @Override
+ protected WifiP2pIfaceAidlImpl createWifiP2pIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiP2pIface p2pIface) {
+ return null;
+ }
+ }
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mDut = new WifiP2pIfaceSpy(mIWifiP2pIfaceAidlMock);
+ }
+
+ /**
+ * Test that we can initialize using the HIDL implementation.
+ */
+ @Test
+ public void testInitWithHidlImpl() {
+ mDut = new WifiP2pIfaceSpy(mIWifiP2pIfaceHidlMock);
+ mDut.getName();
+ verify(mWifiP2pIfaceHidlImplMock).getName();
+ verify(mWifiP2pIfaceAidlImplMock, never()).getName();
+ }
+
+ /**
+ * Test the case where the creation of the xIDL implementation
+ * fails, so mWifiP2pIface is null.
+ */
+ @Test
+ public void testInitFailureCase() {
+ mDut = new NullWifiP2pIfaceSpy();
+ assertNull(mDut.getName());
+ verify(mWifiP2pIfaceHidlImplMock, never()).getName();
+ verify(mWifiP2pIfaceAidlImplMock, never()).getName();
+ }
+
+ @Test
+ public void testGetName() {
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.getName(),
+ mWifiP2pIfaceAidlImplMock.getName(),
+ "wlan0");
+ verify(mWifiP2pIfaceAidlImplMock).getName();
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttNativeTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerHidlImplTest.java
index 8c6a4eec50..a33b4b072f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttNativeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerHidlImplTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -14,13 +14,11 @@
* limitations under the License.
*/
-
-package com.android.server.wifi.rtt;
+package com.android.server.wifi.hal;
import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -47,10 +45,7 @@ import android.net.wifi.rtt.RangingRequest;
import android.net.wifi.rtt.RangingResult;
import android.net.wifi.rtt.ResponderConfig;
-import androidx.test.filters.SmallTest;
-
-import com.android.server.wifi.HalDeviceManager;
-import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.rtt.RttTestUtils;
import org.hamcrest.core.IsNull;
import org.junit.Before;
@@ -64,46 +59,33 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
-/**
- * Unit test harness for the RttNative class.
- */
-@SmallTest
-public class RttNativeTest extends WifiBaseTest {
- private RttNative mDut;
+public class WifiRttControllerHidlImplTest {
+ private WifiRttController mDut;
private WifiStatus mStatusSuccess;
private ArgumentCaptor<ArrayList> mRttConfigCaptor = ArgumentCaptor.forClass(ArrayList.class);
- private ArgumentCaptor<List> mRttResultCaptor = ArgumentCaptor.forClass(List.class);
- private ArgumentCaptor<HalDeviceManager.ManagerStatusListener> mHdmStatusListener =
- ArgumentCaptor.forClass(HalDeviceManager.ManagerStatusListener.class);
- private ArgumentCaptor<HalDeviceManager.InterfaceRttControllerLifecycleCallback>
- mRttLifecycleCbCaptor = ArgumentCaptor.forClass(
- HalDeviceManager.InterfaceRttControllerLifecycleCallback.class);
+ private ArgumentCaptor<ArrayList> mRttResultCaptor = ArgumentCaptor.forClass(ArrayList.class);
private ArgumentCaptor<IWifiRttController.getCapabilitiesCallback> mGetCapCbCatpr =
ArgumentCaptor.forClass(IWifiRttController.getCapabilitiesCallback.class);
private ArgumentCaptor<IWifiRttControllerEventCallback.Stub> mEventCallbackArgumentCaptor =
ArgumentCaptor.forClass(IWifiRttControllerEventCallback.Stub.class);
+ private ArgumentCaptor<ArrayList> mArrayListCaptor = ArgumentCaptor.forClass(ArrayList.class);
@Rule
public ErrorCollector collector = new ErrorCollector();
@Mock
- public RttServiceImpl mockRttServiceImpl;
-
- @Mock
- public HalDeviceManager mockHalDeviceManager;
+ public IWifiRttController mockRttController;
@Mock
- public IWifiRttController mockRttController;
+ public WifiRttController.RttControllerRangingResultsCallback mockRangingResultsCallback;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
-
- when(mockHalDeviceManager.isStarted()).thenReturn(true);
-
mStatusSuccess = new WifiStatus();
mStatusSuccess.code = WifiStatusCode.SUCCESS;
+
when(mockRttController.registerEventCallback(mEventCallbackArgumentCaptor.capture()))
.thenReturn(mStatusSuccess);
when(mockRttController.rangeRequest(anyInt(), any(ArrayList.class))).thenReturn(
@@ -111,20 +93,15 @@ public class RttNativeTest extends WifiBaseTest {
when(mockRttController.rangeCancel(anyInt(), any(ArrayList.class))).thenReturn(
mStatusSuccess);
- mDut = new RttNative(mockRttServiceImpl, mockHalDeviceManager);
- mDut.start(null);
- verify(mockHalDeviceManager).initialize();
- verify(mockHalDeviceManager).registerRttControllerLifecycleCallback(
- mRttLifecycleCbCaptor.capture(), any());
- mRttLifecycleCbCaptor.getValue().onNewRttController(mockRttController);
- verify(mockRttController).registerEventCallback(any());
- verify(mockRttServiceImpl).enableIfPossible();
+ mDut = new WifiRttController(mockRttController);
+ mDut.setup();
+ mDut.registerRangingResultsCallback(mockRangingResultsCallback);
verify(mockRttController).getCapabilities(mGetCapCbCatpr.capture());
+ verify(mockRttController).registerEventCallback(any());
// will override capabilities (just call cb again) for specific tests
mGetCapCbCatpr.getValue().onValues(mStatusSuccess, getFullRttCapabilities());
// This is for the castFrom() call
verify(mockRttController, times(2)).asBinder();
- assertTrue(mDut.isReady());
}
/**
@@ -136,7 +113,7 @@ public class RttNativeTest extends WifiBaseTest {
RangingRequest request = RttTestUtils.getDummyRangingRequest((byte) 0);
// (1) issue range request
- mDut.rangeRequest(cmdId, request, true);
+ mDut.rangeRequest(cmdId, request);
// (2) verify HAL call and parameters
verify(mockRttController).rangeRequest(eq(cmdId), mRttConfigCaptor.capture());
@@ -155,7 +132,7 @@ public class RttNativeTest extends WifiBaseTest {
collector.checkThat("entry 0: lci", rttConfig.mustRequestLci, equalTo(true));
collector.checkThat("entry 0: lcr", rttConfig.mustRequestLcr, equalTo(true));
collector.checkThat("entry 0: rtt burst size", rttConfig.numFramesPerBurst,
- equalTo(RangingRequest.getMaxRttBurstSize()));
+ equalTo(RangingRequest.getMaxRttBurstSize()));
rttConfig = halRequest.get(1);
collector.checkThat("entry 1: MAC", rttConfig.addr,
@@ -177,8 +154,7 @@ public class RttNativeTest extends WifiBaseTest {
collector.checkThat("entry 2: rtt burst size", rttConfig.numFramesPerBurst,
equalTo(RangingRequest.getMaxRttBurstSize()));
-
- verifyNoMoreInteractions(mockRttController, mockRttServiceImpl);
+ verifyNoMoreInteractions(mockRttController);
}
/**
@@ -205,7 +181,7 @@ public class RttNativeTest extends WifiBaseTest {
// Note: request 1: BW = 40MHz --> 10MHz, Preamble = HT (since 40MHz) -> Legacy
// (1) issue range request
- mDut.rangeRequest(cmdId, request, true);
+ mDut.rangeRequest(cmdId, request);
// (2) verify HAL call and parameters
verify(mockRttController).rangeRequest(eq(cmdId), mRttConfigCaptor.capture());
@@ -235,7 +211,7 @@ public class RttNativeTest extends WifiBaseTest {
collector.checkThat("entry 1: lci", rttConfig.mustRequestLci, equalTo(false));
collector.checkThat("entry 1: lcr", rttConfig.mustRequestLcr, equalTo(false));
- verifyNoMoreInteractions(mockRttController, mockRttServiceImpl);
+ verifyNoMoreInteractions(mockRttController);
}
/**
@@ -259,7 +235,7 @@ public class RttNativeTest extends WifiBaseTest {
// dropped
// (1) issue range request
- mDut.rangeRequest(cmdId, request, true);
+ mDut.rangeRequest(cmdId, request);
// (2) verify HAL call and parameters
verify(mockRttController).rangeRequest(eq(cmdId), mRttConfigCaptor.capture());
@@ -277,58 +253,7 @@ public class RttNativeTest extends WifiBaseTest {
collector.checkThat("entry 0: lci", rttConfig.mustRequestLci, equalTo(false));
collector.checkThat("entry 0: lcr", rttConfig.mustRequestLcr, equalTo(false));
- verifyNoMoreInteractions(mockRttController, mockRttServiceImpl);
- }
-
- /**
- * Validate no range request when Wi-Fi is down
- */
- @Test
- public void testWifiDown() throws Exception {
- int cmdId = 55;
- RangingRequest request = RttTestUtils.getDummyRangingRequest((byte) 0);
-
- // (1) simulate Wi-Fi down and send a status change indication
- mRttLifecycleCbCaptor.getValue().onRttControllerDestroyed();
- verify(mockRttServiceImpl).disable();
- assertFalse(mDut.isReady());
-
- // (2) issue range request
- mDut.rangeRequest(cmdId, request, true);
-
- verifyNoMoreInteractions(mockRttServiceImpl, mockRttController);
- }
-
- /**
- * Validate that we react correctly (i.e. enable/disable global RTT availability) when
- * notified that the RTT controller has disappear and appeared.
- */
- @Test
- public void testRttControllerLifecycle() throws Exception {
- // RTT controller disappears
- mRttLifecycleCbCaptor.getValue().onRttControllerDestroyed();
- verify(mockRttServiceImpl).disable();
- assertFalse(mDut.isReady());
-
- // RTT controller re-appears (verification is x2 since 1st time is in setup())
- mRttLifecycleCbCaptor.getValue().onNewRttController(mockRttController);
- verify(mockRttController, times(2)).registerEventCallback(any());
- verify(mockRttServiceImpl, times(2)).enableIfPossible();
- verify(mockRttController, times(2)).getCapabilities(mGetCapCbCatpr.capture());
- // This is for the castFrom() calls
- verify(mockRttController, times(4)).asBinder();
- assertTrue(mDut.isReady());
-
- // RTT controller switch - previous is invalid and new one is created. Should not try to
- // enable
- mRttLifecycleCbCaptor.getValue().onNewRttController(mockRttController);
- verify(mockRttController, times(3)).registerEventCallback(any());
- // This is for the castFrom() calls
- verify(mockRttController, times(6)).asBinder();
- verify(mockRttController, times(3)).getCapabilities(mGetCapCbCatpr.capture());
- assertTrue(mDut.isReady());
-
- verifyNoMoreInteractions(mockRttServiceImpl, mockRttController);
+ verifyNoMoreInteractions(mockRttController);
}
/**
@@ -337,9 +262,9 @@ public class RttNativeTest extends WifiBaseTest {
@Test
public void testRangeCancel() throws Exception {
int cmdId = 66;
- ArrayList<byte[]> macAddresses = new ArrayList<>();
- byte[] mac1 = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
- byte[] mac2 = {0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+ ArrayList<MacAddress> macAddresses = new ArrayList<>();
+ MacAddress mac1 = MacAddress.fromString("00:01:02:03:04:05");
+ MacAddress mac2 = MacAddress.fromString("0A:0B:0C:0D:0E:0F");
macAddresses.add(mac1);
macAddresses.add(mac2);
@@ -347,7 +272,9 @@ public class RttNativeTest extends WifiBaseTest {
mDut.rangeCancel(cmdId, macAddresses);
// (2) verify HAL call and parameters
- verify(mockRttController).rangeCancel(cmdId, macAddresses);
+ verify(mockRttController).rangeCancel(eq(cmdId), mArrayListCaptor.capture());
+ assertArrayEquals(mac1.toByteArray(), (byte[]) mArrayListCaptor.getValue().get(0));
+ assertArrayEquals(mac2.toByteArray(), (byte[]) mArrayListCaptor.getValue().get(1));
verifyNoMoreInteractions(mockRttController);
}
@@ -371,11 +298,11 @@ public class RttNativeTest extends WifiBaseTest {
res.timeStampInUs = 6000;
results.add(res);
- // (1) have HAL call native with results
+ // (1) have the HAL call us with results
mEventCallbackArgumentCaptor.getValue().onResults(cmdId, results);
// (2) verify call to framework
- verify(mockRttServiceImpl).onRangingResults(eq(cmdId), mRttResultCaptor.capture());
+ verify(mockRangingResultsCallback).onRangingResults(eq(cmdId), mRttResultCaptor.capture());
// verify contents of the framework results
List<RangingResult> rttR = mRttResultCaptor.getValue();
@@ -384,13 +311,13 @@ public class RttNativeTest extends WifiBaseTest {
RangingResult rttResult = rttR.get(0);
collector.checkThat("status", rttResult.getStatus(),
- equalTo(RttNative.FRAMEWORK_RTT_STATUS_SUCCESS));
+ equalTo(WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS));
collector.checkThat("mac", rttResult.getMacAddress().toByteArray(),
equalTo(MacAddress.fromString("05:06:07:08:09:0A").toByteArray()));
collector.checkThat("distanceCm", rttResult.getDistanceMm(), equalTo(1500));
collector.checkThat("timestamp", rttResult.getRangingTimestampMillis(), equalTo(6L));
- verifyNoMoreInteractions(mockRttController, mockRttServiceImpl);
+ verifyNoMoreInteractions(mockRttController);
}
/**
@@ -401,7 +328,7 @@ public class RttNativeTest extends WifiBaseTest {
int cmdId = 66;
mEventCallbackArgumentCaptor.getValue().onResults(cmdId, null);
- verify(mockRttServiceImpl).onRangingResults(eq(cmdId), mRttResultCaptor.capture());
+ verify(mockRangingResultsCallback).onRangingResults(eq(cmdId), mRttResultCaptor.capture());
collector.checkThat("number of entries", mRttResultCaptor.getValue().size(), equalTo(0));
}
@@ -422,7 +349,7 @@ public class RttNativeTest extends WifiBaseTest {
results.add(null);
mEventCallbackArgumentCaptor.getValue().onResults(cmdId, results);
- verify(mockRttServiceImpl).onRangingResults(eq(cmdId), mRttResultCaptor.capture());
+ verify(mockRangingResultsCallback).onRangingResults(eq(cmdId), mRttResultCaptor.capture());
List<RttResult> rttR = mRttResultCaptor.getValue();
collector.checkThat("number of entries", rttR.size(), equalTo(2));
@@ -448,11 +375,12 @@ public class RttNativeTest extends WifiBaseTest {
// Add a ResponderConfig with invalid parameter, should be ignored.
request.mRttPeers.add(invalidConfig);
request.mRttPeers.add(config);
- mDut.rangeRequest(cmdId, request, true);
+ mDut.rangeRequest(cmdId, request);
verify(mockRttController).rangeRequest(eq(cmdId), mRttConfigCaptor.capture());
assertEquals(request.mRttPeers.size() - 1, mRttConfigCaptor.getValue().size());
}
+
// Utilities
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerTest.java
new file mode 100644
index 0000000000..00f688b302
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static junit.framework.Assert.assertNull;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class WifiRttControllerTest {
+ // HAL mocks
+ @Mock android.hardware.wifi.V1_0.IWifiRttController mIWifiRttControllerHidlMock;
+ @Mock android.hardware.wifi.IWifiRttController mIWifiRttControllerAidlMock;
+
+ // Framework HIDL/AIDL implementation mocks
+ @Mock WifiRttControllerHidlImpl mWifiRttControllerHidlImplMock;
+ @Mock WifiRttControllerAidlImpl mWifiRttControllerAidlImplMock;
+
+ private WifiRttController mDut;
+
+ private class WifiRttControllerSpy extends WifiRttController {
+ WifiRttControllerSpy(android.hardware.wifi.V1_0.IWifiRttController rttController) {
+ super(rttController);
+ }
+
+ WifiRttControllerSpy(android.hardware.wifi.IWifiRttController rttController) {
+ super(rttController);
+ }
+
+ @Override
+ protected WifiRttControllerHidlImpl createWifiRttControllerHidlImplMockable(
+ android.hardware.wifi.V1_0.IWifiRttController rttController) {
+ return mWifiRttControllerHidlImplMock;
+ }
+
+ @Override
+ protected WifiRttControllerAidlImpl createWifiRttControllerAidlImplMockable(
+ android.hardware.wifi.IWifiRttController rttController) {
+ return mWifiRttControllerAidlImplMock;
+ }
+ }
+
+ private class NullWifiRttControllerSpy extends WifiRttController {
+ NullWifiRttControllerSpy() {
+ super(mIWifiRttControllerAidlMock);
+ }
+
+ @Override
+ protected WifiRttControllerAidlImpl createWifiRttControllerAidlImplMockable(
+ android.hardware.wifi.IWifiRttController rttController) {
+ return null;
+ }
+ }
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mDut = new WifiRttControllerSpy(mIWifiRttControllerAidlMock);
+ }
+
+ /**
+ * Test that we can initialize using the HIDL implementation.
+ */
+ @Test
+ public void testInitWithHidlImpl() {
+ mDut = new WifiRttControllerSpy(mIWifiRttControllerHidlMock);
+ mDut.getRttCapabilities();
+ verify(mWifiRttControllerHidlImplMock).getRttCapabilities();
+ verify(mWifiRttControllerAidlImplMock, never()).getRttCapabilities();
+ }
+
+ /**
+ * Test the case where the creation of the xIDL implementation
+ * fails, so mWifiRttController is null.
+ */
+ @Test
+ public void testInitFailureCase() {
+ mDut = new NullWifiRttControllerSpy();
+ assertNull(mDut.getRttCapabilities());
+ verify(mWifiRttControllerHidlImplMock, never()).getRttCapabilities();
+ verify(mWifiRttControllerAidlImplMock, never()).getRttCapabilities();
+ }
+
+ @Test
+ public void testGetRttCapabilities() {
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.getRttCapabilities(),
+ mWifiRttControllerAidlImplMock.getRttCapabilities(),
+ mock(WifiRttController.Capabilities.class));
+ verify(mWifiRttControllerAidlImplMock).getRttCapabilities();
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceTest.java
new file mode 100644
index 0000000000..8e83433a01
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2022 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.hal;
+
+import static junit.framework.Assert.assertNull;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.annotation.NonNull;
+import android.content.Context;
+
+import com.android.server.wifi.SsidTranslator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class WifiStaIfaceTest {
+ // HAL mocks
+ @Mock android.hardware.wifi.V1_0.IWifiStaIface mIWifiStaIfaceHidlMock;
+ @Mock android.hardware.wifi.IWifiStaIface mIWifiStaIfaceAidlMock;
+
+ // Framework HIDL/AIDL implementation mocks
+ @Mock WifiStaIfaceHidlImpl mWifiStaIfaceHidlImplMock;
+ @Mock WifiStaIfaceAidlImpl mWifiStaIfaceAidlImplMock;
+
+ @Mock Context mContextMock;
+ @Mock SsidTranslator mSsidTranslatorMock;
+
+ private WifiStaIface mDut;
+
+ private class WifiStaIfaceSpy extends WifiStaIface {
+ WifiStaIfaceSpy(android.hardware.wifi.V1_0.IWifiStaIface staIface) {
+ super(staIface, mContextMock, mSsidTranslatorMock);
+ }
+
+ WifiStaIfaceSpy(android.hardware.wifi.IWifiStaIface staIface) {
+ super(staIface, mContextMock, mSsidTranslatorMock);
+ }
+
+ @Override
+ protected WifiStaIfaceHidlImpl createWifiStaIfaceHidlImplMockable(
+ android.hardware.wifi.V1_0.IWifiStaIface staIface,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ return mWifiStaIfaceHidlImplMock;
+ }
+
+ @Override
+ protected WifiStaIfaceAidlImpl createWifiStaIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiStaIface staIface,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ return mWifiStaIfaceAidlImplMock;
+ }
+ }
+
+ private class NullWifiStaIfaceSpy extends WifiStaIface {
+ NullWifiStaIfaceSpy() {
+ super(mIWifiStaIfaceAidlMock, mContextMock, mSsidTranslatorMock);
+ }
+
+ @Override
+ protected WifiStaIfaceAidlImpl createWifiStaIfaceAidlImplMockable(
+ android.hardware.wifi.IWifiStaIface staIface,
+ @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
+ return null;
+ }
+ }
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mDut = new WifiStaIfaceSpy(mIWifiStaIfaceAidlMock);
+ }
+
+ /**
+ * Test that we can initialize using the HIDL implementation.
+ */
+ @Test
+ public void testInitWithHidlImpl() {
+ mDut = new WifiStaIfaceSpy(mIWifiStaIfaceHidlMock);
+ mDut.getName();
+ verify(mWifiStaIfaceHidlImplMock).getName();
+ verify(mWifiStaIfaceAidlImplMock, never()).getName();
+ }
+
+ /**
+ * Test the case where the creation of the xIDL implementation
+ * fails, so mWifiStaIface is null.
+ */
+ @Test
+ public void testInitFailureCase() {
+ mDut = new NullWifiStaIfaceSpy();
+ assertNull(mDut.getName());
+ verify(mWifiStaIfaceHidlImplMock, never()).getName();
+ verify(mWifiStaIfaceAidlImplMock, never()).getName();
+ }
+
+ @Test
+ public void testGetName() {
+ HalTestUtils.verifyReturnValue(
+ () -> mDut.getName(),
+ mWifiStaIfaceAidlImplMock.getName(),
+ "wlan0");
+ verify(mWifiStaIfaceAidlImplMock).getName();
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
index 4036c974dc..a3083ef40a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java
@@ -68,7 +68,6 @@ 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.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.os.test.TestLooper;
@@ -76,6 +75,7 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Base64;
+import android.util.LocalLog;
import android.util.Pair;
import androidx.test.filters.SmallTest;
@@ -85,6 +85,7 @@ import com.android.server.wifi.FakeKeys;
import com.android.server.wifi.FrameworkFacade;
import com.android.server.wifi.MacAddressUtil;
import com.android.server.wifi.NetworkUpdateResult;
+import com.android.server.wifi.RunnerHandler;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiCarrierInfoManager;
import com.android.server.wifi.WifiConfigManager;
@@ -220,7 +221,7 @@ public class PasspointManagerTest extends WifiBaseTest {
@Mock MacAddressUtil mMacAddressUtil;
@Mock WifiPermissionsUtil mWifiPermissionsUtil;
- Handler mHandler;
+ RunnerHandler mHandler;
TestLooper mLooper;
PasspointManager mManager;
boolean mConfigSettingsPasspointEnabled = true;
@@ -271,7 +272,7 @@ public class PasspointManagerTest extends WifiBaseTest {
when(mWifiSettingsStore.isWifiPasspointEnabled())
.thenReturn(mConfigSettingsPasspointEnabled);
mLooper = new TestLooper();
- mHandler = new Handler(mLooper.getLooper());
+ mHandler = new RunnerHandler(mLooper.getLooper(), 100, new LocalLog(128));
mWifiCarrierInfoManager = new WifiCarrierInfoManager(mTelephonyManager,
mSubscriptionManager, mWifiInjector, mock(FrameworkFacade.class),
mock(WifiContext.class), mWifiConfigStore, mHandler, mWifiMetrics, mClock);
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 7a95a41f8e..0c881f6c3e 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
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
+import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
import android.hardware.wifi.supplicant.P2pStatusCode;
import android.hardware.wifi.supplicant.WpsConfigMethods;
@@ -52,7 +53,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
-import java.util.Arrays;;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -401,6 +402,107 @@ public class SupplicantP2pIfaceCallbackAidlImplTest extends WifiBaseTest {
}
/**
+ * Success scenario for onGroupStartedWithParams call.
+ */
+ @Test
+ public void testOnGroupStartedWithParams_success() throws Exception {
+ String fakeName = "group name";
+ String fakePassphrase = "secret";
+ byte[] fakeSsidBytesList = new byte[] {0x30, 0x31, 0x32, 0x33};
+ String fakeSsidString = "0123";
+ HashSet<String> passwords = new HashSet<>();
+ byte[] fakeMacAddress = new byte[] {0x40, 0x41, 0x42, 0x43, 0x44, 0x45};
+
+ 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.interfaceAddress, fakeMacAddress);
+ }
+ }).when(mMonitor).broadcastP2pGroupStarted(
+ anyString(), any(WifiP2pGroup.class));
+
+ P2pGroupStartedEventParams params1 = new P2pGroupStartedEventParams();
+ params1.groupInterfaceName = fakeName;
+ params1.isGroupOwner = true;
+ params1.ssid = fakeSsidBytesList;
+ params1.frequencyMHz = 1;
+ params1.passphrase = fakePassphrase;
+ params1.goDeviceAddress = mDeviceAddress1Bytes;
+ params1.goInterfaceAddress = fakeMacAddress;
+ params1.isPersistent = true;
+ mDut.onGroupStartedWithParams(params1);
+ assertTrue(passwords.contains(fakePassphrase));
+
+ P2pGroupStartedEventParams params2 = new P2pGroupStartedEventParams();
+ params2.groupInterfaceName = fakeName;
+ params2.isGroupOwner = true;
+ params2.ssid = fakeSsidBytesList;
+ params2.frequencyMHz = 1;
+ params2.goDeviceAddress = mDeviceAddress1Bytes;
+ params2.goInterfaceAddress = fakeMacAddress;
+ params2.isPersistent = true;
+ mDut.onGroupStartedWithParams(params2);
+ assertTrue(passwords.contains(null));
+
+ verify(mMonitor, times(2)).broadcastP2pGroupStarted(
+ anyString(), any(WifiP2pGroup.class));
+ }
+
+ /**
+ * Failing scenarios for onGroupStartedWithParams call.
+ */
+ @Test
+ public void testOnGroupStartedWithParams_invalidArguments()
+ throws Exception {
+ String fakeName = "group name";
+ String fakePassphrase = "secret";
+ byte[] fakeSsidBytesList = new byte[] {0x30, 0x31, 0x32, 0x33};
+ byte[] fakeMacAddress = new byte[] {0x40, 0x41, 0x42, 0x43, 0x44, 0x45};
+
+ P2pGroupStartedEventParams params1 = new P2pGroupStartedEventParams();
+ params1.isGroupOwner = true;
+ params1.ssid = fakeSsidBytesList;
+ params1.frequencyMHz = 1;
+ params1.passphrase = fakePassphrase;
+ params1.goDeviceAddress = mDeviceAddress1Bytes;
+ params1.goInterfaceAddress = fakeMacAddress;
+ params1.isPersistent = true;
+ mDut.onGroupStartedWithParams(params1);
+ verify(mMonitor, never()).broadcastP2pGroupStarted(
+ anyString(), any(WifiP2pGroup.class));
+
+ P2pGroupStartedEventParams params2 = new P2pGroupStartedEventParams();
+ params2.groupInterfaceName = fakeName;
+ params2.isGroupOwner = true;
+ params2.frequencyMHz = 1;
+ params1.passphrase = fakePassphrase;
+ params2.goDeviceAddress = mDeviceAddress1Bytes;
+ params2.goInterfaceAddress = fakeMacAddress;
+ params2.isPersistent = true;
+ mDut.onGroupStartedWithParams(params2);
+ verify(mMonitor, never()).broadcastP2pGroupStarted(
+ anyString(), any(WifiP2pGroup.class));
+
+ P2pGroupStartedEventParams params3 = new P2pGroupStartedEventParams();
+ params3.groupInterfaceName = fakeName;
+ params3.isGroupOwner = true;
+ params3.ssid = fakeSsidBytesList;
+ params3.frequencyMHz = 1;
+ params3.passphrase = fakePassphrase;
+ params3.goInterfaceAddress = fakeMacAddress;
+ params3.isPersistent = true;
+ mDut.onGroupStartedWithParams(params3);
+ verify(mMonitor, never()).broadcastP2pGroupStarted(
+ anyString(), any(WifiP2pGroup.class));
+ }
+
+ /**
* Test provision discovery callback.
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImplTest.java
index 2d65645a70..dca52eb615 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackHidlImplTest.java
@@ -345,12 +345,11 @@ public class SupplicantP2pIfaceCallbackHidlImplTest extends WifiBaseTest {
public void testOnGroupStarted_success() throws Exception {
String fakeName = "group name";
String fakePassphrase = "secret";
- ArrayList<Byte> fakeSsidBytesList = new ArrayList<Byte>() {{
- add((byte) 0x30);
- add((byte) 0x31);
- add((byte) 0x32);
- add((byte) 0x33);
- }};
+ ArrayList<Byte> fakeSsidBytesList = new ArrayList<>();
+ fakeSsidBytesList.add((byte) 0x30);
+ fakeSsidBytesList.add((byte) 0x31);
+ fakeSsidBytesList.add((byte) 0x32);
+ fakeSsidBytesList.add((byte) 0x33);
String fakeSsidString = "0123";
HashSet<String> passwords = new HashSet<String>();
@@ -388,12 +387,12 @@ public class SupplicantP2pIfaceCallbackHidlImplTest extends WifiBaseTest {
public void testOnGroupStarted_invalidArguments() throws Exception {
String fakeName = "group name";
String fakePassphrase = "secret";
- ArrayList<Byte> fakeSsidBytesList = new ArrayList<Byte>() {{
- add((byte) 0x30);
- add((byte) 0x31);
- add((byte) 0x32);
- add((byte) 0x33);
- }};
+ ArrayList<Byte> fakeSsidBytesList = new ArrayList<>();
+ fakeSsidBytesList.add((byte) 0x30);
+ fakeSsidBytesList.add((byte) 0x31);
+ fakeSsidBytesList.add((byte) 0x32);
+ fakeSsidBytesList.add((byte) 0x33);
+
String fakeSsidString = "0123";
mDut.onGroupStarted(
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 e49c856f42..32379be019 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
@@ -2357,10 +2357,9 @@ public class SupplicantP2pIfaceHalAidlImplTest extends WifiBaseTest {
// Convert these to long to help with comparisons.
MacAddress[] clients = capturedClients.getValue();
- ArrayList<Long> expectedClients = new ArrayList<Long>() {{
- add(NativeUtil.macAddressToLong(mGroupOwnerMacAddressBytes));
- add(NativeUtil.macAddressToLong(mPeerMacAddressBytes));
- }};
+ List<Long> expectedClients = List.of(
+ NativeUtil.macAddressToLong(mGroupOwnerMacAddressBytes),
+ NativeUtil.macAddressToLong(mPeerMacAddressBytes));
ArrayList<Long> receivedClients = new ArrayList<Long>();
for (MacAddress client : clients) {
receivedClients.add(NativeUtil.macAddressToLong(client.data));
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 16ddd06378..734255abbc 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
@@ -105,9 +105,15 @@ public class SupplicantP2pIfaceHalHidlImplTest extends WifiBaseTest {
final String mIfaceName = "virtual_interface_name";
final String mSsid = "\"SSID\"";
- final ArrayList<Byte> mSsidBytes = new ArrayList<Byte>() {{
- add((byte) 'S'); add((byte) 'S'); add((byte) 'I'); add((byte) 'D');
- }};
+ private static ArrayList<Byte> createSsidBytes() {
+ ArrayList<Byte> result = new ArrayList<Byte>();
+ result.add((byte) 'S');
+ result.add((byte) 'S');
+ result.add((byte) 'I');
+ result.add((byte) 'D');
+ return result;
+ }
+ final ArrayList<Byte> mSsidBytes = createSsidBytes();
final String mPeerMacAddress = "00:11:22:33:44:55";
final byte[] mPeerMacAddressBytes = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
final String mGroupOwnerMacAddress = "01:12:23:34:45:56";
@@ -142,12 +148,24 @@ public class SupplicantP2pIfaceHalHidlImplTest extends WifiBaseTest {
final int mValidUpnpServiceVersion = 16;
final String mValidUpnpServiceName = "serviceName";
final String mValidBonjourService = "bonjour 30313233 34353637";
- final ArrayList<Byte> mValidBonjourServiceRequest = new ArrayList<Byte>() {{
- add((byte) '0'); add((byte) '1'); add((byte) '2'); add((byte) '3');
- }};
- final ArrayList<Byte> mValidBonjourServiceResponse = new ArrayList<Byte>() {{
- add((byte) '4'); add((byte) '5'); add((byte) '6'); add((byte) '7');
- }};
+ private static ArrayList<Byte> createValidBonjourServiceRequest() {
+ ArrayList<Byte> result = new ArrayList<Byte>();
+ result.add((byte) '0');
+ result.add((byte) '1');
+ result.add((byte) '2');
+ result.add((byte) '3');
+ return result;
+ }
+ final ArrayList<Byte> mValidBonjourServiceRequest = createValidBonjourServiceRequest();
+ private static ArrayList<Byte> createValidBonjourServiceResponse() {
+ ArrayList<Byte> result = new ArrayList<Byte>();
+ result.add((byte) '4');
+ result.add((byte) '5');
+ result.add((byte) '6');
+ result.add((byte) '7');
+ return result;
+ }
+ final ArrayList<Byte> mValidBonjourServiceResponse = createValidBonjourServiceResponse();
// variables for groupAdd with config
final String mNetworkName = "DIRECT-xy-Hello";
@@ -2614,10 +2632,9 @@ public class SupplicantP2pIfaceHalHidlImplTest extends WifiBaseTest {
// Convert these to long to help with comparisons.
ArrayList<byte[]> clients = capturedClients.getValue();
- ArrayList<Long> expectedClients = new ArrayList<Long>() {{
- add(NativeUtil.macAddressToLong(mGroupOwnerMacAddressBytes));
- add(NativeUtil.macAddressToLong(mPeerMacAddressBytes));
- }};
+ List<Long> expectedClients = List.of(
+ NativeUtil.macAddressToLong(mGroupOwnerMacAddressBytes),
+ NativeUtil.macAddressToLong(mPeerMacAddressBytes));
ArrayList<Long> receivedClients = new ArrayList<Long>();
for (byte[] client : clients) {
receivedClients.add(NativeUtil.macAddressToLong(client));
@@ -2675,10 +2692,9 @@ public class SupplicantP2pIfaceHalHidlImplTest extends WifiBaseTest {
.getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
doAnswer(new AnswerWithArguments() {
public void answer(ISupplicantP2pNetwork.getClientListCallback cb) {
- ArrayList<byte[]> clients = new ArrayList<byte[]>() {{
- add(mGroupOwnerMacAddressBytes);
- add(mPeerMacAddressBytes);
- }};
+ ArrayList<byte[]> clients = new ArrayList<>();
+ clients.add(mGroupOwnerMacAddressBytes);
+ clients.add(mPeerMacAddressBytes);
cb.onValues(mStatusSuccess, clients);
return;
}
@@ -2712,10 +2728,9 @@ public class SupplicantP2pIfaceHalHidlImplTest extends WifiBaseTest {
.getNetwork(anyInt(), any(ISupplicantP2pIface.getNetworkCallback.class));
doAnswer(new AnswerWithArguments() {
public void answer(ISupplicantP2pNetwork.getClientListCallback cb) {
- ArrayList<byte[]> clients = new ArrayList<byte[]>() {{
- add(mGroupOwnerMacAddressBytes);
- add(mPeerMacAddressBytes);
- }};
+ ArrayList<byte[]> clients = new ArrayList<>();
+ clients.add(mGroupOwnerMacAddressBytes);
+ clients.add(mPeerMacAddressBytes);
cb.onValues(mStatusSuccess, clients);
return;
}
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 8b8f95e2ff..cc2456f238 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
@@ -18,20 +18,18 @@ package com.android.server.wifi.p2p;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.test.MockAnswerUtil;
import android.hardware.wifi.V1_0.IWifiIface;
import android.hardware.wifi.V1_0.IWifiP2pIface;
import android.hardware.wifi.V1_0.WifiStatus;
import android.hardware.wifi.V1_0.WifiStatusCode;
import android.net.wifi.nl80211.WifiNl80211Manager;
import android.os.Handler;
-import android.os.RemoteException;
import android.os.WorkSource;
import androidx.test.filters.SmallTest;
@@ -44,6 +42,7 @@ import com.android.server.wifi.WifiBaseTest;
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 org.junit.Before;
import org.junit.Test;
@@ -86,14 +85,7 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest {
when(mHalDeviceManager.isSupported()).thenReturn(true);
when(mHalDeviceManager.createP2pIface(any(InterfaceDestroyedListener.class),
- any(Handler.class), any(WorkSource.class))).thenReturn(mIWifiP2pIface);
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(IWifiIface.getNameCallback cb)
- throws RemoteException {
- cb.onValues(mWifiStatusSuccess, P2P_IFACE_NAME);
- }
- }).when(mIWifiP2pIface).getName(any(IWifiIface.getNameCallback.class));
-
+ any(Handler.class), any(WorkSource.class))).thenReturn(P2P_IFACE_NAME);
when(mSupplicantP2pIfaceHal.isInitializationStarted()).thenReturn(true);
when(mSupplicantP2pIfaceHal.initialize()).thenReturn(true);
when(mSupplicantP2pIfaceHal.isInitializationComplete()).thenReturn(true);
@@ -146,7 +138,7 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest {
mWifiP2pNative.teardownInterface();
- verify(mHalDeviceManager).removeIface(any(IWifiIface.class));
+ verify(mHalDeviceManager).removeP2pIface(anyString());
verify(mSupplicantP2pIfaceHal).teardownIface(eq(P2P_IFACE_NAME));
}
@@ -162,7 +154,7 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest {
mWifiP2pNative.teardownInterface();
- verify(mHalDeviceManager, never()).removeIface(any(IWifiIface.class));
+ verify(mHalDeviceManager, never()).removeIface(any(WifiHal.WifiInterface.class));
verify(mSupplicantP2pIfaceHal).teardownIface(eq(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 c9dc95e80c..4a7e183f0b 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
@@ -30,7 +30,6 @@ import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
-import android.hardware.wifi.V1_0.IWifiIface;
import android.hardware.wifi.V1_0.IWifiP2pIface;
import android.net.wifi.WifiManager;
import android.net.wifi.nl80211.WifiNl80211Manager;
@@ -53,6 +52,7 @@ import com.android.server.wifi.WifiBaseTest;
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 org.junit.After;
import org.junit.Before;
@@ -129,9 +129,6 @@ public class WifiP2pNativeTest extends WifiBaseTest {
.mockStatic(HalDeviceManager.class, withSettings().lenient())
.strictness(Strictness.LENIENT)
.startMocking();
-
- when(HalDeviceManager.getName(any())).thenReturn(TEST_IFACE);
-
mWifiClientInterfaceNames.add("wlan0");
mWifiClientInterfaceNames.add("wlan1");
@@ -187,8 +184,7 @@ public class WifiP2pNativeTest extends WifiBaseTest {
public void testSetupInterfaceSuccessInCreatingP2pIface() {
when(mHalDeviceManagerMock.createP2pIface(
any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(mIWifiP2pIfaceMock);
- when(HalDeviceManager.getName(any(IWifiIface.class))).thenReturn(TEST_IFACE);
+ 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);
@@ -234,22 +230,6 @@ public class WifiP2pNativeTest extends WifiBaseTest {
}
/**
- * Verifies that setupInterface returns correct values when failing in getting P2P Iface name.
- */
- @Test
- public void testSetupInterfaceFailureInGettingP2pIfaceName() {
- when(mHalDeviceManagerMock.createP2pIface(
- any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(mIWifiP2pIfaceMock);
- when(HalDeviceManager.getName(any(IWifiIface.class))).thenReturn(null);
-
- assertEquals(
- mWifiP2pNative.setupInterface(
- mDestroyedListenerMock, mHandlerMock, mWorkSourceMock),
- null);
- }
-
- /**
* Verifies that setupInterface returns correct values when supplicant connection
* initialization fails.
*/
@@ -257,8 +237,7 @@ public class WifiP2pNativeTest extends WifiBaseTest {
public void testSetupInterfaceFailureInSupplicantConnectionInitialization() {
when(mHalDeviceManagerMock.createP2pIface(
any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(mIWifiP2pIfaceMock);
- when(HalDeviceManager.getName(any(IWifiIface.class))).thenReturn(TEST_IFACE);
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
when(mSupplicantP2pIfaceHalMock.isInitializationStarted()).thenReturn(false);
when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(false);
@@ -278,8 +257,7 @@ public class WifiP2pNativeTest extends WifiBaseTest {
public void testSetupInterfaceFailureInSupplicantConnectionInitNotCompleted() {
when(mHalDeviceManagerMock.createP2pIface(
any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(mIWifiP2pIfaceMock);
- when(HalDeviceManager.getName(any(IWifiIface.class))).thenReturn(TEST_IFACE);
+ 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);
@@ -300,8 +278,7 @@ public class WifiP2pNativeTest extends WifiBaseTest {
public void testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicant() {
when(mHalDeviceManagerMock.createP2pIface(
any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(mIWifiP2pIfaceMock);
- when(HalDeviceManager.getName(any(IWifiIface.class))).thenReturn(TEST_IFACE);
+ 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);
@@ -321,9 +298,6 @@ public class WifiP2pNativeTest extends WifiBaseTest {
@Test
public void testSetupInterfaceSuccessWhenHalDeviceMgrDoesSupport() throws Exception {
prepareDbsMock(true);
-
- when(HalDeviceManager.getName(any(IWifiIface.class))).thenReturn(TEST_IFACE);
-
assertEquals(
mWifiP2pNative.setupInterface(
mDestroyedListenerMock, mHandlerMock, mWorkSourceMock),
@@ -406,7 +380,7 @@ public class WifiP2pNativeTest extends WifiBaseTest {
public void testReplaceRequestorWsSuccessWhenHalDeviceMgrSucceedInReplace() throws Exception {
prepareDbsMock(true);
- when(mHalDeviceManagerMock.replaceRequestorWs(any(IWifiIface.class),
+ when(mHalDeviceManagerMock.replaceRequestorWsForP2pIface(anyString(),
any(WorkSource.class))).thenReturn(true);
assertTrue(mWifiP2pNative.replaceRequestorWs(mWorkSourceMock));
}
@@ -419,7 +393,7 @@ public class WifiP2pNativeTest extends WifiBaseTest {
public void testReplaceRequestorWsSuccessWhenHalDeviceMgrFailInReplace() throws Exception {
prepareDbsMock(true);
- when(mHalDeviceManagerMock.replaceRequestorWs(any(IWifiIface.class),
+ when(mHalDeviceManagerMock.replaceRequestorWs(any(WifiHal.WifiInterface.class),
any(WorkSource.class))).thenReturn(false);
assertFalse(mWifiP2pNative.replaceRequestorWs(mWorkSourceMock));
}
@@ -1028,7 +1002,7 @@ public class WifiP2pNativeTest extends WifiBaseTest {
when(mHalDeviceManagerMock.isSupported()).thenReturn(isHalDeviceManagerSupported);
when(mHalDeviceManagerMock.createP2pIface(
any(HalDeviceManager.InterfaceDestroyedListener.class),
- eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(mIWifiP2pIfaceMock);
+ eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE);
when(mSupplicantP2pIfaceHalMock.isInitializationStarted()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true);
when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(true);
@@ -1043,9 +1017,9 @@ public class WifiP2pNativeTest extends WifiBaseTest {
public void testDbsSupport() throws Exception {
prepareDbsMock(true);
- when(mHalDeviceManagerMock.is5g6gDbsSupported(any())).thenReturn(true);
+ when(mHalDeviceManagerMock.is5g6gDbsSupportedOnP2pIface(any())).thenReturn(true);
assertTrue(mWifiP2pNative.is5g6gDbsSupported());
- when(mHalDeviceManagerMock.is5g6gDbsSupported(any())).thenReturn(false);
+ when(mHalDeviceManagerMock.is5g6gDbsSupportedOnP2pIface(any())).thenReturn(false);
assertFalse(mWifiP2pNative.is5g6gDbsSupported());
}
@@ -1056,9 +1030,9 @@ public class WifiP2pNativeTest extends WifiBaseTest {
public void testDbsSupportWhenHalDeviceManagerNotSupported() throws Exception {
prepareDbsMock(false);
- when(mHalDeviceManagerMock.is5g6gDbsSupported(any())).thenReturn(true);
+ when(mHalDeviceManagerMock.is5g6gDbsSupportedOnP2pIface(any())).thenReturn(true);
assertFalse(mWifiP2pNative.is5g6gDbsSupported());
- when(mHalDeviceManagerMock.is5g6gDbsSupported(any())).thenReturn(false);
+ when(mHalDeviceManagerMock.is5g6gDbsSupportedOnP2pIface(any())).thenReturn(false);
assertFalse(mWifiP2pNative.is5g6gDbsSupported());
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
index e0fb8ec40b..9e6fcdf3e5 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
@@ -137,6 +137,7 @@ import com.android.server.wifi.WifiSettingsConfigStore;
import com.android.server.wifi.coex.CoexManager;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.proto.nano.WifiMetricsProto.P2pConnectionEvent;
+import com.android.server.wifi.util.LastCallerInfoManager;
import com.android.server.wifi.util.NetdWrapper;
import com.android.server.wifi.util.StringUtil;
import com.android.server.wifi.util.WaitingState;
@@ -256,6 +257,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
@Mock AlertDialog.Builder mAlertDialogBuilder;
@Mock AlertDialog mAlertDialog;
@Mock AsyncChannel mAsyncChannel;
+ @Mock LastCallerInfoManager mLastCallerInfoManager;
CoexManager.CoexListener mCoexListener;
@Mock DeviceConfigFacade mDeviceConfigFacade;
@@ -1241,6 +1243,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals);
when(mWifiInjector.makeBroadcastOptions()).thenReturn(mBroadcastOptions);
when(mWifiInjector.getWifiDialogManager()).thenReturn(mWifiDialogManager);
+ when(mWifiInjector.getLastCallerInfoManager()).thenReturn(mLastCallerInfoManager);
when(mWifiDialogManager.createP2pInvitationReceivedDialog(any(), anyBoolean(), any(),
anyInt(), any(), any())).thenReturn(mDialogHandle);
when(mWifiDialogManager.createP2pInvitationSentDialog(any(), any(), anyInt()))
@@ -1987,6 +1990,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
eq("testFeature"), anyInt(), eq(true));
}
assertTrue(mClientHandler.hasMessages(WifiP2pManager.DISCOVER_PEERS_SUCCEEDED));
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_DISCOVER_PEERS), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -2579,6 +2584,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
verify(mWifiPermissionsUtil).checkCanAccessWifiDirect(eq(TEST_PACKAGE_NAME),
eq("testFeature"), anyInt(), eq(true));
}
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_START_LISTENING), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -2605,6 +2612,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
verify(mWifiNative).p2pStopFind();
verify(mWifiNative).p2pExtListen(eq(false), anyInt(), anyInt());
assertTrue(mClientHandler.hasMessages(WifiP2pManager.STOP_LISTEN_SUCCEEDED));
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_STOP_LISTENING), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/** Verify the p2p randomized MAC feature is enabled if OEM supports it. */
@@ -2851,6 +2860,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
eq(WifiMetricsProto.GroupEvent.GROUP_UNKNOWN),
eq(mClient1.getCallingUid()));
assertEquals(mTestWifiP2pPeerConfig.toString(), configCaptor.getValue().toString());
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_CONNECT), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -2917,6 +2928,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
eq(null),
eq(WifiMetricsProto.GroupEvent.GROUP_OWNER),
eq(mClient1.getCallingUid()));
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_CREATE_GROUP), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -3037,6 +3050,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
eq(mClient1.getCallingUid()));
assertEquals(mTestWifiP2pFastConnectionConfig.toString(),
configCaptor.getValue().toString());
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_CREATE_GROUP_P2P_CONFIG),
+ anyInt(), anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -3134,6 +3149,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
reset(mAsyncChannel);
sendSimpleMsg(mClientMessenger, WifiP2pManager.CANCEL_CONNECT);
verify(mAsyncChannel).sendMessage(WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST, 0);
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_CANCEL_CONNECT), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -3703,6 +3720,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
verify(mClientHandler).sendMessage(mMessageCaptor.capture());
Message message = mMessageCaptor.getValue();
assertEquals(WifiP2pManager.STOP_DISCOVERY_SUCCEEDED, message.what);
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_STOP_PEER_DISCOVERY), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -3826,6 +3845,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
verify(mClientHandler).sendMessage(mMessageCaptor.capture());
Message message = mMessageCaptor.getValue();
assertEquals(WifiP2pManager.REMOVE_GROUP_SUCCEEDED, message.what);
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_REMOVE_GROUP), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -3918,6 +3939,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
verify(mClientHandler).sendMessage(mMessageCaptor.capture());
Message message = mMessageCaptor.getValue();
assertEquals(WifiP2pManager.SET_CHANNEL_SUCCEEDED, message.what);
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_SET_CHANNELS), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
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 2c2f892bd1..7cb196d20f 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
@@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.hal.WifiRttController;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import org.junit.Before;
@@ -216,13 +217,17 @@ public class RttMetricsTest extends WifiBaseTest {
RangingRequest requestAp6 = getDummyRangingRequest(6, 0);
mDut.clear();
- mDut.recordResult(requestAp1, getDummyRangingResults(RttNative.FRAMEWORK_RTT_STATUS_SUCCESS,
+ mDut.recordResult(requestAp1, getDummyRangingResults(
+ WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS,
requestAp1, 5, 0), 500);
- mDut.recordResult(requestAp2, getDummyRangingResults(RttNative.FRAMEWORK_RTT_STATUS_SUCCESS,
+ mDut.recordResult(requestAp2, getDummyRangingResults(
+ WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS,
requestAp2, 10, 30), 1500);
- mDut.recordResult(requestAp5, getDummyRangingResults(RttNative.FRAMEWORK_RTT_STATUS_SUCCESS,
+ mDut.recordResult(requestAp5, getDummyRangingResults(
+ WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS,
requestAp5, 0.3, -0.2), 700);
- mDut.recordResult(requestAp6, getDummyRangingResults(RttNative.FRAMEWORK_RTT_STATUS_SUCCESS,
+ mDut.recordResult(requestAp6, getDummyRangingResults(
+ WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS,
requestAp6, 40, 30), 1800);
log = mDut.consolidateProto();
@@ -261,13 +266,17 @@ public class RttMetricsTest extends WifiBaseTest {
mDut.clear();
mDut.recordResult(requestMixed03, getDummyRangingResults(
- RttNative.FRAMEWORK_RTT_STATUS_SUCCESS, requestMixed03, 5, 0), 6400);
+ WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS,
+ requestMixed03, 5, 0), 6400);
mDut.recordResult(requestMixed25, getDummyRangingResults(
- RttNative.FRAMEWORK_RTT_STATUS_SUCCESS, requestMixed25, 10, 30), 7800);
+ WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS,
+ requestMixed25, 10, 30), 7800);
mDut.recordResult(requestMixed50, getDummyRangingResults(
- RttNative.FRAMEWORK_RTT_STATUS_SUCCESS, requestMixed50, 0.3, -0.2), 3100);
+ WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS,
+ requestMixed50, 0.3, -0.2), 3100);
mDut.recordResult(requestMixed08, getDummyRangingResults(
- RttNative.FRAMEWORK_RTT_STATUS_SUCCESS, requestMixed08, 40, 30), 9500);
+ WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS,
+ requestMixed08, 40, 30), 9500);
log = mDut.consolidateProto();
checkMainStats("Sequence Mixed AP/Aware", log, 0, 0, 1, 2);
@@ -321,7 +330,7 @@ public class RttMetricsTest extends WifiBaseTest {
mDut.clear();
RangingRequest requestMixed25 = getDummyRangingRequest(2, 5);
List<RangingResult> resultMixed25 = getDummyRangingResults(
- RttNative.FRAMEWORK_RTT_STATUS_SUCCESS, requestMixed25, 10, 30);
+ WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS, requestMixed25, 10, 30);
// remove some results
resultMixed25.remove(3); // Second Aware result: distance = 100
resultMixed25.remove(0); // First AP result: distance = 10
@@ -401,22 +410,22 @@ public class RttMetricsTest extends WifiBaseTest {
mDut.clear();
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_SUCCESS, 5);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAILURE, 6);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_NO_RSP, 7);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_REJECTED, 8);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET, 9);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT, 10);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, 11);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY, 12);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_ABORTED, 13);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS, 14);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL, 15);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE, 16);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER, 17);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_INVALID_REQ, 18);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_NO_WIFI, 19);
- recordResultNTimes(RttNative.FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE, 20);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS, 5);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAILURE, 6);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NO_RSP, 7);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_REJECTED, 8);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NOT_SCHEDULED_YET, 9);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_TM_TIMEOUT, 10);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, 11);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_NO_CAPABILITY, 12);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_ABORTED, 13);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_INVALID_TS, 14);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_PROTOCOL, 15);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_SCHEDULE, 16);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_BUSY_TRY_LATER, 17);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_INVALID_REQ, 18);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_NO_WIFI, 19);
+ recordResultNTimes(WifiRttController.FRAMEWORK_RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE, 20);
log = mDut.consolidateProto();
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 a5b16f6d6f..33e8407045 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
@@ -17,10 +17,13 @@
package com.android.server.wifi.rtt;
+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_ONE_SIDED_RTT;
+
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_VERBOSE_LOGGING_ENABLED;
import static com.android.server.wifi.rtt.RttTestUtils.compareListContentsNoOrdering;
-import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -31,7 +34,6 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@@ -79,9 +81,11 @@ import androidx.test.filters.SmallTest;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.MockResources;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiSettingsConfigStore;
+import com.android.server.wifi.hal.WifiRttController;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.wifi.resources.R;
@@ -128,6 +132,12 @@ public class RttServiceImplTest extends WifiBaseTest {
private ArgumentCaptor<RangingRequest> mRequestCaptor = ArgumentCaptor.forClass(
RangingRequest.class);
private ArgumentCaptor<List> mListCaptor = ArgumentCaptor.forClass(List.class);
+ private ArgumentCaptor<HalDeviceManager.InterfaceRttControllerLifecycleCallback>
+ mRttLifecycleCbCaptor = ArgumentCaptor.forClass(
+ HalDeviceManager.InterfaceRttControllerLifecycleCallback.class);
+ private ArgumentCaptor<WifiRttController.RttControllerRangingResultsCallback>
+ mRangingResultsCbCaptor = ArgumentCaptor.forClass(
+ WifiRttController.RttControllerRangingResultsCallback.class);
private BinderLinkToDeathAnswer mBinderLinkToDeathCounter = new BinderLinkToDeathAnswer();
private BinderUnlinkToDeathAnswer mBinderUnlinkToDeathCounter = new BinderUnlinkToDeathAnswer();
@@ -145,7 +155,10 @@ public class RttServiceImplTest extends WifiBaseTest {
public Clock mockClock;
@Mock
- public RttNative mockNative;
+ public WifiRttController mockRttControllerHal;
+
+ @Mock
+ public HalDeviceManager mockHalDeviceManager;
@Mock
public RttMetrics mockMetrics;
@@ -218,9 +231,9 @@ public class RttServiceImplTest extends WifiBaseTest {
when(mockPermissionUtil.checkCallersLocationPermission(eq(mPackageName), eq(mFeatureId),
anyInt(), anyBoolean(), nullable(String.class))).thenReturn(true);
when(mockPermissionUtil.isLocationModeEnabled()).thenReturn(true);
- when(mockNative.isReady()).thenReturn(true);
- when(mockNative.rangeRequest(anyInt(), any(RangingRequest.class), anyBoolean())).thenReturn(
+ when(mockRttControllerHal.rangeRequest(anyInt(), any(RangingRequest.class))).thenReturn(
true);
+ when(mockHalDeviceManager.isStarted()).thenReturn(true);
when(mWifiSettingsConfigStore.get(eq(WIFI_VERBOSE_LOGGING_ENABLED))).thenReturn(true);
mMockPowerManager = new PowerManager(mockContext, mock(IPowerManager.class),
@@ -233,17 +246,23 @@ public class RttServiceImplTest extends WifiBaseTest {
doAnswer(mBinderLinkToDeathCounter).when(mockIbinder).linkToDeath(any(), anyInt());
doAnswer(mBinderUnlinkToDeathCounter).when(mockIbinder).unlinkToDeath(any(), anyInt());
- mDut.start(mMockLooper.getLooper(), mockClock, mockAwareManager, mockNative,
- mockMetrics, mockPermissionUtil, mWifiSettingsConfigStore);
+ mDut.start(mMockLooper.getLooper(), mockClock, mockAwareManager, mockMetrics,
+ mockPermissionUtil, mWifiSettingsConfigStore, mockHalDeviceManager);
mMockLooper.dispatchAll();
ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass(
BroadcastReceiver.class);
verify(mockContext, times(2)).registerReceiver(bcastRxCaptor.capture(),
any(IntentFilter.class));
- verify(mockNative).start(any());
mPowerBcastReceiver = bcastRxCaptor.getAllValues().get(0);
mLocationModeReceiver = bcastRxCaptor.getAllValues().get(1);
+ verify(mockHalDeviceManager).registerRttControllerLifecycleCallback(
+ mRttLifecycleCbCaptor.capture(), any());
+ mRttLifecycleCbCaptor.getValue().onNewRttController(mockRttControllerHal);
+ verify(mockRttControllerHal).registerRangingResultsCallback(
+ mRangingResultsCbCaptor.capture());
+
+ validateCorrectRttStatusChangeBroadcast();
assertTrue(mDut.isAvailable());
}
@@ -257,6 +276,34 @@ public class RttServiceImplTest extends WifiBaseTest {
}
/**
+ * Validate that we react correctly (i.e. enable/disable RTT availability) when
+ * notified that the RTT controller has disappeared and appeared.
+ */
+ @Test
+ public void testRttControllerLifecycle() throws Exception {
+ // RTT controller disappears
+ mRttLifecycleCbCaptor.getValue().onRttControllerDestroyed();
+ assertFalse(mDut.isAvailable());
+ validateCorrectRttStatusChangeBroadcast();
+
+ // RTT controller re-appears
+ mRttLifecycleCbCaptor.getValue().onNewRttController(mockRttControllerHal);
+ verify(mockRttControllerHal, times(2)).registerRangingResultsCallback(any());
+ assertTrue(mDut.isAvailable());
+ verify(mockMetrics).enableVerboseLogging(anyBoolean());
+ verifyNoMoreInteractions(mockRttControllerHal);
+ validateCorrectRttStatusChangeBroadcast();
+
+
+ // RTT controller switch - previous is invalid and new one is created. Should not send the
+ // broadcast
+ mRttLifecycleCbCaptor.getValue().onNewRttController(mockRttControllerHal);
+ verify(mockRttControllerHal, times(3)).registerRangingResultsCallback(any());
+ mInOrder.verify(mockContext, never())
+ .sendBroadcastAsUser(any(Intent.class), eq(UserHandle.ALL));
+ }
+
+ /**
* Validate successful ranging flow.
*/
@Test
@@ -286,12 +333,13 @@ public class RttServiceImplTest extends WifiBaseTest {
for (int i = 0; i < numIter; ++i) {
clock.time += MEASUREMENT_DURATION;
- // (2) verify that request issued to native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(requests[i]), eq(true));
+ // (2) verify that the request was issued to the WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(requests[i]));
verifyWakeupSet(i % 2 != 0, 0);
- // (3) native calls back with result
- mDut.onRangingResults(mIntCaptor.getValue(), results.get(i).second);
+ // (3) HAL calls back with result
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.get(i).second);
mMockLooper.dispatchAll();
// (4) verify that results dispatched
@@ -299,7 +347,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verifyWakeupCancelled();
// (5) replicate results - shouldn't dispatch another callback
- mDut.onRangingResults(mIntCaptor.getValue(), results.get(i).second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.get(i).second);
mMockLooper.dispatchAll();
}
@@ -311,10 +360,8 @@ public class RttServiceImplTest extends WifiBaseTest {
}
verify(mockMetrics, times(numIter)).recordOverallStatus(
WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -357,12 +404,12 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- // verify that requested with MAC address translated from the PeerHandle issued to Native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), mRequestCaptor.capture(), eq(true));
+ // verify that the request is translated from the PeerHandle issued to WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), mRequestCaptor.capture());
verifyWakeupSet(true, 0);
RangingRequest finalRequest = mRequestCaptor.getValue();
- assertNotEquals("Request to native is not null", null, finalRequest);
+ assertNotEquals("Request to WifiRttController is not null", null, finalRequest);
assertEquals("Size of request", request.mRttPeers.size() - 1,
finalRequest.mRttPeers.size());
assertEquals("Aware peer 1 MAC", MacAddress.fromBytes(peerMapping1.macAddress),
@@ -379,7 +426,8 @@ public class RttServiceImplTest extends WifiBaseTest {
new RangingResult(RangingResult.STATUS_FAIL, removed.getPeerHandle(), 0, 0, 0, 0, 0,
null, null, null, 0));
clock.time += MEASUREMENT_DURATION;
- mDut.onRangingResults(mIntCaptor.getValue(), results.first);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.first);
mMockLooper.dispatchAll();
// verify that results with MAC addresses filtered out and replaced by PeerHandles issued
@@ -395,11 +443,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockMetrics).recordResult(eq(finalRequest), eq(results.first),
eq(MEASUREMENT_DURATION));
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
if (SdkLevel.isAtLeastT()) {
// Nearby permission should never be checked here since the request contains APs others
@@ -410,7 +455,7 @@ public class RttServiceImplTest extends WifiBaseTest {
}
/**
- * Verifity that for ranging request to only aware APs, nearby devices permission can be used
+ * Verify that for ranging request to only aware APs, nearby devices' permission can be used
* to bypass location check.
* @throws Exception
*/
@@ -432,15 +477,16 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- // verify that requested with MAC address translated from the PeerHandle issued to Native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), mRequestCaptor.capture(), eq(true));
+ // verify that the request is translated from the PeerHandle issued to WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), mRequestCaptor.capture());
verifyWakeupSet(true, 0);
// issue results
Pair<List<RangingResult>, List<RangingResult>> results =
RttTestUtils.getDummyRangingResults(mRequestCaptor.getValue());
clock.time += MEASUREMENT_DURATION;
- mDut.onRangingResults(mIntCaptor.getValue(), results.first);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.first);
mMockLooper.dispatchAll();
// Verify permission checks. Post T Aware ranging can be done with nearby permission.
@@ -450,10 +496,10 @@ public class RttServiceImplTest extends WifiBaseTest {
}
/**
- * Validate failed ranging flow (native failure).
+ * Validate failed ranging flow (WifiRttController failure).
*/
@Test
- public void testRangingFlowNativeFailure() throws Exception {
+ public void testRangingFlowHalFailure() throws Exception {
int numIter = 10;
RangingRequest[] requests = new RangingRequest[numIter];
List<Pair<List<RangingResult>, List<RangingResult>>> results = new ArrayList<>();
@@ -464,13 +510,13 @@ public class RttServiceImplTest extends WifiBaseTest {
}
// (1) request 10 ranging operations: fail the first one
- when(mockNative.rangeRequest(anyInt(), any(RangingRequest.class), anyBoolean())).thenReturn(
+ when(mockRttControllerHal.rangeRequest(anyInt(), any(RangingRequest.class))).thenReturn(
false);
mDut.startRanging(mockIbinder, mPackageName, mFeatureId, null, requests[0],
mockCallback, mExtras);
mMockLooper.dispatchAll();
- when(mockNative.rangeRequest(anyInt(), any(RangingRequest.class), anyBoolean())).thenReturn(
+ when(mockRttControllerHal.rangeRequest(anyInt(), any(RangingRequest.class))).thenReturn(
true);
for (int i = 1; i < numIter; ++i) {
mDut.startRanging(mockIbinder, mPackageName, mFeatureId, null, requests[i],
@@ -479,19 +525,20 @@ public class RttServiceImplTest extends WifiBaseTest {
mMockLooper.dispatchAll();
for (int i = 0; i < numIter; ++i) {
- // (2) verify that request issued to native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(requests[i]), eq(true));
+ // (2) verify that the request was issued to the WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(requests[i]));
- // (3) verify that failure callback dispatched (for the HAL failure)
+ // (3) verify that failure callback dispatched (for the WifiRttController failure)
if (i == 0) {
verify(mockCallback).onRangingFailure(RangingResultCallback.STATUS_CODE_FAIL);
} else {
verifyWakeupSet(true, 0);
}
- // (4) on failed HAL: even if native calls back with result we shouldn't dispatch
+ // (4) on failed HAL: even if the HAL calls back with result we shouldn't dispatch
// callback, otherwise expect result
- mDut.onRangingResults(mIntCaptor.getValue(), results.get(i).second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.get(i).second);
mMockLooper.dispatchAll();
if (i != 0) {
@@ -511,11 +558,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_HAL_FAILURE);
verify(mockMetrics, times(numIter - 1)).recordOverallStatus(
WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -533,15 +577,16 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- // (2) verify that request issued to native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ // (2) verify that the request was issued to the WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
- // (3) native calls back with result - should get a FAILED callback
+ // (3) HAL calls back with result - should get a FAILED callback
when(mockPermissionUtil.checkCallersLocationPermission(eq(mPackageName), eq(mFeatureId),
anyInt(), anyBoolean(), nullable(String.class))).thenReturn(false);
- mDut.onRangingResults(mIntCaptor.getValue(), results.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.second);
mMockLooper.dispatchAll();
verify(mockCallback).onRangingFailure(eq(RangingResultCallback.STATUS_CODE_FAIL));
@@ -551,11 +596,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockMetrics).recordRequest(eq(mDefaultWs), eq(request));
verify(mockMetrics).recordOverallStatus(
WifiMetricsProto.WifiRttLog.OVERALL_LOCATION_PERMISSION_MISSING);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -586,9 +628,9 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockIbinder, times(numIter)).linkToDeath(mDeathRecipientCaptor.capture(), anyInt());
for (int i = 0; i < numIter; ++i) {
- // (3) verify first request and all odd requests issued to HAL
+ // (3) verify first request and all odd requests were issued to the WifiRttController
if (i == 0 || i % 2 == 1) {
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(requests[i]), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(requests[i]));
verifyWakeupSet(true, 0);
}
@@ -597,22 +639,23 @@ public class RttServiceImplTest extends WifiBaseTest {
mDeathRecipientCaptor.getAllValues().get(0).binderDied();
mMockLooper.dispatchAll();
- verify(mockNative).rangeCancel(eq(mIntCaptor.getValue()),
+ verify(mockRttControllerHal).rangeCancel(eq(mIntCaptor.getValue()),
(ArrayList) mListCaptor.capture());
RangingRequest request0 = requests[0];
assertEquals(request0.mRttPeers.size(), mListCaptor.getValue().size());
- assertArrayEquals(MacAddress.fromString("00:01:02:03:04:00").toByteArray(),
- (byte[]) mListCaptor.getValue().get(0));
- assertArrayEquals(MacAddress.fromString("0A:0B:0C:0D:0E:00").toByteArray(),
- (byte[]) mListCaptor.getValue().get(1));
- assertArrayEquals(MacAddress.fromString("08:09:08:07:06:05").toByteArray(),
- (byte[]) mListCaptor.getValue().get(2));
+ assertTrue(MacAddress.fromString("00:01:02:03:04:00")
+ .equals(mListCaptor.getValue().get(0)));
+ assertTrue(MacAddress.fromString("0A:0B:0C:0D:0E:00")
+ .equals(mListCaptor.getValue().get(1)));
+ assertTrue(MacAddress.fromString("08:09:08:07:06:05")
+ .equals(mListCaptor.getValue().get(2)));
}
- // (5) native calls back with all results - should get requests for the odd attempts and
+ // (5) HAL calls back with all results - should get requests for the odd attempts and
// should only get callbacks for the odd attempts (the non-dead UID), but this simulates
// invalid results (or possibly the firmware not cancelling some requests)
- mDut.onRangingResults(mIntCaptor.getValue(), results.get(i).second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.get(i).second);
mMockLooper.dispatchAll();
if (i == 0) {
verifyWakeupCancelled(); // as the first (dispatched) request is aborted
@@ -635,11 +678,8 @@ public class RttServiceImplTest extends WifiBaseTest {
}
verify(mockMetrics, times(numIter / 2)).recordOverallStatus(
WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -661,27 +701,25 @@ public class RttServiceImplTest extends WifiBaseTest {
mMockLooper.dispatchAll();
verify(mockIbinder).linkToDeath(mDeathRecipientCaptor.capture(), anyInt());
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
// (2) execute binder death
mDeathRecipientCaptor.getValue().binderDied();
mMockLooper.dispatchAll();
- verify(mockNative).rangeCancel(eq(mIntCaptor.getValue()), any());
+ verify(mockRttControllerHal).rangeCancel(eq(mIntCaptor.getValue()), any());
verifyWakeupCancelled();
// (3) provide results back - should be ignored
- mDut.onRangingResults(mIntCaptor.getValue(), results.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.second);
mMockLooper.dispatchAll();
// verify metrics
verify(mockMetrics).recordRequest(eq(ws), eq(request));
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -716,25 +754,24 @@ public class RttServiceImplTest extends WifiBaseTest {
// verify metrics
verify(mockMetrics).recordRequest(eq(worksourceRequest), eq(request));
- // (2) verify that request issued to native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ // (2) verify that the request was issued to the WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
// (3) cancel the request
mDut.cancelRanging(worksourceCancel);
mMockLooper.dispatchAll();
- verify(mockNative).rangeCancel(eq(mIntCaptor.getValue()), any());
+ verify(mockRttControllerHal).rangeCancel(eq(mIntCaptor.getValue()), any());
verifyWakeupCancelled();
- // (4) send results back from native
- mDut.onRangingResults(mIntCaptor.getValue(), results.second);
+ // (4) send results back from the HAL
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.second);
mMockLooper.dispatchAll();
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -765,15 +802,16 @@ public class RttServiceImplTest extends WifiBaseTest {
// verify metrics
verify(mockMetrics).recordRequest(eq(worksourceRequest), eq(request));
- // (2) verify that request issued to native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ // (2) verify that the request was issued to the WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
// (3) cancel the request
mDut.cancelRanging(worksourceCancel);
- // (4) send results back from native
- mDut.onRangingResults(mIntCaptor.getValue(), results.second);
+ // (4) send results back from the HAL
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.second);
mMockLooper.dispatchAll();
verify(mockCallback).onRangingResults(results.second);
@@ -782,16 +820,13 @@ public class RttServiceImplTest extends WifiBaseTest {
// verify metrics
verify(mockMetrics).recordResult(eq(request), eq(results.second), anyInt());
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
/**
- * Validate that when an unexpected result is provided by the Native it is not propagated to
+ * Validate that when an unexpected result is provided by the HAL it is not propagated to
* caller (unexpected = different command ID).
*/
@Test
@@ -805,17 +840,19 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- // (2) verify that request issued to native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ // (2) verify that the request was issued to the WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
- // (3) native calls back with result - but wrong ID
- mDut.onRangingResults(mIntCaptor.getValue() + 1,
+ // (3) HAL calls back with result - but wrong ID
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue() + 1,
RttTestUtils.getDummyRangingResults(null).second);
mMockLooper.dispatchAll();
// (4) now send results with correct ID (different set of results to differentiate)
- mDut.onRangingResults(mIntCaptor.getValue(), results.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.second);
mMockLooper.dispatchAll();
// (5) verify that results dispatched
@@ -826,11 +863,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockMetrics).recordRequest(eq(mDefaultWs), eq(request));
verify(mockMetrics).recordResult(eq(request), eq(results.second), anyInt());
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -859,12 +893,13 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- // (2) verify that request issued to native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ // (2) verify that the request was issued to the WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
// (3) return results with missing entries
- mDut.onRangingResults(mIntCaptor.getValue(), results.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), results.second);
mMockLooper.dispatchAll();
// (5) verify that (full) results dispatched
@@ -876,11 +911,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockMetrics).recordRequest(eq(mDefaultWs), eq(request));
verify(mockMetrics).recordResult(eq(request), eq(results.second), anyInt());
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -905,12 +937,13 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- // (2) verify that request issued to native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ // (2) verify that the request was issued to the WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
// (3) return results with ALL results missing
- mDut.onRangingResults(mIntCaptor.getValue(), new ArrayList<>());
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), new ArrayList<>());
mMockLooper.dispatchAll();
// (5) verify that (full) results dispatched
@@ -922,11 +955,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockMetrics).recordRequest(eq(mDefaultWs), eq(request));
verify(mockMetrics).recordResult(eq(request), eq(new ArrayList<>()), anyInt());
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -950,8 +980,8 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- // verify that request 1 issued to native
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request1), eq(true));
+ // verify that request 1 was issued to the WifiRttController
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request1));
int cmdId1 = mIntCaptor.getValue();
verifyWakeupSet(true, 0);
@@ -959,15 +989,17 @@ public class RttServiceImplTest extends WifiBaseTest {
mAlarmManager.dispatch(RttServiceImpl.HAL_RANGING_TIMEOUT_TAG);
mMockLooper.dispatchAll();
- // verify that: failure callback + request 2 issued to native
- verify(mockNative).rangeCancel(eq(cmdId1), any());
+ // verify that the failure callback + request 2 were issued to the WifiRttController
+ verify(mockRttControllerHal).rangeCancel(eq(cmdId1), any());
verify(mockCallback).onRangingFailure(RangingResultCallback.STATUS_CODE_FAIL);
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request2), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request2));
verifyWakeupSet(true, 0);
// (3) send both result 1 and result 2
- mDut.onRangingResults(cmdId1, result1.second);
- mDut.onRangingResults(mIntCaptor.getValue(), result2.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(cmdId1, result1.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), result2.second);
mMockLooper.dispatchAll();
// verify that only result 2 is forwarded to client
@@ -980,11 +1012,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockMetrics).recordResult(eq(request2), eq(result2.second), anyInt());
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_TIMEOUT);
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -1027,11 +1056,12 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request1), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request1));
verifyWakeupSet(true, clock.time);
// (1.1) get result
- mDut.onRangingResults(mIntCaptor.getValue(), result1.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), result1.second);
mMockLooper.dispatchAll();
cbInorder.verify(mockCallback).onRangingResults(result1.second);
@@ -1051,11 +1081,12 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request3), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request3));
verifyWakeupSet(true, clock.time);
// (3.1) get result
- mDut.onRangingResults(mIntCaptor.getValue(), result3.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), result3.second);
mMockLooper.dispatchAll();
cbInorder.verify(mockCallback).onRangingResults(result3.second);
@@ -1070,11 +1101,12 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request4), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request4));
verifyWakeupSet(true, clock.time);
// (4.1) get result
- mDut.onRangingResults(mIntCaptor.getValue(), result4.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), result4.second);
mMockLooper.dispatchAll();
cbInorder.verify(mockCallback).onRangingResults(result4.second);
@@ -1103,11 +1135,12 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request6), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request6));
verifyWakeupSet(true, clock.time);
// (6.1) get result
- mDut.onRangingResults(mIntCaptor.getValue(), result6.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), result6.second);
mMockLooper.dispatchAll();
cbInorder.verify(mockCallback).onRangingResults(result6.second);
@@ -1128,11 +1161,8 @@ public class RttServiceImplTest extends WifiBaseTest {
WifiMetricsProto.WifiRttLog.OVERALL_THROTTLE);
verify(mockMetrics, times(4)).recordOverallStatus(
WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -1189,11 +1219,12 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request1), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request1));
verifyWakeupSet(true, clock.time);
// (1.1) get result
- mDut.onRangingResults(mIntCaptor.getValue(), result1.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), result1.second);
mMockLooper.dispatchAll();
cbInorder.verify(mockCallback).onRangingResults(result1.second);
@@ -1206,11 +1237,12 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request2), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request2));
verifyWakeupSet(true, clock.time);
// (2.1) get result
- mDut.onRangingResults(mIntCaptor.getValue(), result2.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), result2.second);
mMockLooper.dispatchAll();
cbInorder.verify(mockCallback).onRangingResults(result2.second);
@@ -1233,11 +1265,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_THROTTLE);
verify(mockMetrics, times(2)).recordOverallStatus(
WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -1279,7 +1308,7 @@ public class RttServiceImplTest extends WifiBaseTest {
mockCallback, mExtras);
mMockLooper.dispatchAll();
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
// 2. issue FLOOD LEVEL requests + 10 at various UIDs - no failure expected
@@ -1296,7 +1325,7 @@ public class RttServiceImplTest extends WifiBaseTest {
mMockLooper.dispatchAll();
verifyWakeupCancelled();
- verify(mockNative).rangeCancel(eq(mIntCaptor.getValue()), any());
+ verify(mockRttControllerHal).rangeCancel(eq(mIntCaptor.getValue()), any());
verify(mockCallback, times(RttServiceImpl.MAX_QUEUED_PER_UID + 11))
.onRangingFailure(RangingResultCallback.STATUS_CODE_FAIL_RTT_NOT_AVAILABLE);
@@ -1310,14 +1339,24 @@ public class RttServiceImplTest extends WifiBaseTest {
}
verify(mockMetrics, times(RttServiceImpl.MAX_QUEUED_PER_UID + 11))
.recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_RTT_NOT_AVAILABLE);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
+ @Test
+ public void testGetRttCharacteristics() {
+ WifiRttController.Capabilities cap = new WifiRttController.Capabilities();
+ cap.lcrSupported = true;
+ cap.oneSidedRttSupported = true;
+ cap.lciSupported = true;
+ when(mockRttControllerHal.getRttCapabilities()).thenReturn(cap);
+ Bundle characteristics = mDut.getRttCharacteristics();
+ assertTrue(characteristics.getBoolean(CHARACTERISTICS_KEY_BOOLEAN_ONE_SIDED_RTT));
+ assertTrue(characteristics.getBoolean(CHARACTERISTICS_KEY_BOOLEAN_LCI));
+ assertTrue(characteristics.getBoolean(CHARACTERISTICS_KEY_BOOLEAN_LCR));
+ }
+
/**
* Utility to run configurable tests for flooding range requests.
* - Execute a single request
@@ -1342,14 +1381,15 @@ public class RttServiceImplTest extends WifiBaseTest {
}
InOrder cbInorder = inOrder(mockCallback);
- InOrder nativeInorder = inOrder(mockNative);
+ InOrder controllerInorder = inOrder(mockRttControllerHal);
// 1. issue a request
mDut.startRanging(mockIbinder, mPackageName, mFeatureId, useUids ? null : ws, request,
mockCallback, mExtras);
mMockLooper.dispatchAll();
- nativeInorder.verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ controllerInorder.verify(mockRttControllerHal).rangeRequest(
+ mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
// 2. issue FLOOD LEVEL requests + 10: should get 11 failures (10 extra + 1 original)
@@ -1363,13 +1403,15 @@ public class RttServiceImplTest extends WifiBaseTest {
RangingResultCallback.STATUS_CODE_FAIL);
// 3. provide results
- mDut.onRangingResults(mIntCaptor.getValue(), result.second);
+ mRangingResultsCbCaptor.getValue()
+ .onRangingResults(mIntCaptor.getValue(), result.second);
mMockLooper.dispatchAll();
cbInorder.verify(mockCallback).onRangingResults(result.second);
verifyWakeupCancelled();
- nativeInorder.verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request), eq(true));
+ controllerInorder.verify(mockRttControllerHal).rangeRequest(
+ mIntCaptor.capture(), eq(request));
verifyWakeupSet(true, 0);
// 4. issue a request: don't expect a failure
@@ -1382,7 +1424,8 @@ public class RttServiceImplTest extends WifiBaseTest {
mMockLooper.dispatchAll();
verifyWakeupCancelled();
- nativeInorder.verify(mockNative).rangeCancel(eq(mIntCaptor.getValue()), any());
+ controllerInorder.verify(mockRttControllerHal).rangeCancel(
+ eq(mIntCaptor.getValue()), any());
cbInorder.verify(mockCallback, times(RttServiceImpl.MAX_QUEUED_PER_UID)).onRangingFailure(
RangingResultCallback.STATUS_CODE_FAIL_RTT_NOT_AVAILABLE);
@@ -1395,11 +1438,8 @@ public class RttServiceImplTest extends WifiBaseTest {
verify(mockMetrics, times(RttServiceImpl.MAX_QUEUED_PER_UID)).recordOverallStatus(
WifiMetricsProto.WifiRttLog.OVERALL_RTT_NOT_AVAILABLE);
verify(mockMetrics).recordOverallStatus(WifiMetricsProto.WifiRttLog.OVERALL_SUCCESS);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback,
mAlarmManager.getAlarmManager());
}
@@ -1447,20 +1487,19 @@ public class RttServiceImplTest extends WifiBaseTest {
IRttCallback mockCallback2 = mock(IRttCallback.class);
IRttCallback mockCallback3 = mock(IRttCallback.class);
- // (1) request 2 ranging operations: request 1 should be sent to HAL
+ // (1) request 2 ranging operations: request 1 should be sent to the WifiRttController
mDut.startRanging(mockIbinder, mPackageName, mFeatureId, null, request1,
mockCallback, mExtras);
mDut.startRanging(mockIbinder, mPackageName, mFeatureId, null, request2,
mockCallback2, mExtras);
mMockLooper.dispatchAll();
- verify(mockNative).rangeRequest(mIntCaptor.capture(), eq(request1), eq(true));
+ verify(mockRttControllerHal).rangeRequest(mIntCaptor.capture(), eq(request1));
verifyWakeupSet(true, 0);
// (2) disable RTT: all requests should "fail"
if (failureMode == FAILURE_MODE_DISABLE_WIFI) {
- when(mockNative.isReady()).thenReturn(false);
- mDut.disable();
+ mRttLifecycleCbCaptor.getValue().onRttControllerDestroyed();
} else if (failureMode == FAILURE_MODE_ENABLE_DOZE) {
simulatePowerStateChangeDoze(true);
} else if (failureMode == FAILURE_MODE_DISABLE_LOCATIONING) {
@@ -1470,8 +1509,10 @@ public class RttServiceImplTest extends WifiBaseTest {
mMockLooper.dispatchAll();
assertFalse(mDut.isAvailable());
- validateCorrectRttStatusChangeBroadcast(false);
- verify(mockNative).rangeCancel(eq(mIntCaptor.getValue()), any());
+ validateCorrectRttStatusChangeBroadcast();
+ if (failureMode != FAILURE_MODE_DISABLE_WIFI) {
+ verify(mockRttControllerHal).rangeCancel(eq(mIntCaptor.getValue()), any());
+ }
verify(mockCallback).onRangingFailure(
RangingResultCallback.STATUS_CODE_FAIL_RTT_NOT_AVAILABLE);
verify(mockCallback2).onRangingFailure(
@@ -1488,8 +1529,8 @@ public class RttServiceImplTest extends WifiBaseTest {
// (4) enable RTT: nothing should happen (no requests in queue!)
if (failureMode == FAILURE_MODE_DISABLE_WIFI) {
- when(mockNative.isReady()).thenReturn(true);
- mDut.enableIfPossible();
+ mRttLifecycleCbCaptor.getValue().onNewRttController(mockRttControllerHal);
+ verify(mockRttControllerHal, times(2)).registerRangingResultsCallback(any());
} else if (failureMode == FAILURE_MODE_ENABLE_DOZE) {
simulatePowerStateChangeDoze(false);
} else if (failureMode == FAILURE_MODE_DISABLE_LOCATIONING) {
@@ -1499,18 +1540,15 @@ public class RttServiceImplTest extends WifiBaseTest {
mMockLooper.dispatchAll();
assertTrue(mDut.isAvailable());
- validateCorrectRttStatusChangeBroadcast(true);
+ validateCorrectRttStatusChangeBroadcast();
// verify metrics
verify(mockMetrics).recordRequest(eq(mDefaultWs), eq(request1));
verify(mockMetrics).recordRequest(eq(mDefaultWs), eq(request2));
verify(mockMetrics, times(3)).recordOverallStatus(
WifiMetricsProto.WifiRttLog.OVERALL_RTT_NOT_AVAILABLE);
-
- verify(mockNative, atLeastOnce()).isReady();
verify(mockMetrics).enableVerboseLogging(anyBoolean());
- verify(mockNative).enableVerboseLogging(anyBoolean());
- verifyNoMoreInteractions(mockNative, mockMetrics, mockCallback, mockCallback2,
+ verifyNoMoreInteractions(mockRttControllerHal, mockMetrics, mockCallback, mockCallback2,
mockCallback3, mAlarmManager.getAlarmManager());
}
@@ -1556,10 +1594,8 @@ public class RttServiceImplTest extends WifiBaseTest {
/**
* Validates that the broadcast sent on RTT status change is correct.
*
- * @param expectedEnabled The expected change status - i.e. are we expected to announce that
- * RTT is enabled (true) or disabled (false).
*/
- private void validateCorrectRttStatusChangeBroadcast(boolean expectedEnabled) {
+ private void validateCorrectRttStatusChangeBroadcast() {
ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
mInOrder.verify(mockContext).sendBroadcastAsUser(intent.capture(), eq(UserHandle.ALL));
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 9d68fa81aa..32583e69f6 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
@@ -36,6 +36,7 @@ import static com.android.server.wifi.scanner.WifiScanningServiceImpl.WifiSingle
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.any;
@@ -69,6 +70,7 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.os.BatteryStatsManager;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.WorkSource;
@@ -86,6 +88,7 @@ import com.android.server.wifi.MockResources;
import com.android.server.wifi.ScanResults;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiInjector;
+import com.android.server.wifi.WifiLocalServices;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
@@ -104,7 +107,6 @@ import org.mockito.Spy;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -147,6 +149,7 @@ public class WifiScanningServiceTest extends WifiBaseTest {
PresetKnownBandsChannelHelper mChannelHelper1;
TestLooper mLooper;
WifiScanningServiceImpl mWifiScanningServiceImpl;
+ private Bundle mExtras = new Bundle();
@Before
public void setUp() throws Exception {
@@ -195,6 +198,12 @@ public class WifiScanningServiceTest extends WifiBaseTest {
anyInt(), eq(Binder.getCallingUid())))
.thenReturn(PERMISSION_GRANTED);
when(mWifiInjector.getLastCallerInfoManager()).thenReturn(mLastCallerInfoManager);
+ // Defaulting apps to target SDK level that's prior to U. This is needed to test for
+ // backward compatibility of API changes.
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(any(),
+ eq(Build.VERSION_CODES.UPSIDE_DOWN_CAKE),
+ anyInt())).thenReturn(true);
+ WifiLocalServices.removeServiceForTest(WifiScannerInternal.class);
mWifiScanningServiceImpl = new WifiScanningServiceImpl(mContext, mLooper.getLooper(),
mWifiScannerImplFactory, mBatteryStats, mWifiInjector);
}
@@ -593,6 +602,8 @@ public class WifiScanningServiceTest extends WifiBaseTest {
0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings),
ScanResults.create(0, WifiScanner.WIFI_BAND_BOTH, new int[0]));
+ verify(mLastCallerInfoManager).put(eq(WifiManager.API_WIFI_SCANNER_START_SCAN), anyInt(),
+ anyInt(), anyInt(), anyString(), eq(true));
}
/**
@@ -1839,10 +1850,9 @@ public class WifiScanningServiceTest extends WifiBaseTest {
scanResults.getRawScanResults()[1].timestamp = (currentTimeInMillis - 2) * 1000;
scanResults.getRawScanResults()[2].timestamp =
(currentTimeInMillis - CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS) * 1000;
- List<ScanResult> expectedResults = new ArrayList<ScanResult>() {{
- add(scanResults.getRawScanResults()[0]);
- add(scanResults.getRawScanResults()[1]);
- }};
+ List<ScanResult> expectedResults = List.of(
+ scanResults.getRawScanResults()[0],
+ scanResults.getRawScanResults()[1]);
doSuccessfulSingleScan(requestSettings,
computeSingleScanNativeSettings(requestSettings), scanResults);
@@ -3353,6 +3363,44 @@ public class WifiScanningServiceTest extends WifiBaseTest {
mWifiScanningServiceImpl.isScanning());
}
+ @Test
+ public void getAvailableChannels_noPermission_throwsException_After_U() {
+ assumeTrue(SdkLevel.isAtLeastU());
+ startServiceAndLoadDriver();
+
+ // verify app targeting prior to Android U can call API with location permission
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(any(),
+ eq(Build.VERSION_CODES.UPSIDE_DOWN_CAKE),
+ anyInt())).thenReturn(true);
+ mWifiScanningServiceImpl.getAvailableChannels(WifiScanner.WIFI_BAND_24_GHZ,
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras);
+
+ // Verify app targeting prior to Android U fails to call API without location permission
+ doThrow(new SecurityException()).when(mContext).enforcePermission(
+ eq(Manifest.permission.NETWORK_STACK), anyInt(), eq(Binder.getCallingUid()), any());
+ doThrow(new SecurityException())
+ .when(mWifiPermissionsUtil).enforceCanAccessScanResultsForWifiScanner(
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID, Binder.getCallingUid(), false, false);
+ assertThrows(SecurityException.class,
+ () -> mWifiScanningServiceImpl.getAvailableChannels(WifiScanner.WIFI_BAND_24_GHZ,
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras));
+
+ // Verify app targeting Android U no longer need location.
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(any(),
+ eq(Build.VERSION_CODES.UPSIDE_DOWN_CAKE),
+ anyInt())).thenReturn(false);
+ mWifiScanningServiceImpl.getAvailableChannels(WifiScanner.WIFI_BAND_24_GHZ,
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras);
+
+ // Verify app targeting Android U will fail without nearby permission
+ doThrow(new SecurityException())
+ .when(mWifiPermissionsUtil).enforceNearbyDevicesPermission(
+ any(), anyBoolean(), any());
+ assertThrows(SecurityException.class,
+ () -> mWifiScanningServiceImpl.getAvailableChannels(WifiScanner.WIFI_BAND_24_GHZ,
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras));
+ }
+
/**
* Tests that {@link WifiScanningServiceImpl#getAvailableChannels(int, String)} throws a
* {@link SecurityException} if the caller doesn't hold the required permissions.
@@ -3371,7 +3419,7 @@ public class WifiScanningServiceTest extends WifiBaseTest {
TEST_PACKAGE_NAME, TEST_FEATURE_ID, Binder.getCallingUid(), false, false);
mWifiScanningServiceImpl.getAvailableChannels(WifiScanner.WIFI_BAND_24_GHZ,
- TEST_PACKAGE_NAME, TEST_FEATURE_ID);
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras);
}
/**
@@ -3392,7 +3440,7 @@ public class WifiScanningServiceTest extends WifiBaseTest {
mLooper.startAutoDispatch();
Bundle bundle = mWifiScanningServiceImpl.getAvailableChannels(
- WifiScanner.WIFI_BAND_24_GHZ, TEST_PACKAGE_NAME, TEST_FEATURE_ID);
+ WifiScanner.WIFI_BAND_24_GHZ, TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras);
mLooper.stopAutoDispatchAndIgnoreExceptions();
List<Integer> actual = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
@@ -3418,7 +3466,7 @@ public class WifiScanningServiceTest extends WifiBaseTest {
mLooper.startAutoDispatch();
Bundle bundle = mWifiScanningServiceImpl.getAvailableChannels(
- WifiScanner.WIFI_BAND_24_GHZ, TEST_PACKAGE_NAME, TEST_FEATURE_ID);
+ WifiScanner.WIFI_BAND_24_GHZ, TEST_PACKAGE_NAME, TEST_FEATURE_ID, mExtras);
mLooper.stopAutoDispatchAndIgnoreExceptions();
List<Integer> actual = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
@@ -3557,4 +3605,43 @@ public class WifiScanningServiceTest extends WifiBaseTest {
mWifiScanningServiceImpl.stopPnoScan(client.listener, TEST_PACKAGE_NAME, null);
mLooper.dispatchAll();
}
+
+ /**
+ * Do a single scan and then stop.
+ * Expect scan canceled.
+ */
+ @Test
+ public void sendSingleScanRequestAndThenStop()
+ throws Exception {
+ WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2412), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ ScanResults results = ScanResults.create(0, WifiScanner.WIFI_BAND_UNSPECIFIED, 2412);
+
+ startServiceAndLoadDriver();
+
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ TestClient client = new TestClient();
+ InOrder order = inOrder(client.listener, mWifiScannerImpl0);
+
+ // Run scan
+ client.sendSingleScanRequest(requestSettings, null);
+ mLooper.dispatchAll();
+ client.verifySuccessfulResponse();
+ WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order,
+ computeSingleScanNativeSettings(requestSettings));
+ //Stop scan
+ mWifiScanningServiceImpl.stopScan(client.listener, TEST_PACKAGE_NAME, TEST_FEATURE_ID);
+ mLooper.dispatchAll();
+ // dispatch scan results
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
+ .thenReturn(results.getScanData());
+ eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ // Stopped scan should not receive results
+ mLooper.dispatchAll();
+ order.verify(client.listener, never()).onResults(any());
+ order.verify(client.listener, never()).onSingleScanCompleted();
+ }
}
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 3f9cb51010..0ee9ea2484 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
@@ -941,9 +941,8 @@ public class ApConfigUtilTest extends WifiBaseTest {
mockSoftApCapability));
// Reset client control
testConfigBuilder.setClientControlByUserEnabled(false);
- //
- testConfigBuilder.setBlockedClientList(new ArrayList<>() {{
- add(MacAddress.fromString("aa:bb:cc:dd:ee:ff")); }});
+ testConfigBuilder.setBlockedClientList(List.of(
+ MacAddress.fromString("aa:bb:cc:dd:ee:ff")));
assertFalse(ApConfigUtil.checkSupportAllConfiguration(testConfigBuilder.build(),
mockSoftApCapability));
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/NativeUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/NativeUtilTest.java
index 566a94b45c..0ecf3b7d44 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/NativeUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/NativeUtilTest.java
@@ -17,15 +17,24 @@
package com.android.server.wifi.util;
import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.net.MacAddress;
+import android.net.wifi.SecurityParams;
+import android.net.wifi.WifiConfiguration;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.WifiBaseTest;
+import com.android.server.wifi.WifiConfigurationTestUtil;
+import com.android.server.wifi.WifiGlobals;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
/**
* Unit tests for {@link com.android.server.wifi.util.NativeUtil}.
@@ -53,6 +62,19 @@ public class NativeUtilTest extends WifiBaseTest {
}
/**
+ * Test that converting a colon delimited MAC address to android.net.MacAddress works. Also test
+ * invalid input exception is handled by NativeUtil#getMacAddressOrNull() and returns 'null'.
+ */
+ @Test
+ public void testGetMacAddressOrNull() throws Exception {
+ String macAddressStr = "11:22:33:44:55:66";
+ assertEquals(MacAddress.fromString(macAddressStr),
+ NativeUtil.getMacAddressOrNull(macAddressStr));
+ assertNull(NativeUtil.getMacAddressOrNull(":44:55:66"));
+ assertNull(NativeUtil.getMacAddressOrNull(null));
+ }
+
+ /**
* Test that conversion of byte array of mac address to typical colon-delimited MAC address
* works.
*/
@@ -227,4 +249,82 @@ public class NativeUtilTest extends WifiBaseTest {
assertEquals("abcdefgh", NativeUtil.removeEnclosingQuotes("\"abcdefgh\""));
assertEquals("abcdefgh", NativeUtil.removeEnclosingQuotes("abcdefgh"));
}
+
+ /**
+ * Test PMF is disable when SAE is selected when SAE auto-upgrade offload is supported.
+ */
+ @Test
+ public void testPmfIsDisableWhenPmfEnabledAndAutoUpgradeOffloadSupported() throws Exception {
+ WifiGlobals globals = mock(WifiGlobals.class);
+ when(globals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
+ assertFalse(NativeUtil.getOptimalPmfSettingForConfig(
+ WifiConfigurationTestUtil.createPskSaeNetwork(),
+ true, globals));
+ }
+
+ /**
+ * Test pairwise & group cihpers are merged when SAE auto-upgrade offload is supported.
+ */
+ @Test
+ public void testPairwiseCiphersMergedForSaeAutoUpgradeOffloadSupported() throws Exception {
+ WifiGlobals globals = mock(WifiGlobals.class);
+ when(globals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
+
+ SecurityParams saeParams = SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_SAE);
+ BitSet expectedPairwiseCiphers = new BitSet();
+ expectedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
+ expectedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ expectedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_128);
+ expectedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
+
+ BitSet optimalPairwiseCiphers = NativeUtil.getOptimalPairwiseCiphersForConfig(
+ WifiConfigurationTestUtil.createPskSaeNetwork(),
+ saeParams.getAllowedPairwiseCiphers(), globals);
+ assertEquals(expectedPairwiseCiphers, optimalPairwiseCiphers);
+
+ BitSet expectedGroupCiphers = new BitSet();
+ expectedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
+ expectedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
+ expectedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+ expectedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ expectedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_128);
+ expectedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+ BitSet optimalGroupCiphers = NativeUtil.getOptimalGroupCiphersForConfig(
+ WifiConfigurationTestUtil.createPskSaeNetwork(),
+ saeParams.getAllowedGroupCiphers(), globals);
+ assertEquals(expectedGroupCiphers, optimalGroupCiphers);
+ }
+
+ /**
+ * Test pairwise and group cihpers are not merged when SAE auto-upgrade offload
+ * is not supported.
+ */
+ @Test
+ public void testPairwiseCiphersNotMergedForSaeAutoUpgradeOffloadNotSupported()
+ throws Exception {
+ WifiGlobals globals = mock(WifiGlobals.class);
+ when(globals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(false);
+
+ SecurityParams saeParams = SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_SAE);
+ BitSet expectedPairwiseCiphers = new BitSet();
+ expectedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ expectedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_128);
+ expectedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256);
+
+ BitSet optimalPairwiseCiphers = NativeUtil.getOptimalPairwiseCiphersForConfig(
+ WifiConfigurationTestUtil.createPskSaeNetwork(),
+ saeParams.getAllowedPairwiseCiphers(), globals);
+ assertEquals(expectedPairwiseCiphers, optimalPairwiseCiphers);
+
+ BitSet expectedGroupCiphers = new BitSet();
+ expectedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ expectedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_128);
+ expectedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256);
+ BitSet optimalGroupCiphers = NativeUtil.getOptimalGroupCiphersForConfig(
+ WifiConfigurationTestUtil.createPskSaeNetwork(),
+ saeParams.getAllowedGroupCiphers(), globals);
+ assertEquals(expectedGroupCiphers, optimalGroupCiphers);
+ }
}