summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/Android.bp125
-rw-r--r--service/Android.mk68
-rw-r--r--service/AndroidManifest.xml89
-rw-r--r--service/AndroidManifest_InProcess.xml46
-rw-r--r--service/CleanSpec.mk18
-rw-r--r--service/TEST_MAPPING13
-rw-r--r--service/jarjar-rules-shared.txt21
-rw-r--r--service/java/com/android/server/wifi/ActiveModeManager.java18
-rw-r--r--service/java/com/android/server/wifi/ActiveModeWarden.java1091
-rw-r--r--service/java/com/android/server/wifi/AvailableNetworkNotifier.java44
-rw-r--r--service/java/com/android/server/wifi/BootCompleteReceiver.java98
-rw-r--r--service/java/com/android/server/wifi/BubbleFunScorer.java48
-rw-r--r--service/java/com/android/server/wifi/CarrierNetworkConfig.java21
-rw-r--r--service/java/com/android/server/wifi/CarrierNetworkEvaluator.java3
-rw-r--r--service/java/com/android/server/wifi/CarrierNetworkNotifier.java76
-rw-r--r--service/java/com/android/server/wifi/CellularLinkLayerStats.java90
-rw-r--r--service/java/com/android/server/wifi/CellularLinkLayerStatsCollector.java237
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java1387
-rw-r--r--service/java/com/android/server/wifi/ClientModeManager.java253
-rw-r--r--service/java/com/android/server/wifi/CompatibilityScorer.java14
-rw-r--r--service/java/com/android/server/wifi/ConfigurationMap.java6
-rw-r--r--service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java11
-rw-r--r--service/java/com/android/server/wifi/DefaultModeManager.java4
-rw-r--r--service/java/com/android/server/wifi/DeviceConfigFacade.java111
-rw-r--r--service/java/com/android/server/wifi/DppManager.java7
-rw-r--r--service/java/com/android/server/wifi/FrameworkFacade.java86
-rw-r--r--service/java/com/android/server/wifi/HalDeviceManager.java7
-rw-r--r--service/java/com/android/server/wifi/HostapdHal.java5
-rw-r--r--service/java/com/android/server/wifi/LastMileLogger.java2
-rw-r--r--service/java/com/android/server/wifi/LinkProbeManager.java5
-rw-r--r--service/java/com/android/server/wifi/LocalOnlyHotspotRequestInfo.java36
-rw-r--r--service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java16
-rw-r--r--service/java/com/android/server/wifi/NetworkSuggestionStoreData.java23
-rw-r--r--service/java/com/android/server/wifi/OpenNetworkNotifier.java2
-rw-r--r--service/java/com/android/server/wifi/SIMAccessor.java11
-rw-r--r--service/java/com/android/server/wifi/SarManager.java3
-rw-r--r--service/java/com/android/server/wifi/SavedNetworkEvaluator.java5
-rw-r--r--service/java/com/android/server/wifi/ScanDetail.java16
-rw-r--r--service/java/com/android/server/wifi/ScanOnlyModeManager.java286
-rw-r--r--service/java/com/android/server/wifi/ScanRequestProxy.java45
-rw-r--r--service/java/com/android/server/wifi/ScanResultMatchInfo.java35
-rw-r--r--service/java/com/android/server/wifi/ScoreCardBasedScorer.java14
-rw-r--r--service/java/com/android/server/wifi/ScoredNetworkEvaluator.java6
-rw-r--r--service/java/com/android/server/wifi/SelfRecovery.java33
-rw-r--r--service/java/com/android/server/wifi/SoftApManager.java271
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java360
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_1Impl.java147
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_2Impl.java221
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_3Impl.java166
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHal.java994
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaNetworkHal.java207
-rw-r--r--service/java/com/android/server/wifi/SupplicantStateTracker.java20
-rw-r--r--service/java/com/android/server/wifi/WakeupController.java11
-rw-r--r--service/java/com/android/server/wifi/WakeupNotificationFactory.java8
-rw-r--r--service/java/com/android/server/wifi/WakeupOnboarding.java5
-rw-r--r--service/java/com/android/server/wifi/WifiApConfigStore.java42
-rw-r--r--service/java/com/android/server/wifi/WifiBackupDataV1Parser.java3
-rw-r--r--service/java/com/android/server/wifi/WifiCandidates.java59
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java511
-rw-r--r--service/java/com/android/server/wifi/WifiConfigStore.java22
-rw-r--r--service/java/com/android/server/wifi/WifiConfigurationUtil.java144
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityHelper.java12
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java57
-rw-r--r--service/java/com/android/server/wifi/WifiController.java673
-rw-r--r--service/java/com/android/server/wifi/WifiCountryCode.java54
-rw-r--r--service/java/com/android/server/wifi/WifiDataStall.java54
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java211
-rw-r--r--service/java/com/android/server/wifi/WifiLastResortWatchdog.java126
-rw-r--r--service/java/com/android/server/wifi/WifiLockManager.java40
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java118
-rw-r--r--service/java/com/android/server/wifi/WifiMonitor.java6
-rw-r--r--service/java/com/android/server/wifi/WifiMulticastLockManager.java4
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java155
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java59
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSelector.java45
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java331
-rw-r--r--service/java/com/android/server/wifi/WifiScoreCard.java59
-rw-r--r--service/java/com/android/server/wifi/WifiScoreReport.java2
-rw-r--r--service/java/com/android/server/wifi/WifiService.java29
-rw-r--r--service/java/com/android/server/wifi/WifiServiceBase.java62
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java2065
-rw-r--r--service/java/com/android/server/wifi/WifiSettingsStore.java60
-rw-r--r--service/java/com/android/server/wifi/WifiShellCommand.java31
-rw-r--r--service/java/com/android/server/wifi/WifiStackService.java268
-rw-r--r--service/java/com/android/server/wifi/WifiThreadRunner.java220
-rw-r--r--service/java/com/android/server/wifi/WifiTrafficPoller.java6
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java60
-rw-r--r--service/java/com/android/server/wifi/WificondControl.java197
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java5
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareMetrics.java10
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java60
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java12
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareService.java71
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java2
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareStateManager.java46
-rw-r--r--service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java2
-rw-r--r--service/java/com/android/server/wifi/hotspot2/NetworkDetail.java37
-rw-r--r--service/java/com/android/server/wifi/hotspot2/OsuNetworkConnection.java10
-rw-r--r--service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java18
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java10
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointManager.java99
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java11
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java4
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointProvider.java52
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java3
-rw-r--r--service/java/com/android/server/wifi/hotspot2/ServiceProviderVerifier.java13
-rw-r--r--service/java/com/android/server/wifi/hotspot2/WfaKeyStore.java2
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pService.java18
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java55
-rw-r--r--service/java/com/android/server/wifi/rtt/RttService.java48
-rw-r--r--service/java/com/android/server/wifi/rtt/RttServiceImpl.java2
-rw-r--r--service/java/com/android/server/wifi/scanner/BackgroundScanScheduler.java8
-rw-r--r--service/java/com/android/server/wifi/scanner/ChannelHelper.java9
-rw-r--r--service/java/com/android/server/wifi/scanner/HalWifiScannerImpl.java17
-rw-r--r--service/java/com/android/server/wifi/scanner/KnownBandsChannelHelper.java121
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScannerImpl.java24
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningService.java22
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java627
-rw-r--r--service/java/com/android/server/wifi/scanner/WificondScannerImpl.java36
-rw-r--r--service/java/com/android/server/wifi/util/ApConfigUtil.java3
-rw-r--r--service/java/com/android/server/wifi/util/EncryptedData.java7
-rw-r--r--service/java/com/android/server/wifi/util/Environment.java57
-rw-r--r--service/java/com/android/server/wifi/util/ExternalCallbackTracker.java16
-rw-r--r--service/java/com/android/server/wifi/util/FileUtils.java84
-rw-r--r--service/java/com/android/server/wifi/util/InformationElementUtil.java139
-rw-r--r--service/java/com/android/server/wifi/util/TelephonyUtil.java42
-rw-r--r--service/java/com/android/server/wifi/util/WifiPermissionsUtil.java186
-rw-r--r--service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java86
-rw-r--r--service/java/com/android/server/wifi/util/XmlUtil.java13
-rw-r--r--service/java/com/android/server/wifi/wificond/ChannelSettings.java95
-rw-r--r--service/java/com/android/server/wifi/wificond/HiddenNetwork.java87
-rw-r--r--service/java/com/android/server/wifi/wificond/NativeScanResult.java114
-rw-r--r--service/java/com/android/server/wifi/wificond/PnoNetwork.java95
-rw-r--r--service/java/com/android/server/wifi/wificond/PnoSettings.java101
-rw-r--r--service/java/com/android/server/wifi/wificond/RadioChainInfo.java100
-rw-r--r--service/java/com/android/server/wifi/wificond/SingleScanSettings.java119
-rw-r--r--service/proguard.flags1
-rw-r--r--service/res/values/strings.xml20
-rw-r--r--service/tests/Android.bp19
-rw-r--r--service/tests/Android.mk21
-rw-r--r--service/tests/wifitests/Android.bp81
-rw-r--r--service/tests/wifitests/Android.mk123
-rwxr-xr-xservice/tests/wifitests/coverage.sh51
-rwxr-xr-xservice/tests/wifitests/runtests.sh2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java1729
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/BinderUtilTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ByteBufferReaderTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java6
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkConfigTest.java9
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkEvaluatorTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkNotifierTest.java819
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/CellularLinkLayerStatsCollectorTest.java319
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/CellularLinkLayerStatsTest.java68
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java766
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java238
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java12
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java31
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java159
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/IMSIParameterTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java8
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/LocalOnlyHotspotRequestInfoTest.java66
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/LogcatLogTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/MemoryStoreImplTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionEvaluatorTest.java21
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java16
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java34
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/RttManagerTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SarInfoTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java72
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ScanOnlyModeManagerTest.java267
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java158
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ScanResultMatchInfoTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ScanResults.java18
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ScoredNetworkEvaluatorTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ScoringParamsTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java83
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java209
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java631
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java336
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStateTrackerTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/VelocityBasedConnectedScoreTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java17
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WakeupEvaluatorTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WakeupLockTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WakeupOnboardingTest.java6
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java38
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiBaseTest.java34
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java42
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java540
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java26
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java55
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityHelperTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java183
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java1126
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java85
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java46
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java12
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java88
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java32
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java51
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java6
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiMulticastLockManagerTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java90
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java159
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java169
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java485
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiPowerMetricsTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardProtoTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java36
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java1946
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiStateTrackerTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiThreadRunnerTest.java143
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiTrafficPollerTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java139
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiWakeMetricsTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java106
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WrongPasswordNotifierTest.java2
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java39
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeApiTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareNativeManagerTest.java8
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java11
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java238
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPDataTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java18
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPNetworkKeyTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/AnqpCacheTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/DomainMatcherTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuNetworkConnectionTest.java47
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuServerConnectionTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointEventHandlerTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java603
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java23
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkScoreTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java980
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointXmlUtilsTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/ServiceProviderVerifierTest.java19
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/SystemInfoTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/UtilsTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ANQPParserTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/CellularNetworkTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/DomainNameElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSConnectionCapabilityElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSFriendlyNameElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSIconFileElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSOsuProvidersElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSWanMetricsElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/I18NameTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IPAddressTypeAvailabilityElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IconInfoTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmDataTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/OsuProviderInfoTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ProtocolPortTupleTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RawByteElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RoamingConsortiumElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ThreeGPPNetworkElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/VenueNameElementTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/CredentialTypeTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/EAPMethodTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/ExpandedEAPMethodTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/InnerAuthEAPTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/NonEAPInnerAuthTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/VendorSpecificAuthTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevDetailMoTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevInfoMoTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/MoSerializerTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessageTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsServiceConnectionTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsTransportTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataMessageTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataResponseTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/RedirectListenerTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SoapParserTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SppResponseMessageTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/UpdateResponseMessageTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/BrowserUriTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/PpsMoDataTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/SppCommandTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMetricsTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMonitorTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/rtt/RttMetricsTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/rtt/RttNativeTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/rtt/RttServiceImplTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/BackgroundScanSchedulerTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/ChannelHelperTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/KnownBandsChannelHelperTest.java49
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/ScanScheduleUtilFilterTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java1085
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/WificondPnoScannerTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java109
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/BitMaskTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/ByteArrayRingBufferTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/ExternalCallbackTrackerTest.java8
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/FrameParserTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java184
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/IntCounterTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/IntHistogramTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/KalmanFilterTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/MatrixTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/MetricsUtilsTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/NativeUtilTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/ObjectCounterTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/StringUtilTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/TimedQuotaManagerTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/WifiHandlerTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java184
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java6
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/wificond/NativeScanResultTest.java88
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/wificond/PnoSettingsTest.java112
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/wificond/SingleScanSettingsTest.java117
-rw-r--r--service/wifi.rc84
-rw-r--r--service/wifi_inprocess.rc (renamed from service/wifi-events.rc)22
347 files changed, 17063 insertions, 14996 deletions
diff --git a/service/Android.bp b/service/Android.bp
index 091023e6fe..b5b316f5fd 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -1,4 +1,5 @@
-// Copyright (C) 2011 The Android Open Source Project
+//
+// Copyright (C) 2018 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.
@@ -11,11 +12,32 @@
// 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.
+//
+java_defaults {
+ name: "WifiStackCommon",
+ min_sdk_version: "29",
+ platform_apis: true,
+ privileged: true,
+ dex_preopt: {
+ enabled: false,
+ },
+ errorprone: {
+ javacflags: ["-Xep:CheckReturnValue:ERROR"],
+ },
+ product_variables: {
+ pdk: {
+ enabled: false,
+ },
+ },
+ resource_dirs: [
+ "res",
+ ],
+}
// Make the JNI part
// ============================================================
cc_library_shared {
- name: "libwifi-service",
+ name: "libwifi-jni",
cflags: [
"-Wall",
@@ -48,3 +70,102 @@ cc_library_shared {
},
},
}
+
+// Build the wifi-service static library
+// ============================================================
+java_library {
+ name: "wifi-service",
+ installable: true,
+ defaults: ["WifiStackCommon"],
+ srcs: [
+ "java/**/*.java",
+ "java/**/*.logtags",
+ ":framework-wifistack-shared-srcs",
+ ],
+
+ libs: [
+ "error_prone_annotations",
+ "libprotobuf-java-lite",
+ "jsr305",
+ "services",
+ ],
+
+ static_libs: [
+ "android.hardware.wifi-V1.0-java",
+ "android.hardware.wifi-V1.1-java",
+ "android.hardware.wifi-V1.2-java",
+ "android.hardware.wifi-V1.3-java",
+ "android.hardware.wifi-V1.4-java",
+ "android.hardware.wifi.hostapd-V1.0-java",
+ "android.hardware.wifi.hostapd-V1.1-java",
+ "android.hardware.wifi.supplicant-V1.0-java",
+ "android.hardware.wifi.supplicant-V1.1-java",
+ "android.hardware.wifi.supplicant-V1.2-java",
+ "android.hardware.wifi.supplicant-V1.3-java",
+ "android.hidl.manager-V1.2-java",
+ "androidx.annotation_annotation",
+ "bouncycastle-unbundled",
+ "wifi_service_proto",
+ "ksoap2",
+ "libnanohttpd",
+ "services.core",
+ "services.net",
+ "services.wifi",
+ "libwificond_aidl-java",
+ ],
+}
+
+filegroup {
+ name: "wifi-jarjar-rules",
+ srcs: [ "jarjar-rules-shared.txt"]
+}
+
+java_defaults {
+ name: "WifiStackAppCommon",
+ defaults: ["WifiStackCommon"],
+ static_libs: [
+ "wifi-service",
+ ],
+ jni_libs: [
+ "libwifi-jni",
+ ],
+ // Resources already included in wifi-service
+ resource_dirs: [],
+ jarjar_rules: ":wifi-jarjar-rules",
+ optimize: {
+ proguard_flags_files: ["proguard.flags"],
+ },
+
+ required: [
+ "libwifi-jni",
+ "services",
+ "cacerts_wfa",
+ ],
+}
+
+// Updatable stack packaged as an application
+android_app {
+ name: "WifiStack",
+ defaults: ["WifiStackAppCommon"],
+ certificate: "networkstack",
+ manifest: "AndroidManifest.xml",
+ use_embedded_native_libs: true,
+ // The permission configuration *must* be included to ensure security of the device
+ required: ["WifiStackPermissionConfig"],
+ init_rc: ["wifi.rc"],
+}
+
+// Non-updatable wifi stack running in the system server process for devices not using the module
+// TODO (b/135753701): Test this path.
+android_app {
+ name: "InProcessWifiStack",
+ defaults: ["WifiStackAppCommon"],
+ certificate: "platform",
+ manifest: "AndroidManifest_InProcess.xml",
+ // InProcessWifiStack is a replacement for WifiStack
+ overrides: ["WifiStack"],
+ // The permission configuration *must* be included to ensure security of the device
+ required: ["PlatformWifiStackPermissionConfig"],
+ init_rc: ["wifi_inprocess.rc"],
+}
+
diff --git a/service/Android.mk b/service/Android.mk
deleted file mode 100644
index b396214c71..0000000000
--- a/service/Android.mk
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (C) 2011 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.
-
-LOCAL_PATH := $(call my-dir)
-
-ifneq ($(TARGET_BUILD_PDK), true)
-
-# Build the java code
-# ============================================================
-
-wificond_aidl_path := system/connectivity/wificond/aidl
-wificond_aidl_rel_path := ../../../../../$(wificond_aidl_path)
-
-include $(CLEAR_VARS)
-
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/java $(wificond_aidl_path)
-LOCAL_SRC_FILES := $(call all-java-files-under, java) \
- $(call all-Iaidl-files-under, java) \
- $(call all-Iaidl-files-under, $(wificond_aidl_rel_path)) \
- $(call all-logtags-files-under, java)
-
-LOCAL_JAVA_LIBRARIES := \
- android.hidl.manager-V1.2-java \
- error_prone_annotations \
- libprotobuf-java-lite \
- jsr305 \
- services
-LOCAL_STATIC_JAVA_LIBRARIES := \
- android.hardware.wifi-V1.0-java \
- android.hardware.wifi-V1.1-java \
- android.hardware.wifi-V1.2-java \
- android.hardware.wifi-V1.3-java \
- android.hardware.wifi.hostapd-V1.0-java \
- android.hardware.wifi.hostapd-V1.1-java \
- android.hardware.wifi.supplicant-V1.0-java \
- android.hardware.wifi.supplicant-V1.1-java \
- android.hardware.wifi.supplicant-V1.2-java \
- wifi_service_proto \
- ksoap2 \
- libnanohttpd
-
-LOCAL_REQUIRED_MODULES := \
- services \
- libwifi-service \
- cacerts_wfa
-LOCAL_MODULE_TAGS :=
-LOCAL_MODULE := wifi-service
-LOCAL_INIT_RC := wifi-events.rc
-
-LOCAL_DEX_PREOPT_APP_IMAGE := false
-LOCAL_DEX_PREOPT_GENERATE_PROFILE := true
-LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING := frameworks/base/services/art-profile
-LOCAL_ERROR_PRONE_FLAGS := -Xep:CheckReturnValue:ERROR
-
-include $(BUILD_JAVA_LIBRARY)
-
-endif # !TARGET_BUILD_PDK
diff --git a/service/AndroidManifest.xml b/service/AndroidManifest.xml
new file mode 100644
index 0000000000..bb0b66e96a
--- /dev/null
+++ b/service/AndroidManifest.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.wifi"
+ coreApp="true"
+ android:sharedUserId="android.uid.networkstack"
+ android:versionCode="220000000"
+ android:versionName="30 system image">
+
+ <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
+
+ <!-- Permissions must be defined here, and not in the base manifest, as the wifi stack
+ running in the system server process does not need any permission, and having privileged
+ permissions added would cause crashes on startup unless they are also added to the
+ privileged permissions whitelist for that package. -->
+ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+ <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+ <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+ <uses-permission android:name="android.permission.DEVICE_POWER" />
+ <uses-permission android:name="android.permission.DUMP" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+ <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
+ <uses-permission android:name="android.permission.LOCATION_HARDWARE" />
+ <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+ <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
+ <uses-permission android:name="android.permission.MANAGE_USERS" />
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+ <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
+ <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.REORDER_TASKS" />
+ <uses-permission android:name="android.permission.REQUEST_NETWORK_SCORES" />
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+ <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
+ <!-- Signature permission defined for wifi module-->
+ <uses-permission android:name="android.permission.MAINLINE_WIFI_STACK" />
+
+ <application
+ android:persistent="true"
+ android:directBootAware="true"
+ android:process="com.android.networkstack.process"
+ android:label="@string/wifiAppLabel">
+ <service
+ android:name="com.android.server.wifi.WifiStackService"
+ android:directBootAware="true">
+ <intent-filter>
+ <action android:name="android.net.wifi.IWifiStackConnector"/>
+ </intent-filter>
+ </service>
+ <receiver android:name="com.android.server.wifi.BootCompleteReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
+ </intent-filter>
+ </receiver>
+ </application>
+</manifest>
diff --git a/service/AndroidManifest_InProcess.xml b/service/AndroidManifest_InProcess.xml
new file mode 100644
index 0000000000..7d242d928d
--- /dev/null
+++ b/service/AndroidManifest_InProcess.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.wifi.inprocess"
+ coreApp="true"
+ android:sharedUserId="android.uid.system"
+ android:versionCode="220000000"
+ android:versionName="30 system image">
+
+ <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
+
+ <application
+ android:persistent="true"
+ android:directBootAware="true"
+ android:process="system"
+ android:label="@string/wifiAppLabel">
+ <service
+ android:name="com.android.server.wifi.WifiStackService"
+ android:directBootAware="true">
+ <intent-filter>
+ <action android:name="android.net.wifi.IWifiStackConnector.InProcess"/>
+ </intent-filter>
+ </service>
+ <receiver android:name="com.android.server.wifi.BootCompleteReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
+ </intent-filter>
+ </receiver>
+ </application>
+</manifest>
diff --git a/service/CleanSpec.mk b/service/CleanSpec.mk
index 70e8e55e10..4566bd4f9a 100644
--- a/service/CleanSpec.mk
+++ b/service/CleanSpec.mk
@@ -1,4 +1,5 @@
-# Copyright (C) 2011 The Android Open Source Project
+# -*- mode: makefile -*-
+# Copyright (C) 2019 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-
+#
# If you don't need to do a full clean build but would like to touch
# a file or delete some intermediate files, add a clean step to the end
# of the list. These steps will only be run once, if they haven't been
@@ -20,7 +21,7 @@
#
# E.g.:
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
-# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+# $(call add-clean-step, rm -rf $(OUT_DIR)/obj/STATIC_LIBRARIES/libz_intermediates)
#
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
# files that are missing or have been moved.
@@ -37,9 +38,16 @@
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
+#
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/obj/SHARED_LIBRARIES/libdvm*)
-$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/wifi-service_intermediates)
-
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/init/wifi_inprocess.rc)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/InProcessWifiStack)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/service/TEST_MAPPING b/service/TEST_MAPPING
new file mode 100644
index 0000000000..faa68964c4
--- /dev/null
+++ b/service/TEST_MAPPING
@@ -0,0 +1,13 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsBackupHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.cts.backup.OtherSoundsSettingsHostSideTest"
+ }
+ ]
+ }
+ ]
+}
+
diff --git a/service/jarjar-rules-shared.txt b/service/jarjar-rules-shared.txt
new file mode 100644
index 0000000000..8a6435a1a6
--- /dev/null
+++ b/service/jarjar-rules-shared.txt
@@ -0,0 +1,21 @@
+# We don't jar-jar the entire package because, we still use some classes (like
+# AsyncChannel in com.android.internal.util) from these packages which are not
+# inside our jar (currently in framework.jar, but will be in wifisdk.jar in the future).
+rule com.android.internal.util.FastXmlSerializer* com.android.server.wifi.util.FastXmlSerializer@1
+rule com.android.internal.util.HexDump* com.android.server.wifi.util.HexDump@1
+rule com.android.internal.util.IState* com.android.server.wifi.util.IState@1
+rule com.android.internal.util.MessageUtils* com.android.server.wifi.util.MessageUtils@1
+rule com.android.internal.util.Preconditions* com.android.server.wifi.util.Preconditions@1
+rule com.android.internal.util.State* com.android.server.wifi.util.State@1
+rule com.android.internal.util.StateMachine* com.android.server.wifi.util.StateMachine@1
+rule com.android.internal.util.WakeupMessage* com.android.server.wifi.util.WakeupMessage@1
+rule com.android.internal.util.XmlUtils* com.android.server.wifi.util.XmlUtils@1
+
+rule android.util.KeyValueListParser* com.android.server.wifi.util.KeyValueListParser@1
+rule android.util.LocalLog* com.android.server.wifi.util.LocalLog@1
+rule android.util.Rational* com.android.server.wifi.util.Rational@1
+rule android.util.proto.ProtoStream* com.android.server.wifi.util.proto.ProtoStream@1
+rule android.util.proto.ProtoOutputStream* com.android.server.wifi.util.proto.ProtoOutputStream@1
+
+# Use our statically linked bouncy castle version
+rule org.bouncycastle.** com.android.server.wifi.bouncycastle.@1
diff --git a/service/java/com/android/server/wifi/ActiveModeManager.java b/service/java/com/android/server/wifi/ActiveModeManager.java
index 7c50726f9b..0908e26eb2 100644
--- a/service/java/com/android/server/wifi/ActiveModeManager.java
+++ b/service/java/com/android/server/wifi/ActiveModeManager.java
@@ -30,6 +30,24 @@ import java.lang.annotation.RetentionPolicy;
*/
public interface ActiveModeManager {
/**
+ * Listener for ActiveModeManager state changes.
+ */
+ interface Listener {
+ /**
+ * Invoked when mode manager completes start or on mode switch.
+ */
+ void onStarted();
+ /**
+ * Invoked when mode manager completes stop.
+ */
+ void onStopped();
+ /**
+ * Invoked when mode manager encountered a failure on start or on mode switch.
+ */
+ void onStartFailure();
+ }
+
+ /**
* Method used to start the Manager for a given Wifi operational mode.
*/
void start();
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index d118d833ad..818c410ae8 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -17,8 +17,12 @@
package com.android.server.wifi;
import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
import android.content.Context;
-import android.net.wifi.WifiConfiguration;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.location.LocationManager;
+import android.net.wifi.WifiClient;
import android.net.wifi.WifiManager;
import android.os.BatteryStats;
import android.os.Handler;
@@ -28,78 +32,47 @@ import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Log;
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
+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.server.wifi.WifiNative.StatusListener;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.List;
/**
* This class provides the implementation for different WiFi operating modes.
*/
public class ActiveModeWarden {
private static final String TAG = "WifiActiveModeWarden";
-
- private ModeStateMachine mModeStateMachine;
+ private static final String STATE_MACHINE_EXITED_STATE_NAME = "STATE_MACHINE_EXITED";
// Holder for active mode managers
private final ArraySet<ActiveModeManager> mActiveModeManagers;
// DefaultModeManager used to service API calls when there are not active mode managers.
- private DefaultModeManager mDefaultModeManager;
+ private final DefaultModeManager mDefaultModeManager;
private final WifiInjector mWifiInjector;
- private final Context mContext;
private final Looper mLooper;
private final Handler mHandler;
- private final WifiNative mWifiNative;
+ private final Context mContext;
+ private final ClientModeImpl mClientModeImpl;
+ private final WifiSettingsStore mSettingsStore;
+ private final FrameworkFacade mFacade;
+ private final WifiPermissionsUtil mWifiPermissionsUtil;
private final IBatteryStats mBatteryStats;
- private final SelfRecovery mSelfRecovery;
- private BaseWifiDiagnostics mWifiDiagnostics;
private final ScanRequestProxy mScanRequestProxy;
-
- // The base for wifi message types
- static final int BASE = Protocol.BASE_WIFI;
-
- // The message identifiers below are mapped to those in ClientModeImpl when applicable.
- // Start the soft access point
- static final int CMD_START_AP = BASE + 21;
- // Indicates soft ap start failed
- static final int CMD_START_AP_FAILURE = BASE + 22;
- // Stop the soft access point
- static final int CMD_STOP_AP = BASE + 23;
- // Soft access point teardown is completed
- static final int CMD_AP_STOPPED = BASE + 24;
-
- // Start Scan Only mode
- static final int CMD_START_SCAN_ONLY_MODE = BASE + 200;
- // Indicates that start Scan only mode failed
- static final int CMD_START_SCAN_ONLY_MODE_FAILURE = BASE + 201;
- // Indicates that scan only mode stopped
- static final int CMD_STOP_SCAN_ONLY_MODE = BASE + 202;
- // ScanOnly mode teardown is complete
- static final int CMD_SCAN_ONLY_MODE_STOPPED = BASE + 203;
- // ScanOnly mode failed
- static final int CMD_SCAN_ONLY_MODE_FAILED = BASE + 204;
-
- // Start Client mode
- static final int CMD_START_CLIENT_MODE = BASE + 300;
- // Indicates that start client mode failed
- static final int CMD_START_CLIENT_MODE_FAILURE = BASE + 301;
- // Indicates that client mode stopped
- static final int CMD_STOP_CLIENT_MODE = BASE + 302;
- // Client mode teardown is complete
- static final int CMD_CLIENT_MODE_STOPPED = BASE + 303;
- // Client mode failed
- static final int CMD_CLIENT_MODE_FAILED = BASE + 304;
-
- private StatusListener mWifiNativeStatusListener;
+ private final WifiController mWifiController;
private WifiManager.SoftApCallback mSoftApCallback;
- private ScanOnlyModeManager.Listener mScanOnlyCallback;
- private ClientModeManager.Listener mClientModeCallback;
+ private WifiManager.SoftApCallback mLohsCallback;
/**
* Called from WifiServiceImpl to register a callback for notifications from SoftApManager
@@ -109,58 +82,135 @@ public class ActiveModeWarden {
}
/**
- * Called from WifiController to register a callback for notifications from ScanOnlyModeManager
- */
- public void registerScanOnlyCallback(@NonNull ScanOnlyModeManager.Listener callback) {
- mScanOnlyCallback = callback;
- }
-
- /**
- * Called from WifiController to register a callback for notifications from ClientModeManager
+ * Called from WifiServiceImpl to register a callback for notifications from SoftApManager
+ * for local-only hotspot.
*/
- public void registerClientModeCallback(@NonNull ClientModeManager.Listener callback) {
- mClientModeCallback = callback;
+ public void registerLohsCallback(@NonNull WifiManager.SoftApCallback callback) {
+ mLohsCallback = callback;
}
ActiveModeWarden(WifiInjector wifiInjector,
- Context context,
Looper looper,
WifiNative wifiNative,
DefaultModeManager defaultModeManager,
- IBatteryStats batteryStats) {
+ IBatteryStats batteryStats,
+ BaseWifiDiagnostics wifiDiagnostics,
+ Context context,
+ ClientModeImpl clientModeImpl,
+ WifiSettingsStore settingsStore,
+ FrameworkFacade facade,
+ WifiPermissionsUtil wifiPermissionsUtil) {
mWifiInjector = wifiInjector;
- mContext = context;
mLooper = looper;
mHandler = new Handler(looper);
- mWifiNative = wifiNative;
- mActiveModeManagers = new ArraySet();
+ mContext = context;
+ mClientModeImpl = clientModeImpl;
+ mSettingsStore = settingsStore;
+ mFacade = facade;
+ mWifiPermissionsUtil = wifiPermissionsUtil;
+ mActiveModeManagers = new ArraySet<>();
mDefaultModeManager = defaultModeManager;
mBatteryStats = batteryStats;
- mSelfRecovery = mWifiInjector.getSelfRecovery();
- mWifiDiagnostics = mWifiInjector.getWifiDiagnostics();
- mScanRequestProxy = mWifiInjector.getScanRequestProxy();
- mModeStateMachine = new ModeStateMachine();
- mWifiNativeStatusListener = new WifiNativeStatusListener();
- mWifiNative.registerStatusListener(mWifiNativeStatusListener);
+ mScanRequestProxy = wifiInjector.getScanRequestProxy();
+ mWifiController = new WifiController();
+
+ wifiNative.registerStatusListener(isReady -> {
+ if (!isReady) {
+ mHandler.post(() -> {
+ Log.e(TAG, "One of the native daemons died. Triggering recovery");
+ wifiDiagnostics.captureBugReportData(
+ WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
+
+ // immediately trigger SelfRecovery if we receive a notice about an
+ // underlying daemon failure
+ // Note: SelfRecovery has a circular dependency with ActiveModeWarden and is
+ // instantiated after ActiveModeWarden, so use WifiInjector to get the instance
+ // instead of directly passing in SelfRecovery in the constructor.
+ mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ });
+ }
+ });
+ }
+
+ /** Begin listening to broadcasts and start the internal state machine. */
+ public void start() {
+ mWifiController.start();
+ }
+
+ /** Disable Wifi for recovery purposes. */
+ public void recoveryDisableWifi() {
+ mWifiController.sendMessage(WifiController.CMD_RECOVERY_DISABLE_WIFI);
}
/**
- * Method to switch wifi into client mode where connections to configured networks will be
- * attempted.
+ * Restart Wifi for recovery purposes.
+ * @param reason One of {@link SelfRecovery.RecoveryReason}
*/
- public void enterClientMode() {
- changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
+ public void recoveryRestartWifi(@SelfRecovery.RecoveryReason int reason) {
+ mWifiController.sendMessage(WifiController.CMD_RECOVERY_RESTART_WIFI, reason);
+ }
+
+ /** Wifi has been toggled. */
+ public void wifiToggled() {
+ mWifiController.sendMessage(WifiController.CMD_WIFI_TOGGLED);
+ }
+
+ /** Airplane Mode has been toggled. */
+ public void airplaneModeToggled() {
+ mWifiController.sendMessage(WifiController.CMD_AIRPLANE_TOGGLED);
+ }
+
+ /** Starts SoftAp. */
+ public void startSoftAp(SoftApModeConfiguration softApConfig) {
+ mWifiController.sendMessage(WifiController.CMD_SET_AP, 1, 0, softApConfig);
+ }
+
+ /** Stop SoftAp. */
+ public void stopSoftAp(int mode) {
+ mWifiController.sendMessage(WifiController.CMD_SET_AP, 0, mode);
+ }
+
+ /** Emergency Callback Mode has changed. */
+ public void emergencyCallbackModeChanged(boolean isInEmergencyCallbackMode) {
+ mWifiController.sendMessage(
+ WifiController.CMD_EMERGENCY_MODE_CHANGED, isInEmergencyCallbackMode ? 1 : 0);
+ }
+
+ /** Emergency Call state has changed. */
+ public void emergencyCallStateChanged(boolean isInEmergencyCall) {
+ mWifiController.sendMessage(
+ WifiController.CMD_EMERGENCY_CALL_STATE_CHANGED, isInEmergencyCall ? 1 : 0);
+ }
+
+ /** Scan always mode has changed. */
+ public void scanAlwaysModeChanged() {
+ mWifiController.sendMessage(WifiController.CMD_SCAN_ALWAYS_MODE_CHANGED);
+ }
+
+ private boolean hasAnyModeManager() {
+ return !mActiveModeManagers.isEmpty();
+ }
+
+ private boolean hasAnyClientModeManager() {
+ for (ActiveModeManager manager : mActiveModeManagers) {
+ if (manager instanceof ClientModeManager) return true;
+ }
+ return false;
}
/**
- * Method to switch wifi into scan only mode where network connection attempts will not be made.
- *
- * This mode is utilized by location scans. If wifi is disabled by a user, but they have
- * previously configured their device to perform location scans, this mode allows wifi to
- * fulfill the location scan requests but will not be used for connectivity.
+ * @return true if all client mode managers are in scan mode,
+ * false if there are no client mode managers present or if any of them are not in scan mode.
*/
- public void enterScanOnlyMode() {
- changeMode(ModeStateMachine.CMD_START_SCAN_ONLY_MODE);
+ private boolean areAllClientModeManagersInScanMode() {
+ boolean hasAnyClientModeManager = false;
+ for (ActiveModeManager manager : mActiveModeManagers) {
+ if (!(manager instanceof ClientModeManager)) continue;
+ ClientModeManager clientModeManager = (ClientModeManager) manager;
+ hasAnyClientModeManager = true;
+ if (!clientModeManager.isInScanOnlyMode()) return false;
+ }
+ return hasAnyClientModeManager;
}
/**
@@ -168,91 +218,155 @@ public class ActiveModeWarden {
*
* The supplied SoftApModeConfiguration includes the target softap WifiConfiguration (or null if
* the persisted config is to be used) and the target operating mode (ex,
- * {@link WifiManager.IFACE_IP_MODE_TETHERED} {@link WifiManager.IFACE_IP_MODE_LOCAL_ONLY}).
+ * {@link WifiManager#IFACE_IP_MODE_TETHERED} {@link WifiManager#IFACE_IP_MODE_LOCAL_ONLY}).
*
- * @param wifiConfig SoftApModeConfiguration for the hostapd softap
+ * @param softApConfig SoftApModeConfiguration for the hostapd softap
*/
- public void enterSoftAPMode(@NonNull SoftApModeConfiguration wifiConfig) {
- mHandler.post(() -> {
- startSoftAp(wifiConfig);
- });
+ private void startSoftApModeManager(@NonNull SoftApModeConfiguration softApConfig) {
+ Log.d(TAG, "Starting SoftApModeManager config = "
+ + softApConfig.getWifiConfiguration());
+
+ SoftApCallbackImpl callback = new SoftApCallbackImpl(softApConfig.getTargetMode());
+ SoftApListener listener = new SoftApListener();
+ ActiveModeManager manager =
+ mWifiInjector.makeSoftApManager(listener, callback, softApConfig);
+ listener.setActiveModeManager(manager);
+ manager.start();
+ mActiveModeManagers.add(manager);
}
/**
- * Method to stop soft ap for wifi hotspot.
+ * Method to stop all soft ap for the specified mode.
*
* This method will stop any active softAp mode managers.
*
* @param mode the operating mode of APs to bring down (ex,
- * {@link WifiManager.IFACE_IP_MODE_TETHERED} or
- * {@link WifiManager.IFACE_IP_MODE_LOCAL_ONLY}).
- * Use {@link WifiManager.IFACE_IP_MODE_UNSPECIFIED} to stop all APs.
+ * {@link WifiManager#IFACE_IP_MODE_TETHERED} or
+ * {@link WifiManager#IFACE_IP_MODE_LOCAL_ONLY}).
+ * Use {@link WifiManager#IFACE_IP_MODE_UNSPECIFIED} to stop all APs.
*/
- public void stopSoftAPMode(int mode) {
- mHandler.post(() -> {
- for (ActiveModeManager manager : mActiveModeManagers) {
- if (!(manager instanceof SoftApManager)) continue;
- SoftApManager softApManager = (SoftApManager) manager;
-
- if (mode != WifiManager.IFACE_IP_MODE_UNSPECIFIED
- && mode != softApManager.getIpMode()) {
- continue;
- }
- softApManager.stop();
+ private void stopSoftApModeManagers(int mode) {
+ Log.d(TAG, "Shutting down all softap mode managers in mode " + mode);
+ for (ActiveModeManager manager : mActiveModeManagers) {
+ if (!(manager instanceof SoftApManager)) continue;
+ SoftApManager softApManager = (SoftApManager) manager;
+
+ if (mode != WifiManager.IFACE_IP_MODE_UNSPECIFIED
+ && mode != softApManager.getIpMode()) {
+ continue;
}
- updateBatteryStatsWifiState(false);
- });
+ softApManager.stop();
+ }
}
/**
- * Method to disable wifi in sta/client mode scenarios.
- *
- * This mode will stop any client/scan modes and will not perform any network scans.
+ * Method to enable a new client mode manager.
*/
- public void disableWifi() {
- changeMode(ModeStateMachine.CMD_DISABLE_WIFI);
+ private boolean startClientModeManager() {
+ Log.d(TAG, "Starting ClientModeManager");
+ ClientListener listener = new ClientListener();
+ ClientModeManager manager = mWifiInjector.makeClientModeManager(listener);
+ listener.setActiveModeManager(manager);
+ manager.start();
+ if (!switchClientMode(manager)) {
+ return false;
+ }
+ mActiveModeManagers.add(manager);
+ return true;
}
/**
- * Method to stop all active modes, for example, when toggling airplane mode.
+ * Method to stop all client mode mangers.
*/
- public void shutdownWifi() {
- mHandler.post(() -> {
- for (ActiveModeManager manager : mActiveModeManagers) {
- manager.stop();
+ private void stopAllClientModeManagers() {
+ Log.d(TAG, "Shutting down all client mode managers");
+ for (ActiveModeManager manager : mActiveModeManagers) {
+ if (!(manager instanceof ClientModeManager)) continue;
+ ClientModeManager clientModeManager = (ClientModeManager) manager;
+ clientModeManager.stop();
+ }
+ }
+
+ /**
+ * Method to switch all client mode manager mode of operation (from ScanOnly To Connect &
+ * vice-versa) based on the toggle state.
+ */
+ private boolean switchAllClientModeManagers() {
+ Log.d(TAG, "Switching all client mode managers");
+ for (ActiveModeManager manager : mActiveModeManagers) {
+ if (!(manager instanceof ClientModeManager)) continue;
+ ClientModeManager clientModeManager = (ClientModeManager) manager;
+ if (!switchClientMode(clientModeManager)) {
+ return false;
}
- updateBatteryStatsWifiState(false);
- });
+ }
+ updateBatteryStats();
+ return true;
+ }
+
+ /**
+ * Method to switch a client mode manager mode of operation (from ScanOnly To Connect &
+ * vice-versa) based on the toggle state.
+ */
+ private boolean switchClientMode(@NonNull ClientModeManager modeManager) {
+ if (mSettingsStore.isWifiToggleEnabled()) {
+ modeManager.switchToConnectMode();
+ } else if (checkScanOnlyModeAvailable()) {
+ modeManager.switchToScanOnlyMode();
+ } else {
+ Log.e(TAG, "Something is wrong, no client mode toggles enabled");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Method to stop all active modes, for example, when toggling airplane mode.
+ */
+ private void shutdownWifi() {
+ Log.d(TAG, "Shutting down all mode managers");
+ for (ActiveModeManager manager : mActiveModeManagers) {
+ manager.stop();
+ }
}
/**
* Dump current state for active mode managers.
*
- * Must be called from ClientModeImpl thread.
+ * Must be called from the main Wifi thread.
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Dump of " + TAG);
-
pw.println("Current wifi mode: " + getCurrentMode());
pw.println("NumActiveModeManagers: " + mActiveModeManagers.size());
for (ActiveModeManager manager : mActiveModeManagers) {
manager.dump(fd, pw, args);
}
+ mWifiController.dump(fd, pw, args);
}
- protected String getCurrentMode() {
- return mModeStateMachine.getCurrentMode();
+ @VisibleForTesting
+ String getCurrentMode() {
+ IState state = mWifiController.getCurrentState();
+ return state == null ? STATE_MACHINE_EXITED_STATE_NAME : state.getName();
}
- private void changeMode(int newMode) {
- mModeStateMachine.sendMessage(newMode);
+ @VisibleForTesting
+ Collection<ActiveModeManager> getActiveModeManagers() {
+ return new ArraySet<>(mActiveModeManagers);
+ }
+
+ @VisibleForTesting
+ boolean isInEmergencyMode() {
+ IState state = mWifiController.getCurrentState();
+ return ((WifiController.BaseState) state).isInEmergencyMode();
}
/**
* Helper class to wrap the ActiveModeManager callback objects.
*/
- private class ModeCallback {
- ActiveModeManager mActiveManager;
+ private static class ModeCallback {
+ private ActiveModeManager mActiveManager;
void setActiveModeManager(ActiveModeManager manager) {
mActiveManager = manager;
@@ -263,289 +377,500 @@ public class ActiveModeWarden {
}
}
- private class ModeStateMachine extends StateMachine {
- // Commands for the state machine - these will be removed,
- // along with the StateMachine itself
- public static final int CMD_START_CLIENT_MODE = 0;
- public static final int CMD_START_SCAN_ONLY_MODE = 1;
- public static final int CMD_DISABLE_WIFI = 3;
+ private class SoftApCallbackImpl implements WifiManager.SoftApCallback {
+ private final int mMode;
- private final State mWifiDisabledState = new WifiDisabledState();
- private final State mClientModeActiveState = new ClientModeActiveState();
- private final State mScanOnlyModeActiveState = new ScanOnlyModeActiveState();
+ SoftApCallbackImpl(int mode) {
+ Preconditions.checkArgument(mode == WifiManager.IFACE_IP_MODE_TETHERED
+ || mode == WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ mMode = mode;
+ }
- ModeStateMachine() {
- super(TAG, mLooper);
+ @Override
+ public void onStateChanged(int state, int reason) {
+ switch (mMode) {
+ case WifiManager.IFACE_IP_MODE_TETHERED:
+ if (mSoftApCallback != null) mSoftApCallback.onStateChanged(state, reason);
+ break;
+ case WifiManager.IFACE_IP_MODE_LOCAL_ONLY:
+ if (mLohsCallback != null) mLohsCallback.onStateChanged(state, reason);
+ break;
+ }
+ }
- addState(mClientModeActiveState);
- addState(mScanOnlyModeActiveState);
- addState(mWifiDisabledState);
+ @Override
+ public void onConnectedClientsChanged(List<WifiClient> clients) {
+ switch (mMode) {
+ case WifiManager.IFACE_IP_MODE_TETHERED:
+ if (mSoftApCallback != null) {
+ mSoftApCallback.onConnectedClientsChanged(clients);
+ }
+ break;
+ case WifiManager.IFACE_IP_MODE_LOCAL_ONLY:
+ if (mLohsCallback != null) {
+ mLohsCallback.onConnectedClientsChanged(clients);
+ }
+ break;
+ }
+ }
+ }
- Log.d(TAG, "Starting Wifi in WifiDisabledState");
- setInitialState(mWifiDisabledState);
- start();
+ private void updateBatteryStats() {
+ updateBatteryStatsWifiState(hasAnyModeManager());
+ if (areAllClientModeManagersInScanMode()) {
+ updateBatteryStatsScanModeActive();
}
+ }
- private String getCurrentMode() {
- return getCurrentState().getName();
+ private class SoftApListener extends ModeCallback implements ActiveModeManager.Listener {
+ @Override
+ public void onStarted() {
+ updateBatteryStats();
}
- private boolean checkForAndHandleModeChange(Message message) {
- switch(message.what) {
- case ModeStateMachine.CMD_START_CLIENT_MODE:
- Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
- mModeStateMachine.transitionTo(mClientModeActiveState);
+ @Override
+ public void onStopped() {
+ mActiveModeManagers.remove(getActiveModeManager());
+ updateBatteryStats();
+ mWifiController.sendMessage(WifiController.CMD_AP_STOPPED);
+ }
+
+ @Override
+ public void onStartFailure() {
+ mActiveModeManagers.remove(getActiveModeManager());
+ updateBatteryStats();
+ mWifiController.sendMessage(WifiController.CMD_AP_START_FAILURE);
+ }
+ }
+
+ private class ClientListener extends ModeCallback implements ActiveModeManager.Listener {
+ @Override
+ public void onStarted() {
+ updateScanMode();
+ updateBatteryStats();
+ }
+
+ @Override
+ public void onStopped() {
+ mActiveModeManagers.remove(getActiveModeManager());
+ updateScanMode();
+ updateBatteryStats();
+ mWifiController.sendMessage(WifiController.CMD_STA_STOPPED);
+ }
+
+ @Override
+ public void onStartFailure() {
+ mActiveModeManagers.remove(getActiveModeManager());
+ updateScanMode();
+ updateBatteryStats();
+ mWifiController.sendMessage(WifiController.CMD_STA_START_FAILURE);
+ }
+ }
+
+ // Update the scan state based on all active mode managers.
+ private void updateScanMode() {
+ boolean scanEnabled = false;
+ boolean scanningForHiddenNetworksEnabled = false;
+ for (ActiveModeManager modeManager : mActiveModeManagers) {
+ @ActiveModeManager.ScanMode int scanState = modeManager.getScanMode();
+ switch (scanState) {
+ case ActiveModeManager.SCAN_NONE:
break;
- case ModeStateMachine.CMD_START_SCAN_ONLY_MODE:
- Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode");
- mModeStateMachine.transitionTo(mScanOnlyModeActiveState);
+ case ActiveModeManager.SCAN_WITHOUT_HIDDEN_NETWORKS:
+ scanEnabled = true;
break;
- case ModeStateMachine.CMD_DISABLE_WIFI:
- Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled");
- mModeStateMachine.transitionTo(mWifiDisabledState);
+ case ActiveModeManager.SCAN_WITH_HIDDEN_NETWORKS:
+ scanEnabled = true;
+ scanningForHiddenNetworksEnabled = true;
break;
- default:
- return NOT_HANDLED;
}
- return HANDLED;
}
+ mScanRequestProxy.enableScanning(scanEnabled, scanningForHiddenNetworksEnabled);
+ }
- class ModeActiveState extends State {
- ActiveModeManager mManager;
- @Override
- public boolean processMessage(Message message) {
- // handle messages for changing modes here
- return NOT_HANDLED;
- }
-
- @Override
- public void exit() {
- // Active states must have a mode manager, so this should not be null, but it isn't
- // obvious from the structure - add a null check here, just in case this is missed
- // in the future
- if (mManager != null) {
- mManager.stop();
- mActiveModeManagers.remove(mManager);
- updateScanMode();
+ /**
+ * Helper method to report wifi state as on/off (doesn't matter which mode).
+ *
+ * @param enabled boolean indicating that some mode has been turned on or off
+ */
+ private void updateBatteryStatsWifiState(boolean enabled) {
+ try {
+ if (enabled) {
+ if (mActiveModeManagers.size() == 1) {
+ // only report wifi on if we haven't already
+ mBatteryStats.noteWifiOn();
+ }
+ } else {
+ if (mActiveModeManagers.size() == 0) {
+ // only report if we don't have any active modes
+ mBatteryStats.noteWifiOff();
}
- updateBatteryStatsWifiState(false);
}
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to note battery stats in wifi");
+ }
+ }
- // Hook to be used by sub-classes of ModeActiveState to indicate the completion of
- // bringup of the corresponding mode.
- public void onModeActivationComplete() {
- updateScanMode();
+ private void updateBatteryStatsScanModeActive() {
+ try {
+ mBatteryStats.noteWifiState(BatteryStats.WIFI_STATE_OFF_SCANNING, null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to note battery stats in wifi");
+ }
+ }
+
+ private boolean checkScanOnlyModeAvailable() {
+ return mWifiPermissionsUtil.isLocationModeEnabled()
+ && mSettingsStore.isScanAlwaysAvailable();
+ }
+
+ /**
+ * WifiController is the class used to manage wifi state for various operating
+ * modes (normal, airplane, wifi hotspot, etc.).
+ */
+ private class WifiController extends StateMachine {
+ private static final String TAG = "WifiController";
+
+ // Maximum limit to use for timeout delay if the value from overlay setting is too large.
+ private static final int MAX_RECOVERY_TIMEOUT_DELAY_MS = 4000;
+
+ private final int mRecoveryDelayMillis;
+
+ private static final int BASE = Protocol.BASE_WIFI_CONTROLLER;
+
+ static final int CMD_EMERGENCY_MODE_CHANGED = BASE + 1;
+ static final int CMD_SCAN_ALWAYS_MODE_CHANGED = BASE + 7;
+ static final int CMD_WIFI_TOGGLED = BASE + 8;
+ static final int CMD_AIRPLANE_TOGGLED = BASE + 9;
+ static final int CMD_SET_AP = BASE + 10;
+ static final int CMD_EMERGENCY_CALL_STATE_CHANGED = BASE + 14;
+ static final int CMD_AP_STOPPED = BASE + 15;
+ static final int CMD_STA_START_FAILURE = BASE + 16;
+ // Command used to trigger a wifi stack restart when in active mode
+ static final int CMD_RECOVERY_RESTART_WIFI = BASE + 17;
+ // Internal command used to complete wifi stack restart
+ private static final int CMD_RECOVERY_RESTART_WIFI_CONTINUE = BASE + 18;
+ // Command to disable wifi when SelfRecovery is throttled or otherwise not doing full
+ // recovery
+ static final int CMD_RECOVERY_DISABLE_WIFI = BASE + 19;
+ static final int CMD_STA_STOPPED = BASE + 20;
+ static final int CMD_DEFERRED_RECOVERY_RESTART_WIFI = BASE + 22;
+ static final int CMD_AP_START_FAILURE = BASE + 23;
+
+ private final EnabledState mEnabledState = new EnabledState();
+ private final DisabledState mDisabledState = new DisabledState();
+
+ private boolean mIsInEmergencyCall = false;
+ private boolean mIsInEmergencyCallbackMode = false;
+
+ WifiController() {
+ super(TAG, mLooper);
+
+ DefaultState defaultState = new DefaultState();
+ addState(defaultState); {
+ addState(mDisabledState, defaultState);
+ addState(mEnabledState, defaultState);
}
- // Update the scan state based on all active mode managers.
- // Note: This is an overkill currently because there is only 1 of scan-only or client
- // mode present today.
- private void updateScanMode() {
- boolean scanEnabled = false;
- boolean scanningForHiddenNetworksEnabled = false;
- for (ActiveModeManager modeManager : mActiveModeManagers) {
- @ActiveModeManager.ScanMode int scanState = modeManager.getScanMode();
- switch (scanState) {
- case ActiveModeManager.SCAN_NONE:
- break;
- case ActiveModeManager.SCAN_WITHOUT_HIDDEN_NETWORKS:
- scanEnabled = true;
- break;
- case ActiveModeManager.SCAN_WITH_HIDDEN_NETWORKS:
- scanEnabled = true;
- scanningForHiddenNetworksEnabled = true;
- break;
- }
+ setLogRecSize(100);
+ setLogOnlyTransitions(false);
+
+ mRecoveryDelayMillis = readWifiRecoveryDelay();
+ }
+
+ @Override
+ public void start() {
+ boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn();
+ boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled();
+ boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable();
+ boolean isLocationModeActive = mWifiPermissionsUtil.isLocationModeEnabled();
+
+ log("isAirplaneModeOn = " + isAirplaneModeOn
+ + ", isWifiEnabled = " + isWifiEnabled
+ + ", isScanningAvailable = " + isScanningAlwaysAvailable
+ + ", isLocationModeActive = " + isLocationModeActive);
+
+ if (shouldEnableSta()) {
+ startClientModeManager();
+ setInitialState(mEnabledState);
+ } else {
+ setInitialState(mDisabledState);
+ }
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Location mode has been toggled... trigger with the scan change
+ // update to make sure we are in the correct mode
+ scanAlwaysModeChanged();
}
- mScanRequestProxy.enableScanning(scanEnabled, scanningForHiddenNetworksEnabled);
+ }, new IntentFilter(LocationManager.MODE_CHANGED_ACTION));
+ super.start();
+ }
+
+ private int readWifiRecoveryDelay() {
+ int recoveryDelayMillis = mContext.getResources().getInteger(
+ R.integer.config_wifi_framework_recovery_timeout_delay);
+ if (recoveryDelayMillis > MAX_RECOVERY_TIMEOUT_DELAY_MS) {
+ recoveryDelayMillis = MAX_RECOVERY_TIMEOUT_DELAY_MS;
+ Log.w(TAG, "Overriding timeout delay with maximum limit value");
}
+ return recoveryDelayMillis;
}
- class WifiDisabledState extends ModeActiveState {
- @Override
- public void enter() {
- Log.d(TAG, "Entering WifiDisabledState");
+ abstract class BaseState extends State {
+ @VisibleForTesting
+ boolean isInEmergencyMode() {
+ return mIsInEmergencyCall || mIsInEmergencyCallbackMode;
}
- @Override
- public boolean processMessage(Message message) {
- Log.d(TAG, "received a message in WifiDisabledState: " + message);
- if (checkForAndHandleModeChange(message)) {
- return HANDLED;
+ private void updateEmergencyMode(Message msg) {
+ if (msg.what == CMD_EMERGENCY_CALL_STATE_CHANGED) {
+ mIsInEmergencyCall = msg.arg1 == 1;
+ } else if (msg.what == CMD_EMERGENCY_MODE_CHANGED) {
+ mIsInEmergencyCallbackMode = msg.arg1 == 1;
}
- return NOT_HANDLED;
}
- @Override
- public void exit() {
- // do not have an active mode manager... nothing to clean up
+ private void enterEmergencyMode() {
+ stopSoftApModeManagers(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
+ boolean configWiFiDisableInECBM = mFacade.getConfigWiFiDisableInECBM(mContext);
+ log("WifiController msg getConfigWiFiDisableInECBM " + configWiFiDisableInECBM);
+ if (configWiFiDisableInECBM) {
+ shutdownWifi();
+ }
}
- }
+ private void exitEmergencyMode() {
+ if (shouldEnableSta()) {
+ startClientModeManager();
+ transitionTo(mEnabledState);
+ } else {
+ transitionTo(mDisabledState);
+ }
+ }
- class ClientModeActiveState extends ModeActiveState {
- ClientListener mListener;
- private class ClientListener implements ClientModeManager.Listener {
- @Override
- public void onStateChanged(int state) {
- // make sure this listener is still active
- if (this != mListener) {
- Log.d(TAG, "Client mode state change from previous manager");
- return;
+ @Override
+ public final boolean processMessage(Message msg) {
+ // potentially enter emergency mode
+ if (msg.what == CMD_EMERGENCY_CALL_STATE_CHANGED
+ || msg.what == CMD_EMERGENCY_MODE_CHANGED) {
+ boolean wasInEmergencyMode = isInEmergencyMode();
+ updateEmergencyMode(msg);
+ boolean isInEmergencyMode = isInEmergencyMode();
+ if (!wasInEmergencyMode && isInEmergencyMode) {
+ enterEmergencyMode();
+ } else if (wasInEmergencyMode && !isInEmergencyMode) {
+ exitEmergencyMode();
}
-
- Log.d(TAG, "State changed from client mode. state = " + state);
-
- if (state == WifiManager.WIFI_STATE_UNKNOWN) {
- // error while setting up client mode or an unexpected failure.
- mModeStateMachine.sendMessage(CMD_CLIENT_MODE_FAILED, this);
- } else if (state == WifiManager.WIFI_STATE_DISABLED) {
- // client mode stopped
- mModeStateMachine.sendMessage(CMD_CLIENT_MODE_STOPPED, this);
- } else if (state == WifiManager.WIFI_STATE_ENABLED) {
- // client mode is ready to go
- Log.d(TAG, "client mode active");
- onModeActivationComplete();
- } else {
- // only care if client mode stopped or started, dropping
+ return HANDLED;
+ } else if (isInEmergencyMode()) {
+ // already in emergency mode, drop all messages other than mode stop messages
+ // triggered by emergency mode start.
+ if (msg.what == CMD_STA_STOPPED || msg.what == CMD_AP_STOPPED) {
+ if (!hasAnyModeManager()) {
+ log("No active mode managers, return to DisabledState.");
+ transitionTo(mDisabledState);
+ }
}
+ return HANDLED;
}
+ // not in emergency mode, process messages normally
+ return processMessageFiltered(msg);
}
+ protected abstract boolean processMessageFiltered(Message msg);
+ }
+
+ class DefaultState extends State {
@Override
- public void enter() {
- Log.d(TAG, "Entering ClientModeActiveState");
+ public boolean processMessage(Message msg) {
+ switch (msg.what) {
+ case CMD_SCAN_ALWAYS_MODE_CHANGED:
+ case CMD_WIFI_TOGGLED:
+ case CMD_STA_STOPPED:
+ case CMD_STA_START_FAILURE:
+ case CMD_AP_STOPPED:
+ case CMD_AP_START_FAILURE:
+ case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
+ case CMD_DEFERRED_RECOVERY_RESTART_WIFI:
+ break;
+ case CMD_RECOVERY_DISABLE_WIFI:
+ log("Recovery has been throttled, disable wifi");
+ shutdownWifi();
+ // onStopped will move the state machine to "DisabledState".
+ break;
+ case CMD_AIRPLANE_TOGGLED:
+ if (mSettingsStore.isAirplaneModeOn()) {
+ log("Airplane mode toggled, shutdown all modes");
+ shutdownWifi();
+ // onStopped will move the state machine to "DisabledState".
+ } else {
+ log("Airplane mode disabled, determine next state");
+ if (shouldEnableSta()) {
+ startClientModeManager();
+ transitionTo(mEnabledState);
+ }
+ // wifi should remain disabled, do not need to transition
+ }
+ break;
+ default:
+ throw new RuntimeException("WifiController.handleMessage " + msg.what);
+ }
+ return HANDLED;
+ }
+ }
- mListener = new ClientListener();
- mManager = mWifiInjector.makeClientModeManager(mListener);
- mManager.start();
- mActiveModeManagers.add(mManager);
+ private boolean shouldEnableSta() {
+ return mSettingsStore.isWifiToggleEnabled() || checkScanOnlyModeAvailable();
+ }
- updateBatteryStatsWifiState(true);
+ class DisabledState extends BaseState {
+ @Override
+ public void enter() {
+ log("DisabledState.enter()");
+ super.enter();
+ if (hasAnyModeManager()) {
+ Log.e(TAG, "Entered DisabledState, but has active mode managers");
+ }
}
@Override
public void exit() {
+ log("DisabledState.exit()");
super.exit();
- mListener = null;
}
@Override
- public boolean processMessage(Message message) {
- if (checkForAndHandleModeChange(message)) {
- return HANDLED;
- }
-
- switch(message.what) {
- case CMD_START_CLIENT_MODE:
- Log.d(TAG, "Received CMD_START_CLIENT_MODE when active - drop");
+ public boolean processMessageFiltered(Message msg) {
+ switch (msg.what) {
+ case CMD_WIFI_TOGGLED:
+ case CMD_SCAN_ALWAYS_MODE_CHANGED:
+ if (shouldEnableSta()) {
+ startClientModeManager();
+ transitionTo(mEnabledState);
+ }
break;
- case CMD_CLIENT_MODE_FAILED:
- if (mListener != message.obj) {
- Log.d(TAG, "Client mode state change from previous manager");
- return HANDLED;
+ case CMD_SET_AP:
+ // note: CMD_SET_AP is handled/dropped in ECM mode - will not start here
+ if (msg.arg1 == 1) {
+ startSoftApModeManager((SoftApModeConfiguration) msg.obj);
+ transitionTo(mEnabledState);
}
- Log.d(TAG, "ClientMode failed, return to WifiDisabledState.");
- // notify WifiController that ClientMode failed
- mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN);
- mModeStateMachine.transitionTo(mWifiDisabledState);
break;
- case CMD_CLIENT_MODE_STOPPED:
- if (mListener != message.obj) {
- Log.d(TAG, "Client mode state change from previous manager");
- return HANDLED;
+ case CMD_RECOVERY_RESTART_WIFI:
+ log("Recovery triggered, already in disabled state");
+ // intentional fallthrough
+ case CMD_DEFERRED_RECOVERY_RESTART_WIFI:
+ // wait mRecoveryDelayMillis for letting driver clean reset.
+ sendMessageDelayed(CMD_RECOVERY_RESTART_WIFI_CONTINUE,
+ mRecoveryDelayMillis);
+ break;
+ case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
+ if (shouldEnableSta()) {
+ startClientModeManager();
+ transitionTo(mEnabledState);
}
-
- Log.d(TAG, "ClientMode stopped, return to WifiDisabledState.");
- // notify WifiController that ClientMode stopped
- mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
- mModeStateMachine.transitionTo(mWifiDisabledState);
break;
default:
return NOT_HANDLED;
}
- return NOT_HANDLED;
+ return HANDLED;
}
}
- class ScanOnlyModeActiveState extends ModeActiveState {
- ScanOnlyListener mListener;
- private class ScanOnlyListener implements ScanOnlyModeManager.Listener {
- @Override
- public void onStateChanged(int state) {
- if (this != mListener) {
- Log.d(TAG, "ScanOnly mode state change from previous manager");
- return;
- }
-
- if (state == WifiManager.WIFI_STATE_UNKNOWN) {
- Log.d(TAG, "ScanOnlyMode mode failed");
- // error while setting up scan mode or an unexpected failure.
- mModeStateMachine.sendMessage(CMD_SCAN_ONLY_MODE_FAILED, this);
- } else if (state == WifiManager.WIFI_STATE_DISABLED) {
- Log.d(TAG, "ScanOnlyMode stopped");
- //scan only mode stopped
- mModeStateMachine.sendMessage(CMD_SCAN_ONLY_MODE_STOPPED, this);
- } else if (state == WifiManager.WIFI_STATE_ENABLED) {
- // scan mode is ready to go
- Log.d(TAG, "scan mode active");
- onModeActivationComplete();
- } else {
- Log.d(TAG, "unexpected state update: " + state);
- }
- }
- }
-
+ class EnabledState extends BaseState {
@Override
public void enter() {
- Log.d(TAG, "Entering ScanOnlyModeActiveState");
-
- mListener = new ScanOnlyListener();
- mManager = mWifiInjector.makeScanOnlyModeManager(mListener);
- mManager.start();
- mActiveModeManagers.add(mManager);
-
- updateBatteryStatsWifiState(true);
- updateBatteryStatsScanModeActive();
+ log("EnabledState.enter()");
+ super.enter();
+ if (!hasAnyModeManager()) {
+ Log.e(TAG, "Entered EnabledState, but no active mode managers");
+ }
}
@Override
public void exit() {
+ log("EnabledState.exit()");
+ if (hasAnyModeManager()) {
+ Log.e(TAG, "Existing EnabledState, but has active mode managers");
+ }
super.exit();
- mListener = null;
}
@Override
- public boolean processMessage(Message message) {
- if (checkForAndHandleModeChange(message)) {
- return HANDLED;
- }
-
- switch(message.what) {
- case CMD_START_SCAN_ONLY_MODE:
- Log.d(TAG, "Received CMD_START_SCAN_ONLY_MODE when active - drop");
+ public boolean processMessageFiltered(Message msg) {
+ switch (msg.what) {
+ case CMD_WIFI_TOGGLED:
+ case CMD_SCAN_ALWAYS_MODE_CHANGED:
+ if (shouldEnableSta()) {
+ if (hasAnyClientModeManager()) {
+ switchAllClientModeManagers();
+ } else {
+ startClientModeManager();
+ }
+ } else {
+ stopAllClientModeManagers();
+ }
break;
- case CMD_SCAN_ONLY_MODE_FAILED:
- if (mListener != message.obj) {
- Log.d(TAG, "ScanOnly mode state change from previous manager");
- return HANDLED;
+ case CMD_SET_AP:
+ // note: CMD_SET_AP is handled/dropped in ECM mode - will not start here
+ if (msg.arg1 == 1) {
+ startSoftApModeManager((SoftApModeConfiguration) msg.obj);
+ } else {
+ stopSoftApModeManagers(msg.arg2);
}
-
- Log.d(TAG, "ScanOnlyMode failed, return to WifiDisabledState.");
- // notify WifiController that ScanOnlyMode failed
- mScanOnlyCallback.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN);
- mModeStateMachine.transitionTo(mWifiDisabledState);
break;
- case CMD_SCAN_ONLY_MODE_STOPPED:
- if (mListener != message.obj) {
- Log.d(TAG, "ScanOnly mode state change from previous manager");
+ case CMD_AIRPLANE_TOGGLED:
+ // airplane mode toggled on is handled in the default state
+ if (mSettingsStore.isAirplaneModeOn()) {
+ return NOT_HANDLED;
+ } else {
+ // when airplane mode is toggled off, but wifi is on, we can keep it on
+ log("airplane mode toggled - and airplane mode is off. return handled");
return HANDLED;
}
-
- Log.d(TAG, "ScanOnlyMode stopped, return to WifiDisabledState.");
- // notify WifiController that ScanOnlyMode stopped
- mScanOnlyCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
- mModeStateMachine.transitionTo(mWifiDisabledState);
+ case CMD_AP_STOPPED:
+ case CMD_AP_START_FAILURE:
+ if (!hasAnyModeManager()) {
+ if (shouldEnableSta()) {
+ log("SoftAp disabled, start client mode");
+ startClientModeManager();
+ } else {
+ log("SoftAp mode disabled, return to DisabledState");
+ transitionTo(mDisabledState);
+ }
+ } else {
+ log("AP disabled, remain in EnabledState.");
+ }
+ break;
+ case CMD_STA_START_FAILURE:
+ case CMD_STA_STOPPED:
+ // Client mode stopped. Head to Disabled to wait for next command if there
+ // no active mode managers.
+ if (!hasAnyModeManager()) {
+ log("STA disabled, return to DisabledState.");
+ transitionTo(mDisabledState);
+ } else {
+ log("STA disabled, remain in EnabledState.");
+ }
+ break;
+ case CMD_RECOVERY_RESTART_WIFI:
+ final String bugTitle;
+ final String bugDetail;
+ if (msg.arg1 < SelfRecovery.REASON_STRINGS.length && msg.arg1 >= 0) {
+ bugDetail = SelfRecovery.REASON_STRINGS[msg.arg1];
+ bugTitle = "Wi-Fi BugReport: " + bugDetail;
+ } else {
+ bugDetail = "";
+ bugTitle = "Wi-Fi BugReport";
+ }
+ if (msg.arg1 != SelfRecovery.REASON_LAST_RESORT_WATCHDOG) {
+ mHandler.post(() -> mClientModeImpl.takeBugReport(bugTitle, bugDetail));
+ }
+ log("Recovery triggered, disable wifi");
+ deferMessage(obtainMessage(CMD_DEFERRED_RECOVERY_RESTART_WIFI));
+ shutdownWifi();
+ // onStopped will move the state machine to "DisabledState".
break;
default:
return NOT_HANDLED;
@@ -553,105 +878,5 @@ public class ActiveModeWarden {
return HANDLED;
}
}
- } // class ModeStateMachine
-
- private class SoftApCallbackImpl extends ModeCallback implements WifiManager.SoftApCallback {
- private int mMode;
-
- private SoftApCallbackImpl(int mode) {
- mMode = mode;
- }
-
- @Override
- public void onStateChanged(int state, int reason) {
- if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
- mActiveModeManagers.remove(getActiveModeManager());
- updateBatteryStatsWifiState(false);
- } else if (state == WifiManager.WIFI_AP_STATE_FAILED) {
- mActiveModeManagers.remove(getActiveModeManager());
- updateBatteryStatsWifiState(false);
- }
-
- if (mSoftApCallback != null && mMode == WifiManager.IFACE_IP_MODE_TETHERED) {
- mSoftApCallback.onStateChanged(state, reason);
- }
- }
-
- @Override
- public void onNumClientsChanged(int numClients) {
- if (mSoftApCallback == null) {
- Log.d(TAG, "SoftApCallback is null. Dropping NumClientsChanged event.");
- } else if (mMode == WifiManager.IFACE_IP_MODE_TETHERED) {
- mSoftApCallback.onNumClientsChanged(numClients);
- }
- }
}
-
- private void startSoftAp(SoftApModeConfiguration softapConfig) {
- Log.d(TAG, "Starting SoftApModeManager");
-
- WifiConfiguration config = softapConfig.getWifiConfiguration();
- if (config != null && config.SSID != null) {
- Log.d(TAG, "Passing config to SoftApManager! " + config);
- } else {
- config = null;
- }
-
- SoftApCallbackImpl callback = new SoftApCallbackImpl(softapConfig.getTargetMode());
- ActiveModeManager manager = mWifiInjector.makeSoftApManager(callback, softapConfig);
- callback.setActiveModeManager(manager);
- manager.start();
- mActiveModeManagers.add(manager);
- updateBatteryStatsWifiState(true);
- }
-
- /**
- * Helper method to report wifi state as on/off (doesn't matter which mode).
- *
- * @param enabled boolean indicating that some mode has been turned on or off
- */
- private void updateBatteryStatsWifiState(boolean enabled) {
- try {
- if (enabled) {
- if (mActiveModeManagers.size() == 1) {
- // only report wifi on if we haven't already
- mBatteryStats.noteWifiOn();
- }
- } else {
- if (mActiveModeManagers.size() == 0) {
- // only report if we don't have any active modes
- mBatteryStats.noteWifiOff();
- }
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to note battery stats in wifi");
- }
- }
-
- private void updateBatteryStatsScanModeActive() {
- try {
- mBatteryStats.noteWifiState(BatteryStats.WIFI_STATE_OFF_SCANNING, null);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to note battery stats in wifi");
- }
- }
-
- // callback used to receive callbacks about underlying native failures
- private final class WifiNativeStatusListener implements StatusListener {
-
- @Override
- public void onStatusChanged(boolean isReady) {
- if (!isReady) {
- mHandler.post(() -> {
- Log.e(TAG, "One of the native daemons died. Triggering recovery");
- mWifiDiagnostics.captureBugReportData(
- WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
-
- // immediately trigger SelfRecovery if we receive a notice about an
- // underlying daemon failure
- mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
- });
- }
- }
- };
}
diff --git a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
index 7def2f37ae..7af22934f9 100644
--- a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
+++ b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
@@ -31,13 +31,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
+import android.net.wifi.IActionListener;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
+import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
@@ -58,7 +57,7 @@ import java.util.List;
import java.util.Set;
/**
- * Base class for all network notifiers (e.g. OpenNetworkNotifier, CarrierNetworkNotifier).
+ * Base class for all network notifiers (e.g. OpenNetworkNotifier).
*
* NOTE: These API's are not thread safe and should only be used from WifiCoreThread.
*/
@@ -126,7 +125,6 @@ public class AvailableNetworkNotifier {
private final Clock mClock;
private final WifiConfigManager mConfigManager;
private final ClientModeImpl mClientModeImpl;
- private final Messenger mSrcMessenger;
private final ConnectToNetworkNotificationBuilder mNotificationBuilder;
private ScanResult mRecommendedNetwork;
@@ -176,7 +174,6 @@ public class AvailableNetworkNotifier {
mClientModeImpl = clientModeImpl;
mNotificationBuilder = connectToNetworkNotificationBuilder;
mScreenOn = false;
- mSrcMessenger = new Messenger(new Handler(looper, mConnectionStateCallback));
wifiConfigStore.registerStoreData(new SsidSetStoreData(mStoreDataIdentifier,
new AvailableNetworkNotifierStoreData()));
@@ -223,21 +220,19 @@ public class AvailableNetworkNotifier {
}
};
- private final Handler.Callback mConnectionStateCallback = (Message msg) -> {
- switch (msg.what) {
+ private final class ConnectActionListener extends IActionListener.Stub {
+ @Override
+ public void onSuccess() {
// Success here means that an attempt to connect to the network has been initiated.
// Successful connection updates are received via the
// WifiConnectivityManager#handleConnectionStateChanged() callback.
- case WifiManager.CONNECT_NETWORK_SUCCEEDED:
- break;
- case WifiManager.CONNECT_NETWORK_FAILED:
- handleConnectionAttemptFailedToSend();
- break;
- default:
- Log.e("AvailableNetworkNotifier", "Unknown message " + msg.what);
}
- return true;
- };
+
+ @Override
+ public void onFailure(int reason) {
+ handleConnectionAttemptFailedToSend();
+ }
+ }
/**
* Clears the pending notification. This is called by {@link WifiConnectivityManager} on stop.
@@ -264,8 +259,9 @@ public class AvailableNetworkNotifier {
}
private boolean isControllerEnabled() {
- return mSettingEnabled && !UserManager.get(mContext)
- .hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT);
+ return mSettingEnabled && !mContext.getSystemService(UserManager.class)
+ // TODO (b/142234604): This will not work on multi-user device scenarios.
+ .hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT_OR_SELF);
}
/**
@@ -438,13 +434,9 @@ public class AvailableNetworkNotifier {
NetworkUpdateResult result = mConfigManager.addOrUpdateNetwork(network, Process.WIFI_UID);
if (result.isSuccess()) {
mWifiMetrics.setNominatorForNetwork(result.netId, mNominatorId);
-
- Message msg = Message.obtain();
- msg.what = WifiManager.CONNECT_NETWORK;
- msg.arg1 = result.netId;
- msg.obj = null;
- msg.replyTo = mSrcMessenger;
- mClientModeImpl.sendMessage(msg);
+ ConnectActionListener connectActionListener = new ConnectActionListener();
+ mClientModeImpl.connect(null, result.netId, new Binder(), connectActionListener,
+ connectActionListener.hashCode(), Process.WIFI_UID);
addNetworkToBlacklist(mRecommendedNetwork.SSID);
}
diff --git a/service/java/com/android/server/wifi/BootCompleteReceiver.java b/service/java/com/android/server/wifi/BootCompleteReceiver.java
new file mode 100644
index 0000000000..86f263a2d4
--- /dev/null
+++ b/service/java/com/android/server/wifi/BootCompleteReceiver.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.concurrent.GuardedBy;
+
+/**
+ * Receives boot complete broadcast (registered in AndroidManifest.xml).
+ *
+ * Ensures that if WifiStack is initialized after boot complete, we can check whether boot was
+ * already completed, since if we start listening for the boot complete broadcast now it will be too
+ * late and we will never get the broadcast.
+ *
+ * This BroadcastReceiver can be registered multiple times in different places, and it will ensure
+ * that all registered callbacks are triggered exactly once.
+ */
+public class BootCompleteReceiver extends BroadcastReceiver {
+ private static final String TAG = "WifiBootCompleteReceiver";
+
+ private static final Object sLock = new Object();
+ @GuardedBy("sLock")
+ private static boolean sIsBootCompleted = false;
+ @GuardedBy("sLock")
+ private static final List<Runnable> sCallbacks = new ArrayList<>(1);
+
+ public BootCompleteReceiver() {
+ Log.d(TAG, "Constructed BootCompleteReceiver");
+ }
+
+ /**
+ * Registers a callback that will be triggered when boot is completed. Note that if boot has
+ * already been completed when the callback is registered, the callback will be triggered
+ * immediately.
+ *
+ * No guarantees are made about which thread the callback is triggered on. Please do not
+ * perform expensive operations in the callback, instead post to other threads.
+ */
+ public static void registerCallback(Runnable callback) {
+ boolean runImmediately = false;
+
+ synchronized (sLock) {
+ if (sIsBootCompleted) {
+ runImmediately = true;
+ } else {
+ sCallbacks.add(callback);
+ }
+ }
+
+ // run callback outside of synchronized block
+ if (runImmediately) {
+ Log.d(TAG, "Triggering callback immediately since boot is already complete.");
+ callback.run();
+ } else {
+ Log.d(TAG, "Enqueuing callback since boot is not yet complete.");
+ }
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "Received boot complete broadcast");
+
+ List<Runnable> callbacks = new ArrayList<>(1);
+
+ synchronized (sLock) {
+ sIsBootCompleted = true;
+ callbacks.addAll(sCallbacks);
+ sCallbacks.clear();
+ }
+
+ // run callbacks outside of synchronized block
+ for (Runnable r : callbacks) {
+ Log.d(TAG, "Triggered callback");
+ r.run();
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/BubbleFunScorer.java b/service/java/com/android/server/wifi/BubbleFunScorer.java
index 497c22dce5..b5da5f03e8 100644
--- a/service/java/com/android/server/wifi/BubbleFunScorer.java
+++ b/service/java/com/android/server/wifi/BubbleFunScorer.java
@@ -33,12 +33,14 @@ final class BubbleFunScorer implements WifiCandidates.CandidateScorer {
* This should match WifiNetworkSelector.experimentIdFromIdentifier(getIdentifier())
* when using the default ScoringParams.
*/
- public static final int BUBBLE_FUN_SCORER_DEFAULT_EXPID = 42598151;
+ public static final int BUBBLE_FUN_SCORER_DEFAULT_EXPID = 42598152;
- private static final double SECURITY_AWARD = 80.0;
- private static final double CURRENT_NETWORK_BOOST = 80.0;
- private static final double LOW_BAND_FACTOR = 0.3;
+ private static final double SECURITY_AWARD = 44.0;
+ private static final double CURRENT_NETWORK_BOOST = 22.0;
+ private static final double LAST_SELECTION_BOOST = 250.0;
+ private static final double LOW_BAND_FACTOR = 0.25;
private static final double TYPICAL_SCAN_RSSI_STD = 4.0;
+ private static final boolean USE_USER_CONNECT_CHOICE = true;
private final ScoringParams mScoringParams;
@@ -48,7 +50,7 @@ final class BubbleFunScorer implements WifiCandidates.CandidateScorer {
@Override
public String getIdentifier() {
- return "BubbleFunScorer_v1";
+ return "BubbleFunScorer_v2";
}
/**
@@ -65,18 +67,6 @@ final class BubbleFunScorer implements WifiCandidates.CandidateScorer {
// If we are below the entry threshold, make the score more negative
if (score < 0.0) score *= 10.0;
- // A recently selected network gets a large boost
- score += candidate.getLastSelectionWeight() * CURRENT_NETWORK_BOOST;
-
- // Hysteresis to prefer staying on the current network.
- if (candidate.isCurrentNetwork()) {
- score += CURRENT_NETWORK_BOOST;
- }
-
- if (!candidate.isOpenNetwork()) {
- score += SECURITY_AWARD;
- }
-
// The gain is approximately the derivative of shapeFunction at the given rssi
// This is used to estimate the error
double gain = shapeFunction(rssi + 0.5)
@@ -89,7 +79,20 @@ final class BubbleFunScorer implements WifiCandidates.CandidateScorer {
gain *= LOW_BAND_FACTOR;
}
- return new ScoredCandidate(score, TYPICAL_SCAN_RSSI_STD * gain, candidate);
+ // A recently selected network gets a large boost
+ score += candidate.getLastSelectionWeight() * LAST_SELECTION_BOOST;
+
+ // Hysteresis to prefer staying on the current network.
+ if (candidate.isCurrentNetwork()) {
+ score += CURRENT_NETWORK_BOOST;
+ }
+
+ if (!candidate.isOpenNetwork()) {
+ score += SECURITY_AWARD;
+ }
+
+ return new ScoredCandidate(score, TYPICAL_SCAN_RSSI_STD * gain,
+ USE_USER_CONNECT_CHOICE, candidate);
}
/**
@@ -114,9 +117,9 @@ final class BubbleFunScorer implements WifiCandidates.CandidateScorer {
}
@Override
- public ScoredCandidate scoreCandidates(@NonNull Collection<Candidate> group) {
+ public ScoredCandidate scoreCandidates(@NonNull Collection<Candidate> candidates) {
ScoredCandidate choice = ScoredCandidate.NONE;
- for (Candidate candidate : group) {
+ for (Candidate candidate : candidates) {
ScoredCandidate scoredCandidate = scoreCandidate(candidate);
if (scoredCandidate.value > choice.value) {
choice = scoredCandidate;
@@ -127,9 +130,4 @@ final class BubbleFunScorer implements WifiCandidates.CandidateScorer {
return choice;
}
- @Override
- public boolean userConnectChoiceOverrideWanted() {
- return true;
- }
-
}
diff --git a/service/java/com/android/server/wifi/CarrierNetworkConfig.java b/service/java/com/android/server/wifi/CarrierNetworkConfig.java
index 4c92d6b391..174b5d7236 100644
--- a/service/java/com/android/server/wifi/CarrierNetworkConfig.java
+++ b/service/java/com/android/server/wifi/CarrierNetworkConfig.java
@@ -26,7 +26,6 @@ import android.net.Uri;
import android.net.wifi.EAPConstants;
import android.net.wifi.WifiEnterpriseConfig;
import android.os.Handler;
-import android.os.Looper;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.ImsiEncryptionInfo;
@@ -69,7 +68,7 @@ public class CarrierNetworkConfig {
mDbg = verbose > 0;
}
- public CarrierNetworkConfig(@NonNull Context context, @NonNull Looper looper,
+ public CarrierNetworkConfig(@NonNull Context context, @NonNull Handler handler,
@NonNull FrameworkFacade framework) {
mCarrierNetworkMap = new HashMap<>();
updateNetworkConfig(context);
@@ -84,13 +83,17 @@ public class CarrierNetworkConfig {
}
}, filter);
- framework.registerContentObserver(context, CONTENT_URI, false,
- new ContentObserver(new Handler(looper)) {
- @Override
- public void onChange(boolean selfChange) {
- updateNetworkConfig(context);
- }
- });
+ try {
+ framework.registerContentObserver(context, CONTENT_URI, false,
+ new ContentObserver(handler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateNetworkConfig(context);
+ }
+ });
+ } catch (SecurityException e) {
+ Log.e(TAG, "Failed to register content observer", e);
+ }
}
/**
diff --git a/service/java/com/android/server/wifi/CarrierNetworkEvaluator.java b/service/java/com/android/server/wifi/CarrierNetworkEvaluator.java
index 52d7d18449..105b3c69b1 100644
--- a/service/java/com/android/server/wifi/CarrierNetworkEvaluator.java
+++ b/service/java/com/android/server/wifi/CarrierNetworkEvaluator.java
@@ -141,7 +141,8 @@ public class CarrierNetworkEvaluator implements NetworkEvaluator {
mLocalLog.log(TAG + ": Failed to add carrier network: " + config);
continue;
}
- if (!mWifiConfigManager.enableNetwork(result.getNetworkId(), false, Process.WIFI_UID)) {
+ if (!mWifiConfigManager.enableNetwork(
+ result.getNetworkId(), false, Process.WIFI_UID, null)) {
mLocalLog.log(TAG + ": Failed to enable carrier network: " + config);
continue;
}
diff --git a/service/java/com/android/server/wifi/CarrierNetworkNotifier.java b/service/java/com/android/server/wifi/CarrierNetworkNotifier.java
deleted file mode 100644
index 5af4001810..0000000000
--- a/service/java/com/android/server/wifi/CarrierNetworkNotifier.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import android.content.Context;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiEnterpriseConfig;
-import android.net.wifi.WifiEnterpriseConfig.Eap;
-import android.os.Looper;
-import android.provider.Settings;
-
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.server.wifi.nano.WifiMetricsProto;
-
-/**
- * This class handles the "carrier wi-fi network available" notification
- *
- * NOTE: These API's are not thread safe and should only be used from ClientModeImpl thread.
- */
-public class CarrierNetworkNotifier extends AvailableNetworkNotifier {
- public static final String TAG = "WifiCarrierNetworkNotifier";
- private static final String STORE_DATA_IDENTIFIER = "CarrierNetworkNotifierBlacklist";
- private static final String TOGGLE_SETTINGS_NAME =
- Settings.Global.WIFI_CARRIER_NETWORKS_AVAILABLE_NOTIFICATION_ON;
-
- public CarrierNetworkNotifier(
- Context context,
- Looper looper,
- FrameworkFacade framework,
- Clock clock,
- WifiMetrics wifiMetrics,
- WifiConfigManager wifiConfigManager,
- WifiConfigStore wifiConfigStore,
- ClientModeImpl clientModeImpl,
- ConnectToNetworkNotificationBuilder connectToNetworkNotificationBuilder) {
- super(TAG, STORE_DATA_IDENTIFIER, TOGGLE_SETTINGS_NAME,
- SystemMessage.NOTE_CARRIER_NETWORK_AVAILABLE,
- WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER,
- context, looper, framework, clock,
- wifiMetrics, wifiConfigManager, wifiConfigStore, clientModeImpl,
- connectToNetworkNotificationBuilder);
- }
-
- @Override
- WifiConfiguration createRecommendedNetworkConfig(ScanResult recommendedNetwork) {
- WifiConfiguration network = super.createRecommendedNetworkConfig(recommendedNetwork);
-
- int eapMethod = recommendedNetwork.carrierApEapType;
- if (eapMethod == Eap.SIM || eapMethod == Eap.AKA || eapMethod == Eap.AKA_PRIME) {
- network.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
- network.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
- network.enterpriseConfig = new WifiEnterpriseConfig();
- network.enterpriseConfig.setEapMethod(recommendedNetwork.carrierApEapType);
- network.enterpriseConfig.setIdentity("");
- network.enterpriseConfig.setAnonymousIdentity("");
- }
-
- return network;
- }
-}
diff --git a/service/java/com/android/server/wifi/CellularLinkLayerStats.java b/service/java/com/android/server/wifi/CellularLinkLayerStats.java
deleted file mode 100644
index 25f2949a75..0000000000
--- a/service/java/com/android/server/wifi/CellularLinkLayerStats.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.telephony.TelephonyManager.NetworkType;
-
-/**
- * A class representing the link layer statistics of the primary registered cell
- * of cellular network
- */
-public class CellularLinkLayerStats {
- /** Cellular data network type currently in use on the device for data transmission */
- private @NetworkType int mDataNetworkType =
- TelephonyManager.NETWORK_TYPE_UNKNOWN;
- /**
- * Cellular signal strength in dBm, NR: CsiRsrp, LTE: Rsrp, WCDMA/TDSCDMA: Rscp,
- * CDMA: Rssi, EVDO: Rssi, GSM: Rssi
- */
- private int mSignalStrengthDbm = SignalStrength.INVALID;
- /**
- * Cellular signal strength in dB, NR: CsiSinr, LTE: Rsrq, WCDMA: EcNo, TDSCDMA: invalid,
- * CDMA: Ecio, EVDO: SNR, GSM: invalid
- */
- private int mSignalStrengthDb = SignalStrength.INVALID;
- /** Whether it is a new or old registered cell */
- private boolean mIsSameRegisteredCell = false;
-
- public void setDataNetworkType(@NetworkType int dataNetworkType) {
- mDataNetworkType = dataNetworkType;
- }
-
- public void setSignalStrengthDbm(int signalStrengthDbm) {
- mSignalStrengthDbm = signalStrengthDbm;
- }
-
- public void setIsSameRegisteredCell(boolean isSameRegisteredCell) {
- mIsSameRegisteredCell = isSameRegisteredCell;
- }
-
- public void setSignalStrengthDb(int signalStrengthDb) {
- mSignalStrengthDb = signalStrengthDb;
- }
-
- public @NetworkType int getDataNetworkType() {
- return mDataNetworkType;
- }
-
- public boolean getIsSameRegisteredCell() {
- return mIsSameRegisteredCell;
- }
-
- public int getSignalStrengthDb() {
- return mSignalStrengthDb;
- }
-
- public int getSignalStrengthDbm() {
- return mSignalStrengthDbm;
- }
-
- @Override
- public String toString() {
- StringBuilder sbuf = new StringBuilder();
- sbuf.append(" CellularLinkLayerStats: ").append('\n')
- .append(" Data Network Type: ")
- .append(mDataNetworkType).append('\n')
- .append(" Signal Strength in dBm: ")
- .append(mSignalStrengthDbm).append('\n')
- .append(" Signal Strength in dB: ")
- .append(mSignalStrengthDb).append('\n')
- .append(" Is it the same registered cell? ")
- .append(mIsSameRegisteredCell).append('\n');
- return sbuf.toString();
- }
-}
diff --git a/service/java/com/android/server/wifi/CellularLinkLayerStatsCollector.java b/service/java/com/android/server/wifi/CellularLinkLayerStatsCollector.java
deleted file mode 100644
index 81d219ccec..0000000000
--- a/service/java/com/android/server/wifi/CellularLinkLayerStatsCollector.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.wifi;
-
-import static android.telephony.TelephonyManager.NETWORK_TYPE_CDMA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_EVDO_0;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_GSM;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_NR;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_TD_SCDMA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
-
-import android.content.Context;
-import android.telephony.CellInfo;
-import android.telephony.CellInfoCdma;
-import android.telephony.CellInfoGsm;
-import android.telephony.CellInfoLte;
-import android.telephony.CellInfoNr;
-import android.telephony.CellInfoTdscdma;
-import android.telephony.CellInfoWcdma;
-import android.telephony.CellSignalStrength;
-import android.telephony.CellSignalStrengthCdma;
-import android.telephony.CellSignalStrengthGsm;
-import android.telephony.CellSignalStrengthLte;
-import android.telephony.CellSignalStrengthNr;
-import android.telephony.CellSignalStrengthTdscdma;
-import android.telephony.CellSignalStrengthWcdma;
-import android.telephony.SignalStrength;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-/**
- * A class collecting the latest cellular link layer stats
- */
-public class CellularLinkLayerStatsCollector {
- private static final String TAG = "CellStatsCollector";
- private static final boolean DBG = false;
-
- private Context mContext;
- private SubscriptionManager mSubManager = null;
- private TelephonyManager mCachedDefaultDataTelephonyManager = null;
- private int mCachedDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- private CellInfo mLastPrimaryCellInfo = null;
- private int mLastDataNetworkType = NETWORK_TYPE_UNKNOWN;
-
- public CellularLinkLayerStatsCollector(Context context) {
- mContext = context;
- }
-
- /**
- * Get the latest DataNetworkType, SignalStrength, CellInfo and other information from
- * default data sim's TelephonyManager, parse the values of primary registered cell and return
- * them as an instance of CellularLinkLayerStats
- */
- public CellularLinkLayerStats update() {
- CellularLinkLayerStats cellStats = new CellularLinkLayerStats();
-
- retrieveDefaultDataTelephonyManager();
- if (mCachedDefaultDataTelephonyManager == null) {
- if (DBG) Log.v(TAG, cellStats.toString());
- return cellStats;
- }
-
- SignalStrength signalStrength = mCachedDefaultDataTelephonyManager.getSignalStrength();
- List<CellSignalStrength> cssList = null;
- if (signalStrength != null) cssList = signalStrength.getCellSignalStrengths();
-
- if (mCachedDefaultDataTelephonyManager.getDataNetworkType() == NETWORK_TYPE_UNKNOWN
- || cssList == null || cssList.size() == 0) {
- mLastPrimaryCellInfo = null;
- mLastDataNetworkType = NETWORK_TYPE_UNKNOWN;
- if (DBG) Log.v(TAG, cellStats.toString());
- return cellStats;
- }
- if (DBG) Log.v(TAG, "Cell Signal Strength List size = " + cssList.size());
-
- CellSignalStrength primaryCss = cssList.get(0);
- cellStats.setSignalStrengthDbm(primaryCss.getDbm());
-
- updateSignalStrengthDbAndNetworkTypeOfCellStats(primaryCss, cellStats);
-
- int networkType = cellStats.getDataNetworkType();
- CellInfo primaryCellInfo = getPrimaryCellInfo(mCachedDefaultDataTelephonyManager,
- networkType);
- boolean isSameRegisteredCell = getIsSameRegisteredCell(primaryCellInfo, networkType);
- cellStats.setIsSameRegisteredCell(isSameRegisteredCell);
-
- // Update for the next call
- mLastPrimaryCellInfo = primaryCellInfo;
- mLastDataNetworkType = networkType;
-
- if (DBG) Log.v(TAG, cellStats.toString());
- return cellStats;
- }
-
- private void retrieveDefaultDataTelephonyManager() {
- if (!initSubManager()) return;
-
- int defaultDataSubId = mSubManager.getDefaultDataSubscriptionId();
- if (DBG) Log.v(TAG, "default Data Sub ID = " + defaultDataSubId);
- if (defaultDataSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- mCachedDefaultDataTelephonyManager = null;
- return;
- }
-
- if (defaultDataSubId != mCachedDefaultDataSubId
- || mCachedDefaultDataTelephonyManager == null) {
- mCachedDefaultDataSubId = defaultDataSubId;
- // TODO(b/132188983): Inject this using WifiInjector
- TelephonyManager defaultSubTelephonyManager = (TelephonyManager) mContext
- .getSystemService(Context.TELEPHONY_SERVICE);
- if (defaultDataSubId == mSubManager.getDefaultSubscriptionId()) {
- mCachedDefaultDataTelephonyManager = defaultSubTelephonyManager;
- } else {
- mCachedDefaultDataTelephonyManager = defaultSubTelephonyManager
- .createForSubscriptionId(defaultDataSubId);
- }
- }
- }
-
- private boolean initSubManager() {
- if (mSubManager == null) {
- mSubManager = (SubscriptionManager) mContext.getSystemService(
- Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- }
- return (mSubManager != null);
- }
-
- /**
- * Update dB value and network type base on CellSignalStrength subclass type.
- * It follows the same order as that in SignalStrength.getPrimary().
- * TODO: NR may move up in the future
- */
- private void updateSignalStrengthDbAndNetworkTypeOfCellStats(CellSignalStrength primaryCss,
- CellularLinkLayerStats cellStats) {
- if (primaryCss instanceof CellSignalStrengthLte) {
- CellSignalStrengthLte cssLte = (CellSignalStrengthLte) primaryCss;
- cellStats.setSignalStrengthDb(cssLte.getRsrq());
- cellStats.setDataNetworkType(NETWORK_TYPE_LTE);
- } else if (primaryCss instanceof CellSignalStrengthCdma) {
- CellSignalStrengthCdma cssCdma = (CellSignalStrengthCdma) primaryCss;
- int evdoSnr = cssCdma.getEvdoSnr();
- int cdmaEcio = cssCdma.getCdmaEcio();
- if (evdoSnr != SignalStrength.INVALID) {
- cellStats.setSignalStrengthDb(evdoSnr);
- cellStats.setDataNetworkType(NETWORK_TYPE_EVDO_0);
- } else {
- cellStats.setSignalStrengthDb(cdmaEcio);
- cellStats.setDataNetworkType(NETWORK_TYPE_CDMA);
- }
- } else if (primaryCss instanceof CellSignalStrengthTdscdma) {
- cellStats.setDataNetworkType(NETWORK_TYPE_TD_SCDMA);
- } else if (primaryCss instanceof CellSignalStrengthWcdma) {
- CellSignalStrengthWcdma cssWcdma = (CellSignalStrengthWcdma) primaryCss;
- cellStats.setSignalStrengthDb(cssWcdma.getEcNo());
- cellStats.setDataNetworkType(NETWORK_TYPE_UMTS);
- } else if (primaryCss instanceof CellSignalStrengthGsm) {
- cellStats.setDataNetworkType(NETWORK_TYPE_GSM);
- } else if (primaryCss instanceof CellSignalStrengthNr) {
- CellSignalStrengthNr cssNr = (CellSignalStrengthNr) primaryCss;
- cellStats.setSignalStrengthDb(cssNr.getCsiSinr());
- cellStats.setDataNetworkType(NETWORK_TYPE_NR);
- } else {
- Log.e(TAG, "invalid CellSignalStrength");
- }
- }
-
- private CellInfo getPrimaryCellInfo(TelephonyManager defaultDataTelephonyManager,
- int networkType) {
- List<CellInfo> cellInfoList = getRegisteredCellInfo(defaultDataTelephonyManager);
- int cilSize = cellInfoList.size();
- CellInfo primaryCellInfo = null;
- // CellInfo.getCellConnectionStatus() should tell if it is primary serving cell.
- // However, it currently always returns 0 (CONNECTION_NONE) for registered cells.
- // Therefore, the workaround of deriving primary serving cell is
- // to check if the registered cellInfo subclass type matches networkType
- for (int i = 0; i < cilSize; ++i) {
- CellInfo cellInfo = cellInfoList.get(i);
- if ((cellInfo instanceof CellInfoTdscdma && networkType == NETWORK_TYPE_TD_SCDMA)
- || (cellInfo instanceof CellInfoCdma && (networkType == NETWORK_TYPE_CDMA
- || networkType == NETWORK_TYPE_EVDO_0))
- || (cellInfo instanceof CellInfoLte && networkType == NETWORK_TYPE_LTE)
- || (cellInfo instanceof CellInfoWcdma && networkType == NETWORK_TYPE_UMTS)
- || (cellInfo instanceof CellInfoGsm && networkType == NETWORK_TYPE_GSM)
- || (cellInfo instanceof CellInfoNr && networkType == NETWORK_TYPE_NR)) {
- primaryCellInfo = cellInfo;
- }
- }
- return primaryCellInfo;
- }
-
- private boolean getIsSameRegisteredCell(CellInfo primaryCellInfo, int networkType) {
- boolean isSameRegisteredCell;
- if (primaryCellInfo != null && mLastPrimaryCellInfo != null) {
- isSameRegisteredCell = primaryCellInfo.getCellIdentity()
- .equals(mLastPrimaryCellInfo.getCellIdentity());
- } else if (primaryCellInfo == null && mLastPrimaryCellInfo == null) {
- // This is a workaround when it can't find primaryCellInfo for two consecutive times.
- isSameRegisteredCell = true;
- } else {
- // only one of them is null and it is a strong indication of primary cell change.
- isSameRegisteredCell = false;
- }
-
- if (mLastDataNetworkType == NETWORK_TYPE_UNKNOWN || mLastDataNetworkType != networkType) {
- isSameRegisteredCell = false;
- }
- return isSameRegisteredCell;
- }
-
- private List<CellInfo> getRegisteredCellInfo(TelephonyManager defaultDataTelephonyManager) {
- List<CellInfo> allList = defaultDataTelephonyManager.getAllCellInfo();
- List<CellInfo> cellInfoList = new ArrayList<>();
- for (CellInfo ci : allList) {
- if (ci.isRegistered()) cellInfoList.add(ci);
- if (DBG) Log.v(TAG, ci.toString());
- }
- return cellInfoList;
- }
-}
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 438f88550e..2d14f4e7d4 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -16,6 +16,8 @@
package com.android.server.wifi;
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT;
+import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY;
import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
@@ -30,7 +32,6 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
@@ -57,8 +58,9 @@ import android.net.ip.IIpClient;
import android.net.ip.IpClientCallbacks;
import android.net.ip.IpClientManager;
import android.net.shared.ProvisioningConfiguration;
+import android.net.wifi.IActionListener;
import android.net.wifi.INetworkRequestMatchCallback;
-import android.net.wifi.RssiPacketCountInfo;
+import android.net.wifi.ITxPacketCountListener;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
@@ -70,7 +72,6 @@ import android.net.wifi.WifiNetworkAgentSpecifier;
import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.p2p.IWifiP2pManager;
import android.os.BatteryStats;
import android.os.Bundle;
@@ -114,6 +115,7 @@ import com.android.server.wifi.nano.WifiMetricsProto.StaEvent;
import com.android.server.wifi.nano.WifiMetricsProto.WifiIsUnusableEvent;
import com.android.server.wifi.nano.WifiMetricsProto.WifiUsabilityStats;
import com.android.server.wifi.p2p.WifiP2pServiceImpl;
+import com.android.server.wifi.util.ExternalCallbackTracker;
import com.android.server.wifi.util.NativeUtil;
import com.android.server.wifi.util.TelephonyUtil;
import com.android.server.wifi.util.TelephonyUtil.SimAuthRequestData;
@@ -132,9 +134,7 @@ import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -218,6 +218,7 @@ public class ClientModeImpl extends StateMachine {
private final LinkProbeManager mLinkProbeManager;
private final McastLockManagerFilterController mMcastLockManagerFilterController;
+ private final ActivityManager mActivityManager;
private boolean mScreenOn = false;
@@ -256,7 +257,7 @@ public class ClientModeImpl extends StateMachine {
}
private boolean mEnableRssiPolling = false;
- // Accessed via Binder thread ({get,set}PollRssiIntervalMsecs), and ClientModeImpl thread.
+ // Accessed via Binder thread ({get,set}PollRssiIntervalMsecs), and the main Wifi thread.
private volatile int mPollRssiIntervalMsecs = DEFAULT_POLL_RSSI_INTERVAL_MSECS;
private int mRssiPollToken = 0;
/* 3 operational states for STA operation: CONNECT_MODE, SCAN_ONLY_MODE, SCAN_ONLY_WIFI_OFF_MODE
@@ -422,24 +423,16 @@ public class ClientModeImpl extends StateMachine {
// Provide packet filter capabilities to ConnectivityService.
private final NetworkMisc mNetworkMisc = new NetworkMisc();
+ private final ExternalCallbackTracker<IActionListener> mProcessingActionListeners;
+ private final ExternalCallbackTracker<ITxPacketCountListener> mProcessingTxPacketCountListeners;
+
/* The base for wifi message types */
static final int BASE = Protocol.BASE_WIFI;
static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 31;
- /* Supplicant commands */
- /* Add/update a network configuration */
- static final int CMD_ADD_OR_UPDATE_NETWORK = BASE + 52;
- /* Delete a network */
- static final int CMD_REMOVE_NETWORK = BASE + 53;
- /* Enable a network. The device will attempt a connection to the given network. */
- static final int CMD_ENABLE_NETWORK = BASE + 54;
- /* Get configured networks */
- static final int CMD_GET_CONFIGURED_NETWORKS = BASE + 59;
/* Get adaptors */
static final int CMD_GET_SUPPORTED_FEATURES = BASE + 61;
- /* Get configured networks with real preSharedKey */
- static final int CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS = BASE + 62;
/* Get Link Layer Stats thru HAL */
static final int CMD_GET_LINK_LAYER_STATS = BASE + 63;
/* Supplicant commands after driver start*/
@@ -491,43 +484,16 @@ public class ClientModeImpl extends StateMachine {
/* Disconnecting state watchdog */
static final int CMD_DISCONNECTING_WATCHDOG_TIMER = BASE + 96;
- /* Remove a packages associated configurations */
- static final int CMD_REMOVE_APP_CONFIGURATIONS = BASE + 97;
-
- /* Disable an ephemeral network */
- static final int CMD_DISABLE_EPHEMERAL_NETWORK = BASE + 98;
-
/* SIM is removed; reset any cached data for it */
static final int CMD_RESET_SIM_NETWORKS = BASE + 101;
/* OSU APIs */
static final int CMD_QUERY_OSU_ICON = BASE + 104;
- /* try to match a provider with current network */
- static final int CMD_MATCH_PROVIDER_NETWORK = BASE + 105;
-
- // Add or update a Passpoint configuration.
- static final int CMD_ADD_OR_UPDATE_PASSPOINT_CONFIG = BASE + 106;
-
- // Remove a Passpoint configuration.
- static final int CMD_REMOVE_PASSPOINT_CONFIG = BASE + 107;
-
- // Get the list of installed Passpoint configurations.
- static final int CMD_GET_PASSPOINT_CONFIGS = BASE + 108;
-
- // Get the list of OSU providers associated with a Passpoint network.
- static final int CMD_GET_MATCHING_OSU_PROVIDERS = BASE + 109;
-
- // Get the list of installed Passpoint configurations matched with OSU providers
- static final int CMD_GET_MATCHING_PASSPOINT_CONFIGS_FOR_OSU_PROVIDERS = BASE + 110;
-
/* Commands from/to the SupplicantStateTracker */
/* Reset the supplicant state tracker */
static final int CMD_RESET_SUPPLICANT_STATE = BASE + 111;
- // Get the list of wifi configurations for installed Passpoint profiles
- static final int CMD_GET_WIFI_CONFIGS_FOR_PASSPOINT_PROFILES = BASE + 112;
-
int mDisconnectingWatchdogCount = 0;
static final int DISCONNECTING_GUARD_TIMER_MSEC = 5000;
@@ -549,9 +515,6 @@ public class ClientModeImpl extends StateMachine {
/* Link configuration (IP address, DNS, ...) changes notified via netlink */
static final int CMD_UPDATE_LINKPROPERTIES = BASE + 140;
- /* Supplicant is trying to associate to a given BSSID */
- static final int CMD_TARGET_BSSID = BASE + 141;
-
static final int CMD_START_CONNECT = BASE + 143;
private static final int NETWORK_STATUS_UNWANTED_DISCONNECT = 0;
@@ -562,16 +525,11 @@ public class ClientModeImpl extends StateMachine {
static final int CMD_START_ROAM = BASE + 145;
- static final int CMD_ASSOCIATED_BSSID = BASE + 147;
-
static final int CMD_NETWORK_STATUS = BASE + 148;
/* A layer 3 neighbor on the Wi-Fi link became unreachable. */
static final int CMD_IP_REACHABILITY_LOST = BASE + 149;
- /* Remove a packages associated configrations */
- static final int CMD_REMOVE_USER_CONFIGURATIONS = BASE + 152;
-
static final int CMD_ACCEPT_UNVALIDATED = BASE + 153;
/* used to offload sending IP packet */
@@ -592,10 +550,6 @@ public class ClientModeImpl extends StateMachine {
/* Enable/Disable WifiConnectivityManager */
static final int CMD_ENABLE_WIFI_CONNECTIVITY_MANAGER = BASE + 166;
-
- /* Get FQDN list for Passpoint profiles matched with a given scanResults */
- static final int CMD_GET_ALL_MATCHING_FQDNS_FOR_SCAN_RESULTS = BASE + 168;
-
/**
* Used to handle messages bounced between ClientModeImpl and IpClient.
*/
@@ -611,15 +565,6 @@ public class ClientModeImpl extends StateMachine {
/* Enable/disable Neighbor Discovery offload functionality. */
static final int CMD_CONFIG_ND_OFFLOAD = BASE + 204;
- /* used to indicate that the foreground user was switched */
- static final int CMD_USER_SWITCH = BASE + 205;
-
- /* used to indicate that the foreground user was switched */
- static final int CMD_USER_UNLOCK = BASE + 206;
-
- /* used to indicate that the foreground user was switched */
- static final int CMD_USER_STOP = BASE + 207;
-
/* Read the APF program & data buffer */
static final int CMD_READ_PACKET_FILTER = BASE + 208;
@@ -640,6 +585,10 @@ public class ClientModeImpl extends StateMachine {
private static final int CMD_PRE_DHCP_ACTION_COMPLETE = BASE + 256;
private static final int CMD_POST_DHCP_ACTION = BASE + 257;
+ private static final int CMD_CONNECT_NETWORK = BASE + 258;
+ private static final int CMD_SAVE_NETWORK = BASE + 259;
+ private static final int CMD_PKT_CNT_FETCH = BASE + 261;
+
// For message logging.
private static final Class[] sMessageClasses = {
AsyncChannel.class, ClientModeImpl.class };
@@ -820,6 +769,7 @@ public class ClientModeImpl extends StateMachine {
mLinkProperties = new LinkProperties();
mMcastLockManagerFilterController = new McastLockManagerFilterController();
+ mActivityManager = context.getSystemService(ActivityManager.class);
mNetworkInfo.setIsAvailable(false);
mLastBssid = null;
@@ -851,6 +801,8 @@ public class ClientModeImpl extends StateMachine {
mNetworkCapabilitiesFilter, mWifiConnectivityManager);
mWifiNetworkSuggestionsManager = mWifiInjector.getWifiNetworkSuggestionsManager();
+ mProcessingActionListeners = new ExternalCallbackTracker<>(getHandler());
+ mProcessingTxPacketCountListeners = new ExternalCallbackTracker<>(getHandler());
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
@@ -895,6 +847,7 @@ public class ClientModeImpl extends StateMachine {
mTcpBufferSizes = mContext.getResources().getString(
R.string.config_wifi_tcp_buffers);
+ mWifiConfigManager.addOnNetworkUpdateListener(new OnNetworkUpdateListener());
// CHECKSTYLE:OFF IndentationCheck
addState(mDefaultState);
@@ -925,8 +878,9 @@ public class ClientModeImpl extends StateMachine {
}
private void registerForWifiMonitorEvents() {
- mWifiMonitor.registerHandler(mInterfaceName, CMD_TARGET_BSSID, getHandler());
- mWifiMonitor.registerHandler(mInterfaceName, CMD_ASSOCIATED_BSSID, getHandler());
+ mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.TARGET_BSSID_EVENT, getHandler());
+ mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.ASSOCIATED_BSSID_EVENT,
+ getHandler());
mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.ANQP_DONE_EVENT, getHandler());
mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.ASSOCIATION_REJECTION_EVENT,
getHandler());
@@ -960,12 +914,18 @@ public class ClientModeImpl extends StateMachine {
mWifiMetrics.getHandler());
mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT,
mWifiMetrics.getHandler());
- mWifiMonitor.registerHandler(mInterfaceName, CMD_ASSOCIATED_BSSID,
+ mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.ASSOCIATED_BSSID_EVENT,
mWifiMetrics.getHandler());
- mWifiMonitor.registerHandler(mInterfaceName, CMD_TARGET_BSSID,
+ mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.TARGET_BSSID_EVENT,
mWifiMetrics.getHandler());
mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.NETWORK_CONNECTION_EVENT,
mWifiInjector.getWifiLastResortWatchdog().getHandler());
+ mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.ASSOCIATION_REJECTION_EVENT,
+ mSupplicantStateTracker.getHandler());
+ mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.AUTHENTICATION_FAILURE_EVENT,
+ mSupplicantStateTracker.getHandler());
+ mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT,
+ mSupplicantStateTracker.getHandler());
}
private void setMulticastFilter(boolean enabled) {
@@ -1089,6 +1049,62 @@ public class ClientModeImpl extends StateMachine {
}
/**
+ * Listener for config manager network config related events.
+ * TODO (b/117601161) : Move some of the existing handling in WifiConnectivityManager's listener
+ * for the same events.
+ */
+ private class OnNetworkUpdateListener implements
+ WifiConfigManager.OnNetworkUpdateListener {
+ @Override
+ public void onNetworkAdded(WifiConfiguration config) { }
+
+ @Override
+ public void onNetworkEnabled(WifiConfiguration config) { }
+
+ @Override
+ public void onNetworkRemoved(WifiConfiguration config) {
+ // The current connected or connecting network has been removed, trigger a disconnect.
+ if (config.networkId == mTargetNetworkId || config.networkId == mLastNetworkId) {
+ // Disconnect and let autojoin reselect a new network
+ sendMessage(CMD_DISCONNECT);
+ }
+ mWifiNative.removeNetworkCachedData(config.networkId);
+ }
+
+
+ @Override
+ public void onNetworkUpdated(WifiConfiguration config) {
+ // User might have changed meteredOverride, so update capabilities
+ if (config.networkId == mLastNetworkId) {
+ updateCapabilities();
+ }
+ }
+
+ @Override
+ public void onNetworkTemporarilyDisabled(WifiConfiguration config, int disableReason) {
+ if (disableReason == DISABLED_NO_INTERNET_TEMPORARY) return;
+ if (config.networkId == mTargetNetworkId || config.networkId == mLastNetworkId) {
+ // Disconnect and let autojoin reselect a new network
+ sendMessage(CMD_DISCONNECT);
+ }
+
+ }
+
+ @Override
+ public void onNetworkPermanentlyDisabled(WifiConfiguration config, int disableReason) {
+ // For DISABLED_NO_INTERNET_PERMANENT we do not need to remove the network
+ // because supplicant won't be trying to reconnect. If this is due to a
+ // preventAutomaticReconnect request from ConnectivityService, that service
+ // will disconnect as appropriate.
+ if (disableReason == DISABLED_NO_INTERNET_PERMANENT) return;
+ if (config.networkId == mTargetNetworkId || config.networkId == mLastNetworkId) {
+ // Disconnect and let autojoin reselect a new network
+ sendMessage(CMD_DISCONNECT);
+ }
+ }
+ }
+
+ /**
* Set wpa_supplicant log level using |mVerboseLoggingLevel| flag.
*/
void setSupplicantLogLevel() {
@@ -1103,7 +1119,7 @@ public class ClientModeImpl extends StateMachine {
public void enableVerboseLogging(int verbose) {
if (verbose > 0) {
mVerboseLoggingEnabled = true;
- setLogRecSize(ActivityManager.isLowRamDeviceStatic()
+ setLogRecSize(mActivityManager.isLowRamDevice()
? NUM_LOG_RECS_VERBOSE_LOW_MEMORY : NUM_LOG_RECS_VERBOSE);
} else {
mVerboseLoggingEnabled = false;
@@ -1158,23 +1174,9 @@ public class ClientModeImpl extends StateMachine {
* @param forceReconnect Whether to force a connection even if we're connected to the same
* network currently.
*/
- private boolean connectToUserSelectNetwork(int netId, int uid, boolean forceReconnect) {
+ private void connectToUserSelectNetwork(int netId, int uid, boolean forceReconnect) {
logd("connectToUserSelectNetwork netId " + netId + ", uid " + uid
+ ", forceReconnect = " + forceReconnect);
- WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(netId);
- if (config == null) {
- loge("connectToUserSelectNetwork Invalid network Id=" + netId);
- return false;
- }
- if (!mWifiConfigManager.enableNetwork(netId, true, uid)
- || !mWifiConfigManager.updateLastConnectUid(netId, uid)) {
- logi("connectToUserSelectNetwork Allowing uid " + uid
- + " with insufficient permissions to connect=" + netId);
- } else if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
- // Note user connect choice here, so that it will be considered in the next network
- // selection.
- mWifiConnectivityManager.setUserConnectChoice(netId);
- }
if (!forceReconnect && mWifiInfo.getNetworkId() == netId) {
// We're already connected to the user specified network, don't trigger a
// reconnection unless it was forced.
@@ -1182,12 +1184,11 @@ public class ClientModeImpl extends StateMachine {
} else {
mWifiConnectivityManager.prepareForForcedConnection(netId);
if (uid == Process.SYSTEM_UID) {
- mWifiMetrics.setNominatorForNetwork(config.networkId,
+ mWifiMetrics.setNominatorForNetwork(netId,
WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL);
}
startConnectToNetwork(netId, uid, SUPPLICANT_BSSID_ANY);
}
- return true;
}
/**
@@ -1539,20 +1540,6 @@ public class ClientModeImpl extends StateMachine {
}
/**
- * Blocking method to match the provider with the current network
- *
- * @param channel AsyncChannel to use for the response
- * @param fqdn
- * @return int returns message result
- */
- public int matchProviderWithCurrentNetwork(AsyncChannel channel, String fqdn) {
- Message resultMsg = channel.sendMessageSynchronously(CMD_MATCH_PROVIDER_NETWORK, fqdn);
- int result = resultMsg.arg1;
- resultMsg.recycle();
- return result;
- }
-
- /**
* Deauthenticate and set the re-authentication hold off time for the current network
* @param holdoff hold off time in milliseconds
* @param ess set if the hold off pertains to an ESS rather than a BSS
@@ -1562,17 +1549,6 @@ public class ClientModeImpl extends StateMachine {
}
/**
- * Method to disable an ephemeral config for an ssid
- *
- * @param ssid network name to disable
- */
- public void disableEphemeralNetwork(String ssid) {
- if (ssid != null) {
- sendMessage(CMD_DISABLE_EPHEMERAL_NETWORK, ssid);
- }
- }
-
- /**
* Disconnect from Access Point
*/
public void disconnectCommand() {
@@ -1621,197 +1597,6 @@ public class ClientModeImpl extends StateMachine {
private AtomicInteger mNullMessageCounter = new AtomicInteger(0);
/**
- * Add a network synchronously
- *
- * @return network id of the new network
- */
- public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
- Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
- if (messageIsNull(resultMsg)) return WifiConfiguration.INVALID_NETWORK_ID;
- int result = resultMsg.arg1;
- resultMsg.recycle();
- return result;
- }
-
- /**
- * Get configured networks synchronously
- *
- * @param channel
- * @return
- */
- public List<WifiConfiguration> syncGetConfiguredNetworks(int uuid, AsyncChannel channel,
- int targetUid) {
- Message resultMsg = channel.sendMessageSynchronously(CMD_GET_CONFIGURED_NETWORKS, uuid,
- targetUid);
- if (messageIsNull(resultMsg)) return null;
- List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj;
- resultMsg.recycle();
- return result;
- }
-
- /**
- * Blocking call to get the current WifiConfiguration by a privileged caller so private data,
- * like the password, is not redacted.
- *
- * @param channel AsyncChannel to use for the response
- * @return List list of configured networks configs
- */
- public List<WifiConfiguration> syncGetPrivilegedConfiguredNetwork(AsyncChannel channel) {
- Message resultMsg = channel.sendMessageSynchronously(
- CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS);
- if (messageIsNull(resultMsg)) return null;
- List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj;
- resultMsg.recycle();
- return result;
- }
-
- /**
- * Returns the list of FQDN (Fully Qualified Domain Name) to installed Passpoint configurations.
- *
- * Return the map of all matching configurations with corresponding scanResults (or an empty map
- * if none).
- *
- * @param scanResults The list of scan results
- * @return Map that consists of FQDN (Fully Qualified Domain Name) and corresponding
- * scanResults per network type({@link WifiManager#PASSPOINT_HOME_NETWORK} and {@link
- * WifiManager#PASSPOINT_ROAMING_NETWORK}).
- */
- @NonNull
- Map<String, Map<Integer, List<ScanResult>>> syncGetAllMatchingFqdnsForScanResults(
- List<ScanResult> scanResults,
- AsyncChannel channel) {
- Message resultMsg = channel.sendMessageSynchronously(
- CMD_GET_ALL_MATCHING_FQDNS_FOR_SCAN_RESULTS,
- scanResults);
- if (messageIsNull(resultMsg)) return new HashMap<>();
- Map<String, Map<Integer, List<ScanResult>>> configs =
- (Map<String, Map<Integer, List<ScanResult>>>) resultMsg.obj;
- resultMsg.recycle();
- return configs;
- }
-
- /**
- * Retrieve a list of {@link OsuProvider} associated with the given list of ScanResult
- * synchronously.
- *
- * @param scanResults a list of ScanResult that has Passpoint APs.
- * @param channel Channel for communicating with the state machine
- * @return Map that consists of {@link OsuProvider} and a matching list of {@link ScanResult}.
- */
- @NonNull
- public Map<OsuProvider, List<ScanResult>> syncGetMatchingOsuProviders(
- List<ScanResult> scanResults,
- AsyncChannel channel) {
- Message resultMsg =
- channel.sendMessageSynchronously(CMD_GET_MATCHING_OSU_PROVIDERS, scanResults);
- if (messageIsNull(resultMsg)) return new HashMap<>();
- Map<OsuProvider, List<ScanResult>> providers =
- (Map<OsuProvider, List<ScanResult>>) resultMsg.obj;
- resultMsg.recycle();
- return providers;
- }
-
- /**
- * Returns the matching Passpoint configurations for given OSU(Online Sign-Up) Providers
- *
- * @param osuProviders a list of {@link OsuProvider}
- * @param channel AsyncChannel to use for the response
- * @return Map that consists of {@link OsuProvider} and matching {@link PasspointConfiguration}.
- */
- @NonNull
- public Map<OsuProvider, PasspointConfiguration> syncGetMatchingPasspointConfigsForOsuProviders(
- List<OsuProvider> osuProviders, AsyncChannel channel) {
- Message resultMsg =
- channel.sendMessageSynchronously(
- CMD_GET_MATCHING_PASSPOINT_CONFIGS_FOR_OSU_PROVIDERS, osuProviders);
- if (messageIsNull(resultMsg)) return new HashMap<>();
- Map<OsuProvider, PasspointConfiguration> result =
- (Map<OsuProvider, PasspointConfiguration>) resultMsg.obj;
- resultMsg.recycle();
- return result;
- }
-
- /**
- * Returns the corresponding wifi configurations for given FQDN (Fully Qualified Domain Name)
- * list.
- *
- * An empty list will be returned when no match is found.
- *
- * @param fqdnList a list of FQDN
- * @param channel AsyncChannel to use for the response
- * @return List of {@link WifiConfiguration} converted from
- * {@link com.android.server.wifi.hotspot2.PasspointProvider}
- */
- @NonNull
- public List<WifiConfiguration> syncGetWifiConfigsForPasspointProfiles(List<String> fqdnList,
- AsyncChannel channel) {
- Message resultMsg =
- channel.sendMessageSynchronously(
- CMD_GET_WIFI_CONFIGS_FOR_PASSPOINT_PROFILES, fqdnList);
- if (messageIsNull(resultMsg)) return new ArrayList<>();
- List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj;
- resultMsg.recycle();
- return result;
- }
-
- /**
- * Add or update a Passpoint configuration synchronously.
- *
- * @param channel Channel for communicating with the state machine
- * @param config The configuration to add or update
- * @param packageName Package name of the app adding/updating {@code config}.
- * @return true on success
- */
- public boolean syncAddOrUpdatePasspointConfig(AsyncChannel channel,
- PasspointConfiguration config, int uid, String packageName) {
- Bundle bundle = new Bundle();
- bundle.putInt(EXTRA_UID, uid);
- bundle.putString(EXTRA_PACKAGE_NAME, packageName);
- bundle.putParcelable(EXTRA_PASSPOINT_CONFIGURATION, config);
- Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_PASSPOINT_CONFIG,
- bundle);
- if (messageIsNull(resultMsg)) return false;
- boolean result = (resultMsg.arg1 == SUCCESS);
- resultMsg.recycle();
- return result;
- }
-
- /**
- * Remove a Passpoint configuration synchronously.
- *
- * @param channel Channel for communicating with the state machine
- * @param privileged Whether the caller is a privileged entity
- * @param fqdn The FQDN of the Passpoint configuration to remove
- * @return true on success
- */
- public boolean syncRemovePasspointConfig(AsyncChannel channel, boolean privileged,
- String fqdn) {
- Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_PASSPOINT_CONFIG,
- privileged ? 1 : 0, 0, fqdn);
- if (messageIsNull(resultMsg)) return false;
- boolean result = (resultMsg.arg1 == SUCCESS);
- resultMsg.recycle();
- return result;
- }
-
- /**
- * Get the list of installed Passpoint configurations synchronously.
- *
- * @param channel Channel for communicating with the state machine
- * @param privileged Whether the caller is a privileged entity
- * @return List of {@link PasspointConfiguration}
- */
- public List<PasspointConfiguration> syncGetPasspointConfigs(AsyncChannel channel,
- boolean privileged) {
- Message resultMsg = channel.sendMessageSynchronously(CMD_GET_PASSPOINT_CONFIGS,
- privileged ? 1 : 0);
- if (messageIsNull(resultMsg)) return null;
- List<PasspointConfiguration> result = (List<PasspointConfiguration>) resultMsg.obj;
- resultMsg.recycle();
- return result;
- }
-
- /**
* Start subscription provisioning synchronously
*
* @param provider {@link OsuProvider} the provider to provision with
@@ -1864,49 +1649,6 @@ public class ClientModeImpl extends StateMachine {
}
/**
- * Delete a network
- *
- * @param networkId id of the network to be removed
- */
- public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
- Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
- if (messageIsNull(resultMsg)) return false;
- boolean result = (resultMsg.arg1 != FAILURE);
- resultMsg.recycle();
- return result;
- }
-
- /**
- * Enable a network
- *
- * @param netId network id of the network
- * @param disableOthers true, if all other networks have to be disabled
- * @return {@code true} if the operation succeeds, {@code false} otherwise
- */
- public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
- Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
- disableOthers ? 1 : 0);
- if (messageIsNull(resultMsg)) return false;
- boolean result = (resultMsg.arg1 != FAILURE);
- resultMsg.recycle();
- return result;
- }
-
- /**
- * Disable a network
- *
- * @param netId network id of the network
- * @return {@code true} if the operation succeeds, {@code false} otherwise
- */
- public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
- Message resultMsg = channel.sendMessageSynchronously(WifiManager.DISABLE_NETWORK, netId);
- boolean result = (resultMsg.what != WifiManager.DISABLE_NETWORK_FAILED);
- if (messageIsNull(resultMsg)) return false;
- resultMsg.recycle();
- return result;
- }
-
- /**
* Method to enable/disable RSSI polling
* @param enabled boolean idicating if polling should start
*/
@@ -1963,24 +1705,6 @@ public class ClientModeImpl extends StateMachine {
}
/**
- * Send a message indicating a package has been uninstalled.
- */
- public void removeAppConfigs(String packageName, int uid) {
- // Build partial AppInfo manually - package may not exist in database any more
- ApplicationInfo ai = new ApplicationInfo();
- ai.packageName = packageName;
- ai.uid = uid;
- sendMessage(CMD_REMOVE_APP_CONFIGURATIONS, ai);
- }
-
- /**
- * Send a message indicating a user has been removed.
- */
- public void removeUserConfigs(int userId) {
- sendMessage(CMD_REMOVE_USER_CONFIGURATIONS, userId);
- }
-
- /**
* Update the BatteryStats WorkSource.
*/
public void updateBatteryWorkSource(WorkSource newSource) {
@@ -2070,27 +1794,6 @@ public class ClientModeImpl extends StateMachine {
}
/**
- * Trigger message to handle user switch event.
- */
- public void handleUserSwitch(int userId) {
- sendMessage(CMD_USER_SWITCH, userId);
- }
-
- /**
- * Trigger message to handle user unlock event.
- */
- public void handleUserUnlock(int userId) {
- sendMessage(CMD_USER_UNLOCK, userId);
- }
-
- /**
- * Trigger message to handle user stop event.
- */
- public void handleUserStop(int userId) {
- sendMessage(CMD_USER_STOP, userId);
- }
-
- /**
* ******************************************************
* Internal private functions
* ******************************************************
@@ -2144,12 +1847,14 @@ public class ClientModeImpl extends StateMachine {
sb.append(stateChangeResult.toString());
}
break;
- case WifiManager.SAVE_NETWORK:
+ case CMD_CONNECT_NETWORK:
+ case CMD_SAVE_NETWORK: {
+ NetworkUpdateResult result = (NetworkUpdateResult) msg.obj;
sb.append(" ");
- sb.append(Integer.toString(msg.arg1));
+ sb.append(Integer.toString(result.netId));
sb.append(" ");
sb.append(Integer.toString(msg.arg2));
- config = (WifiConfiguration) msg.obj;
+ config = mWifiConfigManager.getConfiguredNetwork(result.netId);
if (config != null) {
sb.append(" ").append(config.configKey());
sb.append(" nid=").append(config.networkId);
@@ -2170,35 +1875,7 @@ public class ClientModeImpl extends StateMachine {
sb.append(" suid=").append(config.lastUpdateUid);
}
break;
- case WifiManager.FORGET_NETWORK:
- sb.append(" ");
- sb.append(Integer.toString(msg.arg1));
- sb.append(" ");
- sb.append(Integer.toString(msg.arg2));
- config = (WifiConfiguration) msg.obj;
- if (config != null) {
- sb.append(" ").append(config.configKey());
- sb.append(" nid=").append(config.networkId);
- if (config.hiddenSSID) {
- sb.append(" hidden");
- }
- if (config.preSharedKey != null) {
- sb.append(" hasPSK");
- }
- if (config.ephemeral) {
- sb.append(" ephemeral");
- }
- if (config.selfAdded) {
- sb.append(" selfAdded");
- }
- sb.append(" cuid=").append(config.creatorUid);
- sb.append(" suid=").append(config.lastUpdateUid);
- WifiConfiguration.NetworkSelectionStatus netWorkSelectionStatus =
- config.getNetworkSelectionStatus();
- sb.append(" ajst=").append(
- netWorkSelectionStatus.getNetworkStatusString());
- }
- break;
+ }
case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
sb.append(" ");
sb.append(" timedOut=" + Integer.toString(msg.arg1));
@@ -2227,8 +1904,8 @@ public class ClientModeImpl extends StateMachine {
sb.append(" last=").append(key);
}
break;
- case CMD_TARGET_BSSID:
- case CMD_ASSOCIATED_BSSID:
+ case WifiMonitor.TARGET_BSSID_EVENT:
+ case WifiMonitor.ASSOCIATED_BSSID_EVENT:
sb.append(" ");
sb.append(Integer.toString(msg.arg1));
sb.append(" ");
@@ -2258,7 +1935,7 @@ public class ClientModeImpl extends StateMachine {
case CMD_RSSI_POLL:
case CMD_ONESHOT_RSSI_POLL:
case CMD_UNWANTED_NETWORK:
- case WifiManager.RSSI_PKTCNT_FETCH:
+ case CMD_PKT_CNT_FETCH:
sb.append(" ");
sb.append(Integer.toString(msg.arg1));
sb.append(" ");
@@ -2287,7 +1964,6 @@ public class ClientModeImpl extends StateMachine {
sb.append(String.format(" score=%d", mWifiInfo.score));
break;
case CMD_START_CONNECT:
- case WifiManager.CONNECT_NETWORK:
sb.append(" ");
sb.append(Integer.toString(msg.arg1));
sb.append(" ");
@@ -2329,53 +2005,6 @@ public class ClientModeImpl extends StateMachine {
sb.append(" roam=").append(Boolean.toString(mIsAutoRoaming));
sb.append(" fail count=").append(Integer.toString(mRoamFailCount));
break;
- case CMD_ADD_OR_UPDATE_NETWORK:
- sb.append(" ");
- sb.append(Integer.toString(msg.arg1));
- sb.append(" ");
- sb.append(Integer.toString(msg.arg2));
- if (msg.obj != null) {
- config = (WifiConfiguration) msg.obj;
- sb.append(" ").append(config.configKey());
- sb.append(" prio=").append(config.priority);
- sb.append(" status=").append(config.status);
- if (config.BSSID != null) {
- sb.append(" ").append(config.BSSID);
- }
- WifiConfiguration curConfig = getCurrentWifiConfiguration();
- if (curConfig != null) {
- if (curConfig.configKey().equals(config.configKey())) {
- sb.append(" is current");
- } else {
- sb.append(" current=").append(curConfig.configKey());
- sb.append(" prio=").append(curConfig.priority);
- sb.append(" status=").append(curConfig.status);
- }
- }
- }
- break;
- case WifiManager.DISABLE_NETWORK:
- case CMD_ENABLE_NETWORK:
- sb.append(" ");
- sb.append(Integer.toString(msg.arg1));
- sb.append(" ");
- sb.append(Integer.toString(msg.arg2));
- key = mWifiConfigManager.getLastSelectedNetworkConfigKey();
- if (key != null) {
- sb.append(" last=").append(key);
- }
- config = mWifiConfigManager.getConfiguredNetwork(msg.arg1);
- if (config != null && (key == null || !config.configKey().equals(key))) {
- sb.append(" target=").append(key);
- }
- break;
- case CMD_GET_CONFIGURED_NETWORKS:
- sb.append(" ");
- sb.append(Integer.toString(msg.arg1));
- sb.append(" ");
- sb.append(Integer.toString(msg.arg2));
- sb.append(" num=").append(mWifiConfigManager.getConfiguredNetworks().size());
- break;
case CMD_PRE_DHCP_ACTION:
sb.append(" ");
sb.append(Integer.toString(msg.arg1));
@@ -2472,10 +2101,6 @@ public class ClientModeImpl extends StateMachine {
sb.append(" thresholds=");
sb.append(Arrays.toString(mRssiRanges));
break;
- case CMD_USER_SWITCH:
- sb.append(" userId=");
- sb.append(Integer.toString(msg.arg1));
- break;
case CMD_IPV4_PROVISIONING_SUCCESS:
sb.append(" ");
sb.append(/* DhcpResults */ msg.obj);
@@ -2504,17 +2129,11 @@ public class ClientModeImpl extends StateMachine {
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
s = "CMD_CHANNEL_DISCONNECTED";
break;
- case WifiManager.DISABLE_NETWORK:
- s = "DISABLE_NETWORK";
+ case CMD_CONNECT_NETWORK:
+ s = "CMD_CONNECT_NETWORK";
break;
- case WifiManager.CONNECT_NETWORK:
- s = "CONNECT_NETWORK";
- break;
- case WifiManager.SAVE_NETWORK:
- s = "SAVE_NETWORK";
- break;
- case WifiManager.FORGET_NETWORK:
- s = "FORGET_NETWORK";
+ case CMD_SAVE_NETWORK:
+ s = "CMD_SAVE_NETWORK";
break;
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
s = "SUPPLICANT_STATE_CHANGE_EVENT";
@@ -2567,8 +2186,8 @@ public class ClientModeImpl extends StateMachine {
case WifiP2pServiceImpl.BLOCK_DISCOVERY:
s = "BLOCK_DISCOVERY";
break;
- case WifiManager.RSSI_PKTCNT_FETCH:
- s = "RSSI_PKTCNT_FETCH";
+ case CMD_PKT_CNT_FETCH:
+ s = "CMD_PKT_CNT_FETCH";
break;
default:
s = "what:" + Integer.toString(what);
@@ -2582,8 +2201,7 @@ public class ClientModeImpl extends StateMachine {
if (mVerboseLoggingEnabled) {
logd(" handleScreenStateChanged Enter: screenOn=" + screenOn
+ " mUserWantsSuspendOpt=" + mUserWantsSuspendOpt
- + " state " + getCurrentState().getName()
- + " suppState:" + mSupplicantStateTracker.getSupplicantStateName());
+ + " state " + getCurrentState().getName());
}
enableRssiPolling(screenOn);
if (mUserWantsSuspendOpt.get()) {
@@ -2912,11 +2530,15 @@ public class ClientModeImpl extends StateMachine {
mWifiInfo.setNetworkId(stateChangeResult.networkId);
mWifiInfo.setBSSID(stateChangeResult.BSSID);
mWifiInfo.setSSID(stateChangeResult.wifiSsid);
+ if (state == SupplicantState.ASSOCIATED) {
+ mWifiInfo.setWifiTechnology(mWifiNative.getWifiTechnology(mInterfaceName));
+ }
} else {
// Reset parameters according to WifiInfo.reset()
mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
mWifiInfo.setBSSID(null);
mWifiInfo.setSSID(null);
+ mWifiInfo.setWifiTechnology(WifiInfo.WIFI_TECHNOLOGY_UNKNOWN);
}
updateL2KeyAndGroupHint();
// SSID might have been updated, so call updateCapabilities
@@ -2946,8 +2568,6 @@ public class ClientModeImpl extends StateMachine {
}
}
}
-
- mSupplicantStateTracker.sendMessage(Message.obtain(message));
mWifiScoreCard.noteSupplicantStateChanged(mWifiInfo);
return state;
}
@@ -3388,8 +3008,7 @@ public class ClientModeImpl extends StateMachine {
String currentMacString = mWifiNative.getMacAddress(mInterfaceName);
MacAddress currentMac = currentMacString == null ? null :
MacAddress.fromString(currentMacString);
- MacAddress newMac = config.getOrCreateRandomizedMacAddress();
- mWifiConfigManager.setNetworkRandomizedMacAddress(config.networkId, newMac);
+ MacAddress newMac = mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config);
if (!WifiConfiguration.isValidMacAddressForRandomization(newMac)) {
Log.wtf(TAG, "Config generated an invalid MAC address");
} else if (newMac.equals(currentMac)) {
@@ -3453,6 +3072,9 @@ public class ClientModeImpl extends StateMachine {
@Override
public boolean processMessage(Message message) {
boolean handleStatus = HANDLED;
+ int callbackIdentifier = -1;
+ int netId;
+ boolean ok;
switch (message.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
@@ -3484,36 +3106,6 @@ public class ClientModeImpl extends StateMachine {
mBluetoothConnectionActive =
(message.arg1 != BluetoothAdapter.STATE_DISCONNECTED);
break;
- case CMD_ENABLE_NETWORK:
- boolean disableOthers = message.arg2 == 1;
- int netId = message.arg1;
- boolean ok = mWifiConfigManager.enableNetwork(
- netId, disableOthers, message.sendingUid);
- if (!ok) {
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- }
- replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
- break;
- case CMD_ADD_OR_UPDATE_NETWORK:
- WifiConfiguration config = (WifiConfiguration) message.obj;
- NetworkUpdateResult result =
- mWifiConfigManager.addOrUpdateNetwork(config, message.sendingUid);
- if (!result.isSuccess()) {
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- }
- replyToMessage(message, message.what, result.getNetworkId());
- break;
- case CMD_REMOVE_NETWORK:
- deleteNetworkConfigAndSendReply(message, false);
- break;
- case CMD_GET_CONFIGURED_NETWORKS:
- replyToMessage(message, message.what,
- mWifiConfigManager.getSavedNetworks(message.arg2));
- break;
- case CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS:
- replyToMessage(message, message.what,
- mWifiConfigManager.getConfiguredNetworksWithPasswords());
- break;
case CMD_ENABLE_RSSI_POLL:
mEnableRssiPolling = (message.arg1 == 1);
break;
@@ -3526,17 +3118,11 @@ public class ClientModeImpl extends StateMachine {
break;
case CMD_INITIALIZE:
ok = mWifiNative.initialize();
- mPasspointManager.initializeProvisioner(
- mWifiInjector.getWifiServiceHandlerThread().getLooper());
replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
break;
case CMD_BOOT_COMPLETED:
// get other services that we need to manage
getAdditionalWifiServiceInterfaces();
- new MemoryStoreImpl(mContext, mWifiInjector, mWifiScoreCard).start();
- if (!mWifiConfigManager.loadFromStore()) {
- Log.e(TAG, "Failed to load from config store");
- }
registerNetworkFactory();
break;
case CMD_SCREEN_STATE_CHANGED:
@@ -3557,16 +3143,13 @@ public class ClientModeImpl extends StateMachine {
case CMD_POST_DHCP_ACTION:
case WifiMonitor.SUP_REQUEST_IDENTITY:
case WifiMonitor.SUP_REQUEST_SIM_AUTH:
- case CMD_TARGET_BSSID:
+ case WifiMonitor.TARGET_BSSID_EVENT:
case CMD_START_CONNECT:
case CMD_START_ROAM:
- case CMD_ASSOCIATED_BSSID:
+ case WifiMonitor.ASSOCIATED_BSSID_EVENT:
case CMD_UNWANTED_NETWORK:
case CMD_DISCONNECTING_WATCHDOG_TIMER:
case CMD_ROAM_WATCHDOG_TIMER:
- case CMD_DISABLE_EPHEMERAL_NETWORK:
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
- break;
case CMD_SET_OPERATIONAL_MODE:
// using the CMD_SET_OPERATIONAL_MODE (sent at front of queue) to trigger the
// state transitions performed in setOperationalMode.
@@ -3581,23 +3164,19 @@ public class ClientModeImpl extends StateMachine {
setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, false);
}
break;
- case WifiManager.CONNECT_NETWORK:
- replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
- WifiManager.BUSY);
+ case CMD_CONNECT_NETWORK:
+ // wifi off, can't connect.
+ callbackIdentifier = message.arg2;
+ sendActionListenerFailure(callbackIdentifier, WifiManager.BUSY);
break;
- case WifiManager.FORGET_NETWORK:
- deleteNetworkConfigAndSendReply(message, true);
+ case CMD_SAVE_NETWORK:
+ // wifi off, nothing more to do here.
+ callbackIdentifier = message.arg2;
+ sendActionListenerSuccess(callbackIdentifier);
break;
- case WifiManager.SAVE_NETWORK:
- saveNetworkConfigAndSendReply(message);
- break;
- case WifiManager.DISABLE_NETWORK:
- replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
- WifiManager.BUSY);
- break;
- case WifiManager.RSSI_PKTCNT_FETCH:
- replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_FAILED,
- WifiManager.BUSY);
+ case CMD_PKT_CNT_FETCH:
+ callbackIdentifier = message.arg2;
+ sendTxPacketCountListenerFailure(callbackIdentifier, WifiManager.BUSY);
break;
case CMD_GET_SUPPORTED_FEATURES:
long featureSet = (mWifiNative.getSupportedFeatureSet(mInterfaceName));
@@ -3619,16 +3198,6 @@ public class ClientModeImpl extends StateMachine {
case CMD_UPDATE_LINKPROPERTIES:
updateLinkProperties((LinkProperties) message.obj);
break;
- case CMD_GET_MATCHING_OSU_PROVIDERS:
- replyToMessage(message, message.what, new HashMap<>());
- break;
- case CMD_GET_MATCHING_PASSPOINT_CONFIGS_FOR_OSU_PROVIDERS:
- replyToMessage(message, message.what,
- new HashMap<OsuProvider, PasspointConfiguration>());
- break;
- case CMD_GET_WIFI_CONFIGS_FOR_PASSPOINT_PROFILES:
- replyToMessage(message, message.what, new ArrayList<>());
- break;
case CMD_START_SUBSCRIPTION_PROVISIONING:
replyToMessage(message, message.what, 0);
break;
@@ -3637,12 +3206,6 @@ public class ClientModeImpl extends StateMachine {
case CMD_IP_REACHABILITY_LOST:
mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
break;
- case CMD_REMOVE_APP_CONFIGURATIONS:
- deferMessage(message);
- break;
- case CMD_REMOVE_USER_CONFIGURATIONS:
- deferMessage(message);
- break;
case CMD_START_IP_PACKET_OFFLOAD:
/* fall-through */
case CMD_STOP_IP_PACKET_OFFLOAD:
@@ -3659,47 +3222,12 @@ public class ClientModeImpl extends StateMachine {
case CMD_STOP_RSSI_MONITORING_OFFLOAD:
mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
break;
- case CMD_USER_SWITCH:
- Set<Integer> removedNetworkIds =
- mWifiConfigManager.handleUserSwitch(message.arg1);
- if (removedNetworkIds.contains(mTargetNetworkId)
- || removedNetworkIds.contains(mLastNetworkId)) {
- // Disconnect and let autojoin reselect a new network
- sendMessage(CMD_DISCONNECT);
- }
- break;
- case CMD_USER_UNLOCK:
- mWifiConfigManager.handleUserUnlock(message.arg1);
- break;
- case CMD_USER_STOP:
- mWifiConfigManager.handleUserStop(message.arg1);
- break;
case CMD_QUERY_OSU_ICON:
- case CMD_MATCH_PROVIDER_NETWORK:
/* reply with arg1 = 0 - it returns API failure to the calling app
* (message.what is not looked at)
*/
replyToMessage(message, message.what);
break;
- case CMD_ADD_OR_UPDATE_PASSPOINT_CONFIG:
- Bundle bundle = (Bundle) message.obj;
- int addResult = mPasspointManager.addOrUpdateProvider(bundle.getParcelable(
- EXTRA_PASSPOINT_CONFIGURATION),
- bundle.getInt(EXTRA_UID),
- bundle.getString(EXTRA_PACKAGE_NAME))
- ? SUCCESS : FAILURE;
- replyToMessage(message, message.what, addResult);
- break;
- case CMD_REMOVE_PASSPOINT_CONFIG:
- int removeResult = mPasspointManager.removeProvider(
- message.sendingUid, message.arg1 == 1, (String) message.obj)
- ? SUCCESS : FAILURE;
- replyToMessage(message, message.what, removeResult);
- break;
- case CMD_GET_PASSPOINT_CONFIGS:
- replyToMessage(message, message.what, mPasspointManager.getProviderConfigs(
- message.sendingUid, message.arg1 == 1));
- break;
case CMD_RESET_SIM_NETWORKS:
/* Defer this message until supplicant is started. */
mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
@@ -3725,9 +3253,6 @@ public class ClientModeImpl extends StateMachine {
mWifiDiagnostics.reportConnectionEvent(
BaseWifiDiagnostics.CONNECTION_EVENT_TIMEOUT);
break;
- case CMD_GET_ALL_MATCHING_FQDNS_FOR_SCAN_RESULTS:
- replyToMessage(message, message.what, new HashMap<>());
- break;
case 0:
// We want to notice any empty messages (with what == 0) that might crop up.
// For example, we may have recycled a message sent to multiple handlers.
@@ -3927,8 +3452,6 @@ public class ClientModeImpl extends StateMachine {
// Inform metrics that Wifi is Enabled (but not yet connected)
mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED);
mWifiMetrics.logStaEvent(StaEvent.TYPE_WIFI_ENABLED);
- // Inform sar manager that wifi is Enabled
- mSarManager.setClientWifiState(WifiManager.WIFI_STATE_ENABLED);
mWifiScoreCard.noteSupplicantStateChanged(mWifiInfo);
}
@@ -3947,8 +3470,6 @@ public class ClientModeImpl extends StateMachine {
mWifiMetrics.logStaEvent(StaEvent.TYPE_WIFI_DISABLED);
// Inform scorecard that wifi is being disabled
mWifiScoreCard.noteWifiDisabled(mWifiInfo);
- // Inform sar manager that wifi is being disabled
- mSarManager.setClientWifiState(WifiManager.WIFI_STATE_DISABLED);
if (!mWifiNative.removeAllNetworks(mInterfaceName)) {
loge("Failed to remove networks on exiting connect mode");
@@ -3972,6 +3493,7 @@ public class ClientModeImpl extends StateMachine {
int reasonCode;
boolean timedOut;
boolean handleStatus = HANDLED;
+ int callbackIdentifier = -1;
switch (message.what) {
case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
@@ -3997,7 +3519,6 @@ public class ClientModeImpl extends StateMachine {
.DISABLED_ASSOCIATION_REJECTION);
mWifiConfigManager.setRecentFailureAssociationStatus(mTargetNetworkId,
reasonCode);
- mSupplicantStateTracker.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT);
// If rejection occurred while Metrics is tracking a ConnnectionEvent, end it.
reportConnectionAttemptEnd(
timedOut
@@ -4013,7 +3534,6 @@ public class ClientModeImpl extends StateMachine {
case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
mWifiDiagnostics.captureBugReportData(
WifiDiagnostics.REPORT_REASON_AUTH_FAILURE);
- mSupplicantStateTracker.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT);
int disableReason = WifiConfiguration.NetworkSelectionStatus
.DISABLED_AUTHENTICATION_FAILURE;
reasonCode = message.arg1;
@@ -4070,7 +3590,8 @@ public class ClientModeImpl extends StateMachine {
if (reasonCode != WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD) {
mWifiInjector.getWifiLastResortWatchdog()
.noteConnectionFailureAndTriggerIfNeeded(
- getTargetSsid(), mTargetRoamBSSID,
+ getTargetSsid(),
+ (mLastBssid == null) ? mTargetRoamBSSID : mLastBssid,
WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION);
}
break;
@@ -4112,59 +3633,6 @@ public class ClientModeImpl extends StateMachine {
mTemporarilyDisconnectWifi = false;
}
break;
- case CMD_REMOVE_NETWORK:
- if (!deleteNetworkConfigAndSendReply(message, false)) {
- // failed to remove the config and caller was notified
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- break;
- }
- // we successfully deleted the network config
- netId = message.arg1;
- if (netId == mTargetNetworkId || netId == mLastNetworkId) {
- // Disconnect and let autojoin reselect a new network
- sendMessage(CMD_DISCONNECT);
- }
- break;
- case CMD_ENABLE_NETWORK:
- boolean disableOthers = message.arg2 == 1;
- netId = message.arg1;
- if (disableOthers) {
- // If the app has all the necessary permissions, this will trigger a connect
- // attempt.
- ok = connectToUserSelectNetwork(netId, message.sendingUid, false);
- } else {
- ok = mWifiConfigManager.enableNetwork(netId, false, message.sendingUid);
- }
- if (!ok) {
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- }
- replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
- break;
- case WifiManager.DISABLE_NETWORK:
- netId = message.arg1;
- if (mWifiConfigManager.disableNetwork(netId, message.sendingUid)) {
- replyToMessage(message, WifiManager.DISABLE_NETWORK_SUCCEEDED);
- if (netId == mTargetNetworkId || netId == mLastNetworkId) {
- // Disconnect and let autojoin reselect a new network
- sendMessage(CMD_DISCONNECT);
- }
- } else {
- loge("Failed to disable network");
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
- WifiManager.ERROR);
- }
- break;
- case CMD_DISABLE_EPHEMERAL_NETWORK:
- config = mWifiConfigManager.disableEphemeralNetwork((String) message.obj);
- if (config != null) {
- if (config.networkId == mTargetNetworkId
- || config.networkId == mLastNetworkId) {
- // Disconnect and let autojoin reselect a new network
- sendMessage(CMD_DISCONNECT);
- }
- }
- break;
case WifiMonitor.SUP_REQUEST_IDENTITY:
netId = message.arg2;
boolean identitySent = false;
@@ -4179,8 +3647,8 @@ public class ClientModeImpl extends StateMachine {
mWifiInjector.getCarrierNetworkConfig());
Log.i(TAG, "SUP_REQUEST_IDENTITY: identityPair=" + identityPair);
if (identityPair != null && identityPair.first != null) {
- mWifiNative.simIdentityResponse(mInterfaceName, netId,
- identityPair.first, identityPair.second);
+ mWifiNative.simIdentityResponse(mInterfaceName, identityPair.first,
+ identityPair.second);
identitySent = true;
} else {
Log.e(TAG, "Unable to retrieve identity from Telephony");
@@ -4217,22 +3685,6 @@ public class ClientModeImpl extends StateMachine {
loge("Invalid SIM auth request");
}
break;
- case CMD_GET_MATCHING_OSU_PROVIDERS:
- replyToMessage(message, message.what,
- mPasspointManager.getMatchingOsuProviders(
- (List<ScanResult>) message.obj));
- break;
- case CMD_GET_MATCHING_PASSPOINT_CONFIGS_FOR_OSU_PROVIDERS:
- replyToMessage(message, message.what,
- mPasspointManager.getMatchingPasspointConfigsForOsuProviders(
- (List<OsuProvider>) message.obj));
- break;
- case CMD_GET_WIFI_CONFIGS_FOR_PASSPOINT_PROFILES:
- replyToMessage(message, message.what,
- mPasspointManager.getWifiConfigsForPasspointProfiles(
- (List<String>) message.obj));
-
- break;
case CMD_START_SUBSCRIPTION_PROVISIONING:
IProvisioningCallback callback = (IProvisioningCallback) message.obj;
OsuProvider provider =
@@ -4270,8 +3722,7 @@ public class ClientModeImpl extends StateMachine {
}
}
config = mWifiConfigManager.getConfiguredNetworkWithoutMasking(netId);
- logd("CMD_START_CONNECT sup state "
- + mSupplicantStateTracker.getSupplicantStateName()
+ logd("CMD_START_CONNECT "
+ " my state " + getCurrentState().getName()
+ " nid=" + Integer.toString(netId)
+ " roam=" + Boolean.toString(mIsAutoRoaming));
@@ -4324,80 +3775,43 @@ public class ClientModeImpl extends StateMachine {
WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
- replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
- WifiManager.ERROR);
- break;
- }
- break;
- case CMD_REMOVE_APP_CONFIGURATIONS:
- removedNetworkIds =
- mWifiConfigManager.removeNetworksForApp((ApplicationInfo) message.obj);
- if (removedNetworkIds.contains(mTargetNetworkId)
- || removedNetworkIds.contains(mLastNetworkId)) {
- // Disconnect and let autojoin reselect a new network.
- sendMessage(CMD_DISCONNECT);
- }
- break;
- case CMD_REMOVE_USER_CONFIGURATIONS:
- removedNetworkIds =
- mWifiConfigManager.removeNetworksForUser((Integer) message.arg1);
- if (removedNetworkIds.contains(mTargetNetworkId)
- || removedNetworkIds.contains(mLastNetworkId)) {
- // Disconnect and let autojoin reselect a new network.
- sendMessage(CMD_DISCONNECT);
- }
- break;
- case WifiManager.CONNECT_NETWORK:
- /**
- * The connect message can contain a network id passed as arg1 on message or
- * or a config passed as obj on message.
- * For a new network, a config is passed to create and connect.
- * For an existing network, a network id is passed
- */
- netId = message.arg1;
- config = (WifiConfiguration) message.obj;
- boolean hasCredentialChanged = false;
- // New network addition.
- if (config != null) {
- result = mWifiConfigManager.addOrUpdateNetwork(config, message.sendingUid);
- if (!result.isSuccess()) {
- loge("CONNECT_NETWORK adding/updating config=" + config + " failed");
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
- WifiManager.ERROR);
- break;
- }
- netId = result.getNetworkId();
- hasCredentialChanged = result.hasCredentialChanged();
- }
- if (!connectToUserSelectNetwork(
- netId, message.sendingUid, hasCredentialChanged)) {
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
- WifiManager.NOT_AUTHORIZED);
break;
}
- mWifiMetrics.logStaEvent(StaEvent.TYPE_CONNECT_NETWORK, config);
- broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config);
- replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
break;
- case WifiManager.SAVE_NETWORK:
- result = saveNetworkConfigAndSendReply(message);
+ case CMD_CONNECT_NETWORK:
+ callbackIdentifier = message.arg2;
+ result = (NetworkUpdateResult) message.obj;
+ netId = result.getNetworkId();
+ connectToUserSelectNetwork(
+ netId, message.sendingUid, result.hasCredentialChanged());
+ mWifiMetrics.logStaEvent(
+ StaEvent.TYPE_CONNECT_NETWORK,
+ mWifiConfigManager.getConfiguredNetwork(netId));
+ sendActionListenerSuccess(callbackIdentifier);
+ break;
+ case CMD_SAVE_NETWORK:
+ callbackIdentifier = message.arg2;
+ result = (NetworkUpdateResult) message.obj;
netId = result.getNetworkId();
- if (result.isSuccess() && mWifiInfo.getNetworkId() == netId) {
+ if (mWifiInfo.getNetworkId() == netId) {
if (result.hasCredentialChanged()) {
- config = (WifiConfiguration) message.obj;
// The network credentials changed and we're connected to this network,
// start a new connection with the updated credentials.
- logi("SAVE_NETWORK credential changed for config=" + config.configKey()
- + ", Reconnecting.");
+ logi("CMD_SAVE_NETWORK credential changed for nid="
+ + netId + ". Reconnecting.");
startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);
} else {
if (result.hasProxyChanged()) {
if (mIpClient != null) {
log("Reconfiguring proxy on connection");
- mIpClient.setHttpProxy(
- getCurrentWifiConfiguration().getHttpProxy());
+ WifiConfiguration currentConfig = getCurrentWifiConfiguration();
+ if (currentConfig != null) {
+ mIpClient.setHttpProxy(currentConfig.getHttpProxy());
+ } else {
+ Log.w(TAG,
+ "CMD_SAVE_NETWORK proxy change - but no current "
+ + "Wi-Fi config");
+ }
}
}
if (result.hasIpChanged()) {
@@ -4405,26 +3819,18 @@ public class ClientModeImpl extends StateMachine {
// We switched from DHCP to static or from static to DHCP, or the
// static IP address has changed.
log("Reconfiguring IP on connection");
- // TODO(b/36576642): clear addresses and disable IPv6
- // to simplify obtainingIpState.
transitionTo(mObtainingIpState);
}
}
+ } else if (mWifiInfo.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID
+ && result.hasCredentialChanged()) {
+ logi("CMD_SAVE_NETWORK credential changed for nid="
+ + netId + " while disconnected. Connecting.");
+ startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);
}
+ sendActionListenerSuccess(callbackIdentifier);
break;
- case WifiManager.FORGET_NETWORK:
- if (!deleteNetworkConfigAndSendReply(message, true)) {
- // Caller was notified of failure, nothing else to do
- break;
- }
- // the network was deleted
- netId = message.arg1;
- if (netId == mTargetNetworkId || netId == mLastNetworkId) {
- // Disconnect and let autojoin reselect a new network
- sendMessage(CMD_DISCONNECT);
- }
- break;
- case CMD_ASSOCIATED_BSSID:
+ case WifiMonitor.ASSOCIATED_BSSID_EVENT:
// This is where we can confirm the connection BSSID. Use it to find the
// right ScanDetail to populate metrics.
String someBssid = (String) message.obj;
@@ -4436,6 +3842,8 @@ public class ClientModeImpl extends StateMachine {
mWifiMetrics.setConnectionScanDetail(scanDetailCache.getScanDetail(
someBssid));
}
+ // Update last associated BSSID
+ mLastBssid = someBssid;
}
handleStatus = NOT_HANDLED;
break;
@@ -4473,14 +3881,25 @@ public class ClientModeImpl extends StateMachine {
config.enterpriseConfig.getEapMethod())) {
String anonymousIdentity =
mWifiNative.getEapAnonymousIdentity(mInterfaceName);
- if (mVerboseLoggingEnabled) {
- log("EAP Pseudonym: " + anonymousIdentity);
- }
- if (!TelephonyUtil.isAnonymousAtRealmIdentity(anonymousIdentity)) {
+ if (!TextUtils.isEmpty(anonymousIdentity)
+ && !TelephonyUtil
+ .isAnonymousAtRealmIdentity(anonymousIdentity)) {
+ String decoratedPseudonym = TelephonyUtil
+ .decoratePseudonymWith3GppRealm(getTelephonyManager(),
+ anonymousIdentity);
+ if (decoratedPseudonym != null) {
+ anonymousIdentity = decoratedPseudonym;
+ }
+ if (mVerboseLoggingEnabled) {
+ log("EAP Pseudonym: " + anonymousIdentity);
+ }
// Save the pseudonym only if it is a real one
config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity);
- mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
+ } else {
+ // Clear any stored pseudonyms
+ config.enterpriseConfig.setAnonymousIdentity(null);
}
+ mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
}
sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mObtainingIpState);
@@ -4509,49 +3928,7 @@ public class ClientModeImpl extends StateMachine {
((Bundle) message.obj).getLong(EXTRA_OSU_ICON_QUERY_BSSID),
((Bundle) message.obj).getString(EXTRA_OSU_ICON_QUERY_FILENAME));
break;
- case CMD_MATCH_PROVIDER_NETWORK:
- // TODO(b/31065385): Passpoint config management.
- replyToMessage(message, message.what, 0);
- break;
- case CMD_ADD_OR_UPDATE_PASSPOINT_CONFIG:
- Bundle bundle = (Bundle) message.obj;
- PasspointConfiguration passpointConfig = bundle.getParcelable(
- EXTRA_PASSPOINT_CONFIGURATION);
- if (mPasspointManager.addOrUpdateProvider(passpointConfig,
- bundle.getInt(EXTRA_UID),
- bundle.getString(EXTRA_PACKAGE_NAME))) {
- String fqdn = passpointConfig.getHomeSp().getFqdn();
- if (isProviderOwnedNetwork(mTargetNetworkId, fqdn)
- || isProviderOwnedNetwork(mLastNetworkId, fqdn)) {
- logd("Disconnect from current network since its provider is updated");
- sendMessage(CMD_DISCONNECT);
- }
- replyToMessage(message, message.what, SUCCESS);
- } else {
- replyToMessage(message, message.what, FAILURE);
- }
- break;
- case CMD_REMOVE_PASSPOINT_CONFIG:
- String fqdn = (String) message.obj;
- if (mPasspointManager.removeProvider(
- message.sendingUid, message.arg1 == 1, fqdn)) {
- if (isProviderOwnedNetwork(mTargetNetworkId, fqdn)
- || isProviderOwnedNetwork(mLastNetworkId, fqdn)) {
- logd("Disconnect from current network since its provider is removed");
- sendMessage(CMD_DISCONNECT);
- }
- mWifiConfigManager.removePasspointConfiguredNetwork(fqdn);
- replyToMessage(message, message.what, SUCCESS);
- } else {
- replyToMessage(message, message.what, FAILURE);
- }
- break;
- case CMD_GET_ALL_MATCHING_FQDNS_FOR_SCAN_RESULTS:
- replyToMessage(message, message.what,
- mPasspointManager.getAllMatchingFqdnsForScanResults(
- (List<ScanResult>) message.obj));
- break;
- case CMD_TARGET_BSSID:
+ case WifiMonitor.TARGET_BSSID_EVENT:
// Trying to associate to this BSSID
if (message.obj != null) {
mTargetRoamBSSID = (String) message.obj;
@@ -4717,25 +4094,6 @@ public class ClientModeImpl extends StateMachine {
mNetworkAgent.sendNetworkCapabilities(getCapabilities(currentWifiConfiguration));
}
- /**
- * Checks if the given network |networkdId| is provided by the given Passpoint provider with
- * |providerFqdn|.
- *
- * @param networkId The ID of the network to check
- * @param providerFqdn The FQDN of the Passpoint provider
- * @return true if the given network is provided by the given Passpoint provider
- */
- private boolean isProviderOwnedNetwork(int networkId, String providerFqdn) {
- if (networkId == WifiConfiguration.INVALID_NETWORK_ID) {
- return false;
- }
- WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(networkId);
- if (config == null) {
- return false;
- }
- return TextUtils.equals(config.FQDN, providerFqdn);
- }
-
private void handleEapAuthFailure(int networkId, int errorCode) {
WifiConfiguration targetedNetwork =
mWifiConfigManager.getConfiguredNetwork(mTargetNetworkId);
@@ -4883,47 +4241,6 @@ public class ClientModeImpl extends StateMachine {
sendMessage(CMD_NETWORK_STATUS, status);
}
- // rfc4186 & rfc4187:
- // create Permanent Identity base on IMSI,
- // identity = usernam@realm
- // with username = prefix | IMSI
- // and realm is derived MMC/MNC tuple according 3GGP spec(TS23.003)
- private String buildIdentity(int eapMethod, String imsi, String mccMnc) {
- String mcc;
- String mnc;
- String prefix;
-
- if (imsi == null || imsi.isEmpty()) {
- return "";
- }
-
- if (eapMethod == WifiEnterpriseConfig.Eap.SIM) {
- prefix = "1";
- } else if (eapMethod == WifiEnterpriseConfig.Eap.AKA) {
- prefix = "0";
- } else if (eapMethod == WifiEnterpriseConfig.Eap.AKA_PRIME) {
- prefix = "6";
- } else {
- // not a valid EapMethod
- return "";
- }
-
- /* extract mcc & mnc from mccMnc */
- if (mccMnc != null && !mccMnc.isEmpty()) {
- mcc = mccMnc.substring(0, 3);
- mnc = mccMnc.substring(3);
- if (mnc.length() == 2) {
- mnc = "0" + mnc;
- }
- } else {
- // extract mcc & mnc from IMSI, assume mnc size is 3
- mcc = imsi.substring(0, 3);
- mnc = imsi.substring(3, 6);
- }
-
- return prefix + imsi + "@wlan.mnc" + mnc + ".mcc" + mcc + ".3gppnetwork.org";
- }
-
class L2ConnectedState extends State {
class RssiEventHandler implements WifiNative.WifiRssiEventHandler {
@Override
@@ -4997,6 +4314,7 @@ public class ClientModeImpl extends StateMachine {
@Override
public boolean processMessage(Message message) {
boolean handleStatus = HANDLED;
+ int callbackIdentifier = -1;
switch (message.what) {
case CMD_PRE_DHCP_ACTION:
@@ -5026,7 +4344,8 @@ public class ClientModeImpl extends StateMachine {
handleIPv4Failure();
mWifiInjector.getWifiLastResortWatchdog()
.noteConnectionFailureAndTriggerIfNeeded(
- getTargetSsid(), mTargetRoamBSSID,
+ getTargetSsid(),
+ (mLastBssid == null) ? mTargetRoamBSSID : mLastBssid,
WifiLastResortWatchdog.FAILURE_CODE_DHCP);
break;
}
@@ -5056,7 +4375,8 @@ public class ClientModeImpl extends StateMachine {
WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
mWifiInjector.getWifiLastResortWatchdog()
.noteConnectionFailureAndTriggerIfNeeded(
- getTargetSsid(), mTargetRoamBSSID,
+ getTargetSsid(),
+ (mLastBssid == null) ? mTargetRoamBSSID : mLastBssid,
WifiLastResortWatchdog.FAILURE_CODE_DHCP);
transitionTo(mDisconnectingState);
break;
@@ -5090,15 +4410,6 @@ public class ClientModeImpl extends StateMachine {
transitionTo(mDisconnectingState);
}
break;
- /* Ignore connection to same network */
- case WifiManager.CONNECT_NETWORK:
- int netId = message.arg1;
- if (mWifiInfo.getNetworkId() == netId) {
- replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
- break;
- }
- handleStatus = NOT_HANDLED;
- break;
case WifiMonitor.NETWORK_CONNECTION_EVENT:
mWifiInfo.setBSSID((String) message.obj);
mLastNetworkId = message.arg1;
@@ -5170,22 +4481,18 @@ public class ClientModeImpl extends StateMachine {
mPollRssiIntervalMsecs);
}
break;
- case WifiManager.RSSI_PKTCNT_FETCH:
- RssiPacketCountInfo info = new RssiPacketCountInfo();
- fetchRssiLinkSpeedAndFrequencyNative();
- info.rssi = mWifiInfo.getRssi();
+ case CMD_PKT_CNT_FETCH:
+ callbackIdentifier = message.arg2;
WifiNative.TxPacketCounters counters =
mWifiNative.getTxPacketCounters(mInterfaceName);
if (counters != null) {
- info.txgood = counters.txSucceeded;
- info.txbad = counters.txFailed;
- replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED, info);
+ sendTxPacketCountListenerSuccess(
+ callbackIdentifier, counters.txSucceeded + counters.txFailed);
} else {
- replyToMessage(message,
- WifiManager.RSSI_PKTCNT_FETCH_FAILED, WifiManager.ERROR);
+ sendTxPacketCountListenerSuccess(callbackIdentifier, WifiManager.ERROR);
}
break;
- case CMD_ASSOCIATED_BSSID:
+ case WifiMonitor.ASSOCIATED_BSSID_EVENT:
if ((String) message.obj == null) {
logw("Associated command w/o BSSID");
break;
@@ -5349,9 +4656,7 @@ public class ClientModeImpl extends StateMachine {
// Stop IpClient in case we're switching from DHCP to static
// configuration or vice versa.
//
- // TODO: Only ever enter this state the first time we connect to a
- // network, never on switching between static configuration and
- // DHCP. When we transition from static configuration to DHCP in
+ // When we transition from static configuration to DHCP in
// particular, we must tell ConnectivityService that we're
// disconnected, because DHCP might take a long time during which
// connectivity APIs such as getActiveNetworkInfo should not return
@@ -5393,19 +4698,17 @@ public class ClientModeImpl extends StateMachine {
boolean handleStatus = HANDLED;
switch(message.what) {
- case CMD_START_CONNECT:
- case CMD_START_ROAM:
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
- break;
- case WifiManager.SAVE_NETWORK:
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
- deferMessage(message);
- break;
case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
reportConnectionAttemptEnd(
WifiMetrics.ConnectionEvent.FAILURE_NETWORK_DISCONNECTION,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
+ mWifiInjector.getWifiLastResortWatchdog()
+ .noteConnectionFailureAndTriggerIfNeeded(
+ getTargetSsid(),
+ (message.obj == null)
+ ? mTargetRoamBSSID : (String) message.obj,
+ WifiLastResortWatchdog.FAILURE_CODE_DHCP);
handleStatus = NOT_HANDLED;
break;
case CMD_SET_HIGH_PERF_MODE:
@@ -5679,8 +4982,7 @@ public class ClientModeImpl extends StateMachine {
mWifiConfigManager.setNetworkValidatedInternetAccess(
config.networkId, false);
mWifiConfigManager.updateNetworkSelectionStatus(config.networkId,
- WifiConfiguration.NetworkSelectionStatus
- .DISABLED_NO_INTERNET_PERMANENT);
+ DISABLED_NO_INTERNET_PERMANENT);
} else {
// stop collect last-mile stats since validation fail
removeMessages(CMD_DIAGS_CONNECT_TIMEOUT);
@@ -5696,8 +4998,7 @@ public class ClientModeImpl extends StateMachine {
+ "no-internet access");
mWifiConfigManager.updateNetworkSelectionStatus(
config.networkId,
- WifiConfiguration.NetworkSelectionStatus
- .DISABLED_NO_INTERNET_TEMPORARY);
+ DISABLED_NO_INTERNET_TEMPORARY);
}
}
}
@@ -5726,7 +5027,7 @@ public class ClientModeImpl extends StateMachine {
boolean accept = (message.arg1 != 0);
mWifiConfigManager.setNetworkNoInternetAccessExpected(mLastNetworkId, accept);
break;
- case CMD_ASSOCIATED_BSSID:
+ case WifiMonitor.ASSOCIATED_BSSID_EVENT:
// ASSOCIATING to a new BSSID while already connected, indicates
// that driver is roaming
mLastDriverRoamAttempt = mClock.getWallClockMillis();
@@ -5780,7 +5081,6 @@ public class ClientModeImpl extends StateMachine {
mTargetNetworkId = netId;
logd("CMD_START_ROAM sup state "
- + mSupplicantStateTracker.getSupplicantStateName()
+ " my state " + getCurrentState().getName()
+ " nid=" + Integer.toString(netId)
+ " config " + config.configKey()
@@ -5800,8 +5100,6 @@ public class ClientModeImpl extends StateMachine {
WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
- replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
- WifiManager.ERROR);
mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
break;
}
@@ -5855,6 +5153,11 @@ public class ClientModeImpl extends StateMachine {
boolean handleStatus = HANDLED;
switch (message.what) {
+ case CMD_CONNECT_NETWORK:
+ case CMD_SAVE_NETWORK:
+ mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
+ deferMessage(message);
+ break;
case CMD_DISCONNECT:
if (mVerboseLoggingEnabled) {
log("Ignore CMD_DISCONNECT when already disconnecting.");
@@ -5873,6 +5176,7 @@ public class ClientModeImpl extends StateMachine {
* we have missed the network disconnection, transition to mDisconnectedState
* and handle the rest of the events there
*/
+ mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
deferMessage(message);
handleNetworkDisconnect();
transitionTo(mDisconnectedState);
@@ -6047,7 +5351,8 @@ public class ClientModeImpl extends StateMachine {
intent.putExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_SSID, config.SSID);
intent.putExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_EVENT_TYPE,
wifiCredentialEventType);
- mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT,
+ // TODO (b/142234604): This will not work on multi-user device scenarios.
+ mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT_OR_SELF,
android.Manifest.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE);
}
}
@@ -6087,12 +5392,11 @@ public class ClientModeImpl extends StateMachine {
}
}
if (response == null || response.length() == 0) {
- mWifiNative.simAuthFailedResponse(mInterfaceName, requestData.networkId);
+ mWifiNative.simAuthFailedResponse(mInterfaceName);
} else {
logv("Supplicant Response -" + response);
mWifiNative.simAuthResponse(
- mInterfaceName, requestData.networkId,
- WifiNative.SIM_AUTH_RESP_TYPE_GSM_AUTH, response);
+ mInterfaceName, WifiNative.SIM_AUTH_RESP_TYPE_GSM_AUTH, response);
}
}
@@ -6110,9 +5414,9 @@ public class ClientModeImpl extends StateMachine {
TelephonyUtil.get3GAuthResponse(requestData, getTelephonyManager());
if (response != null) {
mWifiNative.simAuthResponse(
- mInterfaceName, requestData.networkId, response.type, response.response);
+ mInterfaceName, response.type, response.response);
} else {
- mWifiNative.umtsAuthFailedResponse(mInterfaceName, requestData.networkId);
+ mWifiNative.umtsAuthFailedResponse(mInterfaceName);
}
}
@@ -6165,90 +5469,9 @@ public class ClientModeImpl extends StateMachine {
|| reason == 34; // DISASSOC_LOW_ACK
}
- /**
- * Update WifiMetrics before dumping
- */
- public void updateWifiMetrics() {
- mWifiMetrics.updateSavedNetworks(mWifiConfigManager.getSavedNetworks(Process.WIFI_UID));
- mPasspointManager.updateMetrics();
- }
-
- /**
- * Private method to handle calling WifiConfigManager to forget/remove network configs and reply
- * to the message from the sender of the outcome.
- *
- * The current implementation requires that forget and remove be handled in different ways
- * (responses are handled differently). In the interests of organization, the handling is all
- * now in this helper method. TODO: b/35257965 is filed to track the possibility of merging
- * the two call paths.
- */
- private boolean deleteNetworkConfigAndSendReply(Message message, boolean calledFromForget) {
- boolean success = mWifiConfigManager.removeNetwork(message.arg1, message.sendingUid);
- if (!success) {
- loge("Failed to remove network");
- }
-
- if (calledFromForget) {
- if (success) {
- replyToMessage(message, WifiManager.FORGET_NETWORK_SUCCEEDED);
- broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_FORGOT,
- (WifiConfiguration) message.obj);
- return true;
- }
- replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED, WifiManager.ERROR);
- return false;
- } else {
- // Remaining calls are from the removeNetwork path
- if (success) {
- replyToMessage(message, message.what, SUCCESS);
- return true;
- }
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- replyToMessage(message, message.what, FAILURE);
- return false;
- }
- }
-
- /**
- * Private method to handle calling WifiConfigManager to add & enable network configs and reply
- * to the message from the sender of the outcome.
- *
- * @return NetworkUpdateResult with networkId of the added/updated configuration. Will return
- * {@link WifiConfiguration#INVALID_NETWORK_ID} in case of error.
- */
- private NetworkUpdateResult saveNetworkConfigAndSendReply(Message message) {
- WifiConfiguration config = (WifiConfiguration) message.obj;
- if (config == null) {
- loge("SAVE_NETWORK with null configuration "
- + mSupplicantStateTracker.getSupplicantStateName()
- + " my state " + getCurrentState().getName());
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, WifiManager.ERROR);
- return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
- }
- NetworkUpdateResult result =
- mWifiConfigManager.addOrUpdateNetwork(config, message.sendingUid);
- if (!result.isSuccess()) {
- loge("SAVE_NETWORK adding/updating config=" + config + " failed");
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, WifiManager.ERROR);
- return result;
- }
- if (!mWifiConfigManager.enableNetwork(
- result.getNetworkId(), false, message.sendingUid)) {
- loge("SAVE_NETWORK enabling config=" + config + " failed");
- mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
- replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, WifiManager.ERROR);
- return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
- }
- broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config);
- replyToMessage(message, WifiManager.SAVE_NETWORK_SUCCEEDED);
- return result;
- }
-
private static String getLinkPropertiesSummary(LinkProperties lp) {
List<String> attributes = new ArrayList<>(6);
- if (lp.hasIPv4Address()) {
+ if (lp.hasIpv4Address()) {
attributes.add("v4");
}
if (lp.hasIPv4DefaultRoute()) {
@@ -6257,10 +5480,10 @@ public class ClientModeImpl extends StateMachine {
if (lp.hasIPv4DnsServer()) {
attributes.add("v4dns");
}
- if (lp.hasGlobalIPv6Address()) {
+ if (lp.hasGlobalIpv6Address()) {
attributes.add("v6");
}
- if (lp.hasIPv6DefaultRoute()) {
+ if (lp.hasIpv6DefaultRoute()) {
attributes.add("v6r");
}
if (lp.hasIPv6DnsServer()) {
@@ -6413,4 +5636,178 @@ public class ClientModeImpl extends StateMachine {
mWifiNative.probeLink(mInterfaceName, MacAddress.fromString(mWifiInfo.getBSSID()),
callback, mcs);
}
+
+ private void sendActionListenerFailure(int callbackIdentifier, int reason) {
+ IActionListener actionListener;
+ synchronized (mProcessingActionListeners) {
+ actionListener = mProcessingActionListeners.remove(callbackIdentifier);
+ }
+ if (actionListener != null) {
+ try {
+ actionListener.onFailure(reason);
+ } catch (RemoteException e) {
+ // no-op (client may be dead, nothing to be done)
+ }
+ }
+ }
+
+ private void sendActionListenerSuccess(int callbackIdentifier) {
+ IActionListener actionListener;
+ synchronized (mProcessingTxPacketCountListeners) {
+ actionListener = mProcessingActionListeners.remove(callbackIdentifier);
+ }
+ if (actionListener != null) {
+ try {
+ actionListener.onSuccess();
+ } catch (RemoteException e) {
+ // no-op (client may be dead, nothing to be done)
+ }
+ }
+ }
+
+ private void sendTxPacketCountListenerFailure(int callbackIdentifier, int reason) {
+ ITxPacketCountListener txPacketCountListener;
+ synchronized (mProcessingTxPacketCountListeners) {
+ txPacketCountListener = mProcessingTxPacketCountListeners.remove(callbackIdentifier);
+ }
+ if (txPacketCountListener != null) {
+ try {
+ txPacketCountListener.onFailure(reason);
+ } catch (RemoteException e) {
+ // no-op (client may be dead, nothing to be done)
+ }
+ }
+ }
+
+ private void sendTxPacketCountListenerSuccess(int callbackIdentifier, int count) {
+ ITxPacketCountListener txPacketCountListener;
+ synchronized (mProcessingActionListeners) {
+ txPacketCountListener = mProcessingTxPacketCountListeners.remove(callbackIdentifier);
+ }
+ if (txPacketCountListener != null) {
+ try {
+ txPacketCountListener.onSuccess(count);
+ } catch (RemoteException e) {
+ // no-op (client may be dead, nothing to be done)
+ }
+ }
+ }
+
+ /**
+ * Trigger network connection and provide status via the provided callback.
+ */
+ public void connect(WifiConfiguration config, int netId, @Nullable IBinder binder,
+ @Nullable IActionListener callback, int callbackIdentifier, int callingUid) {
+ mWifiInjector.getWifiThreadRunner().post(() -> {
+ if (callback != null && binder != null) {
+ mProcessingActionListeners.add(binder, callback, callbackIdentifier);
+ }
+ /**
+ * The connect message can contain a network id passed as arg1 on message or
+ * or a config passed as obj on message.
+ * For a new network, a config is passed to create and connect.
+ * For an existing network, a network id is passed
+ */
+ NetworkUpdateResult result = null;
+ if (config != null) {
+ result = mWifiConfigManager.addOrUpdateNetwork(config, callingUid);
+ if (!result.isSuccess()) {
+ loge("connectNetwork adding/updating config=" + config + " failed");
+ sendActionListenerFailure(callbackIdentifier, WifiManager.ERROR);
+ return;
+ }
+ broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config);
+ } else {
+ if (mWifiConfigManager.getConfiguredNetwork(netId) == null) {
+ loge("connectNetwork Invalid network Id=" + netId);
+ sendActionListenerFailure(callbackIdentifier, WifiManager.ERROR);
+ return;
+ }
+ result = new NetworkUpdateResult(netId);
+ }
+ final int networkId = result.getNetworkId();
+ if (!mWifiConfigManager.enableNetwork(networkId, true, callingUid, null)
+ || !mWifiConfigManager.updateLastConnectUid(networkId, callingUid)) {
+ logi("connect Allowing uid " + callingUid
+ + " with insufficient permissions to connect=" + networkId);
+ } else if (mWifiPermissionsUtil.checkNetworkSettingsPermission(callingUid)) {
+ // Note user connect choice here, so that it will be considered in the
+ // next network selection.
+ mWifiConnectivityManager.setUserConnectChoice(networkId);
+ }
+ Message message =
+ obtainMessage(CMD_CONNECT_NETWORK, -1, callbackIdentifier, result);
+ message.sendingUid = callingUid;
+ sendMessage(message);
+ });
+ }
+
+ /**
+ * Trigger network save and provide status via the provided callback.
+ */
+ public void save(WifiConfiguration config, @Nullable IBinder binder,
+ @Nullable IActionListener callback, int callbackIdentifier, int callingUid) {
+ mWifiInjector.getWifiThreadRunner().post(() -> {
+ if (callback != null && binder != null) {
+ mProcessingActionListeners.add(binder, callback, callbackIdentifier);
+ }
+ if (config == null) {
+ loge("saveNetwork with null configuration my state "
+ + getCurrentState().getName());
+ sendActionListenerFailure(callbackIdentifier, WifiManager.ERROR);
+ return;
+ }
+ NetworkUpdateResult result =
+ mWifiConfigManager.addOrUpdateNetwork(config, callingUid);
+ if (!result.isSuccess()) {
+ loge("saveNetwork adding/updating config=" + config + " failed");
+ sendActionListenerFailure(callbackIdentifier, WifiManager.ERROR);
+ return;
+ }
+ if (!mWifiConfigManager.enableNetwork(
+ result.getNetworkId(), false, callingUid, null)) {
+ loge("saveNetwork enabling config=" + config + " failed");
+ sendActionListenerFailure(callbackIdentifier, WifiManager.ERROR);
+ return;
+ }
+ broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config);
+ Message message =
+ obtainMessage(CMD_SAVE_NETWORK, -1 , callbackIdentifier, result);
+ message.sendingUid = callingUid;
+ sendMessage(message);
+ });
+ }
+
+ /**
+ * Trigger network forget and provide status via the provided callback.
+ */
+ public void forget(int netId, @Nullable IBinder binder, @Nullable IActionListener callback,
+ int callbackIdentifier, int callingUid) {
+ mWifiInjector.getWifiThreadRunner().post(() -> {
+ if (callback != null && binder != null) {
+ mProcessingActionListeners.add(binder, callback, callbackIdentifier);
+ }
+ boolean success = mWifiConfigManager.removeNetwork(netId, callingUid, null);
+ if (!success) {
+ loge("Failed to remove network");
+ sendActionListenerFailure(callbackIdentifier, WifiManager.ERROR);
+ }
+ sendActionListenerSuccess(callbackIdentifier);
+ broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_FORGOT, null);
+ });
+ }
+
+ /**
+ * Retrieve tx packet count and provide status via the provided callback.
+ */
+ public void getTxPacketCount(IBinder binder, @NonNull ITxPacketCountListener callback,
+ int callbackIdentifier, int callingUid) {
+ mWifiInjector.getWifiThreadRunner().post(() -> {
+ mProcessingTxPacketCountListeners.add(binder, callback, callbackIdentifier);
+
+ Message message = obtainMessage(CMD_PKT_CNT_FETCH, -1, callbackIdentifier, null);
+ message.sendingUid = callingUid;
+ sendMessage(message);
+ });
+ }
}
diff --git a/service/java/com/android/server/wifi/ClientModeManager.java b/service/java/com/android/server/wifi/ClientModeManager.java
index 883b16a610..0206646845 100644
--- a/service/java/com/android/server/wifi/ClientModeManager.java
+++ b/service/java/com/android/server/wifi/ClientModeManager.java
@@ -44,22 +44,24 @@ public class ClientModeManager implements ActiveModeManager {
private final Context mContext;
private final WifiNative mWifiNative;
-
private final WifiMetrics mWifiMetrics;
- private final Listener mListener;
+ private final SarManager mSarManager;
+ private final WakeupController mWakeupController;
+ private final Listener mModeListener;
private final ClientModeImpl mClientModeImpl;
private String mClientInterfaceName;
private boolean mIfaceIsUp = false;
- private boolean mExpectedStop = false;
-
ClientModeManager(Context context, @NonNull Looper looper, WifiNative wifiNative,
- Listener listener, WifiMetrics wifiMetrics, ClientModeImpl clientModeImpl) {
+ Listener listener, WifiMetrics wifiMetrics, SarManager sarManager,
+ WakeupController wakeupController, ClientModeImpl clientModeImpl) {
mContext = context;
mWifiNative = wifiNative;
- mListener = listener;
+ mModeListener = listener;
mWifiMetrics = wifiMetrics;
+ mSarManager = sarManager;
+ mWakeupController = wakeupController;
mClientModeImpl = clientModeImpl;
mStateMachine = new ClientModeStateMachine(looper);
}
@@ -76,13 +78,12 @@ public class ClientModeManager implements ActiveModeManager {
*/
public void stop() {
Log.d(TAG, " currentstate: " + getCurrentStateName());
- mExpectedStop = true;
- if (mClientInterfaceName != null) {
+ if (isInConnectMode()) {
if (mIfaceIsUp) {
- updateWifiState(WifiManager.WIFI_STATE_DISABLING,
+ updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
WifiManager.WIFI_STATE_ENABLED);
} else {
- updateWifiState(WifiManager.WIFI_STATE_DISABLING,
+ updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
WifiManager.WIFI_STATE_ENABLING);
}
}
@@ -90,7 +91,27 @@ public class ClientModeManager implements ActiveModeManager {
}
public @ScanMode int getScanMode() {
- return SCAN_WITH_HIDDEN_NETWORKS;
+ if (isInConnectMode()) {
+ return SCAN_WITH_HIDDEN_NETWORKS;
+ } else if (isInScanOnlyMode()) {
+ return SCAN_WITHOUT_HIDDEN_NETWORKS;
+ } else {
+ return SCAN_NONE;
+ }
+ }
+
+ /**
+ * Switch client mode manager to scan only mode.
+ */
+ public void switchToScanOnlyMode() {
+ mStateMachine.sendMessage(ClientModeStateMachine.CMD_SWITCH_TO_SCAN_ONLY_MODE);
+ }
+
+ /**
+ * Switch client mode manager to connect mode.
+ */
+ public void switchToConnectMode() {
+ mStateMachine.sendMessage(ClientModeStateMachine.CMD_SWITCH_TO_CONNECT_MODE);
}
/**
@@ -102,17 +123,7 @@ public class ClientModeManager implements ActiveModeManager {
pw.println("current StateMachine mode: " + getCurrentStateName());
pw.println("mClientInterfaceName: " + mClientInterfaceName);
pw.println("mIfaceIsUp: " + mIfaceIsUp);
- }
-
- /**
- * Listener for ClientMode state changes.
- */
- public interface Listener {
- /**
- * Invoke when wifi state changes.
- * @param state new wifi state
- */
- void onStateChanged(int state);
+ mStateMachine.dump(fd, pw, args);
}
private String getCurrentStateName() {
@@ -130,21 +141,7 @@ public class ClientModeManager implements ActiveModeManager {
* @param newState new Wifi state
* @param currentState current wifi state
*/
- private void updateWifiState(int newState, int currentState) {
- if (!mExpectedStop) {
- mListener.onStateChanged(newState);
- } else {
- Log.d(TAG, "expected stop, not triggering callbacks: newState = " + newState);
- }
-
- // Once we report the mode has stopped/failed any other stop signals are redundant
- // note: this can happen in failure modes where we get multiple callbacks as underlying
- // components/interface stops or the underlying interface is destroyed in cleanup
- if (newState == WifiManager.WIFI_STATE_UNKNOWN
- || newState == WifiManager.WIFI_STATE_DISABLED) {
- mExpectedStop = true;
- }
-
+ private void updateConnectModeState(int newState, int currentState) {
if (newState == WifiManager.WIFI_STATE_UNKNOWN) {
// do not need to broadcast failure to system
return;
@@ -159,14 +156,26 @@ public class ClientModeManager implements ActiveModeManager {
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
+ public boolean isInConnectMode() {
+ return mStateMachine.getCurrentState() == mStateMachine.mConnectModeState;
+ }
+
+ public boolean isInScanOnlyMode() {
+ return mStateMachine.getCurrentState() == mStateMachine.mScanOnlyModeState;
+ }
+
private class ClientModeStateMachine extends StateMachine {
// Commands for the state machine.
public static final int CMD_START = 0;
+ public static final int CMD_SWITCH_TO_SCAN_ONLY_MODE = 1;
+ public static final int CMD_SWITCH_TO_CONNECT_MODE = 2;
public static final int CMD_INTERFACE_STATUS_CHANGED = 3;
public static final int CMD_INTERFACE_DESTROYED = 4;
public static final int CMD_INTERFACE_DOWN = 5;
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 InterfaceCallback mWifiNativeInterfaceCallback = new InterfaceCallback() {
@Override
@@ -176,7 +185,7 @@ public class ClientModeManager implements ActiveModeManager {
// we must immediately clean up state in ClientModeImpl to unregister
// all client mode related objects
- // Note: onDestroyed is only called from the ClientModeImpl thread
+ // Note: onDestroyed is only called from the main Wifi thread
mClientModeImpl.handleIfaceDestroyed();
sendMessage(CMD_INTERFACE_DESTROYED);
@@ -201,15 +210,18 @@ public class ClientModeManager implements ActiveModeManager {
ClientModeStateMachine(Looper looper) {
super(TAG, looper);
+ // CHECKSTYLE:OFF IndentationCheck
addState(mIdleState);
addState(mStartedState);
+ addState(mScanOnlyModeState, mStartedState);
+ addState(mConnectModeState, mStartedState);
+ // CHECKSTYLE:ON IndentationCheck
setInitialState(mIdleState);
start();
}
private class IdleState extends State {
-
@Override
public void enter() {
Log.d(TAG, "entering IdleState");
@@ -221,21 +233,16 @@ public class ClientModeManager implements ActiveModeManager {
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_START:
- updateWifiState(WifiManager.WIFI_STATE_ENABLING,
- WifiManager.WIFI_STATE_DISABLED);
-
+ // Always start in scan mode first.
mClientInterfaceName =
- mWifiNative.setupInterfaceForClientInConnectivityMode(
+ mWifiNative.setupInterfaceForClientInScanMode(
mWifiNativeInterfaceCallback);
if (TextUtils.isEmpty(mClientInterfaceName)) {
Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
- updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
- WifiManager.WIFI_STATE_ENABLING);
- updateWifiState(WifiManager.WIFI_STATE_DISABLED,
- WifiManager.WIFI_STATE_UNKNOWN);
+ mModeListener.onStartFailure();
break;
}
- transitionTo(mStartedState);
+ transitionTo(mScanOnlyModeState);
break;
default:
Log.d(TAG, "received an invalid message: " + message);
@@ -252,22 +259,9 @@ public class ClientModeManager implements ActiveModeManager {
return; // no change
}
mIfaceIsUp = isUp;
- if (isUp) {
- Log.d(TAG, "Wifi is ready to use for client mode");
- mClientModeImpl.setOperationalMode(ClientModeImpl.CONNECT_MODE,
- mClientInterfaceName);
- updateWifiState(WifiManager.WIFI_STATE_ENABLED,
- WifiManager.WIFI_STATE_ENABLING);
- } else {
- if (mClientModeImpl.isConnectedMacRandomizationEnabled()) {
- // Handle the error case where our underlying interface went down if we
- // do not have mac randomization enabled (b/72459123).
- return;
- }
+ if (!isUp) {
// if the interface goes down we should exit and go back to idle state.
Log.d(TAG, "interface down!");
- updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
- WifiManager.WIFI_STATE_ENABLED);
mStateMachine.sendMessage(CMD_INTERFACE_DOWN);
}
}
@@ -285,12 +279,33 @@ public class ClientModeManager implements ActiveModeManager {
case CMD_START:
// Already started, ignore this command.
break;
+ case CMD_SWITCH_TO_CONNECT_MODE:
+ updateConnectModeState(WifiManager.WIFI_STATE_ENABLING,
+ WifiManager.WIFI_STATE_DISABLED);
+ if (!mWifiNative.switchClientInterfaceToConnectivityMode(
+ mClientInterfaceName)) {
+ updateConnectModeState(WifiManager.WIFI_STATE_UNKNOWN,
+ WifiManager.WIFI_STATE_ENABLING);
+ updateConnectModeState(WifiManager.WIFI_STATE_DISABLED,
+ WifiManager.WIFI_STATE_UNKNOWN);
+ mModeListener.onStartFailure();
+ break;
+ }
+ transitionTo(mConnectModeState);
+ break;
+ case CMD_SWITCH_TO_SCAN_ONLY_MODE:
+ if (!mWifiNative.switchClientInterfaceToScanMode(mClientInterfaceName)) {
+ mModeListener.onStartFailure();
+ break;
+ }
+ updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
+ WifiManager.WIFI_STATE_ENABLED);
+ transitionTo(mScanOnlyModeState);
+ break;
case CMD_INTERFACE_DOWN:
- Log.e(TAG, "Detected an interface down, reporting failure to SelfRecovery");
+ Log.e(TAG, "Detected an interface down, reporting failure to "
+ + "SelfRecovery");
mClientModeImpl.failureDetected(SelfRecovery.REASON_STA_IFACE_DOWN);
-
- updateWifiState(WifiManager.WIFI_STATE_DISABLING,
- WifiManager.WIFI_STATE_UNKNOWN);
transitionTo(mIdleState);
break;
case CMD_INTERFACE_STATUS_CHANGED:
@@ -299,9 +314,6 @@ public class ClientModeManager implements ActiveModeManager {
break;
case CMD_INTERFACE_DESTROYED:
Log.d(TAG, "interface destroyed - client mode stopping");
-
- updateWifiState(WifiManager.WIFI_STATE_DISABLING,
- WifiManager.WIFI_STATE_ENABLED);
mClientInterfaceName = null;
transitionTo(mIdleState);
break;
@@ -324,11 +336,108 @@ public class ClientModeManager implements ActiveModeManager {
mIfaceIsUp = false;
}
- updateWifiState(WifiManager.WIFI_STATE_DISABLED,
- WifiManager.WIFI_STATE_DISABLING);
-
// once we leave started, nothing else to do... stop the state machine
mStateMachine.quitNow();
+ mModeListener.onStopped();
+ }
+ }
+
+ private class ScanOnlyModeState extends State {
+ @Override
+ public void enter() {
+ Log.d(TAG, "entering ScanOnlyModeState");
+ mClientModeImpl.setOperationalMode(ClientModeImpl.SCAN_ONLY_MODE,
+ mClientInterfaceName);
+ mModeListener.onStarted();
+
+ // Inform sar manager that scan only is being enabled
+ mSarManager.setScanOnlyWifiState(WifiManager.WIFI_STATE_ENABLED);
+ mWakeupController.start();
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ switch (message.what) {
+ case CMD_SWITCH_TO_SCAN_ONLY_MODE:
+ // Already in scan only mode, ignore this command.
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+
+ @Override
+ public void exit() {
+ // Inform sar manager that scan only is being disabled
+ mSarManager.setScanOnlyWifiState(WifiManager.WIFI_STATE_DISABLED);
+ mWakeupController.stop();
+ }
+ }
+
+ private class ConnectModeState extends State {
+ @Override
+ public void enter() {
+ Log.d(TAG, "entering ConnectModeState");
+ mClientModeImpl.setOperationalMode(ClientModeImpl.CONNECT_MODE,
+ mClientInterfaceName);
+ mModeListener.onStarted();
+ updateConnectModeState(WifiManager.WIFI_STATE_ENABLED,
+ WifiManager.WIFI_STATE_ENABLING);
+
+ // Inform sar manager that wifi is Enabled
+ mSarManager.setClientWifiState(WifiManager.WIFI_STATE_ENABLED);
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ switch (message.what) {
+ case CMD_SWITCH_TO_CONNECT_MODE:
+ // Already in connect mode, ignore this command.
+ break;
+ case CMD_SWITCH_TO_SCAN_ONLY_MODE:
+ updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
+ WifiManager.WIFI_STATE_ENABLED);
+ return NOT_HANDLED; // Handled in StartedState.
+ case CMD_INTERFACE_DOWN:
+ updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
+ WifiManager.WIFI_STATE_UNKNOWN);
+ return NOT_HANDLED; // Handled in StartedState.
+ case CMD_INTERFACE_STATUS_CHANGED:
+ boolean isUp = message.arg1 == 1;
+ if (isUp == mIfaceIsUp) {
+ break; // no change
+ }
+ if (!isUp) {
+ if (!mClientModeImpl.isConnectedMacRandomizationEnabled()) {
+ // Handle the error case where our underlying interface went down if
+ // we do not have mac randomization enabled (b/72459123).
+ // if the interface goes down we should exit and go back to idle
+ // state.
+ updateConnectModeState(WifiManager.WIFI_STATE_UNKNOWN,
+ WifiManager.WIFI_STATE_ENABLED);
+ } else {
+ return HANDLED; // For MAC randomization, ignore...
+ }
+ }
+ return NOT_HANDLED; // Handled in StartedState.
+ case CMD_INTERFACE_DESTROYED:
+ updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
+ WifiManager.WIFI_STATE_ENABLED);
+ return NOT_HANDLED; // Handled in StartedState.
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+
+ @Override
+ public void exit() {
+ updateConnectModeState(WifiManager.WIFI_STATE_DISABLED,
+ WifiManager.WIFI_STATE_DISABLING);
+
+ // Inform sar manager that wifi is being disabled
+ mSarManager.setClientWifiState(WifiManager.WIFI_STATE_DISABLED);
}
}
}
diff --git a/service/java/com/android/server/wifi/CompatibilityScorer.java b/service/java/com/android/server/wifi/CompatibilityScorer.java
index 550eca72aa..1bb55b9a24 100644
--- a/service/java/com/android/server/wifi/CompatibilityScorer.java
+++ b/service/java/com/android/server/wifi/CompatibilityScorer.java
@@ -57,6 +57,8 @@ final class CompatibilityScorer implements WifiCandidates.CandidateScorer {
// config_wifi_framework_SAME_BSSID_AWARD
public static final int SAME_BSSID_AWARD_IS_24 = 24;
+ private static final boolean USE_USER_CONNECT_CHOICE = true;
+
CompatibilityScorer(ScoringParams scoringParams) {
mScoringParams = scoringParams;
}
@@ -95,13 +97,14 @@ final class CompatibilityScorer implements WifiCandidates.CandidateScorer {
// The old method breaks ties on the basis of RSSI, which we can
// emulate easily since our score does not need to be an integer.
double tieBreaker = candidate.getScanRssi() / 1000.0;
- return new ScoredCandidate(score + tieBreaker, 10, candidate);
+ return new ScoredCandidate(score + tieBreaker, 10,
+ USE_USER_CONNECT_CHOICE, candidate);
}
@Override
- public ScoredCandidate scoreCandidates(@NonNull Collection<Candidate> group) {
+ public ScoredCandidate scoreCandidates(@NonNull Collection<Candidate> candidates) {
ScoredCandidate choice = ScoredCandidate.NONE;
- for (Candidate candidate : group) {
+ for (Candidate candidate : candidates) {
ScoredCandidate scoredCandidate = scoreCandidate(candidate);
if (scoredCandidate.value > choice.value) {
choice = scoredCandidate;
@@ -112,9 +115,4 @@ final class CompatibilityScorer implements WifiCandidates.CandidateScorer {
return choice;
}
- @Override
- public boolean userConnectChoiceOverrideWanted() {
- return true;
- }
-
}
diff --git a/service/java/com/android/server/wifi/ConfigurationMap.java b/service/java/com/android/server/wifi/ConfigurationMap.java
index a5cd18f2a0..02652a81f1 100644
--- a/service/java/com/android/server/wifi/ConfigurationMap.java
+++ b/service/java/com/android/server/wifi/ConfigurationMap.java
@@ -44,8 +44,10 @@ public class ConfigurationMap {
// RW methods:
public WifiConfiguration put(WifiConfiguration config) {
final WifiConfiguration current = mPerID.put(config.networkId, config);
- if (WifiConfigurationUtil.isVisibleToAnyProfile(config,
- mUserManager.getProfiles(mCurrentUserId))) {
+ final UserHandle currentUser = UserHandle.of(mCurrentUserId);
+ final UserHandle creatorUser = UserHandle.getUserHandleForUid(config.creatorUid);
+ if (config.shared || currentUser.equals(creatorUser)
+ || mUserManager.isSameProfileGroup(currentUser, creatorUser)) {
mPerIDForCurrentUser.put(config.networkId, config);
mScanResultMatchInfoMapForCurrentUser.put(
ScanResultMatchInfo.fromWifiConfiguration(config), config);
diff --git a/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java b/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java
index f500c4e56c..35dcd29319 100644
--- a/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java
+++ b/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java
@@ -53,13 +53,16 @@ public class ConnectToNetworkNotificationBuilder {
"com.android.server.wifi.ConnectToNetworkNotification.AVAILABLE_NETWORK_NOTIFIER_TAG";
private Context mContext;
+ private WifiInjector mWifiInjector;
private Resources mResources;
private FrameworkFacade mFrameworkFacade;
public ConnectToNetworkNotificationBuilder(
Context context,
+ WifiInjector wifiInjector,
FrameworkFacade framework) {
mContext = context;
+ mWifiInjector = wifiInjector;
mResources = context.getResources();
mFrameworkFacade = framework;
}
@@ -81,9 +84,6 @@ public class ConnectToNetworkNotificationBuilder {
case OpenNetworkNotifier.TAG:
title = mContext.getText(R.string.wifi_available_title);
break;
- case CarrierNetworkNotifier.TAG:
- title = mContext.getText(R.string.wifi_available_carrier_network_title);
- break;
default:
Log.wtf("ConnectToNetworkNotificationBuilder", "Unknown network notifier."
+ notifierTag);
@@ -153,8 +153,6 @@ public class ConnectToNetworkNotificationBuilder {
switch (notifierTag) {
case OpenNetworkNotifier.TAG:
return 1;
- case CarrierNetworkNotifier.TAG:
- return 2;
}
return 0;
}
@@ -175,7 +173,8 @@ public class ConnectToNetworkNotificationBuilder {
}
private PendingIntent getPrivateBroadcast(String action, String extraData) {
- Intent intent = new Intent(action).setPackage("android");
+ Intent intent = new Intent(action)
+ .setPackage(mWifiInjector.getWifiStackPackageName());
int requestCode = 0; // Makes the different kinds of notifications distinguishable
if (extraData != null) {
intent.putExtra(AVAILABLE_NETWORK_NOTIFIER_TAG, extraData);
diff --git a/service/java/com/android/server/wifi/DefaultModeManager.java b/service/java/com/android/server/wifi/DefaultModeManager.java
index a802f491ee..88d657b147 100644
--- a/service/java/com/android/server/wifi/DefaultModeManager.java
+++ b/service/java/com/android/server/wifi/DefaultModeManager.java
@@ -16,9 +16,7 @@
package com.android.server.wifi;
-import android.annotation.NonNull;
import android.content.Context;
-import android.os.Looper;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -55,7 +53,7 @@ public class DefaultModeManager implements ActiveModeManager {
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { }
- DefaultModeManager(Context context, @NonNull Looper looper) {
+ DefaultModeManager(Context context) {
mContext = context;
}
}
diff --git a/service/java/com/android/server/wifi/DeviceConfigFacade.java b/service/java/com/android/server/wifi/DeviceConfigFacade.java
index a9889f4240..2eeda1e5fd 100644
--- a/service/java/com/android/server/wifi/DeviceConfigFacade.java
+++ b/service/java/com/android/server/wifi/DeviceConfigFacade.java
@@ -16,93 +16,146 @@
package com.android.server.wifi;
+import android.content.Context;
+import android.os.Handler;
import android.provider.DeviceConfig;
-import java.util.concurrent.Executor;
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.concurrent.TimeUnit;
/**
* This class allows getting all configurable flags from DeviceConfig.
*/
public class DeviceConfigFacade {
- private static final int DEFAULT_ABNORMAL_CONNECTION_DURATION_MS =
- (int) TimeUnit.SECONDS.toMillis(30);
+ private Context mContext;
+ private final WifiMetrics mWifiMetrics;
+
private static final String NAMESPACE = "wifi";
+
+ // Default values of fields
+ @VisibleForTesting
+ protected static final int DEFAULT_ABNORMAL_CONNECTION_DURATION_MS =
+ (int) TimeUnit.SECONDS.toMillis(30);
// Default duration for evaluating Wifi condition to trigger a data stall
// measured in milliseconds
public static final int DEFAULT_DATA_STALL_DURATION_MS = 1500;
- // Default threshold of Tx throughput below which to trigger a data stall measured in Mbps
- public static final int DEFAULT_DATA_STALL_TX_TPUT_THR_MBPS = 2;
- // Default threshold of Rx throughput below which to trigger a data stall measured in Mbps
- public static final int DEFAULT_DATA_STALL_RX_TPUT_THR_MBPS = 2;
+ // Default threshold of Tx throughput below which to trigger a data stall measured in Kbps
+ public static final int DEFAULT_DATA_STALL_TX_TPUT_THR_KBPS = 2000;
+ // Default threshold of Rx throughput below which to trigger a data stall measured in Kbps
+ public static final int DEFAULT_DATA_STALL_RX_TPUT_THR_KBPS = 2000;
// Default threshold of Tx packet error rate above which to trigger a data stall in percentage
public static final int DEFAULT_DATA_STALL_TX_PER_THR = 90;
// Default threshold of CCA level above which to trigger a data stall in percentage
public static final int DEFAULT_DATA_STALL_CCA_LEVEL_THR = 100;
+ private boolean mDefaultMacRandomizationAggressiveModeSsidWhitelistEnabled;
+
+ // Cached values of fields updated via updateDeviceConfigFlags()
+ private boolean mIsAbnormalConnectionBugreportEnabled;
+ private int mAbnormalConnectionDurationMs;
+ private boolean mIsAggressiveMacRandomizationSsidWhitelistEnabled;
+ private int mDataStallDurationMs;
+ private int mDataStallTxTputThrKbps;
+ private int mDataStallRxTputThrKbps;
+ private int mDataStallTxPerThr;
+ private int mDataStallCcaLevelThr;
+
+ public DeviceConfigFacade(Context context, Handler handler, WifiMetrics wifiMetrics) {
+ mContext = context;
+ mWifiMetrics = wifiMetrics;
+ mDefaultMacRandomizationAggressiveModeSsidWhitelistEnabled = mContext.getResources()
+ .getBoolean(R.bool.config_wifi_aggressive_randomization_ssid_whitelist_enabled);
+
+ updateDeviceConfigFlags();
+ DeviceConfig.addOnPropertiesChangedListener(
+ NAMESPACE,
+ command -> handler.post(command),
+ properties -> {
+ updateDeviceConfigFlags();
+ });
+ }
+
+ private void updateDeviceConfigFlags() {
+ mIsAbnormalConnectionBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
+ "abnormal_connection_bugreport_enabled", false);
+ mAbnormalConnectionDurationMs = DeviceConfig.getInt(NAMESPACE,
+ "abnormal_connection_duration_ms",
+ DEFAULT_ABNORMAL_CONNECTION_DURATION_MS);
+ mIsAggressiveMacRandomizationSsidWhitelistEnabled = DeviceConfig.getBoolean(NAMESPACE,
+ "aggressive_randomization_ssid_whitelist_enabled",
+ mDefaultMacRandomizationAggressiveModeSsidWhitelistEnabled);
+
+ mDataStallDurationMs = DeviceConfig.getInt(NAMESPACE,
+ "data_stall_duration_ms", DEFAULT_DATA_STALL_DURATION_MS);
+ mDataStallTxTputThrKbps = DeviceConfig.getInt(NAMESPACE,
+ "data_stall_tx_tput_thr_kbps", DEFAULT_DATA_STALL_TX_TPUT_THR_KBPS);
+ mDataStallRxTputThrKbps = DeviceConfig.getInt(NAMESPACE,
+ "data_stall_rx_tput_thr_kbps", DEFAULT_DATA_STALL_RX_TPUT_THR_KBPS);
+ mDataStallTxPerThr = DeviceConfig.getInt(NAMESPACE,
+ "data_stall_tx_per_thr", DEFAULT_DATA_STALL_TX_PER_THR);
+ mDataStallCcaLevelThr = DeviceConfig.getInt(NAMESPACE,
+ "data_stall_cca_level_thr", DEFAULT_DATA_STALL_CCA_LEVEL_THR);
+ mWifiMetrics.setDataStallDurationMs(mDataStallDurationMs);
+ mWifiMetrics.setDataStallTxTputThrKbps(mDataStallTxTputThrKbps);
+ mWifiMetrics.setDataStallRxTputThrKbps(mDataStallRxTputThrKbps);
+ mWifiMetrics.setDataStallTxPerThr(mDataStallTxPerThr);
+ mWifiMetrics.setDataStallCcaLevelThr(mDataStallCcaLevelThr);
+ }
/**
* Gets the feature flag for reporting abnormally long connections.
*/
public boolean isAbnormalConnectionBugreportEnabled() {
- return DeviceConfig.getBoolean(NAMESPACE, "abnormal_connection_bugreport_enabled", false);
+ return mIsAbnormalConnectionBugreportEnabled;
}
/**
* Gets the threshold for classifying abnormally long connections.
*/
public int getAbnormalConnectionDurationMs() {
- return DeviceConfig.getInt(NAMESPACE, "abnormal_connection_duration_ms",
- DEFAULT_ABNORMAL_CONNECTION_DURATION_MS);
+ return mAbnormalConnectionDurationMs;
}
/**
- * Adds a listener that will be run on the specified executor.
- * @param executor
- * @param onPropertiesChangedListener
+ * Gets the feature flag for aggressive MAC randomization per-SSID opt-in.
*/
- public void addOnPropertiesChangedListener(Executor executor,
- DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener) {
- DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, executor,
- onPropertiesChangedListener);
+ public boolean isAggressiveMacRandomizationSsidWhitelistEnabled() {
+ return mIsAggressiveMacRandomizationSsidWhitelistEnabled;
}
/**
* Gets the duration of evaluating Wifi condition to trigger a data stall.
*/
public int getDataStallDurationMs() {
- return DeviceConfig.getInt(NAMESPACE, "data_stall_duration_ms",
- DEFAULT_DATA_STALL_DURATION_MS);
+ return mDataStallDurationMs;
}
/**
* Gets the threshold of Tx throughput below which to trigger a data stall.
*/
- public int getDataStallTxTputThrMbps() {
- return DeviceConfig.getInt(NAMESPACE, "data_stall_tx_tput_thr_mbps",
- DEFAULT_DATA_STALL_TX_TPUT_THR_MBPS);
+ public int getDataStallTxTputThrKbps() {
+ return mDataStallTxTputThrKbps;
}
/**
* Gets the threshold of Rx throughput below which to trigger a data stall.
*/
- public int getDataStallRxTputThrMbps() {
- return DeviceConfig.getInt(NAMESPACE, "data_stall_rx_tput_thr_mbps",
- DEFAULT_DATA_STALL_RX_TPUT_THR_MBPS);
+ public int getDataStallRxTputThrKbps() {
+ return mDataStallRxTputThrKbps;
}
/**
* Gets the threshold of Tx packet error rate above which to trigger a data stall.
*/
public int getDataStallTxPerThr() {
- return DeviceConfig.getInt(NAMESPACE, "data_stall_tx_per_thr",
- DEFAULT_DATA_STALL_TX_PER_THR);
+ return mDataStallTxPerThr;
}
/**
* Gets the threshold of CCA level above which to trigger a data stall.
*/
public int getDataStallCcaLevelThr() {
- return DeviceConfig.getInt(NAMESPACE, "data_stall_cca_level_thr",
- DEFAULT_DATA_STALL_CCA_LEVEL_THR);
+ return mDataStallCcaLevelThr;
}
}
diff --git a/service/java/com/android/server/wifi/DppManager.java b/service/java/com/android/server/wifi/DppManager.java
index e9f77d4f62..e990f9cfb8 100644
--- a/service/java/com/android/server/wifi/DppManager.java
+++ b/service/java/com/android/server/wifi/DppManager.java
@@ -29,7 +29,6 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
@@ -43,7 +42,7 @@ import com.android.server.wifi.WifiNative.DppEventCallback;
*/
public class DppManager {
private static final String TAG = "DppManager";
- public Handler mHandler;
+ private final Handler mHandler;
private DppRequestInfo mDppRequestInfo = null;
private final WifiNative mWifiNative;
@@ -88,9 +87,9 @@ public class DppManager {
}
};
- DppManager(Looper looper, WifiNative wifiNative, WifiConfigManager wifiConfigManager,
+ DppManager(Handler handler, WifiNative wifiNative, WifiConfigManager wifiConfigManager,
Context context, DppMetrics dppMetrics) {
- mHandler = new Handler(looper);
+ mHandler = handler;
mWifiNative = wifiNative;
mWifiConfigManager = wifiConfigManager;
mWifiNative.registerDppEventCallback(mDppEventCallback);
diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java
index f3c5d4b3df..7c636735ae 100644
--- a/service/java/com/android/server/wifi/FrameworkFacade.java
+++ b/service/java/com/android/server/wifi/FrameworkFacade.java
@@ -16,10 +16,12 @@
package com.android.server.wifi;
-import android.app.ActivityManagerInternal;
-import android.app.AppGlobals;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+
+import android.app.ActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
@@ -30,14 +32,11 @@ import android.net.ip.IpClientUtil;
import android.os.BatteryStats;
import android.os.Handler;
import android.os.IBinder;
-import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.storage.StorageManager;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import com.android.internal.app.IBatteryStats;
-import com.android.server.LocalServices;
import com.android.server.wifi.util.WifiAsyncChannel;
/**
@@ -46,40 +45,65 @@ import com.android.server.wifi.util.WifiAsyncChannel;
public class FrameworkFacade {
public static final String TAG = "FrameworkFacade";
- private ActivityManagerInternal mActivityManagerInternal;
+ private ContentResolver mContentResolver = null;
+ private CarrierConfigManager mCarrierConfigManager = null;
+ private ActivityManager mActivityManager = null;
+
+ private ContentResolver getContentResolver(Context context) {
+ if (mContentResolver == null) {
+ mContentResolver = context.getContentResolver();
+ }
+ return mContentResolver;
+ }
+
+ private CarrierConfigManager getCarrierConfigManager(Context context) {
+ if (mCarrierConfigManager == null) {
+ mCarrierConfigManager =
+ (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ }
+ return mCarrierConfigManager;
+ }
+
+ private ActivityManager getActivityManager(Context context) {
+ if (mActivityManager == null) {
+ mActivityManager =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ }
+ return mActivityManager;
+ }
public boolean setIntegerSetting(Context context, String name, int def) {
- return Settings.Global.putInt(context.getContentResolver(), name, def);
+ return Settings.Global.putInt(getContentResolver(context), name, def);
}
public int getIntegerSetting(Context context, String name, int def) {
- return Settings.Global.getInt(context.getContentResolver(), name, def);
+ return Settings.Global.getInt(getContentResolver(context), name, def);
}
public long getLongSetting(Context context, String name, long def) {
- return Settings.Global.getLong(context.getContentResolver(), name, def);
+ return Settings.Global.getLong(getContentResolver(context), name, def);
}
public boolean setStringSetting(Context context, String name, String def) {
- return Settings.Global.putString(context.getContentResolver(), name, def);
+ return Settings.Global.putString(getContentResolver(context), name, def);
}
public String getStringSetting(Context context, String name) {
- return Settings.Global.getString(context.getContentResolver(), name);
+ return Settings.Global.getString(getContentResolver(context), name);
}
/**
* Mockable facade to Settings.Secure.getInt(.).
*/
public int getSecureIntegerSetting(Context context, String name, int def) {
- return Settings.Secure.getInt(context.getContentResolver(), name, def);
+ return Settings.Secure.getInt(getContentResolver(context), name, def);
}
/**
* Mockable facade to Settings.Secure.getString(.).
*/
public String getSecureStringSetting(Context context, String name) {
- return Settings.Secure.getString(context.getContentResolver(), name);
+ return Settings.Secure.getString(getContentResolver(context), name);
}
/**
@@ -93,7 +117,7 @@ public class FrameworkFacade {
*/
public void registerContentObserver(Context context, Uri uri,
boolean notifyForDescendants, ContentObserver contentObserver) {
- context.getContentResolver().registerContentObserver(uri, notifyForDescendants,
+ getContentResolver(context).registerContentObserver(uri, notifyForDescendants,
contentObserver);
}
@@ -105,7 +129,7 @@ public class FrameworkFacade {
* @param contentObserver
*/
public void unregisterContentObserver(Context context, ContentObserver contentObserver) {
- context.getContentResolver().unregisterContentObserver(contentObserver);
+ getContentResolver(context).unregisterContentObserver(contentObserver);
}
public IBinder getService(String serviceName) {
@@ -137,8 +161,7 @@ public class FrameworkFacade {
}
public boolean getConfigWiFiDisableInECBM(Context context) {
- CarrierConfigManager configManager = (CarrierConfigManager) context
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ CarrierConfigManager configManager = getCarrierConfigManager(context);
if (configManager != null) {
return configManager.getConfig().getBoolean(
CarrierConfigManager.KEY_CONFIG_WIFI_DISABLE_IN_ECBM);
@@ -166,17 +189,6 @@ public class FrameworkFacade {
}
/**
- * Checks whether the given uid has been granted the given permission.
- * @param permName the permission to check
- * @param uid The uid to check
- * @return {@link PackageManager.PERMISSION_GRANTED} if the permission has been granted and
- * {@link PackageManager.PERMISSION_DENIED} otherwise
- */
- public int checkUidPermission(String permName, int uid) throws RemoteException {
- return AppGlobals.getPackageManager().checkUidPermission(permName, uid);
- }
-
- /**
* Create a new instance of WifiAsyncChannel
* @param tag String corresponding to the service creating the channel
* @return WifiAsyncChannel object created
@@ -186,24 +198,14 @@ public class FrameworkFacade {
}
/**
- * Check if the device will be restarting after decrypting during boot by calling {@link
- * StorageManager.inCryptKeeperBounce}.
- * @return true if the device will restart, false otherwise
- */
- public boolean inStorageManagerCryptKeeperBounce() {
- return StorageManager.inCryptKeeperBounce();
- }
-
- /**
* Check if the provided uid is the app in the foreground.
* @param uid the uid to check
* @return true if the app is in the foreground, false otherwise
*/
- public boolean isAppForeground(int uid) {
- if (mActivityManagerInternal == null) {
- mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
- }
- return mActivityManagerInternal.isAppForeground(uid);
+ public boolean isAppForeground(Context context, int uid) {
+ ActivityManager activityManager = getActivityManager(context);
+ if (activityManager == null) return false;
+ return activityManager.getUidImportance(uid) <= IMPORTANCE_VISIBLE;
}
/**
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index e10234f68d..a51a78513e 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -35,9 +35,7 @@ import android.hardware.wifi.V1_0.WifiStatusCode;
import android.hidl.manager.V1_0.IServiceNotification;
import android.hidl.manager.V1_2.IServiceManager;
import android.os.Handler;
-import android.os.HidlSupport.Mutable;
import android.os.HwRemoteBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.util.LongSparseArray;
@@ -47,6 +45,7 @@ import android.util.Pair;
import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.util.GeneralUtil.Mutable;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -82,9 +81,9 @@ public class HalDeviceManager {
private boolean mIsVendorHalSupported = false;
// public API
- public HalDeviceManager(Clock clock, Looper looper) {
+ public HalDeviceManager(Clock clock, Handler handler) {
mClock = clock;
- mEventHandler = new Handler(looper);
+ mEventHandler = handler;
mIWifiDeathRecipient = new WifiDeathRecipient();
mServiceManagerDeathRecipient = new ServiceManagerDeathRecipient();
diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java
index 5ac173447d..35f8021583 100644
--- a/service/java/com/android/server/wifi/HostapdHal.java
+++ b/service/java/com/android/server/wifi/HostapdHal.java
@@ -26,7 +26,6 @@ import android.hidl.manager.V1_0.IServiceNotification;
import android.net.wifi.WifiConfiguration;
import android.os.Handler;
import android.os.HwRemoteBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
@@ -119,8 +118,8 @@ public class HostapdHal {
}
}
- public HostapdHal(Context context, Looper looper) {
- mEventHandler = new Handler(looper);
+ public HostapdHal(Context context, Handler handler) {
+ mEventHandler = handler;
mEnableAcs = context.getResources().getBoolean(R.bool.config_wifi_softap_acs_supported);
mEnableIeee80211AC =
context.getResources().getBoolean(R.bool.config_wifi_softap_ieee80211ac_supported);
diff --git a/service/java/com/android/server/wifi/LastMileLogger.java b/service/java/com/android/server/wifi/LastMileLogger.java
index 1269638b36..cc0685a470 100644
--- a/service/java/com/android/server/wifi/LastMileLogger.java
+++ b/service/java/com/android/server/wifi/LastMileLogger.java
@@ -16,9 +16,9 @@
package com.android.server.wifi;
-import android.os.FileUtils;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.util.FileUtils;
import libcore.io.IoUtils;
diff --git a/service/java/com/android/server/wifi/LinkProbeManager.java b/service/java/com/android/server/wifi/LinkProbeManager.java
index 89c84f76f1..b33b9d3896 100644
--- a/service/java/com/android/server/wifi/LinkProbeManager.java
+++ b/service/java/com/android/server/wifi/LinkProbeManager.java
@@ -21,7 +21,6 @@ import android.database.ContentObserver;
import android.net.MacAddress;
import android.net.wifi.WifiInfo;
import android.os.Handler;
-import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
@@ -105,7 +104,7 @@ public class LinkProbeManager {
private final TimedQuotaManager mTimedQuotaManager;
public LinkProbeManager(Clock clock, WifiNative wifiNative, WifiMetrics wifiMetrics,
- FrameworkFacade frameworkFacade, Looper looper, Context context) {
+ FrameworkFacade frameworkFacade, Handler handler, Context context) {
mClock = clock;
mWifiNative = wifiNative;
mWifiMetrics = wifiMetrics;
@@ -118,7 +117,7 @@ public class LinkProbeManager {
if (mLinkProbingSupported) {
mFrameworkFacade.registerContentObserver(mContext, Settings.Global.getUriFor(
Settings.Global.WIFI_LINK_PROBING_ENABLED), false,
- new ContentObserver(new Handler(looper)) {
+ new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange) {
updateLinkProbeSetting();
diff --git a/service/java/com/android/server/wifi/LocalOnlyHotspotRequestInfo.java b/service/java/com/android/server/wifi/LocalOnlyHotspotRequestInfo.java
index 9e3b4fb2ce..2226518753 100644
--- a/service/java/com/android/server/wifi/LocalOnlyHotspotRequestInfo.java
+++ b/service/java/com/android/server/wifi/LocalOnlyHotspotRequestInfo.java
@@ -17,12 +17,10 @@
package com.android.server.wifi;
import android.annotation.NonNull;
+import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
import android.os.RemoteException;
import com.android.internal.util.Preconditions;
@@ -36,9 +34,8 @@ public class LocalOnlyHotspotRequestInfo implements IBinder.DeathRecipient {
static final int HOTSPOT_NO_ERROR = -1;
private final int mPid;
- private final IBinder mBinder;
- private final RequestingApplicationDeathCallback mCallback;
- private final Messenger mMessenger;
+ private final ILocalOnlyHotspotCallback mCallback;
+ private final RequestingApplicationDeathCallback mDeathCallback;
/**
* Callback for use with LocalOnlyHotspot to unregister requesting applications upon death.
@@ -50,15 +47,14 @@ public class LocalOnlyHotspotRequestInfo implements IBinder.DeathRecipient {
void onLocalOnlyHotspotRequestorDeath(LocalOnlyHotspotRequestInfo requestor);
}
- LocalOnlyHotspotRequestInfo(@NonNull IBinder binder, @NonNull Messenger messenger,
- @NonNull RequestingApplicationDeathCallback callback) {
+ LocalOnlyHotspotRequestInfo(@NonNull ILocalOnlyHotspotCallback callback,
+ @NonNull RequestingApplicationDeathCallback deathCallback) {
mPid = Binder.getCallingPid();
- mBinder = Preconditions.checkNotNull(binder);
- mMessenger = Preconditions.checkNotNull(messenger);
mCallback = Preconditions.checkNotNull(callback);
+ mDeathCallback = Preconditions.checkNotNull(deathCallback);
try {
- mBinder.linkToDeath(this, 0);
+ mCallback.asBinder().linkToDeath(this, 0);
} catch (RemoteException e) {
binderDied();
}
@@ -68,7 +64,7 @@ public class LocalOnlyHotspotRequestInfo implements IBinder.DeathRecipient {
* Allow caller to unlink this object from binder death.
*/
public void unlinkDeathRecipient() {
- mBinder.unlinkToDeath(this, 0);
+ mCallback.asBinder().unlinkToDeath(this, 0);
}
/**
@@ -76,7 +72,7 @@ public class LocalOnlyHotspotRequestInfo implements IBinder.DeathRecipient {
*/
@Override
public void binderDied() {
- mCallback.onLocalOnlyHotspotRequestorDeath(this);
+ mDeathCallback.onLocalOnlyHotspotRequestorDeath(this);
}
/**
@@ -87,10 +83,7 @@ public class LocalOnlyHotspotRequestInfo implements IBinder.DeathRecipient {
* @throws RemoteException
*/
public void sendHotspotFailedMessage(int reasonCode) throws RemoteException {
- Message message = Message.obtain();
- message.what = WifiManager.HOTSPOT_FAILED;
- message.arg1 = reasonCode;
- mMessenger.send(message);
+ mCallback.onHotspotFailed(reasonCode);
}
/**
@@ -101,10 +94,7 @@ public class LocalOnlyHotspotRequestInfo implements IBinder.DeathRecipient {
* @throws RemoteException
*/
public void sendHotspotStartedMessage(WifiConfiguration config) throws RemoteException {
- Message message = Message.obtain();
- message.what = WifiManager.HOTSPOT_STARTED;
- message.obj = config;
- mMessenger.send(message);
+ mCallback.onHotspotStarted(config);
}
/**
@@ -113,9 +103,7 @@ public class LocalOnlyHotspotRequestInfo implements IBinder.DeathRecipient {
* @throws RemoteException
*/
public void sendHotspotStoppedMessage() throws RemoteException {
- Message message = Message.obtain();
- message.what = WifiManager.HOTSPOT_STOPPED;
- mMessenger.send(message);
+ mCallback.onHotspotStopped();
}
public int getPid() {
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java b/service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java
index ddc0b71a7e..690cd97299 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java
@@ -102,11 +102,25 @@ public class NetworkSuggestionEvaluator implements WifiNetworkSelector.NetworkEv
WifiNetworkSuggestion matchingNetworkSuggestion =
matchingNetworkSuggestions.stream().findAny().get();
// Check if we already have a network with the same credentials in WifiConfigManager
- // database. If yes, we should check if the network is currently blacklisted.
+ // database.
WifiConfiguration wCmConfiguredNetwork =
mWifiConfigManager.getConfiguredNetwork(
matchingNetworkSuggestion.wifiConfiguration.configKey());
if (wCmConfiguredNetwork != null) {
+ // If existing network is not from suggestion, ignore.
+ if (!wCmConfiguredNetwork.fromWifiNetworkSuggestion) {
+ continue;
+ }
+ // Update the WifiConfigManager with the latest WifiConfig
+ NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork(
+ matchingNetworkSuggestion.wifiConfiguration,
+ matchingNetworkSuggestion.suggestorUid,
+ matchingNetworkSuggestion.suggestorPackageName);
+ if (result.isSuccess()) {
+ wCmConfiguredNetwork = mWifiConfigManager.getConfiguredNetwork(
+ result.getNetworkId());
+ }
+ // If the network is currently blacklisted, ignore.
if (!wCmConfiguredNetwork.getNetworkSelectionStatus().isNetworkEnabled()
&& !mWifiConfigManager.tryEnableNetwork(wCmConfiguredNetwork.networkId)) {
mLocalLog.log("Ignoring blacklisted network: "
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
index 9627a9daaa..5babd3830c 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
@@ -19,6 +19,7 @@ package com.android.server.wifi;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiNetworkSuggestion;
+import android.net.wifi.hotspot2.PasspointConfiguration;
import android.os.Process;
import android.util.Log;
import android.util.Pair;
@@ -26,6 +27,7 @@ import android.util.Pair;
import com.android.internal.util.XmlUtils;
import com.android.server.wifi.WifiNetworkSuggestionsManager.ExtendedWifiNetworkSuggestion;
import com.android.server.wifi.WifiNetworkSuggestionsManager.PerAppInfo;
+import com.android.server.wifi.hotspot2.PasspointXmlUtils;
import com.android.server.wifi.util.XmlUtil;
import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
@@ -61,6 +63,8 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
private static final String XML_TAG_SUGGESTOR_PACKAGE_NAME = "SuggestorPackageName";
private static final String XML_TAG_SUGGESTOR_HAS_USER_APPROVED = "SuggestorHasUserApproved";
private static final String XML_TAG_SUGGESTOR_MAX_SIZE = "SuggestorMaxSize";
+ private static final String XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION =
+ "PasspointConfiguration";
/**
* Interface define the data source for the network suggestions store data.
@@ -199,6 +203,12 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
out, suggestion.wifiConfiguration.enterpriseConfig);
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
}
+ if (suggestion.passpointConfiguration != null) {
+ XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION);
+ PasspointXmlUtils.serializePasspointConfiguration(out,
+ suggestion.passpointConfiguration);
+ XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION);
+ }
// Serialize other fields
XmlUtil.writeNextValue(out, XML_TAG_IS_APP_INTERACTION_REQUIRED,
@@ -283,6 +293,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
throws XmlPullParserException, IOException {
Pair<String, WifiConfiguration> parsedConfig = null;
WifiEnterpriseConfig enterpriseConfig = null;
+ PasspointConfiguration passpointConfiguration = null;
boolean isAppInteractionRequired = false;
boolean isUserInteractionRequired = false;
int suggestorUid = Process.INVALID_UID;
@@ -334,6 +345,14 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
enterpriseConfig = XmlUtil.WifiEnterpriseConfigXmlUtil.parseFromXml(
in, outerTagDepth + 1);
break;
+ case XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION:
+ if (passpointConfiguration != null) {
+ throw new XmlPullParserException("Detected duplicate tag for: "
+ + XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION);
+ }
+ passpointConfiguration = PasspointXmlUtils
+ .deserializePasspointConfiguration(in, outerTagDepth + 1);
+ break;
default:
throw new XmlPullParserException("Unknown tag under "
+ XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION + ": " + in.getName());
@@ -354,8 +373,8 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
wifiConfiguration.enterpriseConfig = enterpriseConfig;
}
return new WifiNetworkSuggestion(
- wifiConfiguration, isAppInteractionRequired, isUserInteractionRequired,
- suggestorUid, suggestorPackageName);
+ wifiConfiguration, passpointConfiguration, isAppInteractionRequired,
+ isUserInteractionRequired, suggestorUid, suggestorPackageName);
}
}
diff --git a/service/java/com/android/server/wifi/OpenNetworkNotifier.java b/service/java/com/android/server/wifi/OpenNetworkNotifier.java
index 97f390f391..dffee2dc25 100644
--- a/service/java/com/android/server/wifi/OpenNetworkNotifier.java
+++ b/service/java/com/android/server/wifi/OpenNetworkNotifier.java
@@ -26,7 +26,7 @@ import com.android.server.wifi.nano.WifiMetricsProto;
/**
* This class handles the "open wi-fi network available" notification
*
- * NOTE: These API's are not thread safe and should only be used from ClientModeImpl thread.
+ * NOTE: These API's are not thread safe and should only be used from the main Wifi thread.
*/
public class OpenNetworkNotifier extends AvailableNetworkNotifier {
public static final String TAG = "WifiOpenNetworkNotifier";
diff --git a/service/java/com/android/server/wifi/SIMAccessor.java b/service/java/com/android/server/wifi/SIMAccessor.java
index efa303752d..13186f1e1e 100644
--- a/service/java/com/android/server/wifi/SIMAccessor.java
+++ b/service/java/com/android/server/wifi/SIMAccessor.java
@@ -1,6 +1,7 @@
package com.android.server.wifi;
import android.content.Context;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -13,9 +14,9 @@ public class SIMAccessor {
public SIMAccessor(Context context) {
// TODO(b/132188983): Inject this using WifiInjector
- mTelephonyManager = TelephonyManager.from(context);
+ mTelephonyManager = context.getSystemService(TelephonyManager.class);
// TODO(b/132188983): Inject this using WifiInjector
- mSubscriptionManager = SubscriptionManager.from(context);
+ mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
}
public List<String> getMatchingImsis(IMSIParameter mccMnc) {
@@ -23,8 +24,10 @@ public class SIMAccessor {
return null;
}
List<String> imsis = new ArrayList<>();
- for (int subId : mSubscriptionManager.getActiveSubscriptionIdList()) {
- String imsi = mTelephonyManager.getSubscriberId(subId);
+ for (SubscriptionInfo sub : mSubscriptionManager.getActiveSubscriptionInfoList()) {
+ String imsi =
+ mTelephonyManager.createForSubscriptionId(sub.getSubscriptionId())
+ .getSubscriberId();
if (imsi != null && mccMnc.matchesImsi(imsi)) {
imsis.add(imsi);
}
diff --git a/service/java/com/android/server/wifi/SarManager.java b/service/java/com/android/server/wifi/SarManager.java
index a35f65f00b..ebc414f7f2 100644
--- a/service/java/com/android/server/wifi/SarManager.java
+++ b/service/java/com/android/server/wifi/SarManager.java
@@ -32,6 +32,7 @@ import android.media.AudioManager;
import android.media.AudioSystem;
import android.net.wifi.WifiManager;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.Looper;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
@@ -486,7 +487,7 @@ public class SarManager {
*/
private class WifiPhoneStateListener extends PhoneStateListener {
WifiPhoneStateListener(Looper looper) {
- super(looper);
+ super(new HandlerExecutor(new Handler(looper)));
}
/**
diff --git a/service/java/com/android/server/wifi/SavedNetworkEvaluator.java b/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
index 062fa5354a..d12b76a6fb 100644
--- a/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
+++ b/service/java/com/android/server/wifi/SavedNetworkEvaluator.java
@@ -205,6 +205,11 @@ public class SavedNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluat
continue;
}
+ // Ignore networks that the user has disallowed auto-join for.
+ if (!network.allowAutojoin) {
+ continue;
+ }
+
/**
* Ignore Passpoint and Ephemeral networks. They are configured networks,
* but without being persisted to the storage. They are evaluated by
diff --git a/service/java/com/android/server/wifi/ScanDetail.java b/service/java/com/android/server/wifi/ScanDetail.java
index d39888ec45..0ee6cc4885 100644
--- a/service/java/com/android/server/wifi/ScanDetail.java
+++ b/service/java/com/android/server/wifi/ScanDetail.java
@@ -20,13 +20,13 @@ import android.net.wifi.AnqpInformationElement;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiSsid;
+import com.android.server.wifi.hotspot2.NetworkDetail;
+import com.android.server.wifi.hotspot2.Utils;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
import com.android.server.wifi.hotspot2.anqp.Constants;
import com.android.server.wifi.hotspot2.anqp.HSFriendlyNameElement;
import com.android.server.wifi.hotspot2.anqp.RawByteElement;
import com.android.server.wifi.hotspot2.anqp.VenueNameElement;
-import com.android.server.wifi.hotspot2.NetworkDetail;
-import com.android.server.wifi.hotspot2.Utils;
import java.util.List;
import java.util.Map;
@@ -38,10 +38,12 @@ public class ScanDetail {
private final ScanResult mScanResult;
private volatile NetworkDetail mNetworkDetail;
private long mSeen = 0;
+ private byte[] mInformationElementRawData;
public ScanDetail(NetworkDetail networkDetail, WifiSsid wifiSsid, String bssid,
String caps, int level, int frequency, long tsf,
- ScanResult.InformationElement[] informationElements, List<String> anqpLines) {
+ ScanResult.InformationElement[] informationElements, List<String> anqpLines,
+ byte[] informationElementRawData) {
mNetworkDetail = networkDetail;
mScanResult = new ScanResult(wifiSsid, bssid, networkDetail.getHESSID(),
networkDetail.getAnqpDomainID(), networkDetail.getOsuProviders(),
@@ -59,6 +61,7 @@ public class ScanDetail {
if (networkDetail.isInterworking()) {
mScanResult.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK);
}
+ mInformationElementRawData = informationElementRawData;
}
public ScanDetail(WifiSsid wifiSsid, String bssid, String caps, int level, int frequency,
@@ -160,6 +163,13 @@ public class ScanDetail {
return mSeen;
}
+ /**
+ * Return the network information element raw data.
+ */
+ public byte[] getInformationElementRawData() {
+ return mInformationElementRawData;
+ }
+
@Override
public String toString() {
try {
diff --git a/service/java/com/android/server/wifi/ScanOnlyModeManager.java b/service/java/com/android/server/wifi/ScanOnlyModeManager.java
deleted file mode 100644
index c3547be5de..0000000000
--- a/service/java/com/android/server/wifi/ScanOnlyModeManager.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.net.wifi.WifiManager;
-import android.os.Looper;
-import android.os.Message;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.util.IState;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.server.wifi.WifiNative.InterfaceCallback;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Manager WiFi in Scan Only Mode - no network connections.
- */
-public class ScanOnlyModeManager implements ActiveModeManager {
-
- private final ScanOnlyModeStateMachine mStateMachine;
-
- private static final String TAG = "WifiScanOnlyModeManager";
-
- private final Context mContext;
- private final WifiNative mWifiNative;
-
- private final WifiMetrics mWifiMetrics;
- private final Listener mListener;
- private final WakeupController mWakeupController;
- private final SarManager mSarManager;
-
- private String mClientInterfaceName;
- private boolean mIfaceIsUp = false;
-
- private boolean mExpectedStop = false;
-
- ScanOnlyModeManager(@NonNull Context context, @NonNull Looper looper,
- @NonNull WifiNative wifiNative, @NonNull Listener listener,
- @NonNull WifiMetrics wifiMetrics,
- @NonNull WakeupController wakeupController,
- @NonNull SarManager sarManager) {
- mContext = context;
- mWifiNative = wifiNative;
- mListener = listener;
- mWifiMetrics = wifiMetrics;
- mWakeupController = wakeupController;
- mSarManager = sarManager;
- mStateMachine = new ScanOnlyModeStateMachine(looper);
- }
-
- /**
- * Start scan only mode.
- */
- public void start() {
- mStateMachine.sendMessage(ScanOnlyModeStateMachine.CMD_START);
- }
-
- /**
- * Cancel any pending scans and stop scan mode.
- */
- public void stop() {
- Log.d(TAG, " currentstate: " + getCurrentStateName());
- mExpectedStop = true;
- mStateMachine.quitNow();
- }
-
- public @ScanMode int getScanMode() {
- return SCAN_WITHOUT_HIDDEN_NETWORKS;
- }
-
- /**
- * Dump info about this ScanOnlyMode manager.
- */
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("--Dump of ScanOnlyModeManager--");
-
- pw.println("current StateMachine mode: " + getCurrentStateName());
- pw.println("mClientInterfaceName: " + mClientInterfaceName);
- pw.println("mIfaceIsUp: " + mIfaceIsUp);
- }
-
- /**
- * Listener for ScanOnlyMode state changes.
- */
- public interface Listener {
- /**
- * Invoke when wifi state changes.
- * @param state new wifi state
- */
- void onStateChanged(int state);
- }
-
- private String getCurrentStateName() {
- IState currentState = mStateMachine.getCurrentState();
-
- if (currentState != null) {
- return currentState.getName();
- }
-
- return "StateMachine not active";
- }
-
- /**
- * Update Wifi state.
- * @param state new Wifi state
- */
- private void updateWifiState(int state) {
- if (mExpectedStop) {
- Log.d(TAG, "expected stop, not triggering callbacks: state = " + state);
- return;
- }
-
- // Once we report the mode has stopped/failed any other stop signals are redundant
- // note: this can happen in failure modes where we get multiple callbacks as underlying
- // components/interface stops or the underlying interface is destroyed in cleanup
- if (state == WifiManager.WIFI_STATE_UNKNOWN || state == WifiManager.WIFI_STATE_DISABLED) {
- mExpectedStop = true;
- }
-
- mListener.onStateChanged(state);
- }
-
- private class ScanOnlyModeStateMachine extends StateMachine {
- // Commands for the state machine.
- public static final int CMD_START = 0;
- public static final int CMD_INTERFACE_STATUS_CHANGED = 3;
- public static final int CMD_INTERFACE_DESTROYED = 4;
- public static final int CMD_INTERFACE_DOWN = 5;
-
- private final State mIdleState = new IdleState();
- private final State mStartedState = new StartedState();
-
- private final InterfaceCallback mWifiNativeInterfaceCallback = new InterfaceCallback() {
- @Override
- public void onDestroyed(String ifaceName) {
- if (mClientInterfaceName != null && mClientInterfaceName.equals(ifaceName)) {
- sendMessage(CMD_INTERFACE_DESTROYED);
- }
- }
-
- @Override
- public void onUp(String ifaceName) {
- if (mClientInterfaceName != null && mClientInterfaceName.equals(ifaceName)) {
- sendMessage(CMD_INTERFACE_STATUS_CHANGED, 1);
- }
- }
-
- @Override
- public void onDown(String ifaceName) {
- if (mClientInterfaceName != null && mClientInterfaceName.equals(ifaceName)) {
- sendMessage(CMD_INTERFACE_STATUS_CHANGED, 0);
- }
- }
- };
-
- ScanOnlyModeStateMachine(Looper looper) {
- super(TAG, looper);
-
- addState(mIdleState);
- addState(mStartedState);
-
- setInitialState(mIdleState);
- start();
- }
-
- private class IdleState extends State {
-
- @Override
- public void enter() {
- Log.d(TAG, "entering IdleState");
- mClientInterfaceName = null;
- }
-
- @Override
- public boolean processMessage(Message message) {
- switch (message.what) {
- case CMD_START:
- mClientInterfaceName = mWifiNative.setupInterfaceForClientInScanMode(
- mWifiNativeInterfaceCallback);
- if (TextUtils.isEmpty(mClientInterfaceName)) {
- Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
- updateWifiState(WifiManager.WIFI_STATE_UNKNOWN);
- break;
- }
- transitionTo(mStartedState);
- break;
- default:
- Log.d(TAG, "received an invalid message: " + message);
- return NOT_HANDLED;
- }
- return HANDLED;
- }
- }
-
- private class StartedState extends State {
-
- private void onUpChanged(boolean isUp) {
- if (isUp == mIfaceIsUp) {
- return; // no change
- }
- mIfaceIsUp = isUp;
- if (isUp) {
- Log.d(TAG, "Wifi is ready to use for scanning");
- mWakeupController.start();
- updateWifiState(WifiManager.WIFI_STATE_ENABLED);
- } else {
- // if the interface goes down we should exit and go back to idle state.
- Log.d(TAG, "interface down - stop scan mode");
- mStateMachine.sendMessage(CMD_INTERFACE_DOWN);
- }
- }
-
- @Override
- public void enter() {
- Log.d(TAG, "entering StartedState");
-
- mIfaceIsUp = false;
- onUpChanged(mWifiNative.isInterfaceUp(mClientInterfaceName));
- mSarManager.setScanOnlyWifiState(WifiManager.WIFI_STATE_ENABLED);
- }
-
- @Override
- public boolean processMessage(Message message) {
- switch(message.what) {
- case CMD_START:
- // Already started, ignore this command.
- break;
- case CMD_INTERFACE_DESTROYED:
- Log.d(TAG, "Interface cleanly destroyed, report scan mode stop.");
- mClientInterfaceName = null;
- transitionTo(mIdleState);
- break;
- case CMD_INTERFACE_STATUS_CHANGED:
- boolean isUp = message.arg1 == 1;
- onUpChanged(isUp);
- break;
- case CMD_INTERFACE_DOWN:
- Log.d(TAG, "interface down! stop mode");
- updateWifiState(WifiManager.WIFI_STATE_UNKNOWN);
- transitionTo(mIdleState);
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- /**
- * Clean up state and unregister listeners.
- */
- @Override
- public void exit() {
- mWakeupController.stop();
- if (mClientInterfaceName != null) {
- mWifiNative.teardownInterface(mClientInterfaceName);
- mClientInterfaceName = null;
- }
- updateWifiState(WifiManager.WIFI_STATE_DISABLED);
- mSarManager.setScanOnlyWifiState(WifiManager.WIFI_STATE_DISABLED);
-
- // once we leave started, nothing else to do... stop the state machine
- mStateMachine.quitNow();
- }
- }
- }
-}
diff --git a/service/java/com/android/server/wifi/ScanRequestProxy.java b/service/java/com/android/server/wifi/ScanRequestProxy.java
index a4678440b2..9ba112536d 100644
--- a/service/java/com/android/server/wifi/ScanRequestProxy.java
+++ b/service/java/com/android/server/wifi/ScanRequestProxy.java
@@ -22,10 +22,13 @@ import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
+import android.net.wifi.IScanResultsListener;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
@@ -34,6 +37,7 @@ import android.util.Log;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.util.ExternalCallbackTracker;
import com.android.server.wifi.util.WifiPermissionsUtil;
import java.util.ArrayList;
@@ -63,7 +67,7 @@ import javax.annotation.concurrent.NotThreadSafe;
* {@link #SCAN_REQUEST_THROTTLE_TIME_WINDOW_FG_APPS_MS}.
* b) Background apps combined can request 1 scan every
* {@link #SCAN_REQUEST_THROTTLE_INTERVAL_BG_APPS_MS}.
- * Note: This class is not thread-safe. It needs to be invoked from ClientModeImpl thread only.
+ * Note: This class is not thread-safe. It needs to be invoked from the main Wifi thread only.
*/
@NotThreadSafe
public class ScanRequestProxy {
@@ -103,6 +107,8 @@ public class ScanRequestProxy {
new ArrayMap();
// Scan results cached from the last full single scan request.
private final List<ScanResult> mLastScanResults = new ArrayList<>();
+ // external ScanResultListener tracker
+ private final ExternalCallbackTracker<IScanResultsListener> mRegisteredScanResultsListeners;
// Global scan listener for listening to all scan requests.
private class GlobalScanListener implements WifiScanner.ScanListener {
@Override
@@ -137,6 +143,7 @@ public class ScanRequestProxy {
mLastScanResults.clear();
mLastScanResults.addAll(Arrays.asList(scanResults));
sendScanResultBroadcast(true);
+ sendScanResultsAvailableToListeners();
}
}
@@ -244,6 +251,7 @@ public class ScanRequestProxy {
mClock = clock;
mFrameworkFacade = frameworkFacade;
mThrottleEnabledSettingObserver = new ThrottleEnabledSettingObserver(handler);
+ mRegisteredScanResultsListeners = new ExternalCallbackTracker<>(handler);
}
/**
@@ -453,7 +461,7 @@ public class ScanRequestProxy {
* @return true if the scan request was placed or a scan is already ongoing, false otherwise.
*/
public boolean startScan(int callingUid, String packageName) {
- if (!retrieveWifiScannerIfNecessary()) {
+ if (!mScanningEnabled || !retrieveWifiScannerIfNecessary()) {
Log.e(TAG, "Failed to retrieve wifiscanner");
sendScanResultFailureBroadcastToPackage(packageName);
return false;
@@ -528,4 +536,37 @@ public class ScanRequestProxy {
}
mLastScanTimestampsForFgApps.remove(Pair.create(uid, packageName));
}
+
+ private void sendScanResultsAvailableToListeners() {
+ Iterator<IScanResultsListener> iterator =
+ mRegisteredScanResultsListeners.getCallbacks().iterator();
+ while (iterator.hasNext()) {
+ IScanResultsListener listener = iterator.next();
+ try {
+ listener.onScanResultsAvailable();
+ } catch (RemoteException e) {
+ Log.e(TAG, "onScanResultsAvailable: remote exception -- " + e);
+ }
+ }
+ }
+
+ /**
+ * Register a listener on scan event
+ * @param binder IBinder instance to allow cleanup if the app dies.
+ * @param listener IScanResultListener instance to add.
+ * @param listenerIdentifier identifier of the listener, should be hash code of package name.
+ * @return true if succeed otherwise false.
+ */
+ public boolean registerScanResultsListener(IBinder binder, IScanResultsListener listener,
+ int listenerIdentifier) {
+ return mRegisteredScanResultsListeners.add(binder, listener, listenerIdentifier);
+ }
+
+ /**
+ * Unregister a listener on scan event
+ * @param listenerIdentifier identifier of the listener, should be hash code of package name.
+ */
+ public void unregisterScanResultsListener(int listenerIdentifier) {
+ mRegisteredScanResultsListeners.remove(listenerIdentifier);
+ }
}
diff --git a/service/java/com/android/server/wifi/ScanResultMatchInfo.java b/service/java/com/android/server/wifi/ScanResultMatchInfo.java
index b3d10cc386..e623683318 100644
--- a/service/java/com/android/server/wifi/ScanResultMatchInfo.java
+++ b/service/java/com/android/server/wifi/ScanResultMatchInfo.java
@@ -15,6 +15,7 @@
*/
package com.android.server.wifi;
+import android.annotation.NonNull;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
@@ -46,7 +47,7 @@ public class ScanResultMatchInfo {
/**
* Fetch network type from network configuration.
*/
- public static @WifiConfiguration.SecurityType int getNetworkType(WifiConfiguration config) {
+ private static @WifiConfiguration.SecurityType int getNetworkType(WifiConfiguration config) {
if (WifiConfigurationUtil.isConfigForSaeNetwork(config)) {
return WifiConfiguration.SECURITY_TYPE_SAE;
} else if (WifiConfigurationUtil.isConfigForPskNetwork(config)) {
@@ -78,7 +79,7 @@ public class ScanResultMatchInfo {
/**
* Fetch network type from scan result.
*/
- public static @WifiConfiguration.SecurityType int getNetworkType(ScanResult scanResult) {
+ private static @WifiConfiguration.SecurityType int getNetworkType(ScanResult scanResult) {
if (ScanResultUtil.isScanResultForSaeNetwork(scanResult)) {
return WifiConfiguration.SECURITY_TYPE_SAE;
} else if (ScanResultUtil.isScanResultForPskNetwork(scanResult)) {
@@ -123,19 +124,11 @@ public class ScanResultMatchInfo {
return info;
}
- @Override
- public boolean equals(Object otherObj) {
- if (this == otherObj) {
- return true;
- } else if (!(otherObj instanceof ScanResultMatchInfo)) {
- return false;
- }
- ScanResultMatchInfo other = (ScanResultMatchInfo) otherObj;
- if (!Objects.equals(networkSsid, other.networkSsid)) {
- return false;
- }
+ /**
+ * Checks for equality of network type.
+ */
+ public boolean networkTypeEquals(@NonNull ScanResultMatchInfo other) {
boolean networkTypeEquals;
-
// Detect <SSID, PSK+SAE> scan result and say it is equal to <SSID, PSK> configuration
if (other.pskSaeInTransitionMode && networkType == WifiConfiguration.SECURITY_TYPE_PSK
|| (pskSaeInTransitionMode
@@ -154,6 +147,20 @@ public class ScanResultMatchInfo {
}
@Override
+ public boolean equals(Object otherObj) {
+ if (this == otherObj) {
+ return true;
+ } else if (!(otherObj instanceof ScanResultMatchInfo)) {
+ return false;
+ }
+ ScanResultMatchInfo other = (ScanResultMatchInfo) otherObj;
+ if (!Objects.equals(networkSsid, other.networkSsid)) {
+ return false;
+ }
+ return networkTypeEquals(other);
+ }
+
+ @Override
public int hashCode() {
return Objects.hash(networkSsid);
}
diff --git a/service/java/com/android/server/wifi/ScoreCardBasedScorer.java b/service/java/com/android/server/wifi/ScoreCardBasedScorer.java
index 34adfcba47..96c8e6c099 100644
--- a/service/java/com/android/server/wifi/ScoreCardBasedScorer.java
+++ b/service/java/com/android/server/wifi/ScoreCardBasedScorer.java
@@ -64,6 +64,8 @@ final class ScoreCardBasedScorer implements WifiCandidates.CandidateScorer {
// Maximum allowable adjustment of the cutoff rssi (dB)
public static final int RSSI_RAIL = 5;
+ private static final boolean USE_USER_CONNECT_CHOICE = true;
+
ScoreCardBasedScorer(ScoringParams scoringParams) {
mScoringParams = scoringParams;
}
@@ -99,7 +101,8 @@ final class ScoreCardBasedScorer implements WifiCandidates.CandidateScorer {
// which evaluator added the candidate.
score -= 1000 * candidate.getEvaluatorId();
- return new ScoredCandidate(score, 10, candidate);
+ return new ScoredCandidate(score, 10,
+ USE_USER_CONNECT_CHOICE, candidate);
}
private int estimatedCutoff(Candidate candidate) {
@@ -121,9 +124,9 @@ final class ScoreCardBasedScorer implements WifiCandidates.CandidateScorer {
}
@Override
- public ScoredCandidate scoreCandidates(@NonNull Collection<Candidate> group) {
+ public ScoredCandidate scoreCandidates(@NonNull Collection<Candidate> candidates) {
ScoredCandidate choice = ScoredCandidate.NONE;
- for (Candidate candidate : group) {
+ for (Candidate candidate : candidates) {
ScoredCandidate scoredCandidate = scoreCandidate(candidate);
if (scoredCandidate.value > choice.value) {
choice = scoredCandidate;
@@ -134,9 +137,4 @@ final class ScoreCardBasedScorer implements WifiCandidates.CandidateScorer {
return choice;
}
- @Override
- public boolean userConnectChoiceOverrideWanted() {
- return true;
- }
-
}
diff --git a/service/java/com/android/server/wifi/ScoredNetworkEvaluator.java b/service/java/com/android/server/wifi/ScoredNetworkEvaluator.java
index 66222691fb..2eba641997 100644
--- a/service/java/com/android/server/wifi/ScoredNetworkEvaluator.java
+++ b/service/java/com/android/server/wifi/ScoredNetworkEvaluator.java
@@ -27,14 +27,12 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiNetworkScoreCache;
import android.os.Handler;
-import android.os.Looper;
import android.os.Process;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
-import com.android.server.wifi.WifiNetworkSelector.NetworkEvaluator.OnConnectableListener;
import com.android.server.wifi.util.ScanResultUtil;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -57,7 +55,7 @@ public class ScoredNetworkEvaluator implements WifiNetworkSelector.NetworkEvalua
private boolean mNetworkRecommendationsEnabled;
private WifiNetworkScoreCache mScoreCache;
- ScoredNetworkEvaluator(final Context context, Looper looper,
+ ScoredNetworkEvaluator(final Context context, Handler handler,
final FrameworkFacade frameworkFacade, NetworkScoreManager networkScoreManager,
WifiConfigManager wifiConfigManager, LocalLog localLog,
WifiNetworkScoreCache wifiNetworkScoreCache,
@@ -67,7 +65,7 @@ public class ScoredNetworkEvaluator implements WifiNetworkSelector.NetworkEvalua
mNetworkScoreManager = networkScoreManager;
mWifiConfigManager = wifiConfigManager;
mLocalLog = localLog;
- mContentObserver = new ContentObserver(new Handler(looper)) {
+ mContentObserver = new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange) {
mNetworkRecommendationsEnabled = frameworkFacade.getIntegerSetting(context,
diff --git a/service/java/com/android/server/wifi/SelfRecovery.java b/service/java/com/android/server/wifi/SelfRecovery.java
index c9e95a77fd..e789dd3a4a 100644
--- a/service/java/com/android/server/wifi/SelfRecovery.java
+++ b/service/java/com/android/server/wifi/SelfRecovery.java
@@ -16,15 +16,18 @@
package com.android.server.wifi;
+import android.annotation.IntDef;
import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Iterator;
import java.util.LinkedList;
/**
* This class is used to recover the wifi stack from a fatal failure. The recovery mechanism
* involves triggering a stack restart (essentially simulating an airplane mode toggle) using
- * {@link WifiController}.
+ * {@link ActiveModeWarden}.
* The current triggers for:
* 1. Last resort watchdog bite.
* 2. HAL/wificond crashes during normal operation.
@@ -39,6 +42,14 @@ public class SelfRecovery {
public static final int REASON_LAST_RESORT_WATCHDOG = 0;
public static final int REASON_WIFINATIVE_FAILURE = 1;
public static final int REASON_STA_IFACE_DOWN = 2;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"REASON_"}, value = {
+ REASON_LAST_RESORT_WATCHDOG,
+ REASON_WIFINATIVE_FAILURE,
+ REASON_STA_IFACE_DOWN})
+ public @interface RecoveryReason {}
+
public static final long MAX_RESTARTS_IN_TIME_WINDOW = 2; // 2 restarts per hour
public static final long MAX_RESTARTS_TIME_WINDOW_MILLIS = 60 * 60 * 1000; // 1 hour
protected static final String[] REASON_STRINGS = {
@@ -47,14 +58,14 @@ public class SelfRecovery {
"Sta Interface Down" // REASON_STA_IFACE_DOWN
};
- private final WifiController mWifiController;
+ private final ActiveModeWarden mActiveModeWarden;
private final Clock mClock;
// Time since boot (in millis) that restart occurred
private final LinkedList<Long> mPastRestartTimes;
- public SelfRecovery(WifiController wifiController, Clock clock) {
- mWifiController = wifiController;
+ public SelfRecovery(ActiveModeWarden activeModeWarden, Clock clock) {
+ mActiveModeWarden = activeModeWarden;
mClock = clock;
- mPastRestartTimes = new LinkedList<Long>();
+ mPastRestartTimes = new LinkedList<>();
}
/**
@@ -63,13 +74,13 @@ public class SelfRecovery {
* This method does the following:
* 1. Checks reason code used to trigger recovery
* 2. Checks for sta iface down triggers and disables wifi by sending {@link
- * WifiController#CMD_RECOVERY_DISABLE_WIFI} to {@link WifiController} to disable wifi.
+ * ActiveModeWarden#recoveryDisableWifi()} to {@link ActiveModeWarden} to disable wifi.
* 3. Throttles restart calls for underlying native failures
- * 4. Sends {@link WifiController#CMD_RECOVERY_RESTART_WIFI} to {@link WifiController} to
+ * 4. Sends {@link ActiveModeWarden#recoveryRestartWifi(int)} to {@link ActiveModeWarden} to
* initiate the stack restart.
* @param reason One of the above |REASON_*| codes.
*/
- public void trigger(int reason) {
+ public void trigger(@RecoveryReason int reason) {
if (!(reason == REASON_LAST_RESORT_WATCHDOG || reason == REASON_WIFINATIVE_FAILURE
|| reason == REASON_STA_IFACE_DOWN)) {
Log.e(TAG, "Invalid trigger reason. Ignoring...");
@@ -77,7 +88,7 @@ public class SelfRecovery {
}
if (reason == REASON_STA_IFACE_DOWN) {
Log.e(TAG, "STA interface down, disable wifi");
- mWifiController.sendMessage(WifiController.CMD_RECOVERY_DISABLE_WIFI);
+ mActiveModeWarden.recoveryDisableWifi();
return;
}
@@ -88,12 +99,12 @@ public class SelfRecovery {
if (mPastRestartTimes.size() >= MAX_RESTARTS_IN_TIME_WINDOW) {
Log.e(TAG, "Already restarted wifi (" + MAX_RESTARTS_IN_TIME_WINDOW + ") times in"
+ " last (" + MAX_RESTARTS_TIME_WINDOW_MILLIS + "ms ). Disabling wifi");
- mWifiController.sendMessage(WifiController.CMD_RECOVERY_DISABLE_WIFI);
+ mActiveModeWarden.recoveryDisableWifi();
return;
}
mPastRestartTimes.add(mClock.getElapsedSinceBootMillis());
}
- mWifiController.sendMessage(WifiController.CMD_RECOVERY_RESTART_WIFI, reason);
+ mActiveModeWarden.recoveryRestartWifi(reason);
}
/**
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 79bc46fa56..1f6a5fcc60 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -24,7 +24,9 @@ import android.annotation.NonNull;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
+import android.net.MacAddress;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
@@ -45,9 +47,14 @@ import com.android.internal.util.WakeupMessage;
import com.android.server.wifi.WifiNative.InterfaceCallback;
import com.android.server.wifi.WifiNative.SoftApListener;
import com.android.server.wifi.util.ApConfigUtil;
+import com.android.server.wifi.wificond.NativeWifiClient;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
import java.util.Locale;
/**
@@ -72,7 +79,8 @@ public class SoftApManager implements ActiveModeManager {
private final SoftApStateMachine mStateMachine;
- private final WifiManager.SoftApCallback mCallback;
+ private final Listener mModeListener;
+ private final WifiManager.SoftApCallback mSoftApCallback;
private String mApInterfaceName;
private boolean mIfaceIsUp;
@@ -82,18 +90,20 @@ public class SoftApManager implements ActiveModeManager {
private final WifiMetrics mWifiMetrics;
- private final int mMode;
- private WifiConfiguration mApConfig;
+ @NonNull
+ private SoftApModeConfiguration mApConfig;
private int mReportedFrequency = -1;
private int mReportedBandwidth = -1;
- private int mNumAssociatedStations = 0;
+ private List<WifiClient> mConnectedClients = new ArrayList<>();
private boolean mTimeoutEnabled = false;
private final SarManager mSarManager;
- private long mStartTimestamp = -1;
+ private String mStartTimestamp;
+
+ private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
private BaseWifiDiagnostics mWifiDiagnostics;
@@ -108,9 +118,9 @@ public class SoftApManager implements ActiveModeManager {
}
@Override
- public void onNumAssociatedStationsChanged(int numStations) {
- mStateMachine.sendMessage(
- SoftApStateMachine.CMD_NUM_ASSOCIATED_STATIONS_CHANGED, numStations);
+ public void onConnectedClientsChanged(List<NativeWifiClient> clients) {
+ mStateMachine.sendMessage(SoftApStateMachine.CMD_ASSOCIATED_STATIONS_CHANGED,
+ clients);
}
@Override
@@ -125,6 +135,7 @@ public class SoftApManager implements ActiveModeManager {
@NonNull FrameworkFacade framework,
@NonNull WifiNative wifiNative,
String countryCode,
+ @NonNull Listener listener,
@NonNull WifiManager.SoftApCallback callback,
@NonNull WifiApConfigStore wifiApConfigStore,
@NonNull SoftApModeConfiguration apConfig,
@@ -135,14 +146,13 @@ public class SoftApManager implements ActiveModeManager {
mFrameworkFacade = framework;
mWifiNative = wifiNative;
mCountryCode = countryCode;
- mCallback = callback;
+ mModeListener = listener;
+ mSoftApCallback = callback;
mWifiApConfigStore = wifiApConfigStore;
- mMode = apConfig.getTargetMode();
- WifiConfiguration config = apConfig.getWifiConfiguration();
- if (config == null) {
- mApConfig = mWifiApConfigStore.getApConfiguration();
- } else {
- mApConfig = config;
+ mApConfig = apConfig;
+ if (mApConfig.getWifiConfiguration() == null) {
+ WifiConfiguration wifiConfig = mWifiApConfigStore.getApConfiguration();
+ mApConfig = new SoftApModeConfiguration(mApConfig.getTargetMode(), wifiConfig);
}
mWifiMetrics = wifiMetrics;
mSarManager = sarManager;
@@ -151,10 +161,10 @@ public class SoftApManager implements ActiveModeManager {
}
/**
- * Start soft AP with the supplied config.
+ * Start soft AP, as configured in the constructor.
*/
public void start() {
- mStateMachine.sendMessage(SoftApStateMachine.CMD_START, mApConfig);
+ mStateMachine.sendMessage(SoftApStateMachine.CMD_START);
}
/**
@@ -179,7 +189,7 @@ public class SoftApManager implements ActiveModeManager {
}
public int getIpMode() {
- return mMode;
+ return mApConfig.getTargetMode();
}
/**
@@ -191,20 +201,18 @@ public class SoftApManager implements ActiveModeManager {
pw.println("current StateMachine mode: " + getCurrentStateName());
pw.println("mApInterfaceName: " + mApInterfaceName);
pw.println("mIfaceIsUp: " + mIfaceIsUp);
- pw.println("mMode: " + mMode);
- pw.println("mCountryCode: " + mCountryCode);
- if (mApConfig != null) {
- pw.println("mApConfig.SSID: " + mApConfig.SSID);
- pw.println("mApConfig.apBand: " + mApConfig.apBand);
- pw.println("mApConfig.hiddenSSID: " + mApConfig.hiddenSSID);
- } else {
- pw.println("mApConfig: null");
- }
- pw.println("mNumAssociatedStations: " + mNumAssociatedStations);
+ pw.println("mSoftApCountryCode: " + mCountryCode);
+ pw.println("mApConfig.targetMode: " + mApConfig.getTargetMode());
+ WifiConfiguration wifiConfig = mApConfig.getWifiConfiguration();
+ pw.println("mApConfig.wifiConfiguration.SSID: " + wifiConfig.SSID);
+ pw.println("mApConfig.wifiConfiguration.apBand: " + wifiConfig.apBand);
+ pw.println("mApConfig.wifiConfiguration.hiddenSSID: " + wifiConfig.hiddenSSID);
+ pw.println("mConnectedClients.size(): " + mConnectedClients.size());
pw.println("mTimeoutEnabled: " + mTimeoutEnabled);
pw.println("mReportedFrequency: " + mReportedFrequency);
pw.println("mReportedBandwidth: " + mReportedBandwidth);
pw.println("mStartTimestamp: " + mStartTimestamp);
+ mStateMachine.dump(fd, pw, args);
}
private String getCurrentStateName() {
@@ -219,12 +227,13 @@ public class SoftApManager implements ActiveModeManager {
/**
* Update AP state.
- * @param newState new AP state
+ *
+ * @param newState new AP state
* @param currentState current AP state
- * @param reason Failure reason if the new AP state is in failure state
+ * @param reason Failure reason if the new AP state is in failure state
*/
private void updateApState(int newState, int currentState, int reason) {
- mCallback.onStateChanged(newState, reason);
+ mSoftApCallback.onStateChanged(newState, reason);
//send the AP state change broadcast
final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
@@ -237,45 +246,91 @@ public class SoftApManager implements ActiveModeManager {
}
intent.putExtra(WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME, mApInterfaceName);
- intent.putExtra(WifiManager.EXTRA_WIFI_AP_MODE, mMode);
+ intent.putExtra(WifiManager.EXTRA_WIFI_AP_MODE, mApConfig.getTargetMode());
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- /**
- * Start a soft AP instance with the given configuration.
- * @param config AP configuration
- * @return integer result code
- */
- private int startSoftAp(WifiConfiguration config) {
- if (config == null || config.SSID == null) {
- Log.e(TAG, "Unable to start soft AP without valid configuration");
+ private int setMacAddress() {
+ boolean randomize = mContext.getResources().getBoolean(
+ R.bool.config_wifi_ap_mac_randomization_supported);
+ if (!randomize) {
+ MacAddress mac = mWifiNative.getFactoryMacAddress(mApInterfaceName);
+ if (mac == null) {
+ Log.e(TAG, "failed to get factory MAC address");
+ return ERROR_GENERIC;
+ }
+
+ // We're (re-)configuring the factory MAC address. Some drivers may not support setting
+ // the MAC at all, so fail soft in this case.
+ if (!mWifiNative.setMacAddress(mApInterfaceName, mac)) {
+ Log.w(TAG, "failed to reset to factory MAC address; continuing with current MAC");
+ }
+ return SUCCESS;
+ }
+
+ // We're configuring a random MAC address. In this case, driver support is mandatory.
+ MacAddress mac = MacAddress.createRandomUnicastAddress();
+ if (!mWifiNative.setMacAddress(mApInterfaceName, mac)) {
+ Log.e(TAG, "failed to set random MAC address");
return ERROR_GENERIC;
}
- // Setup country code
+ return SUCCESS;
+ }
+
+ private int setCountryCode() {
+ int band = mApConfig.getWifiConfiguration().apBand;
if (TextUtils.isEmpty(mCountryCode)) {
- if (config.apBand == WifiConfiguration.AP_BAND_5GHZ) {
+ if (band == WifiConfiguration.AP_BAND_5GHZ) {
// Country code is mandatory for 5GHz band.
- Log.e(TAG, "Invalid country code, required for setting up "
- + "soft ap in 5GHz");
+ Log.e(TAG, "Invalid country code, required for setting up soft ap in 5GHz");
return ERROR_GENERIC;
}
// Absence of country code is not fatal for 2Ghz & Any band options.
- } else if (!mWifiNative.setCountryCodeHal(
+ return SUCCESS;
+ }
+
+ if (!mWifiNative.setCountryCodeHal(
mApInterfaceName, mCountryCode.toUpperCase(Locale.ROOT))) {
- if (config.apBand == WifiConfiguration.AP_BAND_5GHZ) {
+ if (band == WifiConfiguration.AP_BAND_5GHZ) {
// Return an error if failed to set country code when AP is configured for
// 5GHz band.
- Log.e(TAG, "Failed to set country code, required for setting up "
- + "soft ap in 5GHz");
+ Log.e(TAG, "Failed to set country code, required for setting up soft ap in 5GHz");
return ERROR_GENERIC;
}
// Failure to set country code is not fatal for 2Ghz & Any band options.
}
+ return SUCCESS;
+ }
+
+ /**
+ * Start a soft AP instance as configured.
+ *
+ * @return integer result code
+ */
+ private int startSoftAp() {
+ WifiConfiguration config = mApConfig.getWifiConfiguration();
+ if (config == null || config.SSID == null) {
+ Log.e(TAG, "Unable to start soft AP without valid configuration");
+ return ERROR_GENERIC;
+ }
+
+ Log.d(TAG, "band " + config.apBand + " iface "
+ + mApInterfaceName + " country " + mCountryCode);
+
+ int result = setMacAddress();
+ if (result != SUCCESS) {
+ return result;
+ }
+
+ result = setCountryCode();
+ if (result != SUCCESS) {
+ return result;
+ }
// Make a copy of configuration for updating AP band and channel.
WifiConfiguration localConfig = new WifiConfiguration(config);
- int result = ApConfigUtil.updateApChannelConfig(
+ result = ApConfigUtil.updateApChannelConfig(
mWifiNative, mCountryCode,
mWifiApConfigStore.getAllowed2GChannel(), localConfig);
@@ -287,13 +342,14 @@ public class SoftApManager implements ActiveModeManager {
if (localConfig.hiddenSSID) {
Log.d(TAG, "SoftAP is a hidden network");
}
+
if (!mWifiNative.startSoftAp(mApInterfaceName, localConfig, mSoftApListener)) {
Log.e(TAG, "Soft AP start failed");
return ERROR_GENERIC;
}
mWifiDiagnostics.startLogging(mApInterfaceName);
- mStartTimestamp = SystemClock.elapsedRealtime();
- Log.d(TAG, "Soft AP is started");
+ mStartTimestamp = FORMATTER.format(new Date(System.currentTimeMillis()));
+ Log.d(TAG, "Soft AP is started ");
return SUCCESS;
}
@@ -312,7 +368,7 @@ public class SoftApManager implements ActiveModeManager {
public static final int CMD_START = 0;
public static final int CMD_FAILURE = 2;
public static final int CMD_INTERFACE_STATUS_CHANGED = 3;
- public static final int CMD_NUM_ASSOCIATED_STATIONS_CHANGED = 4;
+ public static final int CMD_ASSOCIATED_STATIONS_CHANGED = 4;
public static final int CMD_NO_ASSOCIATED_STATIONS_TIMEOUT = 5;
public static final int CMD_TIMEOUT_TOGGLE_CHANGED = 6;
public static final int CMD_INTERFACE_DESTROYED = 7;
@@ -376,21 +432,23 @@ public class SoftApManager implements ActiveModeManager {
WifiManager.SAP_START_FAILURE_GENERAL);
mWifiMetrics.incrementSoftApStartResult(
false, WifiManager.SAP_START_FAILURE_GENERAL);
+ mModeListener.onStartFailure();
break;
}
updateApState(WifiManager.WIFI_AP_STATE_ENABLING,
WifiManager.WIFI_AP_STATE_DISABLED, 0);
- int result = startSoftAp((WifiConfiguration) message.obj);
+ int result = startSoftAp();
if (result != SUCCESS) {
int failureReason = WifiManager.SAP_START_FAILURE_GENERAL;
if (result == ERROR_NO_CHANNEL) {
failureReason = WifiManager.SAP_START_FAILURE_NO_CHANNEL;
}
updateApState(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.WIFI_AP_STATE_ENABLING,
- failureReason);
+ WifiManager.WIFI_AP_STATE_ENABLING,
+ failureReason);
stopSoftAp();
mWifiMetrics.incrementSoftApStartResult(false, failureReason);
+ mModeListener.onStartFailure();
break;
}
transitionTo(mStartedState);
@@ -410,8 +468,8 @@ public class SoftApManager implements ActiveModeManager {
private SoftApTimeoutEnabledSettingObserver mSettingObserver;
/**
- * Observer for timeout settings changes.
- */
+ * Observer for timeout settings changes.
+ */
private class SoftApTimeoutEnabledSettingObserver extends ContentObserver {
SoftApTimeoutEnabledSettingObserver(Handler handler) {
super(handler);
@@ -467,49 +525,76 @@ public class SoftApManager implements ActiveModeManager {
}
/**
- * Set number of stations associated with this soft AP
- * @param numStations Number of connected stations
+ * Set stations associated with this soft AP
+ * @param clients The connected stations
*/
- private void setNumAssociatedStations(int numStations) {
- if (mNumAssociatedStations == numStations) {
+ private void setConnectedClients(List<NativeWifiClient> clients) {
+ if (clients == null) {
return;
}
- mNumAssociatedStations = numStations;
- Log.d(TAG, "Number of associated stations changed: " + mNumAssociatedStations);
- if (mCallback != null) {
- mCallback.onNumClientsChanged(mNumAssociatedStations);
+ List<WifiClient> convertedClients = createWifiClients(clients);
+ if (mConnectedClients.equals(convertedClients)) {
+ return;
+ }
+
+ mConnectedClients = new ArrayList<>(convertedClients);
+ Log.d(TAG, "The connected wifi stations have changed with count: "
+ + clients.size());
+
+ if (mSoftApCallback != null) {
+ mSoftApCallback.onConnectedClientsChanged(mConnectedClients);
} else {
- Log.e(TAG, "SoftApCallback is null. Dropping NumClientsChanged event.");
+ Log.e(TAG,
+ "SoftApCallback is null. Dropping ConnectedClientsChanged event."
+ );
}
- mWifiMetrics.addSoftApNumAssociatedStationsChangedEvent(mNumAssociatedStations,
- mMode);
- if (mNumAssociatedStations == 0) {
+ mWifiMetrics.addSoftApNumAssociatedStationsChangedEvent(
+ mConnectedClients.size(), mApConfig.getTargetMode());
+
+ if (mConnectedClients.size() == 0) {
scheduleTimeoutMessage();
} else {
cancelTimeoutMessage();
}
}
+ private List<WifiClient> createWifiClients(List<NativeWifiClient> nativeClients) {
+ List<WifiClient> clients = new ArrayList<>();
+ if (nativeClients == null || nativeClients.size() == 0) {
+ return clients;
+ }
+
+ for (int i = 0; i < nativeClients.size(); i++) {
+ MacAddress macAddress = MacAddress.fromBytes(nativeClients.get(i).macAddress);
+ WifiClient client = new WifiClient(macAddress);
+ clients.add(client);
+ }
+
+ return clients;
+ }
+
private void onUpChanged(boolean isUp) {
if (isUp == mIfaceIsUp) {
return; // no change
}
+
mIfaceIsUp = isUp;
if (isUp) {
Log.d(TAG, "SoftAp is ready for use");
updateApState(WifiManager.WIFI_AP_STATE_ENABLED,
WifiManager.WIFI_AP_STATE_ENABLING, 0);
+ mModeListener.onStarted();
mWifiMetrics.incrementSoftApStartResult(true, 0);
- if (mCallback != null) {
- mCallback.onNumClientsChanged(mNumAssociatedStations);
+ if (mSoftApCallback != null) {
+ mSoftApCallback.onConnectedClientsChanged(mConnectedClients);
}
} else {
// the interface was up, but goes down
sendMessage(CMD_INTERFACE_DOWN);
}
- mWifiMetrics.addSoftApUpChangedEvent(isUp, mMode);
+ mWifiMetrics.addSoftApUpChangedEvent(isUp, mApConfig.getTargetMode());
}
@Override
@@ -531,8 +616,8 @@ public class SoftApManager implements ActiveModeManager {
mSarManager.setSapWifiState(WifiManager.WIFI_AP_STATE_ENABLED);
- Log.d(TAG, "Resetting num stations on start");
- mNumAssociatedStations = 0;
+ Log.d(TAG, "Resetting connected clients on start");
+ mConnectedClients = new ArrayList<>();
scheduleTimeoutMessage();
}
@@ -546,11 +631,11 @@ public class SoftApManager implements ActiveModeManager {
mSettingObserver.unregister();
}
Log.d(TAG, "Resetting num stations on stop");
- setNumAssociatedStations(0);
+ setConnectedClients(new ArrayList<>());
cancelTimeoutMessage();
// Need this here since we are exiting |Started| state and won't handle any
// future CMD_INTERFACE_STATUS_CHANGED events after this point
- mWifiMetrics.addSoftApUpChangedEvent(false, mMode);
+ mWifiMetrics.addSoftApUpChangedEvent(false, mApConfig.getTargetMode());
updateApState(WifiManager.WIFI_AP_STATE_DISABLED,
WifiManager.WIFI_AP_STATE_DISABLING, 0);
@@ -559,17 +644,16 @@ public class SoftApManager implements ActiveModeManager {
mIfaceIsUp = false;
mIfaceIsDestroyed = false;
mStateMachine.quitNow();
+ mModeListener.onStopped();
}
private void updateUserBandPreferenceViolationMetricsIfNeeded() {
- boolean bandPreferenceViolated = false;
- if (mApConfig.apBand == WifiConfiguration.AP_BAND_2GHZ
- && ScanResult.is5GHz(mReportedFrequency)) {
- bandPreferenceViolated = true;
- } else if (mApConfig.apBand == WifiConfiguration.AP_BAND_5GHZ
- && ScanResult.is24GHz(mReportedFrequency)) {
- bandPreferenceViolated = true;
- }
+ int band = mApConfig.getWifiConfiguration().apBand;
+ boolean bandPreferenceViolated =
+ (band == WifiConfiguration.AP_BAND_2GHZ
+ && ScanResult.is5GHz(mReportedFrequency))
+ || (band == WifiConfiguration.AP_BAND_5GHZ
+ && ScanResult.is24GHz(mReportedFrequency));
if (bandPreferenceViolated) {
Log.e(TAG, "Channel does not satisfy user band preference: "
+ mReportedFrequency);
@@ -580,13 +664,16 @@ public class SoftApManager implements ActiveModeManager {
@Override
public boolean processMessage(Message message) {
switch (message.what) {
- case CMD_NUM_ASSOCIATED_STATIONS_CHANGED:
- if (message.arg1 < 0) {
- Log.e(TAG, "Invalid number of associated stations: " + message.arg1);
+ case CMD_ASSOCIATED_STATIONS_CHANGED:
+ if (!(message.obj instanceof List)) {
+ Log.e(TAG, "Invalid type returned for"
+ + " CMD_ASSOCIATED_STATIONS_CHANGED");
break;
}
- Log.d(TAG, "Setting num stations on CMD_NUM_ASSOCIATED_STATIONS_CHANGED");
- setNumAssociatedStations(message.arg1);
+
+ Log.d(TAG, "Setting connected stations on"
+ + " CMD_ASSOCIATED_STATIONS_CHANGED");
+ setConnectedClients((List<NativeWifiClient>) message.obj);
break;
case CMD_SOFT_AP_CHANNEL_SWITCHED:
mReportedFrequency = message.arg1;
@@ -594,7 +681,7 @@ public class SoftApManager implements ActiveModeManager {
Log.d(TAG, "Channel switched. Frequency: " + mReportedFrequency
+ " Bandwidth: " + mReportedBandwidth);
mWifiMetrics.addSoftApChannelSwitchedEvent(mReportedFrequency,
- mReportedBandwidth, mMode);
+ mReportedBandwidth, mApConfig.getTargetMode());
updateUserBandPreferenceViolationMetricsIfNeeded();
break;
case CMD_TIMEOUT_TOGGLE_CHANGED:
@@ -606,7 +693,7 @@ public class SoftApManager implements ActiveModeManager {
if (!mTimeoutEnabled) {
cancelTimeoutMessage();
}
- if (mTimeoutEnabled && mNumAssociatedStations == 0) {
+ if (mTimeoutEnabled && mConnectedClients.size() == 0) {
scheduleTimeoutMessage();
}
break;
@@ -623,7 +710,7 @@ public class SoftApManager implements ActiveModeManager {
+ " Dropping.");
break;
}
- if (mNumAssociatedStations != 0) {
+ if (mConnectedClients.size() != 0) {
Log.wtf(TAG, "Timeout message received but has clients. Dropping.");
break;
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java
new file mode 100644
index 0000000000..124d252cb2
--- /dev/null
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.wifi;
+
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQP3GPPNetwork;
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPDomName;
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPIPAddrAvailability;
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPNAIRealm;
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPRoamingConsortium;
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPVenueName;
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSConnCapability;
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSFriendlyName;
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSOSUProviders;
+import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSWANMetrics;
+
+import android.annotation.NonNull;
+import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
+import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
+import android.util.Log;
+
+import com.android.server.wifi.hotspot2.AnqpEvent;
+import com.android.server.wifi.hotspot2.IconEvent;
+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.NativeUtil;
+
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+abstract class SupplicantStaIfaceCallbackImpl extends ISupplicantStaIfaceCallback.Stub {
+ private static final String TAG = SupplicantStaIfaceCallbackImpl.class.getSimpleName();
+ private final SupplicantStaIfaceHal mStaIfaceHal;
+ private final String mIfaceName;
+ private final Object mLock;
+ private final WifiMonitor mWifiMonitor;
+ private boolean mStateIsFourway = false; // Used to help check for PSK password mismatch
+
+ SupplicantStaIfaceCallbackImpl(@NonNull SupplicantStaIfaceHal staIfaceHal,
+ @NonNull String ifaceName,
+ @NonNull Object lock,
+ @NonNull WifiMonitor wifiMonitor) {
+ mStaIfaceHal = staIfaceHal;
+ mIfaceName = ifaceName;
+ mLock = lock;
+ mWifiMonitor = wifiMonitor;
+ }
+
+ /**
+ * Converts the supplicant state received from HIDL to the equivalent framework state.
+ */
+ private static SupplicantState supplicantHidlStateToFrameworkState(int state) {
+ switch (state) {
+ case ISupplicantStaIfaceCallback.State.DISCONNECTED:
+ return SupplicantState.DISCONNECTED;
+ case ISupplicantStaIfaceCallback.State.IFACE_DISABLED:
+ return SupplicantState.INTERFACE_DISABLED;
+ case ISupplicantStaIfaceCallback.State.INACTIVE:
+ return SupplicantState.INACTIVE;
+ case ISupplicantStaIfaceCallback.State.SCANNING:
+ return SupplicantState.SCANNING;
+ case ISupplicantStaIfaceCallback.State.AUTHENTICATING:
+ return SupplicantState.AUTHENTICATING;
+ case ISupplicantStaIfaceCallback.State.ASSOCIATING:
+ return SupplicantState.ASSOCIATING;
+ case ISupplicantStaIfaceCallback.State.ASSOCIATED:
+ return SupplicantState.ASSOCIATED;
+ case ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE:
+ return SupplicantState.FOUR_WAY_HANDSHAKE;
+ case ISupplicantStaIfaceCallback.State.GROUP_HANDSHAKE:
+ return SupplicantState.GROUP_HANDSHAKE;
+ case ISupplicantStaIfaceCallback.State.COMPLETED:
+ return SupplicantState.COMPLETED;
+ default:
+ throw new IllegalArgumentException("Invalid state: " + state);
+ }
+ }
+
+
+ /**
+ * Parses the provided payload into an ANQP element.
+ *
+ * @param infoID Element type.
+ * @param payload Raw payload bytes.
+ * @return AnqpElement instance on success, null on failure.
+ */
+ private ANQPElement parseAnqpElement(Constants.ANQPElementType infoID,
+ ArrayList<Byte> payload) {
+ synchronized (mLock) {
+ try {
+ return Constants.getANQPElementID(infoID) != null
+ ? ANQPParser.parseElement(
+ infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)))
+ : ANQPParser.parseHS20Element(
+ infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)));
+ } catch (IOException | BufferUnderflowException e) {
+ Log.e(TAG, "Failed parsing ANQP element payload: " + infoID, e);
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Parse the ANQP element data and add to the provided elements map if successful.
+ *
+ * @param elementsMap Map to add the parsed out element to.
+ * @param infoID Element type.
+ * @param payload Raw payload bytes.
+ */
+ private void addAnqpElementToMap(Map<Constants.ANQPElementType, ANQPElement> elementsMap,
+ Constants.ANQPElementType infoID,
+ ArrayList<Byte> payload) {
+ synchronized (mLock) {
+ if (payload == null || payload.isEmpty()) return;
+ ANQPElement element = parseAnqpElement(infoID, payload);
+ if (element != null) {
+ elementsMap.put(infoID, element);
+ }
+ }
+ }
+
+ @Override
+ public void onNetworkAdded(int id) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onNetworkAdded");
+ }
+ }
+
+ @Override
+ public void onNetworkRemoved(int id) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onNetworkRemoved");
+ // Reset 4way handshake state since network has been removed.
+ mStateIsFourway = false;
+ }
+ }
+
+ @Override
+ public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
+ ArrayList<Byte> ssid) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onStateChanged");
+ SupplicantState newSupplicantState =
+ supplicantHidlStateToFrameworkState(newState);
+ WifiSsid wifiSsid =
+ WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
+ String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
+ mStateIsFourway = (newState == ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE);
+ if (newSupplicantState == SupplicantState.COMPLETED) {
+ mWifiMonitor.broadcastNetworkConnectionEvent(
+ mIfaceName, mStaIfaceHal.getCurrentNetworkId(mIfaceName), bssidStr);
+ }
+ mWifiMonitor.broadcastSupplicantStateChangeEvent(
+ mIfaceName, mStaIfaceHal.getCurrentNetworkId(mIfaceName), wifiSsid,
+ bssidStr, newSupplicantState);
+ }
+ }
+
+ @Override
+ public void onAnqpQueryDone(byte[/* 6 */] bssid,
+ ISupplicantStaIfaceCallback.AnqpData data,
+ ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onAnqpQueryDone");
+ Map<Constants.ANQPElementType, ANQPElement> elementsMap = new HashMap<>();
+ addAnqpElementToMap(elementsMap, ANQPVenueName, data.venueName);
+ addAnqpElementToMap(elementsMap, ANQPRoamingConsortium, data.roamingConsortium);
+ addAnqpElementToMap(
+ elementsMap, ANQPIPAddrAvailability, data.ipAddrTypeAvailability);
+ addAnqpElementToMap(elementsMap, ANQPNAIRealm, data.naiRealm);
+ addAnqpElementToMap(elementsMap, ANQP3GPPNetwork, data.anqp3gppCellularNetwork);
+ addAnqpElementToMap(elementsMap, ANQPDomName, data.domainName);
+ addAnqpElementToMap(elementsMap, HSFriendlyName, hs20Data.operatorFriendlyName);
+ addAnqpElementToMap(elementsMap, HSWANMetrics, hs20Data.wanMetrics);
+ addAnqpElementToMap(elementsMap, HSConnCapability, hs20Data.connectionCapability);
+ addAnqpElementToMap(elementsMap, HSOSUProviders, hs20Data.osuProvidersList);
+ mWifiMonitor.broadcastAnqpDoneEvent(
+ mIfaceName, new AnqpEvent(NativeUtil.macAddressToLong(bssid), elementsMap));
+ }
+ }
+
+ @Override
+ public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
+ ArrayList<Byte> data) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onHs20IconQueryDone");
+ mWifiMonitor.broadcastIconDoneEvent(
+ mIfaceName,
+ new IconEvent(NativeUtil.macAddressToLong(bssid), fileName, data.size(),
+ NativeUtil.byteArrayFromArrayList(data)));
+ }
+ }
+
+ @Override
+ public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid, byte osuMethod, String url) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onHs20SubscriptionRemediation");
+ mWifiMonitor.broadcastWnmEvent(
+ mIfaceName,
+ new WnmData(NativeUtil.macAddressToLong(bssid), url, osuMethod));
+ }
+ }
+
+ @Override
+ public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
+ int reAuthDelayInSec, String url) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onHs20DeauthImminentNotice");
+ mWifiMonitor.broadcastWnmEvent(
+ mIfaceName,
+ new WnmData(NativeUtil.macAddressToLong(bssid), url,
+ reasonCode == WnmData.ESS, reAuthDelayInSec));
+ }
+ }
+
+ @Override
+ public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onDisconnected");
+ if (mStaIfaceHal.isVerboseLoggingEnabled()) {
+ Log.e(TAG, "onDisconnected 4way=" + mStateIsFourway
+ + " locallyGenerated=" + locallyGenerated
+ + " reasonCode=" + reasonCode);
+ }
+ if (mStateIsFourway
+ && (!locallyGenerated || reasonCode != ReasonCode.IE_IN_4WAY_DIFFERS)) {
+ mWifiMonitor.broadcastAuthenticationFailureEvent(
+ mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1);
+ }
+ mWifiMonitor.broadcastNetworkDisconnectionEvent(
+ mIfaceName, locallyGenerated ? 1 : 0, reasonCode,
+ NativeUtil.macAddressFromByteArray(bssid));
+ }
+ }
+
+ @Override
+ public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode, boolean timedOut) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onAssociationRejected");
+
+ if (statusCode == StatusCode.UNSPECIFIED_FAILURE) {
+ WifiConfiguration curConfiguration =
+ mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
+
+ if (curConfiguration != null
+ && curConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.SAE)) {
+ // Special handling for WPA3-Personal networks. If the password is
+ // incorrect, the AP will send association rejection, with status code 1
+ // (unspecified failure). In SAE networks, the password authentication
+ // is not related to the 4-way handshake. In this case, we will send an
+ // authentication failure event up.
+ mStaIfaceHal.logCallback("SAE incorrect password");
+ mWifiMonitor.broadcastAuthenticationFailureEvent(
+ mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1);
+ }
+ }
+ mWifiMonitor
+ .broadcastAssociationRejectionEvent(
+ mIfaceName, statusCode, timedOut,
+ NativeUtil.macAddressFromByteArray(bssid));
+ }
+ }
+
+ @Override
+ public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onAuthenticationTimeout");
+ mWifiMonitor.broadcastAuthenticationFailureEvent(
+ mIfaceName, WifiManager.ERROR_AUTH_FAILURE_TIMEOUT, -1);
+ }
+ }
+
+ @Override
+ public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onBssidChanged");
+ if (reason == BssidChangeReason.ASSOC_START) {
+ mWifiMonitor.broadcastTargetBssidEvent(
+ mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
+ } else if (reason == BssidChangeReason.ASSOC_COMPLETE) {
+ mWifiMonitor.broadcastAssociatedBssidEvent(
+ mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
+ }
+ }
+ }
+
+ @Override
+ public void onEapFailure() {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onEapFailure");
+ mWifiMonitor.broadcastAuthenticationFailureEvent(
+ mIfaceName, WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, -1);
+ }
+ }
+
+ @Override
+ public void onWpsEventSuccess() {
+ mStaIfaceHal.logCallback("onWpsEventSuccess");
+ synchronized (mLock) {
+ mWifiMonitor.broadcastWpsSuccessEvent(mIfaceName);
+ }
+ }
+
+ @Override
+ public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onWpsEventFail");
+ if (configError == WpsConfigError.MSG_TIMEOUT
+ && errorInd == WpsErrorIndication.NO_ERROR) {
+ mWifiMonitor.broadcastWpsTimeoutEvent(mIfaceName);
+ } else {
+ mWifiMonitor.broadcastWpsFailEvent(mIfaceName, configError, errorInd);
+ }
+ }
+ }
+
+ @Override
+ public void onWpsEventPbcOverlap() {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onWpsEventPbcOverlap");
+ mWifiMonitor.broadcastWpsOverlapEvent(mIfaceName);
+ }
+ }
+
+ @Override
+ public void onExtRadioWorkStart(int id) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onExtRadioWorkStart");
+ }
+ }
+
+ @Override
+ public void onExtRadioWorkTimeout(int id) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onExtRadioWorkTimeout");
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_1Impl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_1Impl.java
new file mode 100644
index 0000000000..12e025e69f
--- /dev/null
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_1Impl.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.wifi;
+
+import android.annotation.NonNull;
+import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
+import android.net.wifi.WifiManager;
+
+import java.util.ArrayList;
+
+abstract class SupplicantStaIfaceCallbackV1_1Impl extends
+ android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback.Stub {
+ private static final String TAG = SupplicantStaIfaceCallbackV1_1Impl.class.getSimpleName();
+ private final SupplicantStaIfaceHal mStaIfaceHal;
+ private final String mIfaceName;
+ private final Object mLock;
+ private final WifiMonitor mWifiMonitor;
+ private final SupplicantStaIfaceHal.SupplicantStaIfaceHalCallback mCallbackV10;
+
+ SupplicantStaIfaceCallbackV1_1Impl(@NonNull SupplicantStaIfaceHal staIfaceHal,
+ @NonNull String ifaceName,
+ @NonNull Object lock,
+ @NonNull WifiMonitor wifiMonitor) {
+ mStaIfaceHal = staIfaceHal;
+ mIfaceName = ifaceName;
+ mLock = lock;
+ mWifiMonitor = wifiMonitor;
+ // Create an older callback for function delegation,
+ // and it would cascadingly create older one.
+ mCallbackV10 = mStaIfaceHal.new SupplicantStaIfaceHalCallback(mIfaceName);
+ }
+
+ @Override
+ public void onNetworkAdded(int id) {
+ mCallbackV10.onNetworkAdded(id);
+ }
+
+ @Override
+ public void onNetworkRemoved(int id) {
+ mCallbackV10.onNetworkRemoved(id);
+ }
+
+ @Override
+ public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
+ ArrayList<Byte> ssid) {
+ mCallbackV10.onStateChanged(newState, bssid, id, ssid);
+ }
+
+ @Override
+ public void onAnqpQueryDone(byte[/* 6 */] bssid,
+ ISupplicantStaIfaceCallback.AnqpData data,
+ ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
+ mCallbackV10.onAnqpQueryDone(bssid, data, hs20Data);
+ }
+
+ @Override
+ public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
+ ArrayList<Byte> data) {
+ mCallbackV10.onHs20IconQueryDone(bssid, fileName, data);
+ }
+
+ @Override
+ public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid,
+ byte osuMethod, String url) {
+ mCallbackV10.onHs20SubscriptionRemediation(bssid, osuMethod, url);
+ }
+
+ @Override
+ public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
+ int reAuthDelayInSec, String url) {
+ mCallbackV10.onHs20DeauthImminentNotice(bssid, reasonCode, reAuthDelayInSec, url);
+ }
+
+ @Override
+ public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated,
+ int reasonCode) {
+ mCallbackV10.onDisconnected(bssid, locallyGenerated, reasonCode);
+ }
+
+ @Override
+ public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode,
+ boolean timedOut) {
+ mCallbackV10.onAssociationRejected(bssid, statusCode, timedOut);
+ }
+
+ @Override
+ public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
+ mCallbackV10.onAuthenticationTimeout(bssid);
+ }
+
+ @Override
+ public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
+ mCallbackV10.onBssidChanged(reason, bssid);
+ }
+
+ @Override
+ public void onEapFailure() {
+ mCallbackV10.onEapFailure();
+ }
+
+ @Override
+ public void onEapFailure_1_1(int code) {
+ synchronized (mLock) {
+ mStaIfaceHal.logCallback("onEapFailure_1_1");
+ mWifiMonitor.broadcastAuthenticationFailureEvent(
+ mIfaceName, WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, code);
+ }
+ }
+
+ @Override
+ public void onWpsEventSuccess() {
+ mCallbackV10.onWpsEventSuccess();
+ }
+
+ @Override
+ public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
+ mCallbackV10.onWpsEventFail(bssid, configError, errorInd);
+ }
+
+ @Override
+ public void onWpsEventPbcOverlap() {
+ mCallbackV10.onWpsEventPbcOverlap();
+ }
+
+ @Override
+ public void onExtRadioWorkStart(int id) {
+ mCallbackV10.onExtRadioWorkStart(id);
+ }
+
+ @Override
+ public void onExtRadioWorkTimeout(int id) {
+ mCallbackV10.onExtRadioWorkTimeout(id);
+ }
+}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_2Impl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_2Impl.java
new file mode 100644
index 0000000000..b80911736c
--- /dev/null
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_2Impl.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.wifi;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
+import android.hardware.wifi.supplicant.V1_2.DppAkm;
+import android.hardware.wifi.supplicant.V1_2.DppFailureCode;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiSsid;
+import android.os.Process;
+import android.util.Log;
+
+import com.android.server.wifi.util.NativeUtil;
+
+import java.util.ArrayList;
+
+abstract class SupplicantStaIfaceCallbackV1_2Impl extends
+ android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback.Stub {
+ private static final String TAG = SupplicantStaIfaceCallbackV1_2Impl.class.getSimpleName();
+ private final SupplicantStaIfaceHal mStaIfaceHal;
+ private final String mIfaceName;
+ private final Context mContext;
+ private final SupplicantStaIfaceHal.SupplicantStaIfaceHalCallbackV1_1 mCallbackV11;
+
+ SupplicantStaIfaceCallbackV1_2Impl(@NonNull SupplicantStaIfaceHal staIfaceHal,
+ @NonNull String ifaceName,
+ @NonNull Context context) {
+ mStaIfaceHal = staIfaceHal;
+ mIfaceName = ifaceName;
+ mContext = context;
+ // Create an older callback for function delegation,
+ // and it would cascadingly create older one.
+ mCallbackV11 = mStaIfaceHal.new SupplicantStaIfaceHalCallbackV1_1(mIfaceName);
+ }
+
+ @Override
+ public void onNetworkAdded(int id) {
+ mCallbackV11.onNetworkAdded(id);
+ }
+
+ @Override
+ public void onNetworkRemoved(int id) {
+ mCallbackV11.onNetworkRemoved(id);
+ }
+
+ @Override
+ public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
+ ArrayList<Byte> ssid) {
+ mCallbackV11.onStateChanged(newState, bssid, id, ssid);
+ }
+
+ @Override
+ public void onAnqpQueryDone(byte[/* 6 */] bssid,
+ ISupplicantStaIfaceCallback.AnqpData data,
+ ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
+ mCallbackV11.onAnqpQueryDone(bssid, data, hs20Data);
+ }
+
+ @Override
+ public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
+ ArrayList<Byte> data) {
+ mCallbackV11.onHs20IconQueryDone(bssid, fileName, data);
+ }
+
+ @Override
+ public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid,
+ byte osuMethod, String url) {
+ mCallbackV11.onHs20SubscriptionRemediation(bssid, osuMethod, url);
+ }
+
+ @Override
+ public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
+ int reAuthDelayInSec, String url) {
+ mCallbackV11.onHs20DeauthImminentNotice(bssid, reasonCode, reAuthDelayInSec, url);
+ }
+
+ @Override
+ public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated,
+ int reasonCode) {
+ mCallbackV11.onDisconnected(bssid, locallyGenerated, reasonCode);
+ }
+
+ @Override
+ public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode,
+ boolean timedOut) {
+ mCallbackV11.onAssociationRejected(bssid, statusCode, timedOut);
+ }
+
+ @Override
+ public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
+ mCallbackV11.onAuthenticationTimeout(bssid);
+ }
+
+ @Override
+ public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
+ mCallbackV11.onBssidChanged(reason, bssid);
+ }
+
+ @Override
+ public void onEapFailure() {
+ mCallbackV11.onEapFailure();
+ }
+
+ @Override
+ public void onEapFailure_1_1(int code) {
+ mCallbackV11.onEapFailure_1_1(code);
+ }
+
+ @Override
+ public void onWpsEventSuccess() {
+ mCallbackV11.onWpsEventSuccess();
+ }
+
+ @Override
+ public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
+ mCallbackV11.onWpsEventFail(bssid, configError, errorInd);
+ }
+
+ @Override
+ public void onWpsEventPbcOverlap() {
+ mCallbackV11.onWpsEventPbcOverlap();
+ }
+
+ @Override
+ public void onExtRadioWorkStart(int id) {
+ mCallbackV11.onExtRadioWorkStart(id);
+ }
+
+ @Override
+ public void onExtRadioWorkTimeout(int id) {
+ mCallbackV11.onExtRadioWorkTimeout(id);
+ }
+
+ @Override
+ public void onDppSuccessConfigReceived(ArrayList<Byte> ssid, String password,
+ byte[] psk, int securityAkm) {
+ if (mStaIfaceHal.getDppCallback() == null) {
+ Log.e(TAG, "onDppSuccessConfigReceived callback is null");
+ return;
+ }
+
+ WifiConfiguration newWifiConfiguration = new WifiConfiguration();
+
+ // Set up SSID
+ WifiSsid wifiSsid =
+ WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
+
+ newWifiConfiguration.SSID = "\"" + wifiSsid.toString() + "\"";
+
+ // Set up password or PSK
+ if (password != null) {
+ newWifiConfiguration.preSharedKey = "\"" + password + "\"";
+ } else if (psk != null) {
+ newWifiConfiguration.preSharedKey = psk.toString();
+ }
+
+ // Set up key management: SAE or PSK
+ if (securityAkm == DppAkm.SAE || securityAkm == DppAkm.PSK_SAE) {
+ newWifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
+ newWifiConfiguration.requirePMF = true;
+ } else if (securityAkm == DppAkm.PSK) {
+ newWifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ } else {
+ // No other AKMs are currently supported
+ onDppFailure(DppFailureCode.NOT_SUPPORTED);
+ return;
+ }
+
+ // Set up default values
+ newWifiConfiguration.creatorName = mContext.getPackageManager()
+ .getNameForUid(Process.WIFI_UID);
+ newWifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+ newWifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ newWifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ newWifiConfiguration.status = WifiConfiguration.Status.ENABLED;
+
+ mStaIfaceHal.getDppCallback().onSuccessConfigReceived(newWifiConfiguration);
+ }
+
+ @Override
+ public void onDppSuccessConfigSent() {
+ if (mStaIfaceHal.getDppCallback() != null) {
+ mStaIfaceHal.getDppCallback().onSuccessConfigSent();
+ } else {
+ Log.e(TAG, "onSuccessConfigSent callback is null");
+ }
+ }
+
+ @Override
+ public void onDppProgress(int code) {
+ if (mStaIfaceHal.getDppCallback() != null) {
+ mStaIfaceHal.getDppCallback().onProgress(code);
+ } else {
+ Log.e(TAG, "onDppProgress callback is null");
+ }
+ }
+
+ @Override
+ public void onDppFailure(int code) {
+ if (mStaIfaceHal.getDppCallback() != null) {
+ mStaIfaceHal.getDppCallback().onFailure(code);
+ } else {
+ Log.e(TAG, "onDppFailure callback is null");
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_3Impl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_3Impl.java
new file mode 100644
index 0000000000..97b984a7a5
--- /dev/null
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackV1_3Impl.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.wifi;
+
+import android.annotation.NonNull;
+import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
+
+import java.util.ArrayList;
+
+abstract class SupplicantStaIfaceCallbackV1_3Impl extends
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback.Stub {
+ private static final String TAG = SupplicantStaIfaceCallbackV1_3Impl.class.getSimpleName();
+ private final SupplicantStaIfaceHal mStaIfaceHal;
+ private final String mIfaceName;
+ private final SupplicantStaIfaceHal.SupplicantStaIfaceHalCallbackV1_2 mCallbackV12;
+
+ SupplicantStaIfaceCallbackV1_3Impl(@NonNull SupplicantStaIfaceHal staIfaceHal,
+ @NonNull String ifaceName) {
+ mStaIfaceHal = staIfaceHal;
+ mIfaceName = ifaceName;
+ // Create an older callback for function delegation,
+ // and it would cascadingly create older one.
+ mCallbackV12 = mStaIfaceHal.new SupplicantStaIfaceHalCallbackV1_2(mIfaceName);
+ }
+
+ @Override
+ public void onNetworkAdded(int id) {
+ mCallbackV12.onNetworkAdded(id);
+ }
+
+ @Override
+ public void onNetworkRemoved(int id) {
+ mCallbackV12.onNetworkRemoved(id);
+ }
+
+ @Override
+ public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
+ ArrayList<Byte> ssid) {
+ mCallbackV12.onStateChanged(newState, bssid, id, ssid);
+ }
+
+ @Override
+ public void onAnqpQueryDone(byte[/* 6 */] bssid,
+ ISupplicantStaIfaceCallback.AnqpData data,
+ ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
+ mCallbackV12.onAnqpQueryDone(bssid, data, hs20Data);
+ }
+
+ @Override
+ public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
+ ArrayList<Byte> data) {
+ mCallbackV12.onHs20IconQueryDone(bssid, fileName, data);
+ }
+
+ @Override
+ public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid,
+ byte osuMethod, String url) {
+ mCallbackV12.onHs20SubscriptionRemediation(bssid, osuMethod, url);
+ }
+
+ @Override
+ public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
+ int reAuthDelayInSec, String url) {
+ mCallbackV12.onHs20DeauthImminentNotice(bssid, reasonCode, reAuthDelayInSec, url);
+ }
+
+ @Override
+ public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated,
+ int reasonCode) {
+ mCallbackV12.onDisconnected(bssid, locallyGenerated, reasonCode);
+ }
+
+ @Override
+ public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode,
+ boolean timedOut) {
+ mCallbackV12.onAssociationRejected(bssid, statusCode, timedOut);
+ }
+
+ @Override
+ public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
+ mCallbackV12.onAuthenticationTimeout(bssid);
+ }
+
+ @Override
+ public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
+ mCallbackV12.onBssidChanged(reason, bssid);
+ }
+
+ @Override
+ public void onEapFailure() {
+ mCallbackV12.onEapFailure();
+ }
+
+ @Override
+ public void onEapFailure_1_1(int code) {
+ mCallbackV12.onEapFailure_1_1(code);
+ }
+
+ @Override
+ public void onWpsEventSuccess() {
+ mCallbackV12.onWpsEventSuccess();
+ }
+
+ @Override
+ public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
+ mCallbackV12.onWpsEventFail(bssid, configError, errorInd);
+ }
+
+ @Override
+ public void onWpsEventPbcOverlap() {
+ mCallbackV12.onWpsEventPbcOverlap();
+ }
+
+ @Override
+ public void onExtRadioWorkStart(int id) {
+ mCallbackV12.onExtRadioWorkStart(id);
+ }
+
+ @Override
+ public void onExtRadioWorkTimeout(int id) {
+ mCallbackV12.onExtRadioWorkTimeout(id);
+ }
+
+ @Override
+ public void onDppSuccessConfigReceived(ArrayList<Byte> ssid, String password,
+ byte[] psk, int securityAkm) {
+ mCallbackV12.onDppSuccessConfigReceived(
+ ssid, password, psk, securityAkm);
+ }
+
+ @Override
+ public void onDppSuccessConfigSent() {
+ mCallbackV12.onDppSuccessConfigSent();
+ }
+
+ @Override
+ public void onDppProgress(int code) {
+ mCallbackV12.onDppProgress(code);
+ }
+
+ @Override
+ public void onDppFailure(int code) {
+ mCallbackV12.onDppFailure(code);
+ }
+
+ @Override
+ public void onPmkCacheAdded(long expirationTimeInSec, ArrayList<Byte> serializedEntry) {
+ int curNetworkId = mStaIfaceHal.getCurrentNetworkId(mIfaceName);
+ mStaIfaceHal.addPmkCacheEntry(curNetworkId, expirationTimeInSec, serializedEntry);
+ mStaIfaceHal.logCallback(
+ "onPmkCacheAdded: update pmk cache for config id " + curNetworkId);
+ }
+}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
index 86518c7613..8db806e597 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
@@ -20,17 +20,6 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQP3GPPNetwork;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPDomName;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPIPAddrAvailability;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPNAIRealm;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPRoamingConsortium;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPVenueName;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSConnCapability;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSFriendlyName;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSOSUProviders;
-import static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSWANMetrics;
-
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.wifi.supplicant.V1_0.ISupplicant;
@@ -43,46 +32,32 @@ import android.hardware.wifi.supplicant.V1_0.IfaceType;
import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
-import android.hardware.wifi.supplicant.V1_2.DppAkm;
-import android.hardware.wifi.supplicant.V1_2.DppFailureCode;
+import android.hardware.wifi.supplicant.V1_3.ConnectionCapabilities;
+import android.hardware.wifi.supplicant.V1_3.WifiTechnology;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
-import android.net.IpConfiguration;
-import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiSsid;
+import android.net.wifi.WifiInfo;
import android.os.Handler;
-import android.os.HidlSupport.Mutable;
import android.os.HwRemoteBinder;
-import android.os.Looper;
-import android.os.Process;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import android.util.MutableBoolean;
import android.util.MutableInt;
import android.util.Pair;
-import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.WifiNative.DppEventCallback;
import com.android.server.wifi.WifiNative.SupplicantDeathEventHandler;
-import com.android.server.wifi.hotspot2.AnqpEvent;
-import com.android.server.wifi.hotspot2.IconEvent;
-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.GeneralUtil.Mutable;
import com.android.server.wifi.util.NativeUtil;
-import java.io.IOException;
-import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
+import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
@@ -113,6 +88,8 @@ public class SupplicantStaIfaceHal {
public static final String INIT_SERVICE_NAME = "wpa_supplicant";
@VisibleForTesting
public static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L;
+ @VisibleForTesting
+ static final String PMK_CACHE_EXPIRATION_ALARM_TAG = "PMK_CACHE_EXPIRATION_TIMER";
/**
* Regex pattern for extracting the wps device type bytes.
* Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
@@ -131,6 +108,8 @@ public class SupplicantStaIfaceHal {
new HashMap<>();
private HashMap<String, SupplicantStaNetworkHal> mCurrentNetworkRemoteHandles = new HashMap<>();
private HashMap<String, WifiConfiguration> mCurrentNetworkLocalConfigs = new HashMap<>();
+ @VisibleForTesting
+ HashMap<Integer, PmkCacheStoreData> mPmkCacheEntries = new HashMap<>();
private SupplicantDeathEventHandler mDeathEventHandler;
private ServiceManagerDeathRecipient mServiceManagerDeathRecipient;
private SupplicantDeathRecipient mSupplicantDeathRecipient;
@@ -141,6 +120,7 @@ public class SupplicantStaIfaceHal {
private final PropertyService mPropertyService;
private final Handler mEventHandler;
private DppEventCallback mDppCallback = null;
+ private final Clock mClock;
private final IServiceNotification mServiceNotificationCallback =
new IServiceNotification.Stub() {
@@ -183,12 +163,25 @@ public class SupplicantStaIfaceHal {
}
}
+ @VisibleForTesting
+ static class PmkCacheStoreData {
+ public long expirationTimeInSec;
+ public ArrayList<Byte> data;
+
+ PmkCacheStoreData(long timeInSec, ArrayList<Byte> serializedData) {
+ expirationTimeInSec = timeInSec;
+ data = serializedData;
+ }
+ }
+
public SupplicantStaIfaceHal(Context context, WifiMonitor monitor,
- PropertyService propertyService, Looper looper) {
+ PropertyService propertyService, Handler handler,
+ Clock clock) {
mContext = context;
mWifiMonitor = monitor;
mPropertyService = propertyService;
- mEventHandler = new Handler(looper);
+ mEventHandler = handler;
+ mClock = clock;
mServiceManagerDeathRecipient = new ServiceManagerDeathRecipient();
mSupplicantDeathRecipient = new SupplicantDeathRecipient();
@@ -205,6 +198,10 @@ public class SupplicantStaIfaceHal {
}
}
+ protected boolean isVerboseLoggingEnabled() {
+ return mVerboseLoggingEnabled;
+ }
+
private boolean linkToServiceManagerDeath() {
synchronized (mLock) {
if (mIServiceManager == null) return false;
@@ -307,7 +304,7 @@ public class SupplicantStaIfaceHal {
return true;
}
- private int getCurrentNetworkId(@NonNull String ifaceName) {
+ protected int getCurrentNetworkId(@NonNull String ifaceName) {
synchronized (mLock) {
WifiConfiguration currentConfig = getCurrentNetworkLocalConfig(ifaceName);
if (currentConfig == null) {
@@ -317,6 +314,94 @@ public class SupplicantStaIfaceHal {
}
}
+ private boolean trySetupStaIfaceV1_3(@NonNull String ifaceName,
+ @NonNull ISupplicantStaIface iface) throws RemoteException {
+ if (!isV1_3()) return false;
+
+ SupplicantStaIfaceHalCallbackV1_3 callbackV13 =
+ new SupplicantStaIfaceHalCallbackV1_3(ifaceName);
+ if (!registerCallbackV1_3(getStaIfaceMockableV1_3(iface), callbackV13)) {
+ throw new RemoteException("Init StaIface V1_3 failed.");
+ }
+ /* keep this in a store to avoid recycling by garbage collector. */
+ mISupplicantStaIfaceCallbacks.put(ifaceName, callbackV13);
+ return true;
+ }
+
+ private boolean trySetupStaIfaceV1_2(@NonNull String ifaceName,
+ @NonNull ISupplicantStaIface iface) throws RemoteException {
+ if (!isV1_2()) return false;
+
+ /* try newer version fist. */
+ if (trySetupStaIfaceV1_3(ifaceName, iface)) {
+ logd("Newer HAL is found, skip V1_2 remaining init flow.");
+ return true;
+ }
+
+ SupplicantStaIfaceHalCallbackV1_2 callbackV12 =
+ new SupplicantStaIfaceHalCallbackV1_2(ifaceName);
+ if (!registerCallbackV1_2(getStaIfaceMockableV1_2(iface), callbackV12)) {
+ throw new RemoteException("Init StaIface V1_2 failed.");
+ }
+ /* keep this in a store to avoid recycling by garbage collector. */
+ mISupplicantStaIfaceCallbacks.put(ifaceName, callbackV12);
+ return true;
+ }
+
+ private boolean trySetupStaIfaceV1_1(@NonNull String ifaceName,
+ @NonNull ISupplicantStaIface iface) throws RemoteException {
+ if (!isV1_1()) return false;
+
+ /* try newer version fist. */
+ if (trySetupStaIfaceV1_2(ifaceName, iface)) {
+ logd("Newer HAL is found, skip V1_1 remaining init flow.");
+ return true;
+ }
+
+ SupplicantStaIfaceHalCallbackV1_1 callbackV11 =
+ new SupplicantStaIfaceHalCallbackV1_1(ifaceName);
+ if (!registerCallbackV1_1(getStaIfaceMockableV1_1(iface), callbackV11)) {
+ throw new RemoteException("Init StaIface V1_1 failed.");
+ }
+ /* keep this in a store to avoid recycling by garbage collector. */
+ mISupplicantStaIfaceCallbacks.put(ifaceName, callbackV11);
+ return true;
+ }
+
+ /**
+ * Helper function to set up StaIface with different HAL version.
+ *
+ * This helper function would try newer version recursively.
+ * Once the latest version is found, it would register the callback
+ * of the latest version and skip unnecessary older HAL init flow.
+ *
+ * New version callback will be extended from the older one, as a result,
+ * older callback is always created regardless of the latest version.
+ *
+ * Uprev steps:
+ * 1. add new helper function trySetupStaIfaceV1_Y.
+ * 2. call newly added function in trySetupStaIfaceV1_X (X should be Y-1).
+ */
+ private ISupplicantStaIface setupStaIface(@NonNull String ifaceName,
+ @NonNull ISupplicantIface ifaceHwBinder) throws RemoteException {
+ /* Prepare base type for later cast. */
+ ISupplicantStaIface iface = getStaIfaceMockable(ifaceHwBinder);
+
+ /* try newer version first. */
+ if (trySetupStaIfaceV1_1(ifaceName, iface)) {
+ logd("Newer HAL is found, skip V1_0 remaining init flow.");
+ return iface;
+ }
+
+ SupplicantStaIfaceHalCallback callback = new SupplicantStaIfaceHalCallback(ifaceName);
+ if (!registerCallback(iface, callback)) {
+ throw new RemoteException("Init StaIface V1_0 failed.");
+ }
+ /* keep this in a store to avoid recycling by garbage collector. */
+ mISupplicantStaIfaceCallbacks.put(ifaceName, callback);
+ return iface;
+ }
+
/**
* Setup a STA interface for the specified iface name.
*
@@ -337,43 +422,15 @@ public class SupplicantStaIfaceHal {
Log.e(TAG, "setupIface got null iface");
return false;
}
- SupplicantStaIfaceHalCallback callback = new SupplicantStaIfaceHalCallback(ifaceName);
-
- if (isV1_2()) {
- android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface iface =
- getStaIfaceMockableV1_2(ifaceHwBinder);
-
- SupplicantStaIfaceHalCallbackV1_1 callbackV11 =
- new SupplicantStaIfaceHalCallbackV1_1(ifaceName, callback);
-
- SupplicantStaIfaceHalCallbackV1_2 callbackV12 =
- new SupplicantStaIfaceHalCallbackV1_2(callbackV11);
- if (!registerCallbackV1_2(iface, callbackV12)) {
- return false;
- }
- mISupplicantStaIfaces.put(ifaceName, iface);
- mISupplicantStaIfaceCallbacks.put(ifaceName, callbackV11);
- } else if (isV1_1()) {
- android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface iface =
- getStaIfaceMockableV1_1(ifaceHwBinder);
- SupplicantStaIfaceHalCallbackV1_1 callbackV1_1 =
- new SupplicantStaIfaceHalCallbackV1_1(ifaceName, callback);
-
- if (!registerCallbackV1_1(iface, callbackV1_1)) {
- return false;
- }
- mISupplicantStaIfaces.put(ifaceName, iface);
- mISupplicantStaIfaceCallbacks.put(ifaceName, callbackV1_1);
- } else {
- ISupplicantStaIface iface = getStaIfaceMockable(ifaceHwBinder);
-
- if (!registerCallback(iface, callback)) {
- return false;
- }
+ try {
+ ISupplicantStaIface iface = setupStaIface(ifaceName, ifaceHwBinder);
mISupplicantStaIfaces.put(ifaceName, iface);
- mISupplicantStaIfaceCallbacks.put(ifaceName, callback);
+ } catch (RemoteException e) {
+ loge("setup StaIface failed: " + e.toString());
+ return false;
}
+
return true;
}
@@ -736,6 +793,14 @@ public class SupplicantStaIfaceHal {
}
}
+ protected android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
+ getStaIfaceMockableV1_3(ISupplicantIface iface) {
+ synchronized (mLock) {
+ return android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
+ .asInterface(iface.asBinder());
+ }
+ }
+
/**
* Uses the IServiceManager to check if the device is running V1_1 of the HAL from the VINTF for
* the device.
@@ -756,6 +821,16 @@ public class SupplicantStaIfaceHal {
android.hardware.wifi.supplicant.V1_2.ISupplicant.kInterfaceName);
}
+ /**
+ * Uses the IServiceManager to check if the device is running V1_3 of the HAL from the VINTF for
+ * the device.
+ * @return true if supported, false otherwise.
+ */
+ private boolean isV1_3() {
+ return checkHalVersionByInterfaceName(
+ android.hardware.wifi.supplicant.V1_3.ISupplicant.kInterfaceName);
+ }
+
private boolean checkHalVersionByInterfaceName(String interfaceName) {
if (interfaceName == null) {
return false;
@@ -795,7 +870,7 @@ public class SupplicantStaIfaceHal {
/**
* Helper method to look up the network config or the specified iface.
*/
- private WifiConfiguration getCurrentNetworkLocalConfig(@NonNull String ifaceName) {
+ protected WifiConfiguration getCurrentNetworkLocalConfig(@NonNull String ifaceName) {
return mCurrentNetworkLocalConfigs.get(ifaceName);
}
@@ -886,7 +961,22 @@ public class SupplicantStaIfaceHal {
}
SupplicantStaNetworkHal networkHandle =
checkSupplicantStaNetworkAndLogFailure(ifaceName, "connectToNetwork");
- if (networkHandle == null || !networkHandle.select()) {
+ if (networkHandle == null) {
+ loge("No valid remote network handle for network configuration: "
+ + config.configKey());
+ return false;
+ }
+
+ PmkCacheStoreData pmkData = mPmkCacheEntries.get(config.networkId);
+ if (pmkData != null
+ && pmkData.expirationTimeInSec > mClock.getElapsedSinceBootMillis() / 1000) {
+ logi("Set PMK cache for config id " + config.networkId);
+ if (!networkHandle.setPmkCache(pmkData.data)) {
+ loge("Set PMK cache failed.");
+ }
+ }
+
+ if (!networkHandle.select()) {
loge("Failed to select network configuration: " + config.configKey());
return false;
}
@@ -932,72 +1022,15 @@ public class SupplicantStaIfaceHal {
}
/**
- * Load all the configured networks from wpa_supplicant.
- *
- * @param ifaceName Name of the interface.
- * @param configs Map of configuration key to configuration objects corresponding to all
- * the networks.
- * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
- * @return true if succeeds, false otherwise.
- */
- public boolean loadNetworks(@NonNull String ifaceName, Map<String, WifiConfiguration> configs,
- SparseArray<Map<String, String>> networkExtras) {
- synchronized (mLock) {
- List<Integer> networkIds = listNetworks(ifaceName);
- if (networkIds == null) {
- Log.e(TAG, "Failed to list networks");
- return false;
- }
- for (Integer networkId : networkIds) {
- SupplicantStaNetworkHal network = getNetwork(ifaceName, networkId);
- if (network == null) {
- Log.e(TAG, "Failed to get network with ID: " + networkId);
- return false;
- }
- WifiConfiguration config = new WifiConfiguration();
- Map<String, String> networkExtra = new HashMap<>();
- boolean loadSuccess = false;
- try {
- loadSuccess = network.loadWifiConfiguration(config, networkExtra);
- } catch (IllegalArgumentException e) {
- Log.wtf(TAG, "Exception while loading config params: " + config, e);
- }
- if (!loadSuccess) {
- Log.e(TAG, "Failed to load wifi configuration for network with ID: " + networkId
- + ". Skipping...");
- continue;
- }
- // Set the default IP assignments.
- config.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
- config.setProxySettings(IpConfiguration.ProxySettings.NONE);
-
- networkExtras.put(networkId, networkExtra);
- String configKey =
- networkExtra.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY);
- final WifiConfiguration duplicateConfig = configs.put(configKey, config);
- if (duplicateConfig != null) {
- // The network is already known. Overwrite the duplicate entry.
- Log.i(TAG, "Replacing duplicate network: " + duplicateConfig.networkId);
- removeNetwork(ifaceName, duplicateConfig.networkId);
- networkExtras.remove(duplicateConfig.networkId);
- }
- }
- return true;
- }
- }
-
- /**
- * Remove the request |networkId| from supplicant if it's the current network,
- * if the current configured network matches |networkId|.
+ * Clean HAL cached data for |networkId| in the framework.
*
- * @param ifaceName Name of the interface.
* @param networkId network id of the network to be removed from supplicant.
*/
- public void removeNetworkIfCurrent(@NonNull String ifaceName, int networkId) {
+ public void removeNetworkCachedData(int networkId) {
synchronized (mLock) {
- if (getCurrentNetworkId(ifaceName) == networkId) {
- // Currently we only save 1 network in supplicant.
- removeAllNetworks(ifaceName);
+ logd("Remove cached HAL data for config id " + networkId);
+ if (mPmkCacheEntries.remove(networkId) != null) {
+ updatePmkCacheExpiration();
}
}
}
@@ -1332,6 +1365,23 @@ public class SupplicantStaIfaceHal {
}
}
+ private boolean registerCallbackV1_3(
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface iface,
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback callback) {
+ synchronized (mLock) {
+ String methodStr = "registerCallback_1_3";
+
+ if (iface == null) return false;
+ try {
+ SupplicantStatus status = iface.registerCallback_1_3(callback);
+ return checkStatusAndLogFailure(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+ }
+
/**
* @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns
* null if the call fails
@@ -2401,7 +2451,7 @@ public class SupplicantStaIfaceHal {
/**
* Helper function to log callbacks.
*/
- private void logCallback(final String methodStr) {
+ protected void logCallback(final String methodStr) {
synchronized (mLock) {
if (mVerboseLoggingEnabled) {
Log.d(TAG, "ISupplicantStaIfaceCallback." + methodStr + " received");
@@ -2462,593 +2512,73 @@ public class SupplicantStaIfaceHal {
}
}
- /**
- * Converts the supplicant state received from HIDL to the equivalent framework state.
- */
- private static SupplicantState supplicantHidlStateToFrameworkState(int state) {
- switch (state) {
- case ISupplicantStaIfaceCallback.State.DISCONNECTED:
- return SupplicantState.DISCONNECTED;
- case ISupplicantStaIfaceCallback.State.IFACE_DISABLED:
- return SupplicantState.INTERFACE_DISABLED;
- case ISupplicantStaIfaceCallback.State.INACTIVE:
- return SupplicantState.INACTIVE;
- case ISupplicantStaIfaceCallback.State.SCANNING:
- return SupplicantState.SCANNING;
- case ISupplicantStaIfaceCallback.State.AUTHENTICATING:
- return SupplicantState.AUTHENTICATING;
- case ISupplicantStaIfaceCallback.State.ASSOCIATING:
- return SupplicantState.ASSOCIATING;
- case ISupplicantStaIfaceCallback.State.ASSOCIATED:
- return SupplicantState.ASSOCIATED;
- case ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE:
- return SupplicantState.FOUR_WAY_HANDSHAKE;
- case ISupplicantStaIfaceCallback.State.GROUP_HANDSHAKE:
- return SupplicantState.GROUP_HANDSHAKE;
- case ISupplicantStaIfaceCallback.State.COMPLETED:
- return SupplicantState.COMPLETED;
- default:
- throw new IllegalArgumentException("Invalid state: " + state);
- }
- }
-
- private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub {
- private String mIfaceName;
- private boolean mStateIsFourway = false; // Used to help check for PSK password mismatch
-
+ protected class SupplicantStaIfaceHalCallback extends SupplicantStaIfaceCallbackImpl {
SupplicantStaIfaceHalCallback(@NonNull String ifaceName) {
- mIfaceName = ifaceName;
- }
-
- /**
- * Parses the provided payload into an ANQP element.
- *
- * @param infoID Element type.
- * @param payload Raw payload bytes.
- * @return AnqpElement instance on success, null on failure.
- */
- private ANQPElement parseAnqpElement(Constants.ANQPElementType infoID,
- ArrayList<Byte> payload) {
- synchronized (mLock) {
- try {
- return Constants.getANQPElementID(infoID) != null
- ? ANQPParser.parseElement(
- infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)))
- : ANQPParser.parseHS20Element(
- infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)));
- } catch (IOException | BufferUnderflowException e) {
- Log.e(TAG, "Failed parsing ANQP element payload: " + infoID, e);
- return null;
- }
- }
- }
-
- /**
- * Parse the ANQP element data and add to the provided elements map if successful.
- *
- * @param elementsMap Map to add the parsed out element to.
- * @param infoID Element type.
- * @param payload Raw payload bytes.
- */
- private void addAnqpElementToMap(Map<Constants.ANQPElementType, ANQPElement> elementsMap,
- Constants.ANQPElementType infoID,
- ArrayList<Byte> payload) {
- synchronized (mLock) {
- if (payload == null || payload.isEmpty()) return;
- ANQPElement element = parseAnqpElement(infoID, payload);
- if (element != null) {
- elementsMap.put(infoID, element);
- }
- }
- }
-
- @Override
- public void onNetworkAdded(int id) {
- synchronized (mLock) {
- logCallback("onNetworkAdded");
- }
- }
-
- @Override
- public void onNetworkRemoved(int id) {
- synchronized (mLock) {
- logCallback("onNetworkRemoved");
- // Reset 4way handshake state since network has been removed.
- mStateIsFourway = false;
- }
- }
-
- @Override
- public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
- ArrayList<Byte> ssid) {
- synchronized (mLock) {
- logCallback("onStateChanged");
- SupplicantState newSupplicantState = supplicantHidlStateToFrameworkState(newState);
- WifiSsid wifiSsid =
- WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
- String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
- mStateIsFourway = (newState == ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE);
- if (newSupplicantState == SupplicantState.COMPLETED) {
- mWifiMonitor.broadcastNetworkConnectionEvent(
- mIfaceName, getCurrentNetworkId(mIfaceName), bssidStr);
- }
- mWifiMonitor.broadcastSupplicantStateChangeEvent(
- mIfaceName, getCurrentNetworkId(mIfaceName), wifiSsid,
- bssidStr, newSupplicantState);
- }
- }
-
- @Override
- public void onAnqpQueryDone(byte[/* 6 */] bssid,
- ISupplicantStaIfaceCallback.AnqpData data,
- ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
- synchronized (mLock) {
- logCallback("onAnqpQueryDone");
- Map<Constants.ANQPElementType, ANQPElement> elementsMap = new HashMap<>();
- addAnqpElementToMap(elementsMap, ANQPVenueName, data.venueName);
- addAnqpElementToMap(elementsMap, ANQPRoamingConsortium, data.roamingConsortium);
- addAnqpElementToMap(
- elementsMap, ANQPIPAddrAvailability, data.ipAddrTypeAvailability);
- addAnqpElementToMap(elementsMap, ANQPNAIRealm, data.naiRealm);
- addAnqpElementToMap(elementsMap, ANQP3GPPNetwork, data.anqp3gppCellularNetwork);
- addAnqpElementToMap(elementsMap, ANQPDomName, data.domainName);
- addAnqpElementToMap(elementsMap, HSFriendlyName, hs20Data.operatorFriendlyName);
- addAnqpElementToMap(elementsMap, HSWANMetrics, hs20Data.wanMetrics);
- addAnqpElementToMap(elementsMap, HSConnCapability, hs20Data.connectionCapability);
- addAnqpElementToMap(elementsMap, HSOSUProviders, hs20Data.osuProvidersList);
- mWifiMonitor.broadcastAnqpDoneEvent(
- mIfaceName, new AnqpEvent(NativeUtil.macAddressToLong(bssid), elementsMap));
- }
- }
-
- @Override
- public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
- ArrayList<Byte> data) {
- synchronized (mLock) {
- logCallback("onHs20IconQueryDone");
- mWifiMonitor.broadcastIconDoneEvent(
- mIfaceName,
- new IconEvent(NativeUtil.macAddressToLong(bssid), fileName, data.size(),
- NativeUtil.byteArrayFromArrayList(data)));
- }
- }
-
- @Override
- public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid, byte osuMethod, String url) {
- synchronized (mLock) {
- logCallback("onHs20SubscriptionRemediation");
- mWifiMonitor.broadcastWnmEvent(
- mIfaceName,
- new WnmData(NativeUtil.macAddressToLong(bssid), url, osuMethod));
- }
- }
-
- @Override
- public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
- int reAuthDelayInSec, String url) {
- synchronized (mLock) {
- logCallback("onHs20DeauthImminentNotice");
- mWifiMonitor.broadcastWnmEvent(
- mIfaceName,
- new WnmData(NativeUtil.macAddressToLong(bssid), url,
- reasonCode == WnmData.ESS, reAuthDelayInSec));
- }
- }
-
- @Override
- public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
- synchronized (mLock) {
- logCallback("onDisconnected");
- if (mVerboseLoggingEnabled) {
- Log.e(TAG, "onDisconnected 4way=" + mStateIsFourway
- + " locallyGenerated=" + locallyGenerated
- + " reasonCode=" + reasonCode);
- }
- if (mStateIsFourway
- && (!locallyGenerated || reasonCode != ReasonCode.IE_IN_4WAY_DIFFERS)) {
- mWifiMonitor.broadcastAuthenticationFailureEvent(
- mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1);
- }
- mWifiMonitor.broadcastNetworkDisconnectionEvent(
- mIfaceName, locallyGenerated ? 1 : 0, reasonCode,
- NativeUtil.macAddressFromByteArray(bssid));
- }
- }
-
- @Override
- public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode, boolean timedOut) {
- synchronized (mLock) {
- logCallback("onAssociationRejected");
-
- if (statusCode == StatusCode.UNSPECIFIED_FAILURE) {
- WifiConfiguration curConfiguration = getCurrentNetworkLocalConfig(mIfaceName);
-
- if (curConfiguration != null
- && curConfiguration.allowedKeyManagement
- .get(WifiConfiguration.KeyMgmt.SAE)) {
- // Special handling for WPA3-Personal networks. If the password is
- // incorrect, the AP will send association rejection, with status code 1
- // (unspecified failure). In SAE networks, the password authentication
- // is not related to the 4-way handshake. In this case, we will send an
- // authentication failure event up.
- logCallback("SAE incorrect password");
- mWifiMonitor.broadcastAuthenticationFailureEvent(
- mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1);
- }
- }
- mWifiMonitor.broadcastAssociationRejectionEvent(mIfaceName, statusCode, timedOut,
- NativeUtil.macAddressFromByteArray(bssid));
- }
- }
-
- @Override
- public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
- synchronized (mLock) {
- logCallback("onAuthenticationTimeout");
- mWifiMonitor.broadcastAuthenticationFailureEvent(
- mIfaceName, WifiManager.ERROR_AUTH_FAILURE_TIMEOUT, -1);
- }
- }
-
- @Override
- public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
- synchronized (mLock) {
- logCallback("onBssidChanged");
- if (reason == BssidChangeReason.ASSOC_START) {
- mWifiMonitor.broadcastTargetBssidEvent(
- mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
- } else if (reason == BssidChangeReason.ASSOC_COMPLETE) {
- mWifiMonitor.broadcastAssociatedBssidEvent(
- mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
- }
- }
- }
-
- @Override
- public void onEapFailure() {
- synchronized (mLock) {
- logCallback("onEapFailure");
- mWifiMonitor.broadcastAuthenticationFailureEvent(
- mIfaceName, WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, -1);
- }
- }
-
- @Override
- public void onWpsEventSuccess() {
- logCallback("onWpsEventSuccess");
- synchronized (mLock) {
- mWifiMonitor.broadcastWpsSuccessEvent(mIfaceName);
- }
- }
-
- @Override
- public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
- synchronized (mLock) {
- logCallback("onWpsEventFail");
- if (configError == WpsConfigError.MSG_TIMEOUT
- && errorInd == WpsErrorIndication.NO_ERROR) {
- mWifiMonitor.broadcastWpsTimeoutEvent(mIfaceName);
- } else {
- mWifiMonitor.broadcastWpsFailEvent(mIfaceName, configError, errorInd);
- }
- }
- }
-
- @Override
- public void onWpsEventPbcOverlap() {
- synchronized (mLock) {
- logCallback("onWpsEventPbcOverlap");
- mWifiMonitor.broadcastWpsOverlapEvent(mIfaceName);
- }
- }
-
- @Override
- public void onExtRadioWorkStart(int id) {
- synchronized (mLock) {
- logCallback("onExtRadioWorkStart");
- }
- }
-
- @Override
- public void onExtRadioWorkTimeout(int id) {
- synchronized (mLock) {
- logCallback("onExtRadioWorkTimeout");
- }
+ super(SupplicantStaIfaceHal.this, ifaceName, mLock, mWifiMonitor);
}
}
- private class SupplicantStaIfaceHalCallbackV1_1 extends
- android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback.Stub {
- private String mIfaceName;
- private SupplicantStaIfaceHalCallback mCallbackV1_0;
-
- SupplicantStaIfaceHalCallbackV1_1(@NonNull String ifaceName,
- @NonNull SupplicantStaIfaceHalCallback callback) {
- mIfaceName = ifaceName;
- mCallbackV1_0 = callback;
- }
-
- @Override
- public void onNetworkAdded(int id) {
- mCallbackV1_0.onNetworkAdded(id);
- }
-
- @Override
- public void onNetworkRemoved(int id) {
- mCallbackV1_0.onNetworkRemoved(id);
- }
-
- @Override
- public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
- ArrayList<Byte> ssid) {
- mCallbackV1_0.onStateChanged(newState, bssid, id, ssid);
- }
-
- @Override
- public void onAnqpQueryDone(byte[/* 6 */] bssid,
- ISupplicantStaIfaceCallback.AnqpData data,
- ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
- mCallbackV1_0.onAnqpQueryDone(bssid, data, hs20Data);
- }
-
- @Override
- public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
- ArrayList<Byte> data) {
- mCallbackV1_0.onHs20IconQueryDone(bssid, fileName, data);
- }
-
- @Override
- public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid,
- byte osuMethod, String url) {
- mCallbackV1_0.onHs20SubscriptionRemediation(bssid, osuMethod, url);
- }
-
- @Override
- public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
- int reAuthDelayInSec, String url) {
- mCallbackV1_0.onHs20DeauthImminentNotice(bssid, reasonCode, reAuthDelayInSec, url);
- }
-
- @Override
- public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated,
- int reasonCode) {
- mCallbackV1_0.onDisconnected(bssid, locallyGenerated, reasonCode);
- }
-
- @Override
- public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode,
- boolean timedOut) {
- mCallbackV1_0.onAssociationRejected(bssid, statusCode, timedOut);
- }
-
- @Override
- public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
- mCallbackV1_0.onAuthenticationTimeout(bssid);
- }
-
- @Override
- public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
- mCallbackV1_0.onBssidChanged(reason, bssid);
- }
-
- @Override
- public void onEapFailure() {
- mCallbackV1_0.onEapFailure();
- }
-
- @Override
- public void onEapFailure_1_1(int code) {
- synchronized (mLock) {
- logCallback("onEapFailure_1_1");
- mWifiMonitor.broadcastAuthenticationFailureEvent(
- mIfaceName, WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE, code);
- }
- }
-
- @Override
- public void onWpsEventSuccess() {
- mCallbackV1_0.onWpsEventSuccess();
- }
-
- @Override
- public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
- mCallbackV1_0.onWpsEventFail(bssid, configError, errorInd);
- }
-
- @Override
- public void onWpsEventPbcOverlap() {
- mCallbackV1_0.onWpsEventPbcOverlap();
- }
-
- @Override
- public void onExtRadioWorkStart(int id) {
- mCallbackV1_0.onExtRadioWorkStart(id);
- }
-
- @Override
- public void onExtRadioWorkTimeout(int id) {
- mCallbackV1_0.onExtRadioWorkTimeout(id);
+ protected class SupplicantStaIfaceHalCallbackV1_1 extends SupplicantStaIfaceCallbackV1_1Impl {
+ SupplicantStaIfaceHalCallbackV1_1(@NonNull String ifaceName) {
+ super(SupplicantStaIfaceHal.this, ifaceName, mLock, mWifiMonitor);
}
}
- private class SupplicantStaIfaceHalCallbackV1_2 extends
- android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback.Stub {
- private SupplicantStaIfaceHalCallbackV1_1 mCallbackV1_1;
-
- SupplicantStaIfaceHalCallbackV1_2(
- @NonNull SupplicantStaIfaceHalCallbackV1_1 callback) {
- mCallbackV1_1 = callback;
- }
-
- @Override
- public void onNetworkAdded(int id) {
- mCallbackV1_1.onNetworkAdded(id);
- }
-
- @Override
- public void onNetworkRemoved(int id) {
- mCallbackV1_1.onNetworkRemoved(id);
- }
-
- @Override
- public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
- ArrayList<Byte> ssid) {
- mCallbackV1_1.onStateChanged(newState, bssid, id, ssid);
- }
-
- @Override
- public void onAnqpQueryDone(byte[/* 6 */] bssid,
- ISupplicantStaIfaceCallback.AnqpData data,
- ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
- mCallbackV1_1.onAnqpQueryDone(bssid, data, hs20Data);
- }
-
- @Override
- public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
- ArrayList<Byte> data) {
- mCallbackV1_1.onHs20IconQueryDone(bssid, fileName, data);
- }
-
- @Override
- public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid,
- byte osuMethod, String url) {
- mCallbackV1_1.onHs20SubscriptionRemediation(bssid, osuMethod, url);
- }
-
- @Override
- public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
- int reAuthDelayInSec, String url) {
- mCallbackV1_1.onHs20DeauthImminentNotice(bssid, reasonCode, reAuthDelayInSec, url);
- }
-
- @Override
- public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated,
- int reasonCode) {
- mCallbackV1_1.onDisconnected(bssid, locallyGenerated, reasonCode);
- }
-
- @Override
- public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode,
- boolean timedOut) {
- mCallbackV1_1.onAssociationRejected(bssid, statusCode, timedOut);
- }
-
- @Override
- public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
- mCallbackV1_1.onAuthenticationTimeout(bssid);
- }
-
- @Override
- public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
- mCallbackV1_1.onBssidChanged(reason, bssid);
- }
-
- @Override
- public void onEapFailure() {
- mCallbackV1_1.onEapFailure();
- }
-
- @Override
- public void onEapFailure_1_1(int code) {
- mCallbackV1_1.onEapFailure_1_1(code);
- }
-
- @Override
- public void onWpsEventSuccess() {
- mCallbackV1_1.onWpsEventSuccess();
- }
-
- @Override
- public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
- mCallbackV1_1.onWpsEventFail(bssid, configError, errorInd);
- }
-
- @Override
- public void onWpsEventPbcOverlap() {
- mCallbackV1_1.onWpsEventPbcOverlap();
- }
-
- @Override
- public void onExtRadioWorkStart(int id) {
- mCallbackV1_1.onExtRadioWorkStart(id);
+ protected class SupplicantStaIfaceHalCallbackV1_2 extends SupplicantStaIfaceCallbackV1_2Impl {
+ SupplicantStaIfaceHalCallbackV1_2(@NonNull String ifaceName) {
+ super(SupplicantStaIfaceHal.this, ifaceName, mContext);
}
+ }
- @Override
- public void onExtRadioWorkTimeout(int id) {
- mCallbackV1_1.onExtRadioWorkTimeout(id);
+ protected class SupplicantStaIfaceHalCallbackV1_3 extends SupplicantStaIfaceCallbackV1_3Impl {
+ SupplicantStaIfaceHalCallbackV1_3(@NonNull String ifaceName) {
+ super(SupplicantStaIfaceHal.this, ifaceName);
}
+ }
- @Override
- public void onDppSuccessConfigReceived(ArrayList<Byte> ssid, String password,
- byte[] psk, int securityAkm) {
- if (mDppCallback == null) {
- loge("onDppSuccessConfigReceived callback is null");
- return;
- }
-
- WifiConfiguration newWifiConfiguration = new WifiConfiguration();
+ protected void addPmkCacheEntry(
+ int networkId, long expirationTimeInSec, ArrayList<Byte> serializedEntry) {
+ mPmkCacheEntries.put(networkId,
+ new PmkCacheStoreData(expirationTimeInSec, serializedEntry));
+ updatePmkCacheExpiration();
+ }
- // Set up SSID
- WifiSsid wifiSsid =
- WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
+ private void updatePmkCacheExpiration() {
+ synchronized (mLock) {
+ mEventHandler.removeCallbacksAndMessages(PMK_CACHE_EXPIRATION_ALARM_TAG);
- newWifiConfiguration.SSID = "\"" + wifiSsid.toString() + "\"";
+ long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
+ long nextUpdateTimeInSecond = Long.MAX_VALUE;
+ logd("Update PMK cache expiration at " + elapseTimeInSecond);
- // Set up password or PSK
- if (password != null) {
- newWifiConfiguration.preSharedKey = "\"" + password + "\"";
- } else if (psk != null) {
- newWifiConfiguration.preSharedKey = psk.toString();
+ Iterator<Map.Entry<Integer, PmkCacheStoreData>> iter =
+ mPmkCacheEntries.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry<Integer, PmkCacheStoreData> entry = iter.next();
+ if (entry.getValue().expirationTimeInSec <= elapseTimeInSecond) {
+ logd("Config " + entry.getKey() + " PMK is expired.");
+ iter.remove();
+ } else if (entry.getValue().expirationTimeInSec <= 0) {
+ logd("Config " + entry.getKey() + " PMK expiration time is invalid.");
+ iter.remove();
+ } else if (nextUpdateTimeInSecond > entry.getValue().expirationTimeInSec) {
+ nextUpdateTimeInSecond = entry.getValue().expirationTimeInSec;
+ }
}
- // Set up key management: SAE or PSK
- if (securityAkm == DppAkm.SAE || securityAkm == DppAkm.PSK_SAE) {
- newWifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
- newWifiConfiguration.requirePMF = true;
- } else if (securityAkm == DppAkm.PSK) {
- newWifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
- } else {
- // No other AKMs are currently supported
- onDppFailure(DppFailureCode.NOT_SUPPORTED);
+ // No need to arrange next update since there is no valid PMK in the cache.
+ if (nextUpdateTimeInSecond == Long.MAX_VALUE) {
return;
}
- // Set up default values
- newWifiConfiguration.creatorName = mContext.getPackageManager()
- .getNameForUid(Process.WIFI_UID);
- newWifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
- newWifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
- newWifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
- newWifiConfiguration.status = WifiConfiguration.Status.ENABLED;
-
- mDppCallback.onSuccessConfigReceived(newWifiConfiguration);
- }
-
- @Override
- public void onDppSuccessConfigSent() {
- if (mDppCallback != null) {
- mDppCallback.onSuccessConfigSent();
- } else {
- loge("onSuccessConfigSent callback is null");
- }
- }
-
- @Override
- public void onDppProgress(int code) {
- if (mDppCallback != null) {
- mDppCallback.onProgress(code);
- } else {
- loge("onDppProgress callback is null");
- }
- }
-
- @Override
- public void onDppFailure(int code) {
- if (mDppCallback != null) {
- mDppCallback.onFailure(code);
- } else {
- loge("onDppFailure callback is null");
- }
+ logd("PMK cache next expiration time: " + nextUpdateTimeInSecond);
+ long delayedTimeInMs = (nextUpdateTimeInSecond - elapseTimeInSecond) * 1000;
+ mEventHandler.postDelayed(
+ () -> {
+ updatePmkCacheExpiration();
+ },
+ PMK_CACHE_EXPIRATION_ALARM_TAG,
+ (delayedTimeInMs > 0) ? delayedTimeInMs : 0);
}
}
@@ -3166,6 +2696,66 @@ public class SupplicantStaIfaceHal {
return keyMgmtMask.value;
}
+ private @WifiInfo.WifiTechnology int getWifiTechFromCap(ConnectionCapabilities capa) {
+ switch(capa.technology) {
+ case WifiTechnology.HE:
+ return WifiInfo.WIFI_TECHNOLOGY_11AX;
+ case WifiTechnology.VHT:
+ return WifiInfo.WIFI_TECHNOLOGY_11AC;
+ case WifiTechnology.HT:
+ return WifiInfo.WIFI_TECHNOLOGY_11N;
+ case WifiTechnology.LEGACY:
+ return WifiInfo.WIFI_TECHNOLOGY_LEGACY;
+ default:
+ return WifiInfo.WIFI_TECHNOLOGY_UNKNOWN;
+ }
+ }
+
+ /**
+ * Returns wifi technology for connected network
+ *
+ * This is a v1.3+ HAL feature.
+ * On error, or if these features are not supported, 0 is returned.
+ */
+ public @WifiInfo.WifiTechnology int getWifiTechnology(@NonNull String ifaceName) {
+ final String methodStr = "getWifiTechnology";
+ MutableInt wifiTechnology = new MutableInt(WifiInfo.WIFI_TECHNOLOGY_UNKNOWN);
+
+ if (isV1_3()) {
+ ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr);
+ if (iface == null) {
+ return WifiInfo.WIFI_TECHNOLOGY_UNKNOWN;
+ }
+
+ // Get a v1.3 supplicant STA Interface
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface staIfaceV13 =
+ getStaIfaceMockableV1_3(iface);
+
+ if (staIfaceV13 == null) {
+ Log.e(TAG, methodStr
+ + ": SupplicantStaIface is null, cannot get Connection Capabilities");
+ return WifiInfo.WIFI_TECHNOLOGY_UNKNOWN;
+ }
+
+ try {
+ staIfaceV13.getConnectionCapabilities(
+ (SupplicantStatus statusInternal,
+ ConnectionCapabilities connCapabilitiesInternal) -> {
+ if (statusInternal.code == SupplicantStatusCode.SUCCESS) {
+ wifiTechnology.value = getWifiTechFromCap(connCapabilitiesInternal);
+ }
+ checkStatusAndLogFailure(statusInternal, methodStr);
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ } else {
+ Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL");
+ }
+
+ return wifiTechnology.value;
+ }
+
/**
* Adds a DPP peer URI to the URI list.
*
@@ -3393,4 +2983,8 @@ public class SupplicantStaIfaceHal {
public void registerDppCallback(DppEventCallback dppCallback) {
mDppCallback = dppCallback;
}
+
+ protected DppEventCallback getDppCallback() {
+ return mDppCallback;
+ }
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
index dd56b5f578..bd68f77a3d 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
@@ -22,7 +22,7 @@ import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
-import android.os.HidlSupport.Mutable;
+import android.net.wifi.WifiEnterpriseConfig.Ocsp;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
@@ -31,6 +31,7 @@ import android.util.MutableBoolean;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
+import com.android.server.wifi.util.GeneralUtil.Mutable;
import com.android.server.wifi.util.NativeUtil;
import org.json.JSONException;
@@ -130,6 +131,7 @@ public class SupplicantStaNetworkHal {
private boolean mEapEngine;
private String mEapEngineID;
private String mEapDomainSuffixMatch;
+ private @Ocsp int mOcsp;
SupplicantStaNetworkHal(ISupplicantStaNetwork iSupplicantStaNetwork, String ifaceName,
Context context, WifiMonitor monitor) {
@@ -159,6 +161,7 @@ public class SupplicantStaNetworkHal {
* @return true if succeeds, false otherwise.
* @throws IllegalArgumentException on malformed configuration params.
*/
+ @VisibleForTesting
public boolean loadWifiConfiguration(WifiConfiguration config,
Map<String, String> networkExtras) {
synchronized (mLock) {
@@ -214,6 +217,12 @@ public class SupplicantStaNetworkHal {
config.preSharedKey = NativeUtil.hexStringFromByteArray(mPsk);
} /* Do not read SAE password */
+ /** SAE Password id */
+ config.saePasswordId = null;
+ if (getSaePasswordId() && !TextUtils.isEmpty(mSaePasswordId)) {
+ config.saePasswordId = mSaePasswordId;
+ }
+
/** allowedKeyManagement */
if (getKeyMgmt()) {
BitSet keyMgmtMask = supplicantToWifiConfigurationKeyMgmtMask(mKeyMgmtMask);
@@ -313,6 +322,14 @@ public class SupplicantStaNetworkHal {
}
}
+ if (config.saePasswordId != null
+ && config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
+ if (!setSaePasswordId(config.saePasswordId)) {
+ Log.e(TAG, "failed to ste sae password id");
+ return false;
+ }
+ }
+
/** Wep Keys */
boolean hasSetKey = false;
if (config.wepKeys != null) {
@@ -496,6 +513,10 @@ public class SupplicantStaNetworkHal {
if (getEapCACert() && !TextUtils.isEmpty(mEapCACert)) {
eapConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, mEapCACert);
}
+ /** EAP OCSP type */
+ if (getOcsp()) {
+ eapConfig.setOcsp(mOcsp);
+ }
/** EAP Subject Match */
if (getEapSubjectMatch() && !TextUtils.isEmpty(mEapSubjectMatch)) {
eapConfig.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, mEapSubjectMatch);
@@ -686,6 +707,16 @@ public class SupplicantStaNetworkHal {
return false;
}
+ /**
+ * OCSP (Online Certificate Status Protocol)
+ * For older HAL compatibility, omit this step to avoid breaking
+ * connection flow.
+ */
+ if (getV1_3StaNetwork() != null && !setOcsp(eapConfig.getOcsp())) {
+ Log.e(TAG, "failed to set ocsp");
+ return false;
+ }
+
return true;
}
}
@@ -696,6 +727,12 @@ public class SupplicantStaNetworkHal {
}
}
+ private android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork getV1_3StaNetwork() {
+ synchronized (mLock) {
+ return getSupplicantStaNetworkForV1_3Mockable();
+ }
+ }
+
/**
* Maps WifiConfiguration Key Management BitSet to Supplicant HIDL bitmask int
* TODO(b/32571829): Update mapping when fast transition keys are added
@@ -1462,6 +1499,9 @@ public class SupplicantStaNetworkHal {
} catch (RemoteException e) {
handleRemoteException(e, methodStr);
return false;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + e);
+ return false;
}
}
}
@@ -1791,6 +1831,39 @@ public class SupplicantStaNetworkHal {
}
/** See ISupplicantStaNetwork.hal for documentation */
+ private boolean getSaePasswordId() {
+ synchronized (mLock) {
+ final String methodStr = "getSaePasswordId";
+ if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
+ try {
+ android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
+ iSupplicantStaNetworkV12;
+
+ iSupplicantStaNetworkV12 = getV1_2StaNetwork();
+ if (iSupplicantStaNetworkV12 != null) {
+ /* Support for SAE Requires HAL v1.2 or higher */
+ MutableBoolean statusOk = new MutableBoolean(false);
+ iSupplicantStaNetworkV12.getSaePasswordId((SupplicantStatus status,
+ String saePasswordId) -> {
+ statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
+ if (statusOk.value) {
+ this.mSaePasswordId = saePasswordId;
+ } else {
+ checkStatusAndLogFailure(status, methodStr);
+ }
+ });
+ return statusOk.value;
+ } else {
+ return false;
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+ }
+
+ /** See ISupplicantStaNetwork.hal for documentation */
private boolean setSaePasswordId(String saePasswordId) {
synchronized (mLock) {
final String methodStr = "setSaePasswordId";
@@ -2831,6 +2904,19 @@ public class SupplicantStaNetworkHal {
}
/**
+ * Method to mock out the V1_3 ISupplicantStaNetwork retrieval in unit tests.
+ *
+ * @return 1.3 ISupplicantStaNetwork object if the device is running the 1.3 supplicant hal
+ * service, null otherwise.
+ */
+ protected android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
+ getSupplicantStaNetworkForV1_3Mockable() {
+ if (mISupplicantStaNetwork == null) return null;
+ return android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.castFrom(
+ mISupplicantStaNetwork);
+ }
+
+ /**
* Send eap identity response.
*
* @param identityStr identity used for EAP-Identity
@@ -2883,6 +2969,125 @@ public class SupplicantStaNetworkHal {
}
}
+ /** See ISupplicantStaNetwork.hal for documentation */
+ private boolean setOcsp(@Ocsp int ocsp) {
+ synchronized (mLock) {
+ final String methodStr = "setOcsp";
+ if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
+
+ int halOcspValue = android.hardware.wifi.supplicant.V1_3.OcspType.NONE;
+ switch (ocsp) {
+ case WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS:
+ halOcspValue = android.hardware.wifi.supplicant.V1_3
+ .OcspType.REQUEST_CERT_STATUS;
+ break;
+ case WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS:
+ halOcspValue = android.hardware.wifi.supplicant.V1_3
+ .OcspType.REQUIRE_CERT_STATUS;
+ break;
+ case WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS:
+ halOcspValue = android.hardware.wifi.supplicant.V1_3
+ .OcspType.REQUIRE_ALL_CERTS_STATUS;
+ break;
+ }
+ try {
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
+ iSupplicantStaNetworkV13;
+
+ iSupplicantStaNetworkV13 = getV1_3StaNetwork();
+ if (iSupplicantStaNetworkV13 != null) {
+ /* Support for OCSP Requires HAL v1.3 or higher */
+ SupplicantStatus status = iSupplicantStaNetworkV13
+ .setOcsp(halOcspValue);
+ return checkStatusAndLogFailure(status, methodStr);
+ } else {
+ Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
+ return false;
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+ }
+
+ /** See ISupplicantStaNetwork.hal for documentation */
+ private boolean getOcsp() {
+ synchronized (mLock) {
+ final String methodStr = "getOcsp";
+ if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
+
+ try {
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
+ iSupplicantStaNetworkV13;
+ iSupplicantStaNetworkV13 = getV1_3StaNetwork();
+ if (iSupplicantStaNetworkV13 != null) {
+ MutableBoolean statusOk = new MutableBoolean(false);
+ iSupplicantStaNetworkV13.getOcsp((SupplicantStatus status,
+ int halOcspValue) -> {
+ statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
+ if (statusOk.value) {
+ mOcsp = WifiEnterpriseConfig.OCSP_NONE;
+ switch (halOcspValue) {
+ case android.hardware.wifi.supplicant.V1_3
+ .OcspType.REQUEST_CERT_STATUS:
+ mOcsp = WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS;
+ break;
+ case android.hardware.wifi.supplicant.V1_3
+ .OcspType.REQUIRE_CERT_STATUS:
+ mOcsp = WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS;
+ break;
+ case android.hardware.wifi.supplicant.V1_3
+ .OcspType.REQUIRE_ALL_CERTS_STATUS:
+ mOcsp = WifiEnterpriseConfig
+ .OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS;
+ break;
+ default:
+ Log.e(TAG, "Invalid HAL OCSP value " + halOcspValue);
+ break;
+ }
+ } else {
+ checkStatusAndLogFailure(status, methodStr);
+ }
+ });
+ return statusOk.value;
+ } else {
+ Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
+ return false;
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+ }
+
+ /** See ISupplicantStaNetwork.hal for documentation */
+ public boolean setPmkCache(ArrayList<Byte> serializedEntry) {
+ synchronized (mLock) {
+ final String methodStr = "setPmkCache";
+ if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
+
+ try {
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
+ iSupplicantStaNetworkV13;
+
+ iSupplicantStaNetworkV13 = getV1_3StaNetwork();
+ if (iSupplicantStaNetworkV13 != null) {
+ SupplicantStatus status = iSupplicantStaNetworkV13
+ .setPmkCache(serializedEntry);
+ return checkStatusAndLogFailure(status, methodStr);
+ } else {
+ Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
+ return false;
+ }
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ return false;
+ }
+ }
+ }
+
/**
* Retrieve the NFC token for this network.
*
diff --git a/service/java/com/android/server/wifi/SupplicantStateTracker.java b/service/java/com/android/server/wifi/SupplicantStateTracker.java
index c60715b6d5..11148c5ffe 100644
--- a/service/java/com/android/server/wifi/SupplicantStateTracker.java
+++ b/service/java/com/android/server/wifi/SupplicantStateTracker.java
@@ -28,7 +28,6 @@ import android.os.Parcelable;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
-import android.util.Slog;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.State;
@@ -69,9 +68,6 @@ public class SupplicantStateTracker extends StateMachine {
/* Maximum retries on assoc rejection events */
private static final int MAX_RETRIES_ON_ASSOCIATION_REJECT = 16;
- /* Tracks if networks have been disabled during a connection */
- private boolean mNetworksDisabledDuringConnect = false;
-
private final Context mContext;
private final State mUninitializedState = new UninitializedState();
@@ -126,13 +122,9 @@ public class SupplicantStateTracker extends StateMachine {
private void handleNetworkConnectionFailure(int netId, int disableReason) {
if (DBG) {
Log.d(TAG, "handleNetworkConnectionFailure netId=" + Integer.toString(netId)
- + " reason " + Integer.toString(disableReason)
- + " mNetworksDisabledDuringConnect=" + mNetworksDisabledDuringConnect);
+ + " reason " + Integer.toString(disableReason));
}
- /* If other networks disabled during connection, enable them */
- if (mNetworksDisabledDuringConnect) {
- mNetworksDisabledDuringConnect = false; }
/* update network status */
mWifiConfigManager.updateNetworkSelectionStatus(netId, disableReason);
}
@@ -202,7 +194,7 @@ public class SupplicantStateTracker extends StateMachine {
case UNINITIALIZED: supplState = BatteryStats.WIFI_SUPPL_STATE_UNINITIALIZED; break;
case INVALID: supplState = BatteryStats.WIFI_SUPPL_STATE_INVALID; break;
default:
- Slog.w(TAG, "Unknown supplicant state " + state);
+ Log.w(TAG, "Unknown supplicant state " + state);
supplState = BatteryStats.WIFI_SUPPL_STATE_INVALID;
break;
}
@@ -255,9 +247,6 @@ public class SupplicantStateTracker extends StateMachine {
case ClientModeImpl.CMD_RESET_SUPPLICANT_STATE:
transitionTo(mUninitializedState);
break;
- case WifiManager.CONNECT_NETWORK:
- mNetworksDisabledDuringConnect = true;
- break;
case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
default:
Log.e(TAG, "Ignoring " + message);
@@ -368,10 +357,6 @@ public class SupplicantStateTracker extends StateMachine {
@Override
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
- /* Reset authentication failure count */
- if (mNetworksDisabledDuringConnect) {
- mNetworksDisabledDuringConnect = false;
- }
}
@Override
public boolean processMessage(Message message) {
@@ -411,7 +396,6 @@ public class SupplicantStateTracker extends StateMachine {
super.dump(fd, pw, args);
pw.println("mAuthFailureInSupplicantBroadcast " + mAuthFailureInSupplicantBroadcast);
pw.println("mAuthFailureReason " + mAuthFailureReason);
- pw.println("mNetworksDisabledDuringConnect " + mNetworksDisabledDuringConnect);
pw.println();
}
}
diff --git a/service/java/com/android/server/wifi/WakeupController.java b/service/java/com/android/server/wifi/WakeupController.java
index 1b5ccd3e3c..bf36c94821 100644
--- a/service/java/com/android/server/wifi/WakeupController.java
+++ b/service/java/com/android/server/wifi/WakeupController.java
@@ -16,8 +16,6 @@
package com.android.server.wifi;
-import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED;
-
import android.content.Context;
import android.database.ContentObserver;
import android.net.wifi.ScanResult;
@@ -25,7 +23,6 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
import android.os.Handler;
-import android.os.Looper;
import android.os.Process;
import android.provider.Settings;
import android.util.Log;
@@ -128,7 +125,7 @@ public class WakeupController {
public WakeupController(
Context context,
- Looper looper,
+ Handler handler,
WakeupLock wakeupLock,
WakeupEvaluator wakeupEvaluator,
WakeupOnboarding wakeupOnboarding,
@@ -140,7 +137,7 @@ public class WakeupController {
FrameworkFacade frameworkFacade,
Clock clock) {
mContext = context;
- mHandler = new Handler(looper);
+ mHandler = handler;
mWakeupLock = wakeupLock;
mWakeupEvaluator = wakeupEvaluator;
mWakeupOnboarding = wakeupOnboarding;
@@ -404,14 +401,14 @@ public class WakeupController {
/**
* Enables wifi.
*
- * <p>This method ignores all checks and assumes that {@link WifiController} is currently
+ * <p>This method ignores all checks and assumes that {@link ActiveModeWarden} is currently
* in ScanModeState.
*/
private void enableWifi() {
if (USE_PLATFORM_WIFI_WAKE) {
// TODO(b/72180295): ensure that there is no race condition with WifiServiceImpl here
if (mWifiInjector.getWifiSettingsStore().handleWifiToggled(true /* wifiEnabled */)) {
- mWifiInjector.getWifiController().sendMessage(CMD_WIFI_TOGGLED);
+ mWifiInjector.getActiveModeWarden().wifiToggled();
mWifiWakeMetrics.recordWakeupEvent(mNumScansHandled);
}
}
diff --git a/service/java/com/android/server/wifi/WakeupNotificationFactory.java b/service/java/com/android/server/wifi/WakeupNotificationFactory.java
index 23f31a7db4..748a74d6ce 100644
--- a/service/java/com/android/server/wifi/WakeupNotificationFactory.java
+++ b/service/java/com/android/server/wifi/WakeupNotificationFactory.java
@@ -42,10 +42,13 @@ public class WakeupNotificationFactory {
public static final int ONBOARD_ID = SystemMessage.NOTE_WIFI_WAKE_ONBOARD;
private final Context mContext;
+ private final WifiInjector mWifiInjector;
private final FrameworkFacade mFrameworkFacade;
- WakeupNotificationFactory(Context context, FrameworkFacade frameworkFacade) {
+ WakeupNotificationFactory(Context context, WifiInjector wifiInjector,
+ FrameworkFacade frameworkFacade) {
mContext = context;
+ mWifiInjector = wifiInjector;
mFrameworkFacade = frameworkFacade;
}
@@ -80,7 +83,8 @@ public class WakeupNotificationFactory {
private PendingIntent getPrivateBroadcast(String action) {
- Intent intent = new Intent(action).setPackage("android");
+ Intent intent = new Intent(action)
+ .setPackage(mWifiInjector.getWifiStackPackageName());
return mFrameworkFacade.getBroadcast(
mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
diff --git a/service/java/com/android/server/wifi/WakeupOnboarding.java b/service/java/com/android/server/wifi/WakeupOnboarding.java
index b6bcbc3c0e..93540e00ac 100644
--- a/service/java/com/android/server/wifi/WakeupOnboarding.java
+++ b/service/java/com/android/server/wifi/WakeupOnboarding.java
@@ -26,7 +26,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
-import android.os.Looper;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.format.DateUtils;
@@ -93,12 +92,12 @@ public class WakeupOnboarding {
public WakeupOnboarding(
Context context,
WifiConfigManager wifiConfigManager,
- Looper looper,
+ Handler handler,
FrameworkFacade frameworkFacade,
WakeupNotificationFactory wakeupNotificationFactory) {
mContext = context;
mWifiConfigManager = wifiConfigManager;
- mHandler = new Handler(looper);
+ mHandler = handler;
mFrameworkFacade = frameworkFacade;
mWakeupNotificationFactory = wakeupNotificationFactory;
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index 7970ab72f9..87a170c785 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -28,7 +28,6 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.Environment;
import android.os.Handler;
-import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
@@ -45,9 +44,9 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Random;
-import java.util.UUID;
/**
* Provides API for reading/writing soft access point configuration.
@@ -85,24 +84,28 @@ public class WifiApConfigStore {
private ArrayList<Integer> mAllowed2GChannel = null;
private final Context mContext;
+ private final WifiInjector mWifiInjector;
private final Handler mHandler;
private final String mApConfigFile;
private final BackupManagerProxy mBackupManagerProxy;
private final FrameworkFacade mFrameworkFacade;
private boolean mRequiresApBandConversion = false;
- WifiApConfigStore(Context context, Looper looper,
+ WifiApConfigStore(Context context, WifiInjector wifiInjector, Handler handler,
BackupManagerProxy backupManagerProxy, FrameworkFacade frameworkFacade) {
- this(context, looper, backupManagerProxy, frameworkFacade, DEFAULT_AP_CONFIG_FILE);
+ this(context, wifiInjector, handler, backupManagerProxy, frameworkFacade,
+ DEFAULT_AP_CONFIG_FILE);
}
WifiApConfigStore(Context context,
- Looper looper,
+ WifiInjector wifiInjector,
+ Handler handler,
BackupManagerProxy backupManagerProxy,
FrameworkFacade frameworkFacade,
String apConfigFile) {
mContext = context;
- mHandler = new Handler(looper);
+ mWifiInjector = wifiInjector;
+ mHandler = handler;
mBackupManagerProxy = backupManagerProxy;
mFrameworkFacade = frameworkFacade;
mApConfigFile = apConfigFile;
@@ -173,7 +176,7 @@ public class WifiApConfigStore {
* Update the current soft access point configuration.
* Restore to default AP configuration if null is provided.
* This can be invoked under context of binder threads (WifiManager.setWifiApConfiguration)
- * and ClientModeImpl thread (CMD_START_AP).
+ * and the main Wifi thread (CMD_START_AP).
*/
public synchronized void setApConfiguration(WifiConfiguration config) {
if (config == null) {
@@ -340,9 +343,7 @@ public class WifiApConfigStore {
config.SSID = mContext.getResources().getString(
R.string.wifi_tether_configure_ssid_default) + "_" + getRandomIntForDefaultSsid();
config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
- String randomUUID = UUID.randomUUID().toString();
- //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
- config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
+ config.preSharedKey = generatePassword();
return config;
}
@@ -364,9 +365,7 @@ public class WifiApConfigStore {
config.apBand = apBand;
config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
config.networkId = WifiConfiguration.LOCAL_ONLY_NETWORK_ID;
- String randomUUID = UUID.randomUUID().toString();
- // first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
- config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
+ config.preSharedKey = generatePassword();
return config;
}
@@ -496,8 +495,23 @@ public class WifiApConfigStore {
}
private PendingIntent getPrivateBroadcast(String action) {
- Intent intent = new Intent(action).setPackage("android");
+ Intent intent = new Intent(action)
+ .setPackage(mWifiInjector.getWifiStackPackageName());
return mFrameworkFacade.getBroadcast(
mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
+
+ private static String generatePassword() {
+ // Characters that will be used for password generation. Some characters commonly known to
+ // be confusing like 0 and O excluded from this list.
+ final String allowed = "23456789abcdefghijkmnpqrstuvwxyz";
+ final int passLength = 15;
+
+ StringBuilder sb = new StringBuilder(passLength);
+ SecureRandom random = new SecureRandom();
+ for (int i = 0; i < passLength; i++) {
+ sb.append(allowed.charAt(random.nextInt(allowed.length())));
+ }
+ return sb.toString();
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java b/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
index 742cc99d83..9843f0d95a 100644
--- a/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
+++ b/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
@@ -502,9 +502,8 @@ class WifiBackupDataV1Parser implements WifiBackupDataParser {
}
}
if (gatewayAddressString != null) {
- LinkAddress dest = null;
InetAddress gateway = NetworkUtils.numericToInetAddress(gatewayAddressString);
- RouteInfo route = new RouteInfo(dest, gateway);
+ RouteInfo route = new RouteInfo(null, gateway, null, RouteInfo.RTN_UNICAST);
if (route.isIPv4Default()) {
staticIpConfiguration.gateway = gateway;
} else {
diff --git a/service/java/com/android/server/wifi/WifiCandidates.java b/service/java/com/android/server/wifi/WifiCandidates.java
index ee5bd30bfe..ec34b6ece7 100644
--- a/service/java/com/android/server/wifi/WifiCandidates.java
+++ b/service/java/com/android/server/wifi/WifiCandidates.java
@@ -77,6 +77,10 @@ public class WifiCandidates {
*/
boolean isTrusted();
/**
+ * Returns true for a metered network.
+ */
+ boolean isMetered();
+ /**
* Returns the ID of the evaluator that provided the candidate.
*/
@WifiNetworkSelector.NetworkEvaluator.EvaluatorId int getEvaluatorId();
@@ -132,6 +136,7 @@ public class WifiCandidates {
private WifiScoreCard.PerBssid mPerBssid; // For accessing the scorecard entry
private final boolean mIsCurrentNetwork;
private final boolean mIsCurrentBssid;
+ private final boolean mIsMetered;
CandidateImpl(Key key,
ScanDetail scanDetail,
@@ -141,7 +146,8 @@ public class WifiCandidates {
WifiScoreCard.PerBssid perBssid,
double lastSelectionWeight,
boolean isCurrentNetwork,
- boolean isCurrentBssid) {
+ boolean isCurrentBssid,
+ boolean isMetered) {
this.key = key;
this.scanDetail = scanDetail;
this.config = config;
@@ -151,6 +157,7 @@ public class WifiCandidates {
this.lastSelectionWeight = lastSelectionWeight;
this.mIsCurrentNetwork = isCurrentNetwork;
this.mIsCurrentBssid = isCurrentBssid;
+ this.mIsMetered = isMetered;
}
@Override
@@ -190,6 +197,11 @@ public class WifiCandidates {
}
@Override
+ public boolean isMetered() {
+ return (mIsMetered);
+ }
+
+ @Override
public @WifiNetworkSelector.NetworkEvaluator.EvaluatorId int getEvaluatorId() {
return evaluatorId;
}
@@ -248,17 +260,10 @@ public class WifiCandidates {
String getIdentifier();
/**
- * Calculates the score for a group of candidates that belong
- * to the same network.
+ * Calculates the best score for a collection of candidates.
*/
- @Nullable ScoredCandidate scoreCandidates(@NonNull Collection<Candidate> group);
+ @Nullable ScoredCandidate scoreCandidates(@NonNull Collection<Candidate> candidates);
- /**
- * Returns true if the legacy user connect choice logic should be used.
- *
- * @returns false to disable the legacy logic
- */
- boolean userConnectChoiceOverrideWanted();
}
/**
@@ -275,16 +280,20 @@ public class WifiCandidates {
public final double value;
public final double err;
public final Key candidateKey;
- public ScoredCandidate(double value, double err, Candidate candidate) {
+ public final boolean userConnectChoiceOverride;
+ public ScoredCandidate(double value, double err, boolean userConnectChoiceOverride,
+ Candidate candidate) {
this.value = value;
this.err = err;
this.candidateKey = (candidate == null) ? null : candidate.getKey();
+ this.userConnectChoiceOverride = userConnectChoiceOverride;
}
/**
* Represents no score
*/
public static final ScoredCandidate NONE =
- new ScoredCandidate(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, null);
+ new ScoredCandidate(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
+ false, null);
}
/**
@@ -348,7 +357,8 @@ public class WifiCandidates {
WifiConfiguration config,
@WifiNetworkSelector.NetworkEvaluator.EvaluatorId int evaluatorId,
int evaluatorScore,
- double lastSelectionWeightBetweenZeroAndOne) {
+ double lastSelectionWeightBetweenZeroAndOne,
+ boolean isMetered) {
if (config == null) return failure();
if (scanDetail == null) return failure();
ScanResult scanResult = scanDetail.getScanResult();
@@ -381,17 +391,11 @@ public class WifiCandidates {
scanDetail, config, evaluatorId, evaluatorScore, perBssid,
Math.min(Math.max(lastSelectionWeightBetweenZeroAndOne, 0.0), 1.0),
config.networkId == mCurrentNetworkId,
- bssid.equals(mCurrentBssid));
+ bssid.equals(mCurrentBssid),
+ isMetered);
mCandidates.put(key, candidate);
return true;
}
- /** Adds a new candidate with no user selection weight. */
- public boolean add(ScanDetail scanDetail,
- WifiConfiguration config,
- @WifiNetworkSelector.NetworkEvaluator.EvaluatorId int evaluatorId,
- int evaluatorScore) {
- return add(scanDetail, config, evaluatorId, evaluatorScore, 0.0);
- }
/**
* Removes a candidate
@@ -399,7 +403,7 @@ public class WifiCandidates {
*/
public boolean remove(Candidate candidate) {
if (!(candidate instanceof CandidateImpl)) return failure();
- return mCandidates.remove(((CandidateImpl) candidate).key, (CandidateImpl) candidate);
+ return mCandidates.remove(((CandidateImpl) candidate).key, candidate);
}
/**
@@ -432,14 +436,9 @@ public class WifiCandidates {
*/
public @NonNull ScoredCandidate choose(@NonNull CandidateScorer candidateScorer) {
Preconditions.checkNotNull(candidateScorer);
- ScoredCandidate choice = ScoredCandidate.NONE;
- for (Collection<Candidate> group : getGroupedCandidates()) {
- ScoredCandidate scoredCandidate = candidateScorer.scoreCandidates(group);
- if (scoredCandidate != null && scoredCandidate.value > choice.value) {
- choice = scoredCandidate;
- }
- }
- return choice;
+ Collection<Candidate> candidates = new ArrayList<>(mCandidates.values());
+ ScoredCandidate choice = candidateScorer.scoreCandidates(candidates);
+ return choice == null ? ScoredCandidate.NONE : choice;
}
/**
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 683ace4c83..a0a032d540 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -16,10 +16,9 @@
package com.android.server.wifi;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
-import android.app.admin.DeviceAdminInfo;
-import android.app.admin.DevicePolicyManagerInternal;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -38,7 +37,6 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.os.Handler;
-import android.os.Looper;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
@@ -76,6 +74,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.crypto.Mac;
+
/**
* This class provides the APIs to manage configured Wi-Fi networks.
* It deals with the following:
@@ -95,7 +95,7 @@ import java.util.Set;
* in the internal database. Any configuration updates should be triggered with appropriate helper
* methods of this class using the configuration's unique networkId.
*
- * NOTE: These API's are not thread safe and should only be used from ClientModeImpl thread.
+ * NOTE: These API's are not thread safe and should only be used from the main Wifi thread.
*/
public class WifiConfigManager {
/**
@@ -158,34 +158,34 @@ public class WifiConfigManager {
Integer.MAX_VALUE // threshold for DISABLED_AUTHENTICATION_NO_SUBSCRIBED
};
/**
- * Interface for other modules to listen to the saved network updated
+ * Interface for other modules to listen to the network updated
* events.
*/
- public interface OnSavedNetworkUpdateListener {
+ public interface OnNetworkUpdateListener {
/**
- * Invoked on saved network being added.
+ * Invoked on network being added.
*/
- void onSavedNetworkAdded(int networkId);
+ void onNetworkAdded(@NonNull WifiConfiguration config);
/**
- * Invoked on saved network being enabled.
+ * Invoked on network being enabled.
*/
- void onSavedNetworkEnabled(int networkId);
+ void onNetworkEnabled(@NonNull WifiConfiguration config);
/**
- * Invoked on saved network being permanently disabled.
+ * Invoked on network being permanently disabled.
*/
- void onSavedNetworkPermanentlyDisabled(int networkId, int disableReason);
+ void onNetworkPermanentlyDisabled(@NonNull WifiConfiguration config, int disableReason);
/**
- * Invoked on saved network being removed.
+ * Invoked on network being removed.
*/
- void onSavedNetworkRemoved(int networkId);
+ void onNetworkRemoved(@NonNull WifiConfiguration config);
/**
- * Invoked on saved network being temporarily disabled.
+ * Invoked on network being temporarily disabled.
*/
- void onSavedNetworkTemporarilyDisabled(int networkId, int disableReason);
+ void onNetworkTemporarilyDisabled(@NonNull WifiConfiguration config, int disableReason);
/**
- * Invoked on saved network being updated.
+ * Invoked on network being updated.
*/
- void onSavedNetworkUpdated(int networkId);
+ void onNetworkUpdated(@NonNull WifiConfiguration config);
}
/**
* Max size of scan details to cache in {@link #mScanDetailCaches}.
@@ -228,6 +228,12 @@ public class WifiConfigManager {
private static final int WIFI_PNO_FREQUENCY_CULLING_ENABLED_DEFAULT = 1; // 0 = disabled
private static final int WIFI_PNO_RECENCY_SORTING_ENABLED_DEFAULT = 1; // 0 = disabled:
+ @VisibleForTesting
+ protected static final long AGGRESSIVE_MAC_REFRESH_MS = 10 * 60 * 1000; //10 minutes
+
+ private static final MacAddress DEFAULT_MAC_ADDRESS =
+ MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
+
/**
* Expiration timeout for deleted ephemeral ssids. (1 day)
*/
@@ -272,12 +278,12 @@ public class WifiConfigManager {
private final WifiPermissionsWrapper mWifiPermissionsWrapper;
private final WifiInjector mWifiInjector;
private boolean mConnectedMacRandomzationSupported;
+ private final Mac mMac;
/**
* Local log used for debugging any WifiConfigManager issues.
*/
- private final LocalLog mLocalLog =
- new LocalLog(ActivityManager.isLowRamDeviceStatic() ? 128 : 256);
+ private final LocalLog mLocalLog;
/**
* Map of configured networks with network id as the key.
*/
@@ -303,6 +309,13 @@ public class WifiConfigManager {
*/
private final Map<String, String> mRandomizedMacAddressMapping;
+ private final Set<String> mAggressiveMacRandomizationWhitelist;
+ private final Set<String> mAggressiveMacRandomizationBlacklist;
+
+ /**
+ * Store the network update listeners.
+ */
+ private final List<OnNetworkUpdateListener> mListeners;
/**
* Flag to indicate if only networks with the same psk should be linked.
* TODO(b/30706406): Remove this flag if unused.
@@ -314,6 +327,7 @@ public class WifiConfigManager {
private final int mMaxNumActiveChannelsForPartialScans;
private final FrameworkFacade mFrameworkFacade;
+ private final DeviceConfigFacade mDeviceConfigFacade;
/**
* Verbose logging flag. Toggled by developer options.
@@ -366,14 +380,10 @@ public class WifiConfigManager {
private final DeletedEphemeralSsidsStoreData mDeletedEphemeralSsidsStoreData;
private final RandomizedMacStoreData mRandomizedMacStoreData;
- // Store the saved network update listener.
- private OnSavedNetworkUpdateListener mListener = null;
private boolean mPnoFrequencyCullingEnabled = false;
private boolean mPnoRecencySortingEnabled = false;
-
-
/**
* Create new instance of WifiConfigManager.
*/
@@ -388,7 +398,8 @@ public class WifiConfigManager {
NetworkListUserStoreData networkListUserStoreData,
DeletedEphemeralSsidsStoreData deletedEphemeralSsidsStoreData,
RandomizedMacStoreData randomizedMacStoreData,
- FrameworkFacade frameworkFacade, Looper looper) {
+ FrameworkFacade frameworkFacade, Handler handler,
+ DeviceConfigFacade deviceConfigFacade) {
mContext = context;
mClock = clock;
mUserManager = userManager;
@@ -404,6 +415,7 @@ public class WifiConfigManager {
mScanDetailCaches = new HashMap<>(16, 0.75f);
mDeletedEphemeralSsidsToTimeMap = new HashMap<>();
mRandomizedMacAddressMapping = new HashMap<>();
+ mListeners = new ArrayList<>();
// Register store data for network list and deleted ephemeral SSIDs.
mNetworkListSharedStoreData = networkListSharedStoreData;
@@ -422,7 +434,7 @@ public class WifiConfigManager {
mFrameworkFacade = frameworkFacade;
mFrameworkFacade.registerContentObserver(mContext, Settings.Global.getUriFor(
Settings.Global.WIFI_PNO_FREQUENCY_CULLING_ENABLED), false,
- new ContentObserver(new Handler(looper)) {
+ new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange) {
updatePnoFrequencyCullingSetting();
@@ -431,7 +443,7 @@ public class WifiConfigManager {
updatePnoFrequencyCullingSetting();
mFrameworkFacade.registerContentObserver(mContext, Settings.Global.getUriFor(
Settings.Global.WIFI_PNO_RECENCY_SORTING_ENABLED), false,
- new ContentObserver(new Handler(looper)) {
+ new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange) {
updatePnoRecencySortingSetting();
@@ -440,12 +452,27 @@ public class WifiConfigManager {
updatePnoRecencySortingSetting();
mConnectedMacRandomzationSupported = mContext.getResources()
.getBoolean(R.bool.config_wifi_connected_mac_randomization_supported);
+ mDeviceConfigFacade = deviceConfigFacade;
+ mAggressiveMacRandomizationWhitelist = new ArraySet<>();
+ mAggressiveMacRandomizationBlacklist = new ArraySet<>();
+
+ mLocalLog = new LocalLog(
+ context.getSystemService(ActivityManager.class).isLowRamDevice() ? 128 : 256);
+
try {
- mSystemUiUid = mContext.getPackageManager().getPackageUidAsUser(SYSUI_PACKAGE_NAME,
- PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
+ // TODO(b/141890172): do not hardcode SYSUI_PACKAGE_NAME
+ mSystemUiUid = mContext
+ .createPackageContextAsUser(SYSUI_PACKAGE_NAME, 0, UserHandle.SYSTEM)
+ .getPackageManager()
+ .getPackageUid(SYSUI_PACKAGE_NAME, PackageManager.MATCH_SYSTEM_ONLY);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable to resolve SystemUI's UID.");
}
+ mMac = WifiConfigurationUtil.obtainMacRandHashFunction(Process.WIFI_UID);
+ if (mMac == null) {
+ Log.wtf(TAG, "Failed to obtain secret for MAC randomization."
+ + " All randomized MAC addresses are lost!");
+ }
}
/**
@@ -465,6 +492,136 @@ public class WifiConfigManager {
}
/**
+ * Determine if the framework should perform "aggressive" MAC randomization when connecting
+ * to the SSID in the input WifiConfiguration.
+ * @param config
+ * @return
+ */
+ private boolean shouldUseAggressiveRandomization(WifiConfiguration config) {
+ if (mDeviceConfigFacade.isAggressiveMacRandomizationSsidWhitelistEnabled()) {
+ return isSsidOptInForAggressiveRandomization(config.SSID);
+ }
+ return false;
+ }
+
+ private boolean isSsidOptInForAggressiveRandomization(String ssid) {
+ if (mAggressiveMacRandomizationBlacklist.contains(ssid)) {
+ return false;
+ }
+ return mAggressiveMacRandomizationWhitelist.contains(ssid);
+ }
+
+ /**
+ * Sets the list of SSIDs that the framework should perform aggressive MAC randomization on.
+ * @param whitelist
+ */
+ public void setAggressiveMacRandomizationWhitelist(Set<String> whitelist) {
+ // TODO: b/137795359 persist this with WifiConfigStore
+ mAggressiveMacRandomizationWhitelist.clear();
+ mAggressiveMacRandomizationWhitelist.addAll(whitelist);
+ }
+
+ /**
+ * Sets the list of SSIDs that the framework will never perform aggressive MAC randomization
+ * on.
+ * @param blacklist
+ */
+ public void setAggressiveMacRandomizationBlacklist(Set<String> blacklist) {
+ mAggressiveMacRandomizationBlacklist.clear();
+ mAggressiveMacRandomizationBlacklist.addAll(blacklist);
+ }
+
+ @VisibleForTesting
+ protected int getRandomizedMacAddressMappingSize() {
+ return mRandomizedMacAddressMapping.size();
+ }
+
+ /**
+ * The persistent randomized MAC address is locally generated for each SSID and does not
+ * change until factory reset of the device. In the initial Q release the per-SSID randomized
+ * MAC is saved on the device, but in an update the storing of randomized MAC is removed.
+ * Instead, the randomized MAC is calculated directly from the SSID and a on device secret.
+ * For backward compatibility, this method first checks the device storage for saved
+ * randomized MAC. If it is not found or the saved MAC is invalid then it will calculate the
+ * randomized MAC directly.
+ *
+ * In the future as devices launched on Q no longer get supported, this method should get
+ * simplified to return the calculated MAC address directly.
+ * @param config the WifiConfiguration to obtain MAC address for.
+ * @return persistent MAC address for this WifiConfiguration
+ */
+ private MacAddress getPersistentMacAddress(WifiConfiguration config) {
+ // mRandomizedMacAddressMapping had been the location to save randomized MAC addresses.
+ String persistentMacString = mRandomizedMacAddressMapping.get(
+ config.getSsidAndSecurityTypeString());
+ // Use the MAC address stored in the storage if it exists and is valid. Otherwise
+ // use the MAC address calculated from a hash function as the persistent MAC.
+ if (persistentMacString != null) {
+ try {
+ return MacAddress.fromString(persistentMacString);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Error creating randomized MAC address from stored value.");
+ mRandomizedMacAddressMapping.remove(config.getSsidAndSecurityTypeString());
+ }
+ }
+ return WifiConfigurationUtil.calculatePersistentMacForConfiguration(config, mMac);
+ }
+
+ /**
+ * Obtain the persistent MAC address by first reading from an internal database. If non exists
+ * then calculate the persistent MAC using HMAC-SHA256.
+ * Finally set the randomized MAC of the configuration to the randomized MAC obtained.
+ * @param config the WifiConfiguration to make the update
+ * @return the persistent MacAddress or null if the operation is unsuccessful
+ */
+ private MacAddress setRandomizedMacToPersistentMac(WifiConfiguration config) {
+ MacAddress persistentMac = getPersistentMacAddress(config);
+ if (persistentMac == null || persistentMac.equals(config.getRandomizedMacAddress())) {
+ return persistentMac;
+ }
+ WifiConfiguration internalConfig = getInternalConfiguredNetwork(config.networkId);
+ internalConfig.setRandomizedMacAddress(persistentMac);
+ internalConfig.randomizedMacLastModifiedTimeMs = mClock.getWallClockMillis();
+ return persistentMac;
+ }
+
+ /**
+ * Re-randomizes the randomized MAC address if needed.
+ * @param config the WifiConfiguration to make the update
+ * @return the updated MacAddress
+ */
+ private MacAddress updateRandomizedMacIfNeeded(WifiConfiguration config) {
+ boolean shouldUpdateMac = config.randomizedMacLastModifiedTimeMs
+ + AGGRESSIVE_MAC_REFRESH_MS
+ < mClock.getWallClockMillis();
+ if (!shouldUpdateMac) {
+ return config.getRandomizedMacAddress();
+ }
+ WifiConfiguration internalConfig = getInternalConfiguredNetwork(config.networkId);
+ internalConfig.setRandomizedMacAddress(MacAddress.createRandomUnicastAddress());
+ internalConfig.randomizedMacLastModifiedTimeMs = mClock.getWallClockMillis();
+ return internalConfig.getRandomizedMacAddress();
+ }
+
+ /**
+ * Returns the randomized MAC address that should be used for this WifiConfiguration.
+ * This API may return a randomized MAC different from the persistent randomized MAC if
+ * the WifiConfiguration is configured for aggressive MAC randomization.
+ * @param config
+ * @return MacAddress
+ */
+ public MacAddress getRandomizedMacAndUpdateIfNeeded(WifiConfiguration config) {
+ MacAddress mac;
+ if (!config.getNetworkSelectionStatus().getHasEverConnected()
+ || !shouldUseAggressiveRandomization(config)) {
+ mac = setRandomizedMacToPersistentMac(config);
+ } else {
+ mac = updateRandomizedMacIfNeeded(config);
+ }
+ return mac;
+ }
+
+ /**
* Enable/disable verbose logging in WifiConfigManager & its helper classes.
*/
public void enableVerboseLogging(int verbose) {
@@ -508,7 +665,8 @@ public class WifiConfigManager {
}
}
}
- if (!TextUtils.isEmpty(configuration.enterpriseConfig.getPassword())) {
+ if (configuration.enterpriseConfig != null && !TextUtils.isEmpty(
+ configuration.enterpriseConfig.getPassword())) {
configuration.enterpriseConfig.setPassword(PASSWORD_MASK);
}
}
@@ -520,8 +678,7 @@ public class WifiConfigManager {
* @param configuration WifiConfiguration to hide the MAC address
*/
private void maskRandomizedMacAddressInWifiConfiguration(WifiConfiguration configuration) {
- MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
- configuration.setRandomizedMacAddress(defaultMac);
+ configuration.setRandomizedMacAddress(DEFAULT_MAC_ADDRESS);
}
/**
@@ -770,8 +927,10 @@ public class WifiConfigManager {
*
* @param config WifiConfiguration object corresponding to the network to be modified.
* @param uid UID of the app requesting the modification.
+ * @param packageName Package name of the app requesting the modification.
*/
- private boolean canModifyNetwork(WifiConfiguration config, int uid) {
+ private boolean canModifyNetwork(WifiConfiguration config, int uid,
+ @Nullable String packageName) {
// System internals can always update networks; they're typically only
// making meteredHint or meteredOverride changes
if (uid == Process.SYSTEM_UID) {
@@ -795,31 +954,21 @@ public class WifiConfigManager {
return true;
}
- final DevicePolicyManagerInternal dpmi =
- mWifiPermissionsWrapper.getDevicePolicyManagerInternal();
-
- final boolean isUidDeviceOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(uid,
- DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ final boolean isDeviceOwner = mWifiPermissionsUtil.isDeviceOwner(uid, packageName);
// If |uid| corresponds to the device owner, allow all modifications.
- if (isUidDeviceOwner) {
+ if (isDeviceOwner) {
return true;
}
final boolean isCreator = (config.creatorUid == uid);
- // Check if device has DPM capability. If it has and |dpmi| is still null, then we
- // treat this case with suspicion and bail out.
- if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)
- && dpmi == null) {
- Log.w(TAG, "Error retrieving DPMI service.");
- return false;
- }
-
// WiFi config lockdown related logic. At this point we know uid is NOT a Device Owner.
- final boolean isConfigEligibleForLockdown = dpmi != null && dpmi.isActiveAdminWithPolicy(
- config.creatorUid, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ final boolean isConfigEligibleForLockdown =
+ mWifiPermissionsUtil.isDeviceOwner(config.creatorUid, config.creatorName);
if (!isConfigEligibleForLockdown) {
+ // App that created the network or settings app (i.e user) has permission to
+ // modify the network.
return isCreator || mWifiPermissionsUtil.checkNetworkSettingsPermission(uid);
}
@@ -827,6 +976,7 @@ public class WifiConfigManager {
final boolean isLockdownFeatureEnabled = Settings.Global.getInt(resolver,
Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0) != 0;
return !isLockdownFeatureEnabled
+ // If not locked down, settings app (i.e user) has permission to modify the network.
&& mWifiPermissionsUtil.checkNetworkSettingsPermission(uid);
}
@@ -846,8 +996,10 @@ public class WifiConfigManager {
if (uid == android.os.Process.SYSTEM_UID || uid == mSystemUiUid) {
return true;
} else {
- return WifiConfigurationUtil.doesUidBelongToAnyProfile(
- uid, mUserManager.getProfiles(mCurrentUserId));
+ UserHandle currentUser = UserHandle.of(mCurrentUserId);
+ UserHandle callingUser = UserHandle.getUserHandleForUid(uid);
+ return currentUser.equals(callingUser)
+ || mUserManager.isSameProfileGroup(currentUser, callingUser);
}
}
@@ -882,6 +1034,7 @@ public class WifiConfigManager {
&& !externalConfig.preSharedKey.equals(PASSWORD_MASK)) {
internalConfig.preSharedKey = externalConfig.preSharedKey;
}
+ internalConfig.saePasswordId = externalConfig.saePasswordId;
// Modify only wep keys are present in the provided configuration. This is a little tricky
// because there is no easy way to tell if the app is actually trying to null out the
// existing keys or not.
@@ -1050,34 +1203,11 @@ public class WifiConfigManager {
packageName != null ? packageName : mContext.getPackageManager().getNameForUid(uid);
newInternalConfig.creationTime = newInternalConfig.updateTime =
createDebugTimeStampString(mClock.getWallClockMillis());
- updateRandomizedMacAddress(newInternalConfig);
-
- return newInternalConfig;
- }
-
- /**
- * Sets the randomized address for the given configuration from stored map if it exist.
- * Otherwise generates a new randomized address and save to the stored map.
- * @param config
- */
- private void updateRandomizedMacAddress(WifiConfiguration config) {
- // Update randomized MAC address according to stored map
- final String key = config.getSsidAndSecurityTypeString();
- // If the key is not found in the current store, then it means this network has never been
- // seen before. So add it to store.
- if (!mRandomizedMacAddressMapping.containsKey(key)) {
- mRandomizedMacAddressMapping.put(key,
- config.getOrCreateRandomizedMacAddress().toString());
- } else { // Otherwise read from the store and set the WifiConfiguration
- try {
- config.setRandomizedMacAddress(
- MacAddress.fromString(mRandomizedMacAddressMapping.get(key)));
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Error creating randomized MAC address from stored value.");
- mRandomizedMacAddressMapping.put(key,
- config.getOrCreateRandomizedMacAddress().toString());
- }
+ MacAddress randomizedMac = getPersistentMacAddress(newInternalConfig);
+ if (randomizedMac != null) {
+ newInternalConfig.setRandomizedMacAddress(randomizedMac);
}
+ return newInternalConfig;
}
/**
@@ -1146,7 +1276,7 @@ public class WifiConfigManager {
return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
}
// Check for the app's permission before we let it update this network.
- if (!canModifyNetwork(existingInternalConfig, uid)) {
+ if (!canModifyNetwork(existingInternalConfig, uid, packageName)) {
Log.e(TAG, "UID " + uid + " does not have permission to update configuration "
+ config.configKey());
return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
@@ -1158,7 +1288,7 @@ public class WifiConfigManager {
// Only add networks with proxy settings if the user has permission to
if (WifiConfigurationUtil.hasProxyChanged(existingInternalConfig, newInternalConfig)
- && !canModifyProxySettings(uid)) {
+ && !canModifyProxySettings(uid, packageName)) {
Log.e(TAG, "UID " + uid + " does not have permission to modify proxy Settings "
+ config.configKey() + ". Must have NETWORK_SETTINGS,"
+ " or be device or profile owner.");
@@ -1210,6 +1340,8 @@ public class WifiConfigManager {
}
if (mDeletedEphemeralSsidsToTimeMap.remove(config.SSID) != null) {
+ updateNetworkSelectionStatus(
+ newInternalConfig, NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Removed from ephemeral blacklist: " + config.SSID);
}
@@ -1262,7 +1394,8 @@ public class WifiConfigManager {
// In this case, new connection for this config won't happen because same
// network is already registered as an ephemeral network.
// Clear the Ephemeral Network to address the situation.
- removeNetwork(existingConfig.networkId, mSystemUiUid);
+ removeNetwork(
+ existingConfig.networkId, existingConfig.creatorUid, config.creatorName);
}
}
@@ -1280,16 +1413,17 @@ public class WifiConfigManager {
// Unless the added network is ephemeral or Passpoint, persist the network update/addition.
if (!config.ephemeral && !config.isPasspoint()) {
saveToStore(true);
- if (mListener != null) {
- if (result.isNewNetwork()) {
- mListener.onSavedNetworkAdded(newConfig.networkId);
- } else {
- mListener.onSavedNetworkUpdated(newConfig.networkId);
- }
+ }
+
+ for (OnNetworkUpdateListener listener : mListeners) {
+ WifiConfiguration configForListener = new WifiConfiguration(newConfig);
+ if (result.isNewNetwork()) {
+ listener.onNetworkAdded(configForListener);
+ } else {
+ listener.onNetworkUpdated(configForListener);
}
}
return result;
-
}
/**
@@ -1343,7 +1477,7 @@ public class WifiConfigManager {
* @param uid UID of the app requesting the network deletion.
* @return true if successful, false otherwise.
*/
- public boolean removeNetwork(int networkId, int uid) {
+ public boolean removeNetwork(int networkId, int uid, String packageName) {
if (!doesUidBelongToCurrentUser(uid)) {
Log.e(TAG, "UID " + uid + " not visible to the current user");
return false;
@@ -1352,7 +1486,7 @@ public class WifiConfigManager {
if (config == null) {
return false;
}
- if (!canModifyNetwork(config, uid)) {
+ if (!canModifyNetwork(config, uid, packageName)) {
Log.e(TAG, "UID " + uid + " does not have permission to delete configuration "
+ config.configKey());
return false;
@@ -1368,7 +1502,10 @@ public class WifiConfigManager {
// Unless the removed network is ephemeral or Passpoint, persist the network removal.
if (!config.ephemeral && !config.isPasspoint()) {
saveToStore(true);
- if (mListener != null) mListener.onSavedNetworkRemoved(networkId);
+ }
+ for (OnNetworkUpdateListener listener : mListeners) {
+ WifiConfiguration configForListener = new WifiConfiguration(config);
+ listener.onNetworkRemoved(configForListener);
}
return true;
}
@@ -1406,8 +1543,8 @@ public class WifiConfigManager {
}
localLog("Removing network " + config.SSID
+ ", application \"" + app.packageName + "\" uninstalled"
- + " from user " + UserHandle.getUserId(app.uid));
- if (removeNetwork(config.networkId, mSystemUiUid)) {
+ + " from user " + UserHandle.getUserHandleForUid(app.uid));
+ if (removeNetwork(config.networkId, config.creatorUid, config.creatorName)) {
removedNetworks.add(config.networkId);
}
}
@@ -1427,11 +1564,11 @@ public class WifiConfigManager {
WifiConfiguration[] copiedConfigs =
mConfiguredNetworks.valuesForAllUsers().toArray(new WifiConfiguration[0]);
for (WifiConfiguration config : copiedConfigs) {
- if (userId != UserHandle.getUserId(config.creatorUid)) {
+ if (userId != UserHandle.getUserHandleForUid(config.creatorUid).getIdentifier()) {
continue;
}
localLog("Removing network " + config.SSID + ", user " + userId + " removed");
- if (removeNetwork(config.networkId, mSystemUiUid)) {
+ if (removeNetwork(config.networkId, config.creatorUid, config.creatorName)) {
removedNetworks.add(config.networkId);
}
}
@@ -1454,11 +1591,11 @@ public class WifiConfigManager {
for (WifiConfiguration config : copiedConfigs) {
if (config.isPasspoint()) {
Log.d(TAG, "Removing passpoint network config " + config.configKey());
- removeNetwork(config.networkId, mSystemUiUid);
+ removeNetwork(config.networkId, config.creatorUid, config.creatorName);
didRemove = true;
} else if (config.ephemeral) {
Log.d(TAG, "Removing ephemeral network config " + config.configKey());
- removeNetwork(config.networkId, mSystemUiUid);
+ removeNetwork(config.networkId, config.creatorUid, config.creatorName);
didRemove = true;
}
}
@@ -1466,20 +1603,31 @@ public class WifiConfigManager {
}
/**
- * Removes the passpoint network configuration matched with {@code fqdn} provided.
+ * Removes the suggestion network configuration matched with {@code configKey} provided.
*
- * @param fqdn Fully Qualified Domain Name to remove.
+ * @param configKey Config Key for the corresponding network suggestion.
* @return true if a network was removed, false otherwise.
*/
- public boolean removePasspointConfiguredNetwork(String fqdn) {
- WifiConfiguration[] copiedConfigs =
- mConfiguredNetworks.valuesForAllUsers().toArray(new WifiConfiguration[0]);
- for (WifiConfiguration config : copiedConfigs) {
- if (config.isPasspoint() && TextUtils.equals(fqdn, config.FQDN)) {
- Log.d(TAG, "Removing passpoint network config " + config.configKey());
- removeNetwork(config.networkId, mSystemUiUid);
- return true;
- }
+ public boolean removeSuggestionConfiguredNetwork(@NonNull String configKey) {
+ WifiConfiguration config = getInternalConfiguredNetwork(configKey);
+ if (config != null && config.ephemeral && config.fromWifiNetworkSuggestion) {
+ Log.d(TAG, "Removing suggestion network config " + config.configKey());
+ return removeNetwork(config.networkId, config.creatorUid, config.creatorName);
+ }
+ return false;
+ }
+
+ /**
+ * Removes the passpoint network configuration matched with {@code configKey} provided.
+ *
+ * @param configKey Config Key for the corresponding passpoint.
+ * @return true if a network was removed, false otherwise.
+ */
+ public boolean removePasspointConfiguredNetwork(@NonNull String configKey) {
+ WifiConfiguration config = getInternalConfiguredNetwork(configKey);
+ if (config != null && config.isPasspoint()) {
+ Log.d(TAG, "Removing passpoint network config " + config.configKey());
+ return removeNetwork(config.networkId, config.creatorUid, config.creatorName);
}
return false;
}
@@ -1497,7 +1645,10 @@ public class WifiConfigManager {
// Clear out all the disable reason counters.
status.clearDisableReasonCounter();
- if (mListener != null) mListener.onSavedNetworkEnabled(config.networkId);
+ for (OnNetworkUpdateListener listener : mListeners) {
+ WifiConfiguration configForListener = new WifiConfiguration(config);
+ listener.onNetworkEnabled(configForListener);
+ }
}
/**
@@ -1511,8 +1662,9 @@ public class WifiConfigManager {
// Only need a valid time filled in for temporarily disabled networks.
status.setDisableTime(mClock.getElapsedSinceBootMillis());
status.setNetworkSelectionDisableReason(disableReason);
- if (mListener != null) {
- mListener.onSavedNetworkTemporarilyDisabled(config.networkId, disableReason);
+ for (OnNetworkUpdateListener listener : mListeners) {
+ WifiConfiguration configForListener = new WifiConfiguration(config);
+ listener.onNetworkTemporarilyDisabled(configForListener, disableReason);
}
}
@@ -1527,8 +1679,9 @@ public class WifiConfigManager {
status.setDisableTime(
NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP);
status.setNetworkSelectionDisableReason(disableReason);
- if (mListener != null) {
- mListener.onSavedNetworkPermanentlyDisabled(config.networkId, disableReason);
+ for (OnNetworkUpdateListener listener : mListeners) {
+ WifiConfiguration configForListener = new WifiConfiguration(config);
+ listener.onNetworkPermanentlyDisabled(configForListener, disableReason);
}
}
@@ -1724,7 +1877,8 @@ public class WifiConfigManager {
* @param uid uid of the app requesting the update.
* @return true if it succeeds, false otherwise
*/
- public boolean enableNetwork(int networkId, boolean disableOthers, int uid) {
+ public boolean enableNetwork(int networkId, boolean disableOthers, int uid,
+ String packageName) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Enabling network " + networkId + " (disableOthers " + disableOthers + ")");
}
@@ -1742,7 +1896,7 @@ public class WifiConfigManager {
if (disableOthers) {
setLastSelectedNetwork(networkId);
}
- if (!canModifyNetwork(config, uid)) {
+ if (!canModifyNetwork(config, uid, packageName)) {
Log.e(TAG, "UID " + uid + " does not have permission to update configuration "
+ config.configKey());
return false;
@@ -1762,7 +1916,7 @@ public class WifiConfigManager {
* @param uid uid of the app requesting the update.
* @return true if it succeeds, false otherwise
*/
- public boolean disableNetwork(int networkId, int uid) {
+ public boolean disableNetwork(int networkId, int uid, String packageName) {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Disabling network " + networkId);
}
@@ -1779,7 +1933,7 @@ public class WifiConfigManager {
if (networkId == mLastSelectedNetworkId) {
clearLastSelectedNetwork();
}
- if (!canModifyNetwork(config, uid)) {
+ if (!canModifyNetwork(config, uid, packageName)) {
Log.e(TAG, "UID " + uid + " does not have permission to update configuration "
+ config.configKey());
return false;
@@ -1793,6 +1947,30 @@ public class WifiConfigManager {
}
/**
+ * Changes the user's choice to allow auto-join using the
+ * {@link WifiManager#allowAutojoin(int, boolean)} API.
+ *
+ * @param networkId network ID of the network that needs the update.
+ * @param choice the choice to allow auto-join or not
+ * @return true if it succeeds, false otherwise
+ */
+ public boolean allowAutojoin(int networkId, boolean choice) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Setting allowAutojoin to " + choice + " for netId " + networkId);
+ }
+ WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+ if (config == null) {
+ Log.e(TAG, "allowAutojoin: Supplied networkId " + networkId
+ + " has no matching config");
+ return false;
+ }
+ config.allowAutojoin = choice;
+ sendConfiguredNetworkChangedBroadcast(config, WifiManager.CHANGE_REASON_CONFIG_CHANGE);
+ saveToStore(true);
+ return true;
+ }
+
+ /**
* Updates the last connected UID for the provided configuration.
*
* @param networkId network ID corresponding to the network.
@@ -1890,22 +2068,6 @@ public class WifiConfigManager {
}
/**
- * Set randomized MAC address for the provided network.
- *
- * @param networkId network ID corresponding to the network.
- * @param macAddress Randomized MAC address to be used for network connection.
- * @return true if the network was found, false otherwise.
- */
- public boolean setNetworkRandomizedMacAddress(int networkId, MacAddress macAddress) {
- WifiConfiguration config = getInternalConfiguredNetwork(networkId);
- if (config == null) {
- return false;
- }
- config.setRandomizedMacAddress(macAddress);
- return true;
- }
-
- /**
* Clear the {@link NetworkSelectionStatus#mCandidate},
* {@link NetworkSelectionStatus#mCandidateScore} &
* {@link NetworkSelectionStatus#mSeenInLastQualifiedNetworkSelection} for the provided network.
@@ -2708,6 +2870,16 @@ public class WifiConfigManager {
return hiddenList;
}
+ private @Nullable WifiConfiguration getInternalEphemeralConfiguredNetwork(
+ @NonNull String ssid) {
+ for (WifiConfiguration config : getInternalConfiguredNetworks()) {
+ if ((config.ephemeral || config.isPasspoint()) && TextUtils.equals(config.SSID, ssid)) {
+ return config;
+ }
+ }
+ return null;
+ }
+
/**
* Check if the provided ephemeral network was deleted by the user or not. This call also clears
* the SSID from the deleted ephemeral network map, if the duration has expired the
@@ -2726,6 +2898,11 @@ public class WifiConfigManager {
// Clear the ssid from the map if the age > |DELETED_EPHEMERAL_SSID_EXPIRY_MS|.
if (nowInMs - deletedTimeInMs > DELETED_EPHEMERAL_SSID_EXPIRY_MS) {
mDeletedEphemeralSsidsToTimeMap.remove(ssid);
+ WifiConfiguration foundConfig = getInternalEphemeralConfiguredNetwork(ssid);
+ if (foundConfig != null) {
+ updateNetworkSelectionStatus(
+ foundConfig, NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
+ }
return false;
}
return true;
@@ -2747,16 +2924,13 @@ public class WifiConfigManager {
if (ssid == null) {
return null;
}
- WifiConfiguration foundConfig = null;
- for (WifiConfiguration config : getInternalConfiguredNetworks()) {
- if ((config.ephemeral || config.isPasspoint()) && TextUtils.equals(config.SSID, ssid)) {
- foundConfig = config;
- break;
- }
- }
+ WifiConfiguration foundConfig = getInternalEphemeralConfiguredNetwork(ssid);
if (foundConfig == null) return null;
// Store the ssid & the wall clock time at which the network was disabled.
mDeletedEphemeralSsidsToTimeMap.put(ssid, mClock.getWallClockMillis());
+ // Also, mark the ephemeral permanently blacklisted. Will be taken out of blacklist
+ // when the ssid is taken out of |mDeletedEphemeralSsidsToTimeMap|.
+ updateNetworkSelectionStatus(foundConfig, NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER);
Log.d(TAG, "Forget ephemeral SSID " + ssid + " num="
+ mDeletedEphemeralSsidsToTimeMap.size());
if (foundConfig.ephemeral) {
@@ -2867,15 +3041,15 @@ public class WifiConfigManager {
mPendingUnlockStoreRead = true;
return new HashSet<>();
}
- if (mUserManager.isUserUnlockingOrUnlocked(mCurrentUserId)) {
+ if (mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(mCurrentUserId))) {
saveToStore(true);
}
// Remove any private networks of the old user before switching the userId.
- Set<Integer> removedNetworkIds = clearInternalUserData(mCurrentUserId);
+ Set<Integer> removedNetworkIds = clearInternalDataForCurrentUser();
mConfiguredNetworks.setNewUser(userId);
mCurrentUserId = userId;
- if (mUserManager.isUserUnlockingOrUnlocked(mCurrentUserId)) {
+ if (mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(mCurrentUserId))) {
handleUserUnlockOrSwitch(mCurrentUserId);
} else {
// Cannot read data from new user's CE store file before they log-in.
@@ -2923,9 +3097,10 @@ public class WifiConfigManager {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Handling user stop for " + userId);
}
- if (userId == mCurrentUserId && mUserManager.isUserUnlockingOrUnlocked(mCurrentUserId)) {
+ if (userId == mCurrentUserId
+ && mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(mCurrentUserId))) {
saveToStore(true);
- clearInternalUserData(mCurrentUserId);
+ clearInternalDataForCurrentUser();
}
}
@@ -2952,17 +3127,15 @@ public class WifiConfigManager {
* - Map of scan detail caches.
* - List of deleted ephemeral networks.
*
- * @param userId The identifier of the current foreground user, before the switch.
* @return List of network ID's of all the private networks of the old user which will be
* removed from memory.
*/
- private Set<Integer> clearInternalUserData(int userId) {
- localLog("clearInternalUserData: Clearing user internal data for " + userId);
+ private Set<Integer> clearInternalDataForCurrentUser() {
+ localLog("clearInternalUserData: Clearing user internal data for " + mCurrentUserId);
Set<Integer> removedNetworkIds = new HashSet<>();
// Remove any private networks of the old user before switching the userId.
for (WifiConfiguration config : getInternalConfiguredNetworks()) {
- if (!config.shared && WifiConfigurationUtil.doesUidBelongToAnyProfile(
- config.creatorUid, mUserManager.getProfiles(userId))) {
+ if (!config.shared && doesUidBelongToCurrentUser(config.creatorUid)) {
removedNetworkIds.add(config.networkId);
localLog("clearInternalUserData: removed config."
+ " netId=" + config.networkId
@@ -3026,12 +3199,16 @@ public class WifiConfigManager {
}
/**
- * Generate randomized MAC addresses for configured networks and persist mapping to storage.
+ * Assign randomized MAC addresses for configured networks.
+ * This is needed to generate persistent randomized MAC address for existing networks when
+ * a device updates to Q+ for the first time since we are not calling addOrUpdateNetwork when
+ * we load configuration at boot.
*/
private void generateRandomizedMacAddresses() {
for (WifiConfiguration config : getInternalConfiguredNetworks()) {
- mRandomizedMacAddressMapping.put(config.getSsidAndSecurityTypeString(),
- config.getOrCreateRandomizedMacAddress().toString());
+ if (DEFAULT_MAC_ADDRESS.equals(config.getRandomizedMacAddress())) {
+ setRandomizedMacToPersistentMac(config);
+ }
}
}
@@ -3168,8 +3345,7 @@ public class WifiConfigManager {
// Migrate the legacy Passpoint configurations owned by the current user to
// {@link PasspointManager}.
- if (config.isLegacyPasspointConfig && WifiConfigurationUtil.doesUidBelongToAnyProfile(
- config.creatorUid, mUserManager.getProfiles(mCurrentUserId))) {
+ if (config.isLegacyPasspointConfig && doesUidBelongToCurrentUser(config.creatorUid)) {
legacyPasspointNetId.add(config.networkId);
// Migrate the legacy Passpoint configuration and add it to PasspointManager.
if (!PasspointManager.addLegacyPasspointConfig(config)) {
@@ -3186,8 +3362,7 @@ public class WifiConfigManager {
// because all networks were previously stored in a central file. We cannot
// write these private networks to the user specific store until the corresponding
// user logs in.
- if (config.shared || !WifiConfigurationUtil.doesUidBelongToAnyProfile(
- config.creatorUid, mUserManager.getProfiles(mCurrentUserId))) {
+ if (config.shared || !doesUidBelongToCurrentUser(config.creatorUid)) {
sharedConfigurations.add(config);
} else {
userConfigurations.add(config);
@@ -3251,19 +3426,15 @@ public class WifiConfigManager {
/**
* Returns true if the given uid has permission to add, update or remove proxy settings
*/
- private boolean canModifyProxySettings(int uid) {
- final DevicePolicyManagerInternal dpmi =
- mWifiPermissionsWrapper.getDevicePolicyManagerInternal();
- final boolean isUidProfileOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(uid,
- DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- final boolean isUidDeviceOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(uid,
- DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ private boolean canModifyProxySettings(int uid, String packageName) {
+ final boolean isDeviceOwner = mWifiPermissionsUtil.isDeviceOwner(uid, packageName);
+ final boolean isProfileOwner = mWifiPermissionsUtil.isProfileOwner(uid, packageName);
final boolean hasNetworkSettingsPermission =
mWifiPermissionsUtil.checkNetworkSettingsPermission(uid);
final boolean hasNetworkSetupWizardPermission =
mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid);
// If |uid| corresponds to the device owner, allow all modifications.
- if (isUidDeviceOwner || isUidProfileOwner || hasNetworkSettingsPermission
+ if (isProfileOwner || isDeviceOwner || hasNetworkSettingsPermission
|| hasNetworkSetupWizardPermission) {
return true;
}
@@ -3271,17 +3442,17 @@ public class WifiConfigManager {
Log.v(TAG, "UID: " + uid + " cannot modify WifiConfiguration proxy settings."
+ " hasNetworkSettings=" + hasNetworkSettingsPermission
+ " hasNetworkSetupWizard=" + hasNetworkSetupWizardPermission
- + " DeviceOwner=" + isUidDeviceOwner
- + " ProfileOwner=" + isUidProfileOwner);
+ + " DeviceOwner=" + isDeviceOwner
+ + " ProfileOwner=" + isProfileOwner);
}
return false;
}
/**
- * Set the saved network update event listener
+ * Set the network update event listener
*/
- public void setOnSavedNetworkUpdateListener(OnSavedNetworkUpdateListener listener) {
- mListener = listener;
+ public void addOnNetworkUpdateListener(OnNetworkUpdateListener listener) {
+ mListeners.add(listener);
}
/**
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index e189d00e1d..083f442ca9 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -23,20 +23,19 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
import android.content.Context;
-import android.os.Environment;
-import android.os.FileUtils;
import android.os.Handler;
-import android.os.Looper;
+import android.util.AtomicFile;
import android.util.Log;
import android.util.SparseArray;
import android.util.Xml;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.AtomicFile;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.server.wifi.util.DataIntegrityChecker;
import com.android.server.wifi.util.EncryptedData;
+import com.android.server.wifi.util.Environment;
+import com.android.server.wifi.util.FileUtils;
import com.android.server.wifi.util.XmlUtil;
import org.xmlpull.v1.XmlPullParser;
@@ -218,17 +217,17 @@ public class WifiConfigStore {
* Note: The store file instances have been made inputs to this class to ease unit-testing.
*
* @param context context to use for retrieving the alarm manager.
- * @param looper looper instance to post alarm timeouts to.
+ * @param handler handler instance to post alarm timeouts to.
* @param clock clock instance to retrieve timestamps for alarms.
* @param wifiMetrics Metrics instance.
* @param sharedStore StoreFile instance pointing to the shared store file. This should
* be retrieved using {@link #createSharedFile()} method.
*/
- public WifiConfigStore(Context context, Looper looper, Clock clock, WifiMetrics wifiMetrics,
+ public WifiConfigStore(Context context, Handler handler, Clock clock, WifiMetrics wifiMetrics,
StoreFile sharedStore) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- mEventHandler = new Handler(looper);
+ mEventHandler = handler;
mClock = clock;
mWifiMetrics = wifiMetrics;
mStoreDataList = new ArrayList<>();
@@ -685,15 +684,16 @@ public class WifiConfigStore {
String[] headerName = new String[1];
Set<StoreData> storeDatasInvoked = new HashSet<>();
while (XmlUtil.gotoNextSectionOrEnd(in, headerName, rootTagDepth)) {
- // There can only be 1 store data matching the tag (O indicates a fatal
- // error).
+ // There can only be 1 store data matching the tag, O indicates a previous StoreData
+ // module that no longer exists (ignore this XML section).
StoreData storeData = storeDataList.stream()
.filter(s -> s.getName().equals(headerName[0]))
.findAny()
.orElse(null);
if (storeData == null) {
- throw new XmlPullParserException("Unknown store data: " + headerName[0]
- + ". List of store data: " + storeDataList);
+ Log.e(TAG, "Unknown store data: " + headerName[0] + ". List of store data: "
+ + storeDataList);
+ continue;
}
storeData.deserializeData(in, rootTagDepth + 1);
storeDatasInvoked.add(storeData);
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index 59d3eb3f49..f79cc9230e 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -18,7 +18,6 @@ package com.android.server.wifi;
import static com.android.server.wifi.util.NativeUtil.addEnclosingQuotes;
-import android.content.pm.UserInfo;
import android.net.IpConfiguration;
import android.net.MacAddress;
import android.net.StaticIpConfiguration;
@@ -27,7 +26,9 @@ import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiScanner;
import android.os.PatternMatcher;
-import android.os.UserHandle;
+import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -36,14 +37,27 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.util.NativeUtil;
import com.android.server.wifi.util.TelephonyUtil;
+import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.ProviderException;
+import java.security.UnrecoverableKeyException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Comparator;
-import java.util.List;
import java.util.Objects;
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+
/**
* WifiConfiguration utility for any {@link android.net.wifi.WifiConfiguration} related operations.
* Currently contains:
@@ -65,44 +79,19 @@ public class WifiConfigurationUtil {
private static final int SAE_ASCII_MIN_LEN = 1 + ENCLOSING_QUOTES_LEN;
private static final int PSK_SAE_ASCII_MAX_LEN = 63 + ENCLOSING_QUOTES_LEN;
private static final int PSK_SAE_HEX_LEN = 64;
+ private static final MacAddress ALL_ZEROS_MAC_ADDRESS =
+ MacAddress.fromString("00:00:00:00:00:00");
@VisibleForTesting
public static final String PASSWORD_MASK = "*";
private static final String MATCH_EMPTY_SSID_PATTERN_PATH = "";
private static final Pair<MacAddress, MacAddress> MATCH_NONE_BSSID_PATTERN =
new Pair(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS);
private static final Pair<MacAddress, MacAddress> MATCH_ALL_BSSID_PATTERN =
- new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
-
- /**
- * Check whether a network configuration is visible to a user or any of its managed profiles.
- *
- * @param config the network configuration whose visibility should be checked
- * @param profiles the user IDs of the user itself and all its managed profiles (can be obtained
- * via {@link android.os.UserManager#getProfiles})
- * @return whether the network configuration is visible to the user or any of its managed
- * profiles
- */
- public static boolean isVisibleToAnyProfile(WifiConfiguration config, List<UserInfo> profiles) {
- return (config.shared || doesUidBelongToAnyProfile(config.creatorUid, profiles));
- }
-
- /**
- * Check whether a uid belong to a user or any of its managed profiles.
- *
- * @param uid uid of the app.
- * @param profiles the user IDs of the user itself and all its managed profiles (can be obtained
- * via {@link android.os.UserManager#getProfiles})
- * @return whether the uid belongs to the user or any of its managed profiles.
- */
- public static boolean doesUidBelongToAnyProfile(int uid, List<UserInfo> profiles) {
- final int userId = UserHandle.getUserId(uid);
- for (UserInfo profile : profiles) {
- if (profile.id == userId) {
- return true;
- }
- }
- return false;
- }
+ new Pair(ALL_ZEROS_MAC_ADDRESS, ALL_ZEROS_MAC_ADDRESS);
+ private static final String MAC_RANDOMIZATION_ALIAS = "MacRandSecret";
+ private static final long MAC_ADDRESS_VALID_LONG_MASK = (1L << 48) - 1;
+ private static final long MAC_ADDRESS_LOCALLY_ASSIGNED_MASK = 1L << 41;
+ private static final long MAC_ADDRESS_MULTICAST_MASK = 1L << 40;
/**
* Checks if the provided |wepKeys| array contains any non-null value;
@@ -227,6 +216,87 @@ public class WifiConfigurationUtil {
}
/**
+ * Computes the persistent randomized MAC of the given configuration using the given
+ * hash function.
+ * @param config the WifiConfiguration to compute MAC address for
+ * @param hashFunction the hash function that will perform the MAC address computation.
+ * @return The persistent randomized MAC address or null if inputs are invalid.
+ */
+ public static MacAddress calculatePersistentMacForConfiguration(WifiConfiguration config,
+ Mac hashFunction) {
+ if (config == null || hashFunction == null) {
+ return null;
+ }
+ byte[] hashedBytes = hashFunction.doFinal(
+ config.getSsidAndSecurityTypeString().getBytes(StandardCharsets.UTF_8));
+ ByteBuffer bf = ByteBuffer.wrap(hashedBytes);
+ long longFromSsid = bf.getLong();
+ /**
+ * Masks the generated long so that it represents a valid randomized MAC address.
+ * Specifically, this sets the locally assigned bit to 1, multicast bit to 0
+ */
+ longFromSsid &= MAC_ADDRESS_VALID_LONG_MASK;
+ longFromSsid |= MAC_ADDRESS_LOCALLY_ASSIGNED_MASK;
+ longFromSsid &= ~MAC_ADDRESS_MULTICAST_MASK;
+ bf.clear();
+ bf.putLong(0, longFromSsid);
+
+ // MacAddress.fromBytes requires input of length 6, which is obtained from the
+ // last 6 bytes from the generated long.
+ MacAddress macAddress = MacAddress.fromBytes(Arrays.copyOfRange(bf.array(), 2, 8));
+ return macAddress;
+ }
+
+ /**
+ * Retrieves a Hash function that could be used to calculate the persistent randomized MAC
+ * for a WifiConfiguration.
+ * @param uid the UID of the KeyStore to get the secret of the hash function from.
+ */
+ public static Mac obtainMacRandHashFunction(int uid) {
+ try {
+ KeyStore keyStore = AndroidKeyStoreProvider.getKeyStoreForUid(uid);
+ // tries to retrieve the secret, and generate a new one if it's unavailable.
+ Key key = keyStore.getKey(MAC_RANDOMIZATION_ALIAS, null);
+ if (key == null) {
+ key = generateAndPersistNewMacRandomizationSecret(uid);
+ }
+ if (key == null) {
+ Log.e(TAG, "Failed to generate secret for " + MAC_RANDOMIZATION_ALIAS);
+ return null;
+ }
+ Mac result = Mac.getInstance("HmacSHA256");
+ result.init(key);
+ return result;
+ } catch (KeyStoreException | NoSuchAlgorithmException | InvalidKeyException
+ | UnrecoverableKeyException | NoSuchProviderException e) {
+ Log.e(TAG, "Failure in obtainMacRandHashFunction", e);
+ return null;
+ }
+ }
+
+ /**
+ * Generates and returns a secret key to use for Mac randomization.
+ * Will also persist the generated secret inside KeyStore, accessible in the
+ * future with KeyGenerator#getKey.
+ */
+ private static SecretKey generateAndPersistNewMacRandomizationSecret(int uid) {
+ try {
+ KeyGenerator keyGenerator = KeyGenerator.getInstance(
+ KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore");
+ keyGenerator.init(
+ new KeyGenParameterSpec.Builder(MAC_RANDOMIZATION_ALIAS,
+ KeyProperties.PURPOSE_SIGN)
+ .setUid(uid)
+ .build());
+ return keyGenerator.generateKey();
+ } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
+ | NoSuchProviderException | ProviderException e) {
+ Log.e(TAG, "Failure in generateMacRandomizationSecret", e);
+ return null;
+ }
+ }
+
+ /**
* Compare existing and new WifiEnterpriseConfig objects after a network update and return if
* credential parameters have changed or not.
*
@@ -639,8 +709,8 @@ public class WifiConfigurationUtil {
Log.e(TAG, "validateBssidPatternMatcher failed : invalid base address: " + baseAddress);
return false;
}
- if (mask.equals(MacAddress.ALL_ZEROS_ADDRESS)
- && !baseAddress.equals(MacAddress.ALL_ZEROS_ADDRESS)) {
+ if (mask.equals(ALL_ZEROS_MAC_ADDRESS)
+ && !baseAddress.equals(ALL_ZEROS_MAC_ADDRESS)) {
Log.e(TAG, "validateBssidPatternMatcher failed : invalid mask/base: " + mask + "/"
+ baseAddress);
return false;
diff --git a/service/java/com/android/server/wifi/WifiConnectivityHelper.java b/service/java/com/android/server/wifi/WifiConnectivityHelper.java
index ed541a9591..248877f3bb 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityHelper.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityHelper.java
@@ -29,7 +29,7 @@ import java.util.ArrayList;
* access WifiNative. It starts with firmware roaming. TODO(b/34819513): Move operations
* such as connection to network and legacy framework roaming here.
*
- * NOTE: This class is not thread safe and should only be used from the ClientModeImpl thread.
+ * NOTE: This class is not thread safe and should only be used from the main Wifi thread.
*/
public class WifiConnectivityHelper {
private static final String TAG = "WifiConnectivityHelper";
@@ -162,14 +162,4 @@ public class WifiConnectivityHelper {
return mWifiNative.configureRoaming(mWifiNative.getClientInterfaceName(), roamConfig);
}
-
- /**
- * Remove the request |networkId| from supplicant if it's the current network,
- * if the current configured network matches |networkId|.
- *
- * @param networkId network id of the network to be removed from supplicant.
- */
- public void removeNetworkIfCurrent(int networkId) {
- mWifiNative.removeNetworkIfCurrent(mWifiNative.getClientInterfaceName(), networkId);
- }
}
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 2e4b5c891a..b1d0a05fe9 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -16,9 +16,6 @@
package com.android.server.wifi;
-import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT;
-import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY;
-
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.server.wifi.ClientModeImpl.WIFI_WORK_SOURCE;
@@ -34,7 +31,6 @@ import android.net.wifi.WifiScanner;
import android.net.wifi.WifiScanner.PnoSettings;
import android.net.wifi.WifiScanner.ScanSettings;
import android.os.Handler;
-import android.os.Looper;
import android.os.Process;
import android.os.WorkSource;
import android.util.LocalLog;
@@ -143,7 +139,6 @@ public class WifiConnectivityManager {
private final WifiNetworkSelector mNetworkSelector;
private final WifiLastResortWatchdog mWifiLastResortWatchdog;
private final OpenNetworkNotifier mOpenNetworkNotifier;
- private final CarrierNetworkNotifier mCarrierNetworkNotifier;
private final CarrierNetworkConfig mCarrierNetworkConfig;
private final WifiMetrics mWifiMetrics;
private final AlarmManager mAlarmManager;
@@ -289,11 +284,6 @@ public class WifiConnectivityManager {
if (mWifiState == WIFI_STATE_DISCONNECTED) {
mOpenNetworkNotifier.handleScanResults(
mNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks());
- if (mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()) {
- mCarrierNetworkNotifier.handleScanResults(
- mNetworkSelector.getFilteredScanDetailsForCarrierUnsavedNetworks(
- mCarrierNetworkConfig));
- }
}
return false;
}
@@ -539,39 +529,29 @@ public class WifiConnectivityManager {
private final PnoScanListener mPnoScanListener = new PnoScanListener();
- private class OnSavedNetworkUpdateListener implements
- WifiConfigManager.OnSavedNetworkUpdateListener {
+ private class OnNetworkUpdateListener implements
+ WifiConfigManager.OnNetworkUpdateListener {
@Override
- public void onSavedNetworkAdded(int networkId) {
+ public void onNetworkAdded(WifiConfiguration config) {
updatePnoScan();
}
@Override
- public void onSavedNetworkEnabled(int networkId) {
+ public void onNetworkEnabled(WifiConfiguration config) {
updatePnoScan();
}
@Override
- public void onSavedNetworkRemoved(int networkId) {
+ public void onNetworkRemoved(WifiConfiguration config) {
updatePnoScan();
}
@Override
- public void onSavedNetworkUpdated(int networkId) {
- // User might have changed meteredOverride, so update capabilties
- mStateMachine.updateCapabilities();
+ public void onNetworkUpdated(WifiConfiguration config) {
updatePnoScan();
}
@Override
- public void onSavedNetworkTemporarilyDisabled(int networkId, int disableReason) {
- if (disableReason == DISABLED_NO_INTERNET_TEMPORARY) return;
- mConnectivityHelper.removeNetworkIfCurrent(networkId);
- }
+ public void onNetworkTemporarilyDisabled(WifiConfiguration config, int disableReason) { }
+
@Override
- public void onSavedNetworkPermanentlyDisabled(int networkId, int disableReason) {
- // For DISABLED_NO_INTERNET_PERMANENT we do not need to remove the network
- // because supplicant won't be trying to reconnect. If this is due to a
- // preventAutomaticReconnect request from ConnectivityService, that service
- // will disconnect as appropriate.
- if (disableReason == DISABLED_NO_INTERNET_PERMANENT) return;
- mConnectivityHelper.removeNetworkIfCurrent(networkId);
+ public void onNetworkPermanentlyDisabled(WifiConfiguration config, int disableReason) {
updatePnoScan();
}
private void updatePnoScan() {
@@ -592,8 +572,7 @@ public class WifiConnectivityManager {
WifiInjector injector, WifiConfigManager configManager, WifiInfo wifiInfo,
WifiNetworkSelector networkSelector, WifiConnectivityHelper connectivityHelper,
WifiLastResortWatchdog wifiLastResortWatchdog, OpenNetworkNotifier openNetworkNotifier,
- CarrierNetworkNotifier carrierNetworkNotifier,
- CarrierNetworkConfig carrierNetworkConfig, WifiMetrics wifiMetrics, Looper looper,
+ CarrierNetworkConfig carrierNetworkConfig, WifiMetrics wifiMetrics, Handler handler,
Clock clock, LocalLog localLog) {
mStateMachine = stateMachine;
mWifiInjector = injector;
@@ -604,11 +583,10 @@ public class WifiConnectivityManager {
mLocalLog = localLog;
mWifiLastResortWatchdog = wifiLastResortWatchdog;
mOpenNetworkNotifier = openNetworkNotifier;
- mCarrierNetworkNotifier = carrierNetworkNotifier;
mCarrierNetworkConfig = carrierNetworkConfig;
mWifiMetrics = wifiMetrics;
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- mEventHandler = new Handler(looper);
+ mEventHandler = handler;
mClock = clock;
mScoringParams = scoringParams;
mConnectionAttemptTimeStamps = new LinkedList<>();
@@ -647,7 +625,7 @@ public class WifiConnectivityManager {
+ " initialScoreMax " + initialScoreMax());
// Listen to WifiConfigManager network update events
- mConfigManager.setOnSavedNetworkUpdateListener(new OnSavedNetworkUpdateListener());
+ mConfigManager.addOnNetworkUpdateListener(new OnNetworkUpdateListener());
}
/** Returns maximum PNO score, before any awards/bonuses. */
@@ -1146,7 +1124,6 @@ public class WifiConnectivityManager {
mScreenOn = screenOn;
mOpenNetworkNotifier.handleScreenStateChanged(screenOn);
- mCarrierNetworkNotifier.handleScreenStateChanged(screenOn);
startConnectivityScan(SCAN_ON_SCHEDULE);
}
@@ -1197,10 +1174,8 @@ public class WifiConnectivityManager {
? null
: mWifiInfo.getWifiSsid().toString();
mOpenNetworkNotifier.handleWifiConnected(ssid);
- mCarrierNetworkNotifier.handleWifiConnected(ssid);
} else {
mOpenNetworkNotifier.handleConnectionFailure();
- mCarrierNetworkNotifier.handleConnectionFailure();
}
}
@@ -1390,9 +1365,13 @@ public class WifiConnectivityManager {
}
int maxBlacklistSize = mConnectivityHelper.getMaxNumBlacklistBssid();
- if (maxBlacklistSize <= 0) {
+ if (maxBlacklistSize < 0) {
Log.wtf(TAG, "Invalid max BSSID blacklist size: " + maxBlacklistSize);
return;
+ } else if (maxBlacklistSize == 0) {
+ Log.d(TAG, "Skip setting firmware roaming configuration" +
+ " since max BSSID blacklist size is zero");
+ return;
}
ArrayList<String> blacklistedBssids = new ArrayList<String>(buildBssidBlacklist());
@@ -1485,7 +1464,6 @@ public class WifiConnectivityManager {
clearBssidBlacklist();
resetLastPeriodicSingleScanTimeStamp();
mOpenNetworkNotifier.clearPendingNotification(true /* resetRepeatDelay */);
- mCarrierNetworkNotifier.clearPendingNotification(true /* resetRepeatDelay */);
mLastConnectionAttemptBssid = null;
mWaitForFullBandScanResults = false;
}
@@ -1545,7 +1523,6 @@ public class WifiConnectivityManager {
mLocalLog.dump(fd, pw, args);
pw.println("WifiConnectivityManager - Log End ----");
mOpenNetworkNotifier.dump(fd, pw, args);
- mCarrierNetworkNotifier.dump(fd, pw, args);
mCarrierNetworkConfig.dump(fd, pw, args);
}
}
diff --git a/service/java/com/android/server/wifi/WifiController.java b/service/java/com/android/server/wifi/WifiController.java
deleted file mode 100644
index bfa2ae0331..0000000000
--- a/service/java/com/android/server/wifi/WifiController.java
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.location.LocationManager;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.internal.R;
-import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.server.wifi.util.WifiPermissionsUtil;
-
-/**
- * WifiController is the class used to manage wifi state for various operating
- * modes (normal, airplane, wifi hotspot, etc.).
- */
-public class WifiController extends StateMachine {
- private static final String TAG = "WifiController";
- private static final boolean DBG = false;
- private Context mContext;
- private boolean mFirstUserSignOnSeen = false;
-
- /**
- * See {@link Settings.Global#WIFI_REENABLE_DELAY_MS}. This is the default value if a
- * Settings.Global value is not present. This is the minimum time after wifi is disabled
- * we'll act on an enable. Enable requests received before this delay will be deferred.
- */
- private static final long DEFAULT_REENABLE_DELAY_MS = 500;
-
- // Maximum limit to use for timeout delay if the value from overlay setting is too large.
- private static final int MAX_RECOVERY_TIMEOUT_DELAY_MS = 4000;
-
- // finding that delayed messages can sometimes be delivered earlier than expected
- // probably rounding errors. add a margin to prevent problems
- private static final long DEFER_MARGIN_MS = 5;
-
- /* References to values tracked in WifiService */
- private final ClientModeImpl mClientModeImpl;
- private final Looper mClientModeImplLooper;
- private final ActiveModeWarden mActiveModeWarden;
- private final WifiSettingsStore mSettingsStore;
- private final FrameworkFacade mFacade;
- private final WifiPermissionsUtil mWifiPermissionsUtil;
-
- private long mReEnableDelayMillis;
-
- private int mRecoveryDelayMillis;
-
- private static final int BASE = Protocol.BASE_WIFI_CONTROLLER;
-
- static final int CMD_EMERGENCY_MODE_CHANGED = BASE + 1;
- static final int CMD_SCAN_ALWAYS_MODE_CHANGED = BASE + 7;
- static final int CMD_WIFI_TOGGLED = BASE + 8;
- static final int CMD_AIRPLANE_TOGGLED = BASE + 9;
- static final int CMD_SET_AP = BASE + 10;
- static final int CMD_DEFERRED_TOGGLE = BASE + 11;
- static final int CMD_AP_START_FAILURE = BASE + 13;
- static final int CMD_EMERGENCY_CALL_STATE_CHANGED = BASE + 14;
- static final int CMD_AP_STOPPED = BASE + 15;
- static final int CMD_STA_START_FAILURE = BASE + 16;
- // Command used to trigger a wifi stack restart when in active mode
- static final int CMD_RECOVERY_RESTART_WIFI = BASE + 17;
- // Internal command used to complete wifi stack restart
- private static final int CMD_RECOVERY_RESTART_WIFI_CONTINUE = BASE + 18;
- // Command to disable wifi when SelfRecovery is throttled or otherwise not doing full recovery
- static final int CMD_RECOVERY_DISABLE_WIFI = BASE + 19;
- static final int CMD_STA_STOPPED = BASE + 20;
- static final int CMD_SCANNING_STOPPED = BASE + 21;
- static final int CMD_DEFERRED_RECOVERY_RESTART_WIFI = BASE + 22;
-
- private DefaultState mDefaultState = new DefaultState();
- private StaEnabledState mStaEnabledState = new StaEnabledState();
- private StaDisabledState mStaDisabledState = new StaDisabledState();
- private StaDisabledWithScanState mStaDisabledWithScanState = new StaDisabledWithScanState();
- private EcmState mEcmState = new EcmState();
-
- private ScanOnlyModeManager.Listener mScanOnlyModeCallback = new ScanOnlyCallback();
- private ClientModeManager.Listener mClientModeCallback = new ClientModeCallback();
-
- WifiController(Context context, ClientModeImpl clientModeImpl, Looper clientModeImplLooper,
- WifiSettingsStore wss, Looper wifiServiceLooper, FrameworkFacade f,
- ActiveModeWarden amw, WifiPermissionsUtil wifiPermissionsUtil) {
- super(TAG, wifiServiceLooper);
- mFacade = f;
- mContext = context;
- mClientModeImpl = clientModeImpl;
- mClientModeImplLooper = clientModeImplLooper;
- mActiveModeWarden = amw;
- mSettingsStore = wss;
- mWifiPermissionsUtil = wifiPermissionsUtil;
-
- // CHECKSTYLE:OFF IndentationCheck
- addState(mDefaultState);
- addState(mStaDisabledState, mDefaultState);
- addState(mStaEnabledState, mDefaultState);
- addState(mStaDisabledWithScanState, mDefaultState);
- addState(mEcmState, mDefaultState);
- // CHECKSTYLE:ON IndentationCheck
-
- setLogRecSize(100);
- setLogOnlyTransitions(false);
-
- // register for state updates via callbacks (vs the intents registered below)
- mActiveModeWarden.registerScanOnlyCallback(mScanOnlyModeCallback);
- mActiveModeWarden.registerClientModeCallback(mClientModeCallback);
-
- readWifiReEnableDelay();
- readWifiRecoveryDelay();
- }
-
- @Override
- public void start() {
- boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn();
- boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled();
- boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable();
- boolean isLocationModeActive = mWifiPermissionsUtil.isLocationModeEnabled();
-
- log("isAirplaneModeOn = " + isAirplaneModeOn
- + ", isWifiEnabled = " + isWifiEnabled
- + ", isScanningAvailable = " + isScanningAlwaysAvailable
- + ", isLocationModeActive = " + isLocationModeActive);
-
- if (checkScanOnlyModeAvailable()) {
- setInitialState(mStaDisabledWithScanState);
- } else {
- setInitialState(mStaDisabledState);
- }
- IntentFilter filter = new IntentFilter();
- filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
- filter.addAction(LocationManager.MODE_CHANGED_ACTION);
- mContext.registerReceiver(
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
- int state = intent.getIntExtra(
- WifiManager.EXTRA_WIFI_AP_STATE,
- WifiManager.WIFI_AP_STATE_FAILED);
- if (state == WifiManager.WIFI_AP_STATE_FAILED) {
- Log.e(TAG, "SoftAP start failed");
- sendMessage(CMD_AP_START_FAILURE);
- } else if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
- sendMessage(CMD_AP_STOPPED);
- }
- } else if (action.equals(LocationManager.MODE_CHANGED_ACTION)) {
- // Location mode has been toggled... trigger with the scan change
- // update to make sure we are in the correct mode
- sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
- }
- }
- },
- new IntentFilter(filter));
- super.start();
- }
-
- private boolean checkScanOnlyModeAvailable() {
- // first check if Location service is disabled, if so return false
- if (!mWifiPermissionsUtil.isLocationModeEnabled()) {
- return false;
- }
- return mSettingsStore.isScanAlwaysAvailable();
- }
-
- /**
- * Listener used to receive scan mode updates - really needed for disabled updates to trigger
- * mode changes.
- */
- private class ScanOnlyCallback implements ScanOnlyModeManager.Listener {
- @Override
- public void onStateChanged(int state) {
- if (state == WifiManager.WIFI_STATE_UNKNOWN) {
- Log.d(TAG, "ScanOnlyMode unexpected failure: state unknown");
- } else if (state == WifiManager.WIFI_STATE_DISABLED) {
- Log.d(TAG, "ScanOnlyMode stopped");
- sendMessage(CMD_SCANNING_STOPPED);
- } else if (state == WifiManager.WIFI_STATE_ENABLED) {
- // scan mode is ready to go
- Log.d(TAG, "scan mode active");
- } else {
- Log.d(TAG, "unexpected state update: " + state);
- }
- }
- }
-
- /**
- * Listener used to receive client mode updates
- */
- private class ClientModeCallback implements ClientModeManager.Listener {
- @Override
- public void onStateChanged(int state) {
- if (state == WifiManager.WIFI_STATE_UNKNOWN) {
- logd("ClientMode unexpected failure: state unknown");
- sendMessage(CMD_STA_START_FAILURE);
- } else if (state == WifiManager.WIFI_STATE_DISABLED) {
- logd("ClientMode stopped");
- sendMessage(CMD_STA_STOPPED);
- } else if (state == WifiManager.WIFI_STATE_ENABLED) {
- // scan mode is ready to go
- logd("client mode active");
- } else {
- logd("unexpected state update: " + state);
- }
- }
- }
-
- private void readWifiReEnableDelay() {
- mReEnableDelayMillis = mFacade.getLongSetting(mContext,
- Settings.Global.WIFI_REENABLE_DELAY_MS, DEFAULT_REENABLE_DELAY_MS);
- }
-
- private void readWifiRecoveryDelay() {
- mRecoveryDelayMillis = mContext.getResources().getInteger(
- R.integer.config_wifi_framework_recovery_timeout_delay);
- if (mRecoveryDelayMillis > MAX_RECOVERY_TIMEOUT_DELAY_MS) {
- mRecoveryDelayMillis = MAX_RECOVERY_TIMEOUT_DELAY_MS;
- Log.w(TAG, "Overriding timeout delay with maximum limit value");
- }
- }
-
- class DefaultState extends State {
- @Override
- public boolean processMessage(Message msg) {
- switch (msg.what) {
- case CMD_SCAN_ALWAYS_MODE_CHANGED:
- case CMD_WIFI_TOGGLED:
- case CMD_AP_START_FAILURE:
- case CMD_SCANNING_STOPPED:
- case CMD_STA_STOPPED:
- case CMD_STA_START_FAILURE:
- case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
- case CMD_DEFERRED_RECOVERY_RESTART_WIFI:
- break;
- case CMD_RECOVERY_DISABLE_WIFI:
- log("Recovery has been throttled, disable wifi");
- mActiveModeWarden.shutdownWifi();
- transitionTo(mStaDisabledState);
- break;
- case CMD_RECOVERY_RESTART_WIFI:
- deferMessage(obtainMessage(CMD_DEFERRED_RECOVERY_RESTART_WIFI));
- mActiveModeWarden.shutdownWifi();
- transitionTo(mStaDisabledState);
- break;
- case CMD_DEFERRED_TOGGLE:
- log("DEFERRED_TOGGLE ignored due to state change");
- break;
- case CMD_SET_AP:
- // note: CMD_SET_AP is handled/dropped in ECM mode - will not start here
- if (msg.arg1 == 1) {
- SoftApModeConfiguration config = (SoftApModeConfiguration) msg.obj;
- mActiveModeWarden.enterSoftAPMode((SoftApModeConfiguration) msg.obj);
- } else {
- mActiveModeWarden.stopSoftAPMode(msg.arg2);
- }
- break;
- case CMD_AIRPLANE_TOGGLED:
- if (mSettingsStore.isAirplaneModeOn()) {
- log("Airplane mode toggled, shutdown all modes");
- mActiveModeWarden.shutdownWifi();
- transitionTo(mStaDisabledState);
- } else {
- log("Airplane mode disabled, determine next state");
- if (mSettingsStore.isWifiToggleEnabled()) {
- transitionTo(mStaEnabledState);
- } else if (checkScanOnlyModeAvailable()) {
- transitionTo(mStaDisabledWithScanState);
- }
- // wifi should remain disabled, do not need to transition
- }
- break;
- case CMD_EMERGENCY_CALL_STATE_CHANGED:
- case CMD_EMERGENCY_MODE_CHANGED:
- if (msg.arg1 == 1) {
- transitionTo(mEcmState);
- }
- break;
- case CMD_AP_STOPPED:
- log("SoftAp mode disabled, determine next state");
- if (mSettingsStore.isWifiToggleEnabled()) {
- transitionTo(mStaEnabledState);
- } else if (checkScanOnlyModeAvailable()) {
- transitionTo(mStaDisabledWithScanState);
- }
- // wifi should remain disabled, do not need to transition
- break;
- default:
- throw new RuntimeException("WifiController.handleMessage " + msg.what);
- }
- return HANDLED;
- }
-
- }
-
- class StaDisabledState extends State {
- private int mDeferredEnableSerialNumber = 0;
- private boolean mHaveDeferredEnable = false;
- private long mDisabledTimestamp;
-
- @Override
- public void enter() {
- mActiveModeWarden.disableWifi();
- // Supplicant can't restart right away, so note the time we switched off
- mDisabledTimestamp = SystemClock.elapsedRealtime();
- mDeferredEnableSerialNumber++;
- mHaveDeferredEnable = false;
- }
- @Override
- public boolean processMessage(Message msg) {
- switch (msg.what) {
- case CMD_WIFI_TOGGLED:
- if (mSettingsStore.isWifiToggleEnabled()) {
- if (doDeferEnable(msg)) {
- if (mHaveDeferredEnable) {
- // have 2 toggles now, inc serial number and ignore both
- mDeferredEnableSerialNumber++;
- }
- mHaveDeferredEnable = !mHaveDeferredEnable;
- break;
- }
- transitionTo(mStaEnabledState);
- } else if (checkScanOnlyModeAvailable()) {
- // only go to scan mode if we aren't in airplane mode
- if (mSettingsStore.isAirplaneModeOn()) {
- transitionTo(mStaDisabledWithScanState);
- }
- }
- break;
- case CMD_SCAN_ALWAYS_MODE_CHANGED:
- if (checkScanOnlyModeAvailable()) {
- transitionTo(mStaDisabledWithScanState);
- break;
- }
- break;
- case CMD_SET_AP:
- if (msg.arg1 == 1) {
- // remember that we were disabled, but pass the command up to start softap
- mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);
- }
- return NOT_HANDLED;
- case CMD_DEFERRED_TOGGLE:
- if (msg.arg1 != mDeferredEnableSerialNumber) {
- log("DEFERRED_TOGGLE ignored due to serial mismatch");
- break;
- }
- log("DEFERRED_TOGGLE handled");
- sendMessage((Message)(msg.obj));
- break;
- case CMD_DEFERRED_RECOVERY_RESTART_WIFI:
- // wait mRecoveryDelayMillis for letting driver clean reset.
- sendMessageDelayed(CMD_RECOVERY_RESTART_WIFI_CONTINUE, mRecoveryDelayMillis);
- break;
- case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
- if (mSettingsStore.isWifiToggleEnabled()) {
- // wifi is currently disabled but the toggle is on, must have had an
- // interface down before the recovery triggered
- transitionTo(mStaEnabledState);
- break;
- } else if (checkScanOnlyModeAvailable()) {
- transitionTo(mStaDisabledWithScanState);
- break;
- }
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- private boolean doDeferEnable(Message msg) {
- long delaySoFar = SystemClock.elapsedRealtime() - mDisabledTimestamp;
- if (delaySoFar >= mReEnableDelayMillis) {
- return false;
- }
-
- log("WifiController msg " + msg + " deferred for " +
- (mReEnableDelayMillis - delaySoFar) + "ms");
-
- // need to defer this action.
- Message deferredMsg = obtainMessage(CMD_DEFERRED_TOGGLE);
- deferredMsg.obj = Message.obtain(msg);
- deferredMsg.arg1 = ++mDeferredEnableSerialNumber;
- sendMessageDelayed(deferredMsg, mReEnableDelayMillis - delaySoFar + DEFER_MARGIN_MS);
- return true;
- }
-
- }
-
- class StaEnabledState extends State {
- @Override
- public void enter() {
- log("StaEnabledState.enter()");
- mActiveModeWarden.enterClientMode();
- }
-
- @Override
- public boolean processMessage(Message msg) {
- switch (msg.what) {
- case CMD_WIFI_TOGGLED:
- if (! mSettingsStore.isWifiToggleEnabled()) {
- if (checkScanOnlyModeAvailable()) {
- transitionTo(mStaDisabledWithScanState);
- } else {
- transitionTo(mStaDisabledState);
- }
- }
- break;
- case CMD_AIRPLANE_TOGGLED:
- // airplane mode toggled on is handled in the default state
- if (mSettingsStore.isAirplaneModeOn()) {
- return NOT_HANDLED;
- } else {
- // when airplane mode is toggled off, but wifi is on, we can keep it on
- log("airplane mode toggled - and airplane mode is off. return handled");
- return HANDLED;
- }
- case CMD_STA_START_FAILURE:
- if (!checkScanOnlyModeAvailable()) {
- transitionTo(mStaDisabledState);
- } else {
- transitionTo(mStaDisabledWithScanState);
- }
- break;
- case CMD_SET_AP:
- if (msg.arg1 == 1) {
- // remember that we were enabled, but pass the command up to start softap
- mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_ENABLED);
- }
- return NOT_HANDLED;
- case CMD_AP_START_FAILURE:
- case CMD_AP_STOPPED:
- // already in a wifi mode, no need to check where we should go with softap
- // stopped
- break;
- case CMD_STA_STOPPED:
- // Client mode stopped. head to Disabled to wait for next command
- transitionTo(mStaDisabledState);
- break;
- case CMD_RECOVERY_RESTART_WIFI:
- final String bugTitle;
- final String bugDetail;
- if (msg.arg1 < SelfRecovery.REASON_STRINGS.length && msg.arg1 >= 0) {
- bugDetail = SelfRecovery.REASON_STRINGS[msg.arg1];
- bugTitle = "Wi-Fi BugReport: " + bugDetail;
- } else {
- bugDetail = "";
- bugTitle = "Wi-Fi BugReport";
- }
- if (msg.arg1 != SelfRecovery.REASON_LAST_RESORT_WATCHDOG) {
- (new Handler(mClientModeImplLooper)).post(() -> {
- mClientModeImpl.takeBugReport(bugTitle, bugDetail);
- });
- }
- // after the bug report trigger, more handling needs to be done
- return NOT_HANDLED;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
- }
-
- class StaDisabledWithScanState extends State {
- private int mDeferredEnableSerialNumber = 0;
- private boolean mHaveDeferredEnable = false;
- private long mDisabledTimestamp;
-
- @Override
- public void enter() {
- // now trigger the actual mode switch in ActiveModeWarden
- mActiveModeWarden.enterScanOnlyMode();
-
- // TODO b/71559473: remove the defered enable after mode management changes are complete
- // Supplicant can't restart right away, so not the time we switched off
- mDisabledTimestamp = SystemClock.elapsedRealtime();
- mDeferredEnableSerialNumber++;
- mHaveDeferredEnable = false;
- }
-
- @Override
- public boolean processMessage(Message msg) {
- switch (msg.what) {
- case CMD_WIFI_TOGGLED:
- if (mSettingsStore.isWifiToggleEnabled()) {
- if (doDeferEnable(msg)) {
- if (mHaveDeferredEnable) {
- // have 2 toggles now, inc serial number and ignore both
- mDeferredEnableSerialNumber++;
- }
- mHaveDeferredEnable = !mHaveDeferredEnable;
- break;
- }
- transitionTo(mStaEnabledState);
- }
- break;
- case CMD_SCAN_ALWAYS_MODE_CHANGED:
- if (!checkScanOnlyModeAvailable()) {
- log("StaDisabledWithScanState: scan no longer available");
- transitionTo(mStaDisabledState);
- }
- break;
- case CMD_SET_AP:
- if (msg.arg1 == 1) {
- // remember that we were disabled, but pass the command up to start softap
- mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);
- }
- return NOT_HANDLED;
- case CMD_DEFERRED_TOGGLE:
- if (msg.arg1 != mDeferredEnableSerialNumber) {
- log("DEFERRED_TOGGLE ignored due to serial mismatch");
- break;
- }
- logd("DEFERRED_TOGGLE handled");
- sendMessage((Message)(msg.obj));
- break;
- case CMD_AP_START_FAILURE:
- case CMD_AP_STOPPED:
- // already in a wifi mode, no need to check where we should go with softap
- // stopped
- break;
- case CMD_SCANNING_STOPPED:
- // stopped due to interface destruction - return to disabled and wait
- log("WifiController: SCANNING_STOPPED when in scan mode -> StaDisabled");
- transitionTo(mStaDisabledState);
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- private boolean doDeferEnable(Message msg) {
- long delaySoFar = SystemClock.elapsedRealtime() - mDisabledTimestamp;
- if (delaySoFar >= mReEnableDelayMillis) {
- return false;
- }
-
- log("WifiController msg " + msg + " deferred for " +
- (mReEnableDelayMillis - delaySoFar) + "ms");
-
- // need to defer this action.
- Message deferredMsg = obtainMessage(CMD_DEFERRED_TOGGLE);
- deferredMsg.obj = Message.obtain(msg);
- deferredMsg.arg1 = ++mDeferredEnableSerialNumber;
- sendMessageDelayed(deferredMsg, mReEnableDelayMillis - delaySoFar + DEFER_MARGIN_MS);
- return true;
- }
-
- }
-
- /**
- * Determine the next state based on the current settings (e.g. saved
- * wifi state).
- */
- private State getNextWifiState() {
- if (mSettingsStore.getWifiSavedState() == WifiSettingsStore.WIFI_ENABLED) {
- return mStaEnabledState;
- }
-
- if (checkScanOnlyModeAvailable()) {
- return mStaDisabledWithScanState;
- }
-
- return mStaDisabledState;
- }
-
- class EcmState extends State {
- // we can enter EcmState either because an emergency call started or because
- // emergency callback mode started. This count keeps track of how many such
- // events happened; so we can exit after all are undone
-
- private int mEcmEntryCount;
- @Override
- public void enter() {
- mActiveModeWarden.stopSoftAPMode(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- boolean configWiFiDisableInECBM =
- mFacade.getConfigWiFiDisableInECBM(mContext);
- log("WifiController msg getConfigWiFiDisableInECBM "
- + configWiFiDisableInECBM);
- if (configWiFiDisableInECBM) {
- mActiveModeWarden.shutdownWifi();
- }
- mEcmEntryCount = 1;
- }
-
- /**
- * Handles messages received while in EcmMode.
- */
- @Override
- public boolean processMessage(Message msg) {
- switch (msg.what) {
- case CMD_EMERGENCY_CALL_STATE_CHANGED:
- if (msg.arg1 == 1) {
- // nothing to do - just says emergency call started
- mEcmEntryCount++;
- } else if (msg.arg1 == 0) {
- // emergency call ended
- decrementCountAndReturnToAppropriateState();
- }
- return HANDLED;
- case CMD_EMERGENCY_MODE_CHANGED:
- if (msg.arg1 == 1) {
- // Transitioned into emergency callback mode
- mEcmEntryCount++;
- } else if (msg.arg1 == 0) {
- // out of emergency callback mode
- decrementCountAndReturnToAppropriateState();
- }
- return HANDLED;
- case CMD_RECOVERY_RESTART_WIFI:
- case CMD_RECOVERY_DISABLE_WIFI:
- // do not want to restart wifi if we are in emergency mode
- return HANDLED;
- case CMD_AP_STOPPED:
- case CMD_SCANNING_STOPPED:
- case CMD_STA_STOPPED:
- // do not want to trigger a mode switch if we are in emergency mode
- return HANDLED;
- case CMD_SET_AP:
- // do not want to start softap if we are in emergency mode
- return HANDLED;
- default:
- return NOT_HANDLED;
- }
- }
-
- private void decrementCountAndReturnToAppropriateState() {
- boolean exitEcm = false;
-
- if (mEcmEntryCount == 0) {
- loge("mEcmEntryCount is 0; exiting Ecm");
- exitEcm = true;
- } else if (--mEcmEntryCount == 0) {
- exitEcm = true;
- }
-
- if (exitEcm) {
- if (mSettingsStore.isWifiToggleEnabled()) {
- transitionTo(mStaEnabledState);
- } else if (checkScanOnlyModeAvailable()) {
- transitionTo(mStaDisabledWithScanState);
- } else {
- transitionTo(mStaDisabledState);
- }
- }
- }
- }
-}
diff --git a/service/java/com/android/server/wifi/WifiCountryCode.java b/service/java/com/android/server/wifi/WifiCountryCode.java
index f9d147c6b5..1d4edf319c 100644
--- a/service/java/com/android/server/wifi/WifiCountryCode.java
+++ b/service/java/com/android/server/wifi/WifiCountryCode.java
@@ -16,9 +16,17 @@
package com.android.server.wifi;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
@@ -33,6 +41,7 @@ import java.util.Locale;
*/
public class WifiCountryCode {
private static final String TAG = "WifiCountryCode";
+ private final TelephonyManager mTelephonyManager;
private final WifiNative mWifiNative;
private boolean DBG = false;
private boolean mReady = false;
@@ -51,10 +60,12 @@ public class WifiCountryCode {
private boolean mForceCountryCode = false;
public WifiCountryCode(
+ Context context,
+ Handler handler,
WifiNative wifiNative,
String oemDefaultCountryCode,
boolean revertCountryCodeOnCellularLoss) {
-
+ mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
mWifiNative = wifiNative;
mRevertCountryCodeOnCellularLoss = revertCountryCodeOnCellularLoss;
@@ -67,6 +78,13 @@ public class WifiCountryCode {
mRevertCountryCodeOnCellularLoss = false;
}
}
+ context.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String countryCode = intent.getStringExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY);
+ Log.d(TAG, "Country code changed");
+ setCountryCodeAndUpdate(countryCode);
+ }}, new IntentFilter(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED), null, handler);
Log.d(TAG, "mDefaultCountryCode " + mDefaultCountryCode
+ " mRevertCountryCodeOnCellularLoss " + mRevertCountryCodeOnCellularLoss);
@@ -83,6 +101,14 @@ public class WifiCountryCode {
}
}
+ private void initializeTelephonyCountryCodeIfNeeded() {
+ // If we don't have a country code set, read it from telephony on bootup.
+ if (mTelephonyCountryCode == null) {
+ Log.d(TAG, "Reading country code on initialization");
+ setCountryCode(mTelephonyManager.getNetworkCountryIso());
+ }
+ }
+
/**
* Change the state to indicates if wpa_supplicant is ready to handle country code changing
* request or not.
@@ -95,6 +121,7 @@ public class WifiCountryCode {
// We are ready to set country code now.
// We need to post pending country code request.
if (mReady) {
+ initializeTelephonyCountryCodeIfNeeded();
updateCountryCode();
}
}
@@ -129,19 +156,12 @@ public class WifiCountryCode {
mTelephonyCountryCode = null;
}
- /**
- * Handle country code change request.
- * @param countryCode The country code intended to set.
- * This is supposed to be from Telephony service.
- * otherwise we think it is from other applications.
- * @return Returns true if the country code passed in is acceptable.
- */
- public synchronized boolean setCountryCode(String countryCode) {
+ private boolean setCountryCode(String countryCode) {
if (mForceCountryCode) {
Log.d(TAG, "Country code can't be set because it is the force-country-code mode");
return false;
}
- Log.d(TAG, "Receive set country code request: " + countryCode);
+ Log.d(TAG, "Set country code to: " + countryCode);
mTelephonyCountryTimestamp = FORMATTER.format(new Date(System.currentTimeMillis()));
// Empty country code.
@@ -153,6 +173,18 @@ public class WifiCountryCode {
} else {
mTelephonyCountryCode = countryCode.toUpperCase(Locale.US);
}
+ return true;
+ }
+
+ /**
+ * Handle country code change request.
+ * @param countryCode The country code intended to set.
+ * This is supposed to be from Telephony service.
+ * otherwise we think it is from other applications.
+ * @return Returns true if the country code passed in is acceptable.
+ */
+ private boolean setCountryCodeAndUpdate(String countryCode) {
+ if (!setCountryCode(countryCode)) return false;
// If wpa_supplicant is ready we set the country code now, otherwise it will be
// set once wpa_supplicant is ready.
if (mReady) {
@@ -173,6 +205,7 @@ public class WifiCountryCode {
* country code.
* Returns null if no Country Code was sent to driver.
*/
+ @VisibleForTesting
public synchronized String getCountryCodeSentToDriver() {
return mDriverCountryCode;
}
@@ -192,7 +225,6 @@ public class WifiCountryCode {
* Method to dump the current state of this WifiCounrtyCode object.
*/
public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-
pw.println("mRevertCountryCodeOnCellularLoss: " + mRevertCountryCodeOnCellularLoss);
pw.println("mDefaultCountryCode: " + mDefaultCountryCode);
pw.println("mDriverCountryCode: " + mDriverCountryCode);
diff --git a/service/java/com/android/server/wifi/WifiDataStall.java b/service/java/com/android/server/wifi/WifiDataStall.java
index 6eb3b41e5e..e32c87c9ec 100644
--- a/service/java/com/android/server/wifi/WifiDataStall.java
+++ b/service/java/com/android/server/wifi/WifiDataStall.java
@@ -18,8 +18,6 @@ package com.android.server.wifi;
import android.content.Context;
import android.net.wifi.WifiInfo;
-import android.os.Handler;
-import android.os.Looper;
import android.provider.Settings;
import com.android.server.wifi.nano.WifiMetricsProto.WifiIsUnusableEvent;
@@ -48,14 +46,8 @@ public class WifiDataStall {
private final FrameworkFacade mFacade;
private final WifiMetrics mWifiMetrics;
- private Handler mHandler;
private int mMinTxBad;
private int mMinTxSuccessWithoutRx;
- private int mDataStallDurationMs;
- private int mDataStallTxTputThrMbps;
- private int mDataStallRxTputThrMbps;
- private int mDataStallTxPerThr;
- private int mDataStallCcaLevelThr;
private int mLastFrequency = -1;
private String mLastBssid;
private long mLastTotalRadioOnFreqTimeMs = -1;
@@ -66,20 +58,13 @@ public class WifiDataStall {
private boolean mDataStallRx = false;
public WifiDataStall(Context context, FrameworkFacade facade, WifiMetrics wifiMetrics,
- DeviceConfigFacade deviceConfigFacade, Looper clientModeImplLooper, Clock clock) {
+ DeviceConfigFacade deviceConfigFacade, Clock clock) {
mContext = context;
mDeviceConfigFacade = deviceConfigFacade;
mFacade = facade;
- mHandler = new Handler(clientModeImplLooper);
mWifiMetrics = wifiMetrics;
mClock = clock;
loadSettings();
-
- mDeviceConfigFacade.addOnPropertiesChangedListener(
- command -> mHandler.post(command),
- properties -> {
- updateUsabilityDataCollectionFlags();
- });
}
/**
@@ -93,7 +78,6 @@ public class WifiDataStall {
MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT);
mWifiMetrics.setWifiDataStallMinTxBad(mMinTxBad);
mWifiMetrics.setWifiDataStallMinRxWithoutTx(mMinTxSuccessWithoutRx);
- updateUsabilityDataCollectionFlags();
}
/**
@@ -140,7 +124,6 @@ public class WifiDataStall {
mWifiMetrics.updateWifiIsUnusableLinkLayerStats(txSuccessDelta, txRetriesDelta,
txBadDelta, rxSuccessDelta, timeMsDelta);
-
if (timeMsDelta < MAX_MS_DELTA_FOR_DATA_STALL) {
int txLinkSpeed = wifiInfo.getLinkSpeed();
int rxLinkSpeed = wifiInfo.getRxLinkSpeedMbps();
@@ -156,17 +139,20 @@ public class WifiDataStall {
boolean isTxTputLow = false;
boolean isRxTputLow = false;
if (txLinkSpeed > 0) {
- int txTput = txLinkSpeed * (100 - txPer) * (100 - ccaLevel);
- isTxTputLow = txTput < mDataStallTxTputThrMbps * 100 * 100;
+ long txTputKbps = (long) txLinkSpeed * 1000 * (100 - txPer) * (100 - ccaLevel);
+ isTxTputLow =
+ txTputKbps < mDeviceConfigFacade.getDataStallTxTputThrKbps() * 100 * 100;
}
if (rxLinkSpeed > 0) {
- int rxTput = rxLinkSpeed * (100 - ccaLevel);
- isRxTputLow = rxTput < mDataStallRxTputThrMbps * 100;
+ long rxTputKbps = (long) rxLinkSpeed * 1000 * (100 - ccaLevel);
+ isRxTputLow = rxTputKbps < mDeviceConfigFacade.getDataStallRxTputThrKbps() * 100;
}
- boolean dataStallTx = isTxTputLow || ccaLevel >= mDataStallCcaLevelThr
- || txPer >= mDataStallTxPerThr;
- boolean dataStallRx = isRxTputLow || ccaLevel >= mDataStallCcaLevelThr;
+ boolean dataStallTx = isTxTputLow
+ || ccaLevel >= mDeviceConfigFacade.getDataStallCcaLevelThr()
+ || txPer >= mDeviceConfigFacade.getDataStallTxPerThr();
+ boolean dataStallRx = isRxTputLow
+ || ccaLevel >= mDeviceConfigFacade.getDataStallCcaLevelThr();
// Data stall event is triggered if there are consecutive Tx and/or Rx data stalls
// Reset mDataStallStartTimeMs to -1 if currently there is no Tx or Rx data stall
@@ -175,7 +161,7 @@ public class WifiDataStall {
mDataStallRx = mDataStallRx || dataStallRx;
if (mDataStallStartTimeMs == -1) {
mDataStallStartTimeMs = mClock.getElapsedSinceBootMillis();
- if (mDataStallDurationMs == 0) {
+ if (mDeviceConfigFacade.getDataStallDurationMs() == 0) {
mDataStallStartTimeMs = -1;
int result = calculateUsabilityEventType(mDataStallTx, mDataStallRx);
mDataStallRx = false;
@@ -184,7 +170,7 @@ public class WifiDataStall {
}
} else {
long elapsedTime = mClock.getElapsedSinceBootMillis() - mDataStallStartTimeMs;
- if (elapsedTime >= mDataStallDurationMs) {
+ if (elapsedTime >= mDeviceConfigFacade.getDataStallDurationMs()) {
mDataStallStartTimeMs = -1;
if (elapsedTime <= VALIDITY_PERIOD_OF_DATA_STALL_START_MS) {
int result = calculateUsabilityEventType(mDataStallTx, mDataStallRx);
@@ -252,18 +238,4 @@ public class WifiDataStall {
mWifiMetrics.logWifiIsUnusableEvent(result);
return result;
}
-
- private void updateUsabilityDataCollectionFlags() {
- mDataStallDurationMs = mDeviceConfigFacade.getDataStallDurationMs();
- mDataStallTxTputThrMbps = mDeviceConfigFacade.getDataStallTxTputThrMbps();
- mDataStallRxTputThrMbps = mDeviceConfigFacade.getDataStallRxTputThrMbps();
- mDataStallTxPerThr = mDeviceConfigFacade.getDataStallTxPerThr();
- mDataStallCcaLevelThr = mDeviceConfigFacade.getDataStallCcaLevelThr();
-
- mWifiMetrics.setDataStallDurationMs(mDataStallDurationMs);
- mWifiMetrics.setDataStallTxTputThrMbps(mDataStallTxTputThrMbps);
- mWifiMetrics.setDataStallRxTputThrMbps(mDataStallRxTputThrMbps);
- mWifiMetrics.setDataStallTxPerThr(mDataStallTxPerThr);
- mWifiMetrics.setDataStallCcaLevelThr(mDataStallCcaLevelThr);
- }
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index fe9ebea17c..19bdf2eca3 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -21,14 +21,12 @@ import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.hardware.SystemSensorManager;
import android.net.IpMemoryStore;
import android.net.NetworkCapabilities;
import android.net.NetworkKey;
import android.net.NetworkScoreManager;
import android.net.wifi.IWifiScanner;
-import android.net.wifi.IWificond;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkScoreCache;
import android.net.wifi.WifiScanner;
@@ -63,6 +61,7 @@ import com.android.server.wifi.p2p.WifiP2pNative;
import com.android.server.wifi.rtt.RttMetrics;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
+import com.android.server.wifi.wificond.IWificond;
import java.util.Random;
@@ -83,9 +82,11 @@ public class WifiInjector {
private final Context mContext;
private final FrameworkFacade mFrameworkFacade = new FrameworkFacade();
private final DeviceConfigFacade mDeviceConfigFacade;
- private final HandlerThread mWifiServiceHandlerThread;
- private final HandlerThread mWifiCoreHandlerThread;
+ private final UserManager mUserManager;
+ private final HandlerThread mAsyncChannelHandlerThread;
+ private final HandlerThread mWifiHandlerThread;
private final HandlerThread mWifiP2pServiceHandlerThread;
+ private final HandlerThread mPasspointProvisionerHandlerThread;
private final WifiTrafficPoller mWifiTrafficPoller;
private final WifiCountryCode mCountryCode;
private final BackupManagerProxy mBackupManagerProxy = new BackupManagerProxy();
@@ -103,10 +104,8 @@ public class WifiInjector {
private final ActiveModeWarden mActiveModeWarden;
private final WifiSettingsStore mSettingsStore;
private OpenNetworkNotifier mOpenNetworkNotifier;
- private CarrierNetworkNotifier mCarrierNetworkNotifier;
private final CarrierNetworkConfig mCarrierNetworkConfig;
private final WifiLockManager mLockManager;
- private final WifiController mWifiController;
private final WificondControl mWificondControl;
private final Clock mClock = new Clock();
private final WifiMetrics mWifiMetrics;
@@ -152,8 +151,8 @@ public class WifiInjector {
private final DppMetrics mDppMetrics;
private final DppManager mDppManager;
private final LinkProbeManager mLinkProbeManager;
- private final IpMemoryStore mIpMemoryStore;
- private final CellularLinkLayerStatsCollector mCellularLinkLayerStatsCollector;
+ private IpMemoryStore mIpMemoryStore;
+ private final WifiThreadRunner mWifiThreadRunner;
public WifiInjector(Context context) {
if (context == null) {
@@ -169,7 +168,6 @@ public class WifiInjector {
sWifiInjector = this;
mContext = context;
- mDeviceConfigFacade = new DeviceConfigFacade();
mWifiScoreCard = new WifiScoreCard(mClock,
Secure.getString(mContext.getContentResolver(), Secure.ANDROID_ID));
mSettingsStore = new WifiSettingsStore(mContext);
@@ -178,48 +176,50 @@ public class WifiInjector {
mWifiNetworkScoreCache = new WifiNetworkScoreCache(mContext);
mNetworkScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
mWifiNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_NONE);
+ mUserManager = mContext.getSystemService(UserManager.class);
mWifiPermissionsUtil = new WifiPermissionsUtil(mWifiPermissionsWrapper, mContext,
- UserManager.get(mContext), this);
+ mUserManager, this);
mWifiBackupRestore = new WifiBackupRestore(mWifiPermissionsUtil);
mBatteryStats = IBatteryStats.Stub.asInterface(mFrameworkFacade.getService(
BatteryStats.SERVICE_NAME));
mWifiStateTracker = new WifiStateTracker(mBatteryStats);
// Now create and start handler threads
- mWifiServiceHandlerThread = new HandlerThread("WifiService");
- mWifiServiceHandlerThread.start();
- mWifiCoreHandlerThread = new HandlerThread("ClientModeImpl");
- mWifiCoreHandlerThread.start();
+ mAsyncChannelHandlerThread = new HandlerThread("AsyncChannelHandlerThread");
+ mAsyncChannelHandlerThread.start();
+ mWifiHandlerThread = new HandlerThread("WifiHandlerThread");
+ mWifiHandlerThread.start();
+ Looper wifiLooper = mWifiHandlerThread.getLooper();
+ Handler wifiHandler = mWifiHandlerThread.getThreadHandler();
+ mWifiThreadRunner = new WifiThreadRunner(wifiHandler);
mWifiP2pServiceHandlerThread = new HandlerThread("WifiP2pService");
mWifiP2pServiceHandlerThread.start();
- Looper clientModeImplLooper = mWifiCoreHandlerThread.getLooper();
- mCarrierNetworkConfig = new CarrierNetworkConfig(mContext,
- clientModeImplLooper, mFrameworkFacade);
+ mPasspointProvisionerHandlerThread =
+ new HandlerThread("PasspointProvisionerHandlerThread");
+ mPasspointProvisionerHandlerThread.start();
+ mCarrierNetworkConfig = new CarrierNetworkConfig(mContext, wifiHandler, mFrameworkFacade);
WifiAwareMetrics awareMetrics = new WifiAwareMetrics(mClock);
RttMetrics rttMetrics = new RttMetrics(mClock);
mWifiP2pMetrics = new WifiP2pMetrics(mClock);
mDppMetrics = new DppMetrics();
- mCellularLinkLayerStatsCollector = new CellularLinkLayerStatsCollector(mContext);
- mWifiMetrics = new WifiMetrics(mContext, mFrameworkFacade, mClock, clientModeImplLooper,
- awareMetrics, rttMetrics, new WifiPowerMetrics(), mWifiP2pMetrics, mDppMetrics,
- mCellularLinkLayerStatsCollector);
+ mWifiMetrics = new WifiMetrics(mContext, mFrameworkFacade, mClock, wifiLooper,
+ awareMetrics, rttMetrics, new WifiPowerMetrics(), mWifiP2pMetrics, mDppMetrics);
+ mDeviceConfigFacade = new DeviceConfigFacade(mContext, wifiHandler, mWifiMetrics);
// Modules interacting with Native.
mWifiMonitor = new WifiMonitor(this);
- mHalDeviceManager = new HalDeviceManager(mClock, clientModeImplLooper);
- mWifiVendorHal =
- new WifiVendorHal(mHalDeviceManager, mWifiCoreHandlerThread.getLooper());
- mSupplicantStaIfaceHal =
- new SupplicantStaIfaceHal(mContext, mWifiMonitor, mPropertyService,
- clientModeImplLooper);
- mHostapdHal = new HostapdHal(mContext, clientModeImplLooper);
+ mHalDeviceManager = new HalDeviceManager(mClock, wifiHandler);
+ mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, wifiHandler);
+ mSupplicantStaIfaceHal = new SupplicantStaIfaceHal(
+ mContext, mWifiMonitor, mPropertyService, wifiHandler, mClock);
+ mHostapdHal = new HostapdHal(mContext, wifiHandler);
mWificondControl = new WificondControl(this, mWifiMonitor, mCarrierNetworkConfig,
(AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE),
- clientModeImplLooper, mClock);
+ wifiHandler, mClock);
mNwManagementService = INetworkManagementService.Stub.asInterface(
ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
mWifiNative = new WifiNative(
mWifiVendorHal, mSupplicantStaIfaceHal, mHostapdHal, mWificondControl,
mWifiMonitor, mNwManagementService, mPropertyService, mWifiMetrics,
- new Handler(mWifiCoreHandlerThread.getLooper()), new Random());
+ wifiHandler, new Random());
mWifiP2pMonitor = new WifiP2pMonitor(this);
mSupplicantP2pIfaceHal = new SupplicantP2pIfaceHal(mWifiP2pMonitor);
mWifiP2pNative = new WifiP2pNative(
@@ -227,36 +227,34 @@ public class WifiInjector {
mPropertyService);
// Now get instances of all the objects that depend on the HandlerThreads
- mWifiTrafficPoller = new WifiTrafficPoller(clientModeImplLooper);
- mCountryCode = new WifiCountryCode(mWifiNative,
+ mWifiTrafficPoller = new WifiTrafficPoller(wifiHandler);
+ mCountryCode = new WifiCountryCode(mContext, wifiHandler, mWifiNative,
SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
mContext.getResources()
.getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss));
mWifiApConfigStore = new WifiApConfigStore(
- mContext, mWifiCoreHandlerThread.getLooper(), mBackupManagerProxy,
- mFrameworkFacade);
+ mContext,this, wifiHandler, mBackupManagerProxy, mFrameworkFacade);
// WifiConfigManager/Store objects and their dependencies.
// New config store
mWifiKeyStore = new WifiKeyStore(mKeyStore);
- mWifiConfigStore = new WifiConfigStore(
- mContext, clientModeImplLooper, mClock, mWifiMetrics,
+ mWifiConfigStore = new WifiConfigStore(mContext, wifiHandler, mClock, mWifiMetrics,
WifiConfigStore.createSharedFile());
SubscriptionManager subscriptionManager =
mContext.getSystemService(SubscriptionManager.class);
// Config Manager
mWifiConfigManager = new WifiConfigManager(mContext, mClock,
- UserManager.get(mContext), makeTelephonyManager(),
+ mUserManager, makeTelephonyManager(),
mWifiKeyStore, mWifiConfigStore, mWifiPermissionsUtil,
mWifiPermissionsWrapper, this, new NetworkListSharedStoreData(mContext),
new NetworkListUserStoreData(mContext),
new DeletedEphemeralSsidsStoreData(mClock), new RandomizedMacStoreData(),
- mFrameworkFacade, mWifiCoreHandlerThread.getLooper());
+ mFrameworkFacade, wifiHandler, mDeviceConfigFacade);
mWifiMetrics.setWifiConfigManager(mWifiConfigManager);
mWifiConnectivityHelper = new WifiConnectivityHelper(mWifiNative);
- mConnectivityLocalLog = new LocalLog(ActivityManager.isLowRamDeviceStatic() ? 256 : 512);
- mScoringParams = new ScoringParams(mContext, mFrameworkFacade,
- new Handler(clientModeImplLooper));
+ mConnectivityLocalLog = new LocalLog(
+ mContext.getSystemService(ActivityManager.class).isLowRamDevice() ? 256 : 512);
+ mScoringParams = new ScoringParams(mContext, mFrameworkFacade, wifiHandler);
mWifiMetrics.setScoringParams(mScoringParams);
mWifiNetworkSelector = new WifiNetworkSelector(mContext, mWifiScoreCard, mScoringParams,
mWifiConfigManager, mClock, mConnectivityLocalLog, mWifiMetrics, mWifiNative);
@@ -270,19 +268,18 @@ public class WifiInjector {
mSavedNetworkEvaluator = new SavedNetworkEvaluator(mContext, mScoringParams,
mWifiConfigManager, mClock, mConnectivityLocalLog, mWifiConnectivityHelper,
subscriptionManager);
- mWifiNetworkSuggestionsManager = new WifiNetworkSuggestionsManager(mContext,
- new Handler(mWifiCoreHandlerThread.getLooper()), this,
- mWifiPermissionsUtil, mWifiConfigManager, mWifiConfigStore, mWifiMetrics);
+ mWifiNetworkSuggestionsManager = new WifiNetworkSuggestionsManager(mContext, wifiHandler,
+ this, mWifiPermissionsUtil, mWifiConfigManager, mWifiConfigStore, mWifiMetrics);
mNetworkSuggestionEvaluator = new NetworkSuggestionEvaluator(mWifiNetworkSuggestionsManager,
mWifiConfigManager, mConnectivityLocalLog);
- mScoredNetworkEvaluator = new ScoredNetworkEvaluator(context, clientModeImplLooper,
+ mScoredNetworkEvaluator = new ScoredNetworkEvaluator(context, wifiHandler,
mFrameworkFacade, mNetworkScoreManager, mWifiConfigManager, mConnectivityLocalLog,
mWifiNetworkScoreCache, mWifiPermissionsUtil);
mCarrierNetworkEvaluator = new CarrierNetworkEvaluator(mWifiConfigManager,
mCarrierNetworkConfig, mConnectivityLocalLog, this);
mSimAccessor = new SIMAccessor(mContext);
mPasspointManager = new PasspointManager(mContext, this,
- new Handler(mWifiCoreHandlerThread.getLooper()), mWifiNative, mWifiKeyStore, mClock,
+ wifiHandler, mWifiNative, mWifiKeyStore, mClock,
mSimAccessor, new PasspointObjectFactory(), mWifiConfigManager, mWifiConfigStore,
mWifiMetrics, makeTelephonyManager(), subscriptionManager);
mPasspointNetworkEvaluator = new PasspointNetworkEvaluator(
@@ -293,59 +290,49 @@ public class WifiInjector {
(AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE),
(ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE),
this, mWifiConfigManager,
- mWifiPermissionsUtil, mWifiMetrics, mClock, mFrameworkFacade,
- new Handler(clientModeImplLooper));
- mSarManager = new SarManager(mContext, makeTelephonyManager(), clientModeImplLooper,
- mWifiNative, new SystemSensorManager(mContext, clientModeImplLooper),
+ mWifiPermissionsUtil, mWifiMetrics, mClock, mFrameworkFacade, wifiHandler);
+ mSarManager = new SarManager(mContext, makeTelephonyManager(), wifiLooper,
+ mWifiNative, new SystemSensorManager(mContext, wifiLooper),
mWifiMetrics);
mWifiDiagnostics = new WifiDiagnostics(
mContext, this, mWifiNative, mBuildProperties,
new LastMileLogger(this), mClock);
mWifiDataStall = new WifiDataStall(mContext, mFrameworkFacade, mWifiMetrics,
- mDeviceConfigFacade, clientModeImplLooper, mClock);
+ mDeviceConfigFacade, mClock);
mWifiMetrics.setWifiDataStall(mWifiDataStall);
mLinkProbeManager = new LinkProbeManager(mClock, mWifiNative, mWifiMetrics,
- mFrameworkFacade, mWifiCoreHandlerThread.getLooper(), mContext);
+ mFrameworkFacade, wifiHandler, mContext);
mClientModeImpl = new ClientModeImpl(mContext, mFrameworkFacade,
- clientModeImplLooper, UserManager.get(mContext),
+ wifiLooper, mUserManager,
this, mBackupManagerProxy, mCountryCode, mWifiNative,
new WrongPasswordNotifier(mContext, mFrameworkFacade),
mSarManager, mWifiTrafficPoller, mLinkProbeManager);
- mActiveModeWarden = new ActiveModeWarden(this, mContext, clientModeImplLooper,
- mWifiNative, new DefaultModeManager(mContext, clientModeImplLooper),
- mBatteryStats);
+ mActiveModeWarden = new ActiveModeWarden(this, wifiLooper,
+ mWifiNative, new DefaultModeManager(mContext), mBatteryStats, mWifiDiagnostics,
+ mContext, mClientModeImpl, mSettingsStore, mFrameworkFacade, mWifiPermissionsUtil);
WakeupNotificationFactory wakeupNotificationFactory =
- new WakeupNotificationFactory(mContext, mFrameworkFacade);
+ new WakeupNotificationFactory(mContext, this, mFrameworkFacade);
WakeupOnboarding wakeupOnboarding = new WakeupOnboarding(mContext, mWifiConfigManager,
- mWifiCoreHandlerThread.getLooper(), mFrameworkFacade,
- wakeupNotificationFactory);
- mWakeupController = new WakeupController(mContext,
- mWifiCoreHandlerThread.getLooper(),
+ wifiHandler, mFrameworkFacade, wakeupNotificationFactory);
+ mWakeupController = new WakeupController(mContext, wifiHandler,
new WakeupLock(mWifiConfigManager, mWifiMetrics.getWakeupMetrics(), mClock),
new WakeupEvaluator(mScoringParams), wakeupOnboarding, mWifiConfigManager,
mWifiConfigStore, mWifiNetworkSuggestionsManager, mWifiMetrics.getWakeupMetrics(),
this, mFrameworkFacade, mClock);
mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService(),
- mClientModeImpl, mFrameworkFacade, new Handler(clientModeImplLooper), mWifiNative,
- mClock, mWifiMetrics);
- mWifiController = new WifiController(mContext, mClientModeImpl, clientModeImplLooper,
- mSettingsStore, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade,
- mActiveModeWarden, mWifiPermissionsUtil);
- mSelfRecovery = new SelfRecovery(mWifiController, mClock);
+ mClientModeImpl, mFrameworkFacade, wifiHandler, mWifiNative, mClock, mWifiMetrics);
+ mSelfRecovery = new SelfRecovery(mActiveModeWarden, mClock);
mWifiMulticastLockManager = new WifiMulticastLockManager(
mClientModeImpl.getMcastLockManagerFilterController(),
BatteryStatsService.getService());
- mDppManager = new DppManager(mWifiCoreHandlerThread.getLooper(), mWifiNative,
+ mDppManager = new DppManager(wifiHandler, mWifiNative,
mWifiConfigManager, mContext, mDppMetrics);
- mIpMemoryStore = IpMemoryStore.getMemoryStore(mContext);
// Register the various network evaluators with the network selector.
mWifiNetworkSelector.registerNetworkEvaluator(mSavedNetworkEvaluator);
mWifiNetworkSelector.registerNetworkEvaluator(mNetworkSuggestionEvaluator);
- if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)) {
- mWifiNetworkSelector.registerNetworkEvaluator(mPasspointNetworkEvaluator);
- }
+ mWifiNetworkSelector.registerNetworkEvaluator(mPasspointNetworkEvaluator);
mWifiNetworkSelector.registerNetworkEvaluator(mCarrierNetworkEvaluator);
mWifiNetworkSelector.registerNetworkEvaluator(mScoredNetworkEvaluator);
@@ -383,7 +370,7 @@ public class WifiInjector {
}
public UserManager getUserManager() {
- return UserManager.get(mContext);
+ return mUserManager;
}
public WifiMetrics getWifiMetrics() {
@@ -406,16 +393,20 @@ public class WifiInjector {
return mFrameworkFacade;
}
- public HandlerThread getWifiServiceHandlerThread() {
- return mWifiServiceHandlerThread;
+ public HandlerThread getAsyncChannelHandlerThread() {
+ return mAsyncChannelHandlerThread;
}
public HandlerThread getWifiP2pServiceHandlerThread() {
return mWifiP2pServiceHandlerThread;
}
- public HandlerThread getWifiCoreHandlerThread() {
- return mWifiCoreHandlerThread;
+ public HandlerThread getPasspointProvisionerHandlerThread() {
+ return mPasspointProvisionerHandlerThread;
+ }
+
+ public HandlerThread getWifiHandlerThread() {
+ return mWifiHandlerThread;
}
public WifiTrafficPoller getWifiTrafficPoller() {
@@ -438,10 +429,6 @@ public class WifiInjector {
return mClientModeImpl;
}
- public Handler getClientModeImplHandler() {
- return mClientModeImpl.getHandler();
- }
-
public ActiveModeWarden getActiveModeWarden() {
return mActiveModeWarden;
}
@@ -454,10 +441,6 @@ public class WifiInjector {
return mLockManager;
}
- public WifiController getWifiController() {
- return mWifiController;
- }
-
public WifiLastResortWatchdog getWifiLastResortWatchdog() {
return mWifiLastResortWatchdog;
}
@@ -534,35 +517,24 @@ public class WifiInjector {
* @param config SoftApModeConfiguration object holding the config and mode
* @return an instance of SoftApManager
*/
- public SoftApManager makeSoftApManager(@NonNull WifiManager.SoftApCallback callback,
+ public SoftApManager makeSoftApManager(@NonNull ActiveModeManager.Listener listener,
+ @NonNull WifiManager.SoftApCallback callback,
@NonNull SoftApModeConfiguration config) {
- return new SoftApManager(mContext, mWifiCoreHandlerThread.getLooper(),
- mFrameworkFacade, mWifiNative, mCountryCode.getCountryCode(), callback,
+ return new SoftApManager(mContext, mWifiHandlerThread.getLooper(),
+ mFrameworkFacade, mWifiNative, mCountryCode.getCountryCode(), listener, callback,
mWifiApConfigStore, config, mWifiMetrics, mSarManager, mWifiDiagnostics);
}
/**
- * Create a ScanOnlyModeManager
- *
- * @param listener listener for ScanOnlyModeManager state changes
- * @return a new instance of ScanOnlyModeManager
- */
- public ScanOnlyModeManager makeScanOnlyModeManager(
- @NonNull ScanOnlyModeManager.Listener listener) {
- return new ScanOnlyModeManager(mContext, mWifiCoreHandlerThread.getLooper(),
- mWifiNative, listener, mWifiMetrics, mWakeupController,
- mSarManager);
- }
-
- /**
* Create a ClientModeManager
*
* @param listener listener for ClientModeManager state changes
* @return a new instance of ClientModeManager
*/
public ClientModeManager makeClientModeManager(ClientModeManager.Listener listener) {
- return new ClientModeManager(mContext, mWifiCoreHandlerThread.getLooper(),
- mWifiNative, listener, mWifiMetrics, mClientModeImpl);
+ return new ClientModeManager(mContext, mWifiHandlerThread.getLooper(),
+ mWifiNative, listener, mWifiMetrics, mSarManager, mWakeupController,
+ mClientModeImpl);
}
/**
@@ -587,7 +559,7 @@ public class WifiInjector {
mWifiScanner = new WifiScanner(mContext,
IWifiScanner.Stub.asInterface(ServiceManager.getService(
Context.WIFI_SCANNING_SERVICE)),
- mWifiCoreHandlerThread.getLooper());
+ mWifiHandlerThread.getLooper());
}
return mWifiScanner;
}
@@ -601,22 +573,18 @@ public class WifiInjector {
*/
public WifiConnectivityManager makeWifiConnectivityManager(ClientModeImpl clientModeImpl) {
mOpenNetworkNotifier = new OpenNetworkNotifier(mContext,
- mWifiCoreHandlerThread.getLooper(), mFrameworkFacade, mClock, mWifiMetrics,
+ mWifiHandlerThread.getLooper(), mFrameworkFacade, mClock, mWifiMetrics,
mWifiConfigManager, mWifiConfigStore, clientModeImpl,
- new ConnectToNetworkNotificationBuilder(mContext, mFrameworkFacade));
- mCarrierNetworkNotifier = new CarrierNetworkNotifier(mContext,
- mWifiCoreHandlerThread.getLooper(), mFrameworkFacade, mClock, mWifiMetrics,
- mWifiConfigManager, mWifiConfigStore, clientModeImpl,
- new ConnectToNetworkNotificationBuilder(mContext, mFrameworkFacade));
+ new ConnectToNetworkNotificationBuilder(mContext, this, mFrameworkFacade));
mWifiLastResortWatchdog = new WifiLastResortWatchdog(this, mContext, mClock,
- mWifiMetrics, clientModeImpl, clientModeImpl.getHandler().getLooper(),
- mDeviceConfigFacade);
+ mWifiMetrics, clientModeImpl, mWifiHandlerThread.getLooper(), mDeviceConfigFacade,
+ mWifiThreadRunner);
return new WifiConnectivityManager(mContext, getScoringParams(),
clientModeImpl, this,
mWifiConfigManager, clientModeImpl.getWifiInfo(),
mWifiNetworkSelector, mWifiConnectivityHelper,
- mWifiLastResortWatchdog, mOpenNetworkNotifier, mCarrierNetworkNotifier,
- mCarrierNetworkConfig, mWifiMetrics, mWifiCoreHandlerThread.getLooper(),
+ mWifiLastResortWatchdog, mOpenNetworkNotifier,
+ mCarrierNetworkConfig, mWifiMetrics, mWifiHandlerThread.getThreadHandler(),
mClock, mConnectivityLocalLog);
}
@@ -627,7 +595,7 @@ public class WifiInjector {
public WifiNetworkFactory makeWifiNetworkFactory(
NetworkCapabilities nc, WifiConnectivityManager wifiConnectivityManager) {
return new WifiNetworkFactory(
- mWifiCoreHandlerThread.getLooper(), mContext, nc,
+ mWifiHandlerThread.getLooper(), mContext, nc,
(ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE),
(AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE),
(AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE),
@@ -650,7 +618,7 @@ public class WifiInjector {
public UntrustedWifiNetworkFactory makeUntrustedWifiNetworkFactory(
NetworkCapabilities nc, WifiConnectivityManager wifiConnectivityManager) {
return new UntrustedWifiNetworkFactory(
- mWifiCoreHandlerThread.getLooper(), mContext, nc, wifiConnectivityManager);
+ mWifiHandlerThread.getLooper(), mContext, nc, wifiConnectivityManager);
}
/**
@@ -747,10 +715,21 @@ public class WifiInjector {
}
public IpMemoryStore getIpMemoryStore() {
+ if (mIpMemoryStore == null) {
+ mIpMemoryStore = IpMemoryStore.getMemoryStore(mContext);
+ }
return mIpMemoryStore;
}
public HostapdHal getHostapdHal() {
return mHostapdHal;
}
+
+ public String getWifiStackPackageName() {
+ return mContext.getPackageName();
+ }
+
+ public WifiThreadRunner getWifiThreadRunner() {
+ return mWifiThreadRunner;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
index e8a06881bd..18f447aac1 100644
--- a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
+++ b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
@@ -32,9 +32,11 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* This Class is a Work-In-Progress, intended behavior is as follows:
@@ -77,9 +79,6 @@ public class WifiLastResortWatchdog {
@VisibleForTesting
public static final long LAST_TRIGGER_TIMEOUT_MILLIS = 2 * 3600 * 1000; // 2 hours
- private int mAbnormalConnectionDurationMs;
- private boolean mAbnormalConnectionBugreportEnabled;
-
/**
* Cached WifiConfigurations of available networks seen within MAX_BSSID_AGE scan results
@@ -94,6 +93,9 @@ public class WifiLastResortWatchdog {
private Map<String, Pair<AvailableNetworkFailureCount, Integer>> mSsidFailureCount =
new HashMap<>();
+ /* List of failure BSSID */
+ private Set<String> mBssidFailureList = new HashSet<>();
+
// Tracks: if ClientModeImpl is in ConnectedState
private boolean mWifiIsConnected = false;
// Is Watchdog allowed to trigger now? Set to false after triggering. Set to true after
@@ -115,6 +117,9 @@ public class WifiLastResortWatchdog {
private boolean mWatchdogFixedWifi = true;
private long mLastStartConnectTime = 0;
private Handler mHandler;
+ private final WifiThreadRunner mWifiThreadRunner;
+
+ private boolean mWatchdogFeatureEnabled = true;
/**
* Local log used for debugging any WifiLastResortWatchdog issues.
@@ -123,7 +128,7 @@ public class WifiLastResortWatchdog {
WifiLastResortWatchdog(WifiInjector wifiInjector, Context context, Clock clock,
WifiMetrics wifiMetrics, ClientModeImpl clientModeImpl, Looper clientModeImplLooper,
- DeviceConfigFacade deviceConfigFacade) {
+ DeviceConfigFacade deviceConfigFacade, WifiThreadRunner wifiThreadRunner) {
mWifiInjector = wifiInjector;
mClock = clock;
mWifiMetrics = wifiMetrics;
@@ -131,29 +136,12 @@ public class WifiLastResortWatchdog {
mClientModeImplLooper = clientModeImplLooper;
mContext = context;
mDeviceConfigFacade = deviceConfigFacade;
- updateDeviceConfigFlags();
+ mWifiThreadRunner = wifiThreadRunner;
mHandler = new Handler(clientModeImplLooper) {
public void handleMessage(Message msg) {
processMessage(msg);
}
};
-
- mDeviceConfigFacade.addOnPropertiesChangedListener(
- command -> mHandler.post(command),
- properties -> {
- updateDeviceConfigFlags();
- });
- }
-
- private void updateDeviceConfigFlags() {
- mAbnormalConnectionBugreportEnabled =
- mDeviceConfigFacade.isAbnormalConnectionBugreportEnabled();
- mAbnormalConnectionDurationMs =
- mDeviceConfigFacade.getAbnormalConnectionDurationMs();
- logv("updateDeviceConfigFlags: mAbnormalConnectionDurationMs = "
- + mAbnormalConnectionDurationMs
- + ", mAbnormalConnectionBugreportEnabled = "
- + mAbnormalConnectionBugreportEnabled);
}
/**
@@ -177,17 +165,19 @@ public class WifiLastResortWatchdog {
switch (msg.what) {
case WifiMonitor.NETWORK_CONNECTION_EVENT:
// Trigger bugreport for successful connections that take abnormally long
- if (mAbnormalConnectionBugreportEnabled && mLastStartConnectTime > 0) {
+ if (mDeviceConfigFacade.isAbnormalConnectionBugreportEnabled()
+ && mLastStartConnectTime > 0) {
long durationMs = mClock.getElapsedSinceBootMillis() - mLastStartConnectTime;
- if (durationMs > mAbnormalConnectionDurationMs) {
+ long abnormalConnectionDurationMs =
+ mDeviceConfigFacade.getAbnormalConnectionDurationMs();
+ if (durationMs > abnormalConnectionDurationMs) {
final String bugTitle = "Wi-Fi Bugreport: Abnormal connection time";
final String bugDetail = "Expected connection to take less than "
- + mAbnormalConnectionDurationMs + " milliseconds. "
+ + abnormalConnectionDurationMs + " milliseconds. "
+ "Actually took " + durationMs + " milliseconds.";
logv("Triggering bug report for abnormal connection time.");
- mWifiInjector.getClientModeImplHandler().post(() -> {
- mClientModeImpl.takeBugReport(bugTitle, bugDetail);
- });
+ mWifiThreadRunner.post(() ->
+ mClientModeImpl.takeBugReport(bugTitle, bugDetail));
}
}
// Should reset last connection time after each connection regardless if bugreport
@@ -208,11 +198,11 @@ public class WifiLastResortWatchdog {
*/
public void updateAvailableNetworks(
List<Pair<ScanDetail, WifiConfiguration>> availableNetworks) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "updateAvailableNetworks: size = " + availableNetworks.size());
- }
// Add new networks to mRecentAvailableNetworks
if (availableNetworks != null) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "updateAvailableNetworks: size = " + availableNetworks.size());
+ }
for (Pair<ScanDetail, WifiConfiguration> pair : availableNetworks) {
final ScanDetail scanDetail = pair.first;
final WifiConfiguration config = pair.second;
@@ -240,9 +230,9 @@ public class WifiLastResortWatchdog {
1);
// Do not re-enable Watchdog in LAST_TRIGGER_TIMEOUT_MILLIS
// after last time Watchdog be triggered
- if (mTimeLastTrigger == 0
+ if (!mWatchdogAllowedToTrigger && (mTimeLastTrigger == 0
|| (mClock.getElapsedSinceBootMillis() - mTimeLastTrigger)
- >= LAST_TRIGGER_TIMEOUT_MILLIS) {
+ >= LAST_TRIGGER_TIMEOUT_MILLIS)) {
localLog("updateAvailableNetworks: setWatchdogTriggerEnabled to true");
setWatchdogTriggerEnabled(true);
}
@@ -320,17 +310,23 @@ public class WifiLastResortWatchdog {
Log.v(TAG, "isRestartNeeded = " + isRestartNeeded);
}
if (isRestartNeeded) {
- // Stop the watchdog from triggering until re-enabled
- localLog("noteConnectionFailureAndTriggerIfNeeded: setWatchdogTriggerEnabled to false");
- setWatchdogTriggerEnabled(false);
- mWatchdogFixedWifi = true;
- loge("Watchdog triggering recovery");
- mSsidLastTrigger = ssid;
- mTimeLastTrigger = mClock.getElapsedSinceBootMillis();
- localLog(toString());
- mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
- incrementWifiMetricsTriggerCounts();
- clearAllFailureCounts();
+ if (mWatchdogFeatureEnabled) {
+ // Stop the watchdog from triggering until re-enabled
+ localLog("Trigger recovery: setWatchdogTriggerEnabled to false");
+ setWatchdogTriggerEnabled(false);
+ mWatchdogFixedWifi = true;
+ loge("Watchdog triggering recovery");
+ mSsidLastTrigger = ssid;
+ mTimeLastTrigger = mClock.getElapsedSinceBootMillis();
+ localLog(toString());
+ mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
+ incrementWifiMetricsTriggerCounts();
+ } else {
+ // auto bugreport if issue happens
+ loge("bugreport notification");
+ setWatchdogTriggerEnabled(false);
+ takeBugReportWithCurrentProbability("Wifi Watchdog bite");
+ }
}
return isRestartNeeded;
}
@@ -348,8 +344,10 @@ public class WifiLastResortWatchdog {
return;
}
if (!mWatchdogAllowedToTrigger && mWatchdogFixedWifi
+ && mWatchdogFeatureEnabled
&& checkIfAtleastOneNetworkHasEverConnected()
- && checkIfConnectedBackToSameSsid()) {
+ && checkIfConnectedBackToSameSsid()
+ && checkIfConnectedBssidHasEverFailed()) {
takeBugReportWithCurrentProbability("Wifi fixed after restart");
// WiFi has connected after a Watchdog trigger, without any new networks becoming
// available, log a Watchdog success in wifi metrics
@@ -357,8 +355,6 @@ public class WifiLastResortWatchdog {
long durationMs = mClock.getElapsedSinceBootMillis() - mTimeLastTrigger;
mWifiMetrics.setWatchdogSuccessTimeDurationMs(durationMs);
}
- // We connected to something! Reset failure counts for everything
- clearAllFailureCounts();
// If the watchdog trigger was disabled (it triggered), connecting means we did
// something right, re-enable it so it can fire again.
localLog("connectedStateTransition: setWatchdogTriggerEnabled to true");
@@ -366,6 +362,14 @@ public class WifiLastResortWatchdog {
}
/**
+ * Helper function to check if device connected to BSSID
+ * which is in BSSID failure list after watchdog trigger.
+ */
+ private boolean checkIfConnectedBssidHasEverFailed() {
+ return mBssidFailureList.contains(mClientModeImpl.getWifiInfo().getBSSID());
+ }
+
+ /**
* Helper function to check if device connect back to same
* SSID after watchdog trigger
*/
@@ -408,6 +412,7 @@ public class WifiLastResortWatchdog {
// Bssid count is actually unused except for logging purposes
// SSID count is incremented within the BSSID counting method
incrementBssidFailureCount(ssid, bssid, reason);
+ mBssidFailureList.add(bssid);
}
}
@@ -587,7 +592,7 @@ public class WifiLastResortWatchdog {
}
/**
- * Clear failure counts for each network in recentAvailableNetworks
+ * Clear all failure counts
*/
public void clearAllFailureCounts() {
if (mVerboseLoggingEnabled) Log.v(TAG, "clearAllFailureCounts.");
@@ -601,6 +606,7 @@ public class WifiLastResortWatchdog {
final AvailableNetworkFailureCount failureCount = entry.getValue().first;
failureCount.resetCounts();
}
+ mBssidFailureList.clear();
}
/**
* Gets the buffer of recently available networks
@@ -615,6 +621,10 @@ public class WifiLastResortWatchdog {
*/
private void setWatchdogTriggerEnabled(boolean enable) {
if (mVerboseLoggingEnabled) Log.v(TAG, "setWatchdogTriggerEnabled: enable = " + enable);
+ // Reset failure counts before actives watchdog
+ if (enable) {
+ clearAllFailureCounts();
+ }
mWatchdogAllowedToTrigger = enable;
}
@@ -623,7 +633,8 @@ public class WifiLastResortWatchdog {
*/
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("mWatchdogAllowedToTrigger: ").append(mWatchdogAllowedToTrigger);
+ sb.append("mWatchdogFeatureEnabled: ").append(mWatchdogFeatureEnabled);
+ sb.append("\nmWatchdogAllowedToTrigger: ").append(mWatchdogAllowedToTrigger);
sb.append("\nmWifiIsConnected: ").append(mWifiIsConnected);
sb.append("\nmRecentAvailableNetworks: ").append(mRecentAvailableNetworks.size());
for (Map.Entry<String, AvailableNetworkFailureCount> entry
@@ -682,6 +693,23 @@ public class WifiLastResortWatchdog {
}
}
+ /**
+ * Sets whether wifi watchdog should trigger recovery
+ */
+ public void setWifiWatchdogFeature(boolean enable) {
+ logv("setWifiWatchdogFeature: " + enable);
+ mWatchdogFeatureEnabled = enable;
+ // for debugging purpose, reset mWatchdogAllowedToTrigger as well
+ setWatchdogTriggerEnabled(true);
+ }
+
+ /**
+ * Returns whether wifi watchdog should trigger recovery.
+ */
+ public boolean getWifiWatchdogFeature() {
+ return mWatchdogFeatureEnabled;
+ }
+
protected void enableVerboseLogging(int verbose) {
if (verbose > 0) {
mVerboseLoggingEnabled = true;
diff --git a/service/java/com/android/server/wifi/WifiLockManager.java b/service/java/com/android/server/wifi/WifiLockManager.java
index e292a84d8a..8086fc945a 100644
--- a/service/java/com/android/server/wifi/WifiLockManager.java
+++ b/service/java/com/android/server/wifi/WifiLockManager.java
@@ -25,7 +25,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.WorkSource;
import android.os.WorkSource.WorkChain;
-import android.util.Slog;
+import android.util.Log;
import android.util.SparseArray;
import android.util.StatsLog;
@@ -270,7 +270,7 @@ public class WifiLockManager {
WorkSource newWorkSource = new WorkSource(ws);
if (mVerboseLoggingEnabled) {
- Slog.d(TAG, "updateWifiLockWakeSource: " + wl + ", newWorkSource=" + newWorkSource);
+ Log.d(TAG, "updateWifiLockWakeSource: " + wl + ", newWorkSource=" + newWorkSource);
}
// Note:
@@ -309,7 +309,7 @@ public class WifiLockManager {
mForceHiPerfMode = isEnabled;
mForceLowLatencyMode = false;
if (!updateOpMode()) {
- Slog.e(TAG, "Failed to force hi-perf mode, returning to normal mode");
+ Log.e(TAG, "Failed to force hi-perf mode, returning to normal mode");
mForceHiPerfMode = false;
return false;
}
@@ -326,7 +326,7 @@ public class WifiLockManager {
mForceLowLatencyMode = isEnabled;
mForceHiPerfMode = false;
if (!updateOpMode()) {
- Slog.e(TAG, "Failed to force low-latency mode, returning to normal mode");
+ Log.e(TAG, "Failed to force low-latency mode, returning to normal mode");
mForceLowLatencyMode = false;
return false;
}
@@ -338,7 +338,7 @@ public class WifiLockManager {
*/
public void handleScreenStateChanged(boolean screenOn) {
if (mVerboseLoggingEnabled) {
- Slog.d(TAG, "handleScreenStateChanged: screenOn = " + screenOn);
+ Log.d(TAG, "handleScreenStateChanged: screenOn = " + screenOn);
}
mScreenOn = screenOn;
@@ -404,7 +404,7 @@ public class WifiLockManager {
mLowLatencyUidWatchList.put(uid, uidRec);
// Now check if the uid is running in foreground
- if (mFrameworkFacade.isAppForeground(uid)) {
+ if (mFrameworkFacade.isAppForeground(mContext, uid)) {
uidRec.mIsFg = true;
}
@@ -418,14 +418,14 @@ public class WifiLockManager {
private void removeUidFromLlWatchList(int uid) {
UidRec uidRec = mLowLatencyUidWatchList.get(uid);
if (uidRec == null) {
- Slog.e(TAG, "Failed to find uid in low-latency watch list");
+ Log.e(TAG, "Failed to find uid in low-latency watch list");
return;
}
if (uidRec.mLockCount > 0) {
uidRec.mLockCount--;
} else {
- Slog.e(TAG, "Error, uid record conatains no locks");
+ Log.e(TAG, "Error, uid record conatains no locks");
}
if (uidRec.mLockCount == 0) {
mLowLatencyUidWatchList.remove(uid);
@@ -475,12 +475,12 @@ public class WifiLockManager {
private synchronized boolean addLock(WifiLock lock) {
if (mVerboseLoggingEnabled) {
- Slog.d(TAG, "addLock: " + lock);
+ Log.d(TAG, "addLock: " + lock);
}
if (findLockByBinder(lock.getBinder()) != null) {
if (mVerboseLoggingEnabled) {
- Slog.d(TAG, "attempted to add a lock when already holding one");
+ Log.d(TAG, "attempted to add a lock when already holding one");
}
return false;
}
@@ -527,7 +527,7 @@ public class WifiLockManager {
}
if (mVerboseLoggingEnabled) {
- Slog.d(TAG, "releaseLock: " + wifiLock);
+ Log.d(TAG, "releaseLock: " + wifiLock);
}
switch(wifiLock.mMode) {
@@ -568,14 +568,14 @@ public class WifiLockManager {
}
if (mVerboseLoggingEnabled) {
- Slog.d(TAG, "Current opMode: " + mCurrentOpMode + " New LockMode: " + newLockMode);
+ Log.d(TAG, "Current opMode: " + mCurrentOpMode + " New LockMode: " + newLockMode);
}
// Otherwise, we need to change current mode, first reset it to normal
switch (mCurrentOpMode) {
case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
if (!mClientModeImpl.setPowerSave(true)) {
- Slog.e(TAG, "Failed to reset the OpMode from hi-perf to Normal");
+ Log.e(TAG, "Failed to reset the OpMode from hi-perf to Normal");
return false;
}
mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
@@ -584,7 +584,7 @@ public class WifiLockManager {
case WifiManager.WIFI_MODE_FULL_LOW_LATENCY:
if (!setLowLatencyMode(false)) {
- Slog.e(TAG, "Failed to reset the OpMode from low-latency to Normal");
+ Log.e(TAG, "Failed to reset the OpMode from low-latency to Normal");
return false;
}
mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
@@ -604,7 +604,7 @@ public class WifiLockManager {
switch (newLockMode) {
case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
if (!mClientModeImpl.setPowerSave(false)) {
- Slog.e(TAG, "Failed to set the OpMode to hi-perf");
+ Log.e(TAG, "Failed to set the OpMode to hi-perf");
return false;
}
mCurrentSessionStartTimeMs = mClock.getElapsedSinceBootMillis();
@@ -612,7 +612,7 @@ public class WifiLockManager {
case WifiManager.WIFI_MODE_FULL_LOW_LATENCY:
if (!setLowLatencyMode(true)) {
- Slog.e(TAG, "Failed to set the OpMode to low-latency");
+ Log.e(TAG, "Failed to set the OpMode to low-latency");
return false;
}
mCurrentSessionStartTimeMs = mClock.getElapsedSinceBootMillis();
@@ -624,7 +624,7 @@ public class WifiLockManager {
default:
// Invalid mode, don't change currentOpMode , and exit with error
- Slog.e(TAG, "Invalid new opMode: " + newLockMode);
+ Log.e(TAG, "Invalid new opMode: " + newLockMode);
return false;
}
@@ -663,12 +663,12 @@ public class WifiLockManager {
if (lowLatencySupport == LOW_LATENCY_SUPPORTED) {
if (!mClientModeImpl.setLowLatencyMode(enabled)) {
- Slog.e(TAG, "Failed to set low latency mode");
+ Log.e(TAG, "Failed to set low latency mode");
return false;
}
if (!mClientModeImpl.setPowerSave(!enabled)) {
- Slog.e(TAG, "Failed to set power save mode");
+ Log.e(TAG, "Failed to set power save mode");
// Revert the low latency mode
mClientModeImpl.setLowLatencyMode(!enabled);
return false;
@@ -676,7 +676,7 @@ public class WifiLockManager {
} else if (lowLatencySupport == LOW_LATENCY_NOT_SUPPORTED) {
// Only set power save mode
if (!mClientModeImpl.setPowerSave(!enabled)) {
- Slog.e(TAG, "Failed to set power save mode");
+ Log.e(TAG, "Failed to set power save mode");
return false;
}
}
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 27fe140a78..a875cd6c3f 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -39,7 +39,6 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.provider.Settings;
-import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.Base64;
import android.util.Log;
@@ -432,8 +431,6 @@ public class WifiMetrics {
private int mNetworkSelectorExperimentId;
- private final CellularLinkLayerStatsCollector mCellularLinkLayerStatsCollector;
-
/**
* Tracks the nominator for each network (i.e. which entity made the suggestion to connect).
* This object should not be cleared.
@@ -758,8 +755,7 @@ public class WifiMetrics {
public WifiMetrics(Context context, FrameworkFacade facade, Clock clock, Looper looper,
WifiAwareMetrics awareMetrics, RttMetrics rttMetrics,
WifiPowerMetrics wifiPowerMetrics, WifiP2pMetrics wifiP2pMetrics,
- DppMetrics dppMetrics,
- CellularLinkLayerStatsCollector cellularLinkLayerStatsCollector) {
+ DppMetrics dppMetrics) {
mContext = context;
mFacade = facade;
mClock = clock;
@@ -772,7 +768,6 @@ public class WifiMetrics {
mWifiPowerMetrics = wifiPowerMetrics;
mWifiP2pMetrics = wifiP2pMetrics;
mDppMetrics = dppMetrics;
- mCellularLinkLayerStatsCollector = cellularLinkLayerStatsCollector;
loadSettings();
mHandler = new Handler(looper) {
public void handleMessage(Message msg) {
@@ -905,24 +900,6 @@ public class WifiMetrics {
}
/**
- * Increment number of pno scans started successfully over offload
- */
- public void incrementPnoScanStartedOverOffloadCount() {
- synchronized (mLock) {
- mPnoScanMetrics.numPnoScanStartedOverOffload++;
- }
- }
-
- /**
- * Increment number of pno scans failed over offload
- */
- public void incrementPnoScanFailedOverOffloadCount() {
- synchronized (mLock) {
- mPnoScanMetrics.numPnoScanFailedOverOffload++;
- }
- }
-
- /**
* Increment number of times pno scan found a result
*/
public void incrementPnoFoundNetworkEventCount() {
@@ -2266,10 +2243,6 @@ public class WifiMetrics {
}
}
- /**
- * TODO: (b/72443859) Use notifierTag param to separate metrics for OpenNetworkNotifier and
- * CarrierNetworkNotifier, for this method and all other related metrics.
- */
/** Increments the occurence of a "Connect to Network" notification. */
public void incrementConnectToNetworkNotification(String notifierTag, int notificationType) {
synchronized (mLock) {
@@ -2784,10 +2757,10 @@ public class WifiMetrics {
+ mExperimentValues.linkSpeedCountsLoggingEnabled);
pw.println("mExperimentValues.dataStallDurationMs="
+ mExperimentValues.dataStallDurationMs);
- pw.println("mExperimentValues.dataStallTxTputThrMbps="
- + mExperimentValues.dataStallTxTputThrMbps);
- pw.println("mExperimentValues.dataStallRxTputThrMbps="
- + mExperimentValues.dataStallRxTputThrMbps);
+ pw.println("mExperimentValues.dataStallTxTputThrKbps="
+ + mExperimentValues.dataStallTxTputThrKbps);
+ pw.println("mExperimentValues.dataStallRxTputThrKbps="
+ + mExperimentValues.dataStallRxTputThrKbps);
pw.println("mExperimentValues.dataStallTxPerThr="
+ mExperimentValues.dataStallTxPerThr);
pw.println("mExperimentValues.dataStallCcaLevelThr="
@@ -2917,10 +2890,6 @@ public class WifiMetrics {
line.append(",rx_link_speed_mbps=" + entry.rxLinkSpeedMbps);
line.append(",seq_num_inside_framework=" + entry.seqNumInsideFramework);
line.append(",is_same_bssid_and_freq=" + entry.isSameBssidAndFreq);
- line.append(",cellular_data_network_type=" + entry.cellularDataNetworkType);
- line.append(",cellular_signal_strength_dbm=" + entry.cellularSignalStrengthDbm);
- line.append(",cellular_signal_strength_db=" + entry.cellularSignalStrengthDb);
- line.append(",is_same_registered_cell=" + entry.isSameRegisteredCell);
line.append(",device_mobility_state=" + entry.deviceMobilityState);
pw.println(line.toString());
}
@@ -3696,10 +3665,10 @@ public class WifiMetrics {
StateChangeResult stateChangeResult = (StateChangeResult) msg.obj;
mSupplicantStateChangeBitmask |= supplicantStateToBit(stateChangeResult.state);
break;
- case ClientModeImpl.CMD_ASSOCIATED_BSSID:
+ case WifiMonitor.ASSOCIATED_BSSID_EVENT:
event.type = StaEvent.TYPE_CMD_ASSOCIATED_BSSID;
break;
- case ClientModeImpl.CMD_TARGET_BSSID:
+ case WifiMonitor.TARGET_BSSID_EVENT:
event.type = StaEvent.TYPE_CMD_TARGET_BSSID;
break;
default:
@@ -4386,14 +4355,6 @@ public class WifiMetrics {
wifiUsabilityStatsEntry.seqNumInsideFramework = mSeqNumInsideFramework;
wifiUsabilityStatsEntry.deviceMobilityState = mCurrentDeviceMobilityState;
- CellularLinkLayerStats cls = mCellularLinkLayerStatsCollector.update();
- if (DBG) Log.v(TAG, "Latest Cellular Link Layer Stats: " + cls);
- wifiUsabilityStatsEntry.cellularDataNetworkType =
- parseDataNetworkTypeToProto(cls.getDataNetworkType());
- wifiUsabilityStatsEntry.cellularSignalStrengthDbm = cls.getSignalStrengthDbm();
- wifiUsabilityStatsEntry.cellularSignalStrengthDb = cls.getSignalStrengthDb();
- wifiUsabilityStatsEntry.isSameRegisteredCell = cls.getIsSameRegisteredCell();
-
mWifiUsabilityStatsEntriesList.add(wifiUsabilityStatsEntry);
mWifiUsabilityStatsCounter++;
if (mWifiUsabilityStatsCounter >= NUM_WIFI_USABILITY_STATS_ENTRIES_PER_WIFI_GOOD) {
@@ -4423,53 +4384,6 @@ public class WifiMetrics {
}
}
- private int parseDataNetworkTypeToProto(int cellularDataNetworkType) {
- switch (cellularDataNetworkType) {
- case TelephonyManager.NETWORK_TYPE_UNKNOWN:
- return WifiUsabilityStatsEntry.NETWORK_TYPE_UNKNOWN;
- case TelephonyManager.NETWORK_TYPE_GSM:
- return WifiUsabilityStatsEntry.NETWORK_TYPE_GSM;
- case TelephonyManager.NETWORK_TYPE_CDMA:
- return WifiUsabilityStatsEntry.NETWORK_TYPE_CDMA;
- case TelephonyManager.NETWORK_TYPE_EVDO_0:
- return WifiUsabilityStatsEntry.NETWORK_TYPE_EVDO_0;
- case TelephonyManager.NETWORK_TYPE_UMTS:
- return WifiUsabilityStatsEntry.NETWORK_TYPE_UMTS;
- case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
- return WifiUsabilityStatsEntry.NETWORK_TYPE_TD_SCDMA;
- case TelephonyManager.NETWORK_TYPE_LTE:
- return WifiUsabilityStatsEntry.NETWORK_TYPE_LTE;
- case TelephonyManager.NETWORK_TYPE_NR:
- return WifiUsabilityStatsEntry.NETWORK_TYPE_NR;
- default:
- Log.e(TAG, "Unknown data network type : " + cellularDataNetworkType);
- return WifiUsabilityStatsEntry.NETWORK_TYPE_UNKNOWN;
- }
- }
-
- private int parseDataNetworkTypeFromProto(int cellularDataNetworkType) {
- switch (cellularDataNetworkType) {
- case WifiUsabilityStatsEntry.NETWORK_TYPE_UNKNOWN:
- return TelephonyManager.NETWORK_TYPE_UNKNOWN;
- case WifiUsabilityStatsEntry.NETWORK_TYPE_GSM:
- return TelephonyManager.NETWORK_TYPE_GSM;
- case WifiUsabilityStatsEntry.NETWORK_TYPE_CDMA:
- return TelephonyManager.NETWORK_TYPE_CDMA;
- case WifiUsabilityStatsEntry.NETWORK_TYPE_EVDO_0:
- return TelephonyManager.NETWORK_TYPE_EVDO_0;
- case WifiUsabilityStatsEntry.NETWORK_TYPE_UMTS:
- return TelephonyManager.NETWORK_TYPE_UMTS;
- case WifiUsabilityStatsEntry.NETWORK_TYPE_TD_SCDMA:
- return TelephonyManager.NETWORK_TYPE_TD_SCDMA;
- case WifiUsabilityStatsEntry.NETWORK_TYPE_LTE:
- return TelephonyManager.NETWORK_TYPE_LTE;
- case WifiUsabilityStatsEntry.NETWORK_TYPE_NR:
- return TelephonyManager.NETWORK_TYPE_NR;
- default:
- Log.e(TAG, "Unknown data network type : " + cellularDataNetworkType);
- return TelephonyManager.NETWORK_TYPE_UNKNOWN;
- }
- }
/**
* Send Wifi usability stats.
* @param seqNum
@@ -4505,7 +4419,7 @@ public class WifiMetrics {
probeStatus = android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN;
Log.e(TAG, "Unknown link probe status: " + s.probeStatusSinceLastUpdate);
}
- int cellularDataNetworkType = parseDataNetworkTypeFromProto(s.cellularDataNetworkType);
+ // TODO: remove the following hardcoded values once if they are removed from public API
return new android.net.wifi.WifiUsabilityStatsEntry(s.timeStampMs, s.rssi,
s.linkSpeedMbps, s.totalTxSuccess, s.totalTxRetries,
s.totalTxBad, s.totalRxSuccess, s.totalRadioOnTimeMs,
@@ -4514,9 +4428,7 @@ public class WifiMetrics {
s.totalPnoScanTimeMs, s.totalHotspot2ScanTimeMs, s.totalCcaBusyFreqTimeMs,
s.totalRadioOnFreqTimeMs, s.totalBeaconRx, probeStatus,
s.probeElapsedTimeSinceLastUpdateMs, s.probeMcsRateSinceLastUpdate,
- s.rxLinkSpeedMbps, cellularDataNetworkType,
- s.cellularSignalStrengthDbm, s.cellularSignalStrengthDb,
- s.isSameRegisteredCell
+ s.rxLinkSpeedMbps, 0, 0, 0, false
);
}
@@ -4551,10 +4463,6 @@ public class WifiMetrics {
out.rxLinkSpeedMbps = s.rxLinkSpeedMbps;
out.isSameBssidAndFreq = s.isSameBssidAndFreq;
out.seqNumInsideFramework = s.seqNumInsideFramework;
- out.cellularDataNetworkType = s.cellularDataNetworkType;
- out.cellularSignalStrengthDbm = s.cellularSignalStrengthDbm;
- out.cellularSignalStrengthDb = s.cellularSignalStrengthDb;
- out.isSameRegisteredCell = s.isSameRegisteredCell;
out.deviceMobilityState = s.deviceMobilityState;
return out;
}
@@ -5215,18 +5123,18 @@ public class WifiMetrics {
/**
* Sets the threshold of Tx throughput below which to trigger a data stall
*/
- public void setDataStallTxTputThrMbps(int txTputThr) {
+ public void setDataStallTxTputThrKbps(int txTputThr) {
synchronized (mLock) {
- mExperimentValues.dataStallTxTputThrMbps = txTputThr;
+ mExperimentValues.dataStallTxTputThrKbps = txTputThr;
}
}
/**
* Sets the threshold of Rx throughput below which to trigger a data stall
*/
- public void setDataStallRxTputThrMbps(int rxTputThr) {
+ public void setDataStallRxTputThrKbps(int rxTputThr) {
synchronized (mLock) {
- mExperimentValues.dataStallRxTputThrMbps = rxTputThr;
+ mExperimentValues.dataStallRxTputThrKbps = rxTputThr;
}
}
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index 54b1d6bed7..59d844aed3 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -85,6 +85,8 @@ public class WifiMonitor {
/* Indicates assoc reject event */
public static final int ASSOCIATION_REJECTION_EVENT = BASE + 43;
public static final int ANQP_DONE_EVENT = BASE + 44;
+ public static final int ASSOCIATED_BSSID_EVENT = BASE + 45;
+ public static final int TARGET_BSSID_EVENT = BASE + 46;
/* hotspot 2.0 ANQP events */
public static final int GAS_QUERY_START_EVENT = BASE + 51;
@@ -473,7 +475,7 @@ public class WifiMonitor {
* @param bssid BSSID of the access point.
*/
public void broadcastAssociatedBssidEvent(String iface, String bssid) {
- sendMessage(iface, ClientModeImpl.CMD_ASSOCIATED_BSSID, 0, 0, bssid);
+ sendMessage(iface, ASSOCIATED_BSSID_EVENT, 0, 0, bssid);
}
/**
@@ -483,7 +485,7 @@ public class WifiMonitor {
* @param bssid BSSID of the access point.
*/
public void broadcastTargetBssidEvent(String iface, String bssid) {
- sendMessage(iface, ClientModeImpl.CMD_TARGET_BSSID, 0, 0, bssid);
+ sendMessage(iface, TARGET_BSSID_EVENT, 0, 0, bssid);
}
/**
diff --git a/service/java/com/android/server/wifi/WifiMulticastLockManager.java b/service/java/com/android/server/wifi/WifiMulticastLockManager.java
index f7cd5811b0..ade4dfa8ed 100644
--- a/service/java/com/android/server/wifi/WifiMulticastLockManager.java
+++ b/service/java/com/android/server/wifi/WifiMulticastLockManager.java
@@ -19,7 +19,7 @@ package com.android.server.wifi;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
-import android.util.Slog;
+import android.util.Log;
import android.util.StatsLog;
import com.android.internal.app.IBatteryStats;
@@ -75,7 +75,7 @@ public class WifiMulticastLockManager {
@Override
public void binderDied() {
- Slog.e(TAG, "Multicaster binderDied");
+ Log.e(TAG, "Multicaster binderDied");
synchronized (mMulticasters) {
int i = mMulticasters.indexOf(this);
if (i != -1) {
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 3e5dc3c793..b9e7668112 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -24,20 +24,22 @@ import android.net.TrafficStats;
import android.net.apf.ApfCapabilities;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
import android.net.wifi.WifiScanner;
import android.os.Handler;
import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.SystemClock;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.Log;
-import android.util.SparseArray;
import com.android.internal.annotations.Immutable;
import com.android.internal.util.HexDump;
import com.android.server.net.BaseNetworkObserver;
import com.android.server.wifi.util.FrameParser;
import com.android.server.wifi.util.NativeUtil;
+import com.android.server.wifi.wificond.NativeWifiClient;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -130,7 +132,7 @@ public class WifiNative {
/** Identifier allocated for the interface */
public final int id;
/** Type of the iface: STA (for Connectivity or Scan) or AP */
- public final @IfaceType int type;
+ public @IfaceType int type;
/** Name of the interface */
public String name;
/** Is the interface up? This is used to mask up/down notifications to external clients. */
@@ -280,6 +282,17 @@ public class WifiNative {
return iface.name;
}
+ private @NonNull Set<String> findAllStaIfaceNames() {
+ Set<String> ifaceNames = new ArraySet<>();
+ for (Iface iface : mIfaces.values()) {
+ if (iface.type == Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY
+ || iface.type == Iface.IFACE_TYPE_STA_FOR_SCAN) {
+ ifaceNames.add(iface.name);
+ }
+ }
+ return ifaceNames;
+ }
+
/** Removes the existing iface that does not match the provided id. */
public Iface removeExistingIface(int newIfaceId) {
Iface removedIface = null;
@@ -999,7 +1012,7 @@ public class WifiNative {
return null;
}
iface.externalListener = interfaceCallback;
- iface.name = createStaIface(iface, /* lowPrioritySta */ true);
+ iface.name = createStaIface(iface, /* lowPrioritySta */ false);
if (TextUtils.isEmpty(iface.name)) {
Log.e(TAG, "Failed to create iface in vendor HAL");
mIfaceMgr.removeIface(iface.id);
@@ -1086,6 +1099,79 @@ public class WifiNative {
}
/**
+ * Switches an existing Client mode interface from connectivity
+ * {@link Iface#IFACE_TYPE_STA_FOR_CONNECTIVITY} to scan mode
+ * {@link Iface#IFACE_TYPE_STA_FOR_SCAN}.
+ *
+ * @param ifaceName Name of the interface.
+ * @return true if the operation succeeded, false if there is an error or the iface is already
+ * in scan mode.
+ */
+ public boolean switchClientInterfaceToScanMode(@NonNull String ifaceName) {
+ synchronized (mLock) {
+ final Iface iface = mIfaceMgr.getIface(ifaceName);
+ if (iface == null) {
+ Log.e(TAG, "Trying to switch to scan mode on an invalid iface=" + ifaceName);
+ return false;
+ }
+ if (iface.type == Iface.IFACE_TYPE_STA_FOR_SCAN) {
+ Log.e(TAG, "Already in scan mode on iface=" + ifaceName);
+ return true;
+ }
+ if (!mSupplicantStaIfaceHal.teardownIface(iface.name)) {
+ Log.e(TAG, "Failed to teardown iface in supplicant on " + iface);
+ teardownInterface(iface.name);
+ return false;
+ }
+ iface.type = Iface.IFACE_TYPE_STA_FOR_SCAN;
+ stopSupplicantIfNecessary();
+ iface.featureSet = getSupportedFeatureSetInternal(iface.name);
+ Log.i(TAG, "Successfully switched to scan mode on iface=" + iface);
+ return true;
+ }
+ }
+
+ /**
+ * Switches an existing Client mode interface from scan mode
+ * {@link Iface#IFACE_TYPE_STA_FOR_SCAN} to connectivity mode
+ * {@link Iface#IFACE_TYPE_STA_FOR_CONNECTIVITY}.
+ *
+ * @param ifaceName Name of the interface.
+ * @return true if the operation succeeded, false if there is an error or the iface is already
+ * in scan mode.
+ */
+ public boolean switchClientInterfaceToConnectivityMode(@NonNull String ifaceName) {
+ synchronized (mLock) {
+ final Iface iface = mIfaceMgr.getIface(ifaceName);
+ if (iface == null) {
+ Log.e(TAG, "Trying to switch to connectivity mode on an invalid iface="
+ + ifaceName);
+ return false;
+ }
+ if (iface.type == Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY) {
+ Log.e(TAG, "Already in connectivity mode on iface=" + ifaceName);
+ return true;
+ }
+ if (!startSupplicant()) {
+ Log.e(TAG, "Failed to start supplicant");
+ teardownInterface(iface.name);
+ mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
+ return false;
+ }
+ if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
+ Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
+ teardownInterface(iface.name);
+ mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
+ return false;
+ }
+ iface.type = Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY;
+ iface.featureSet = getSupportedFeatureSetInternal(iface.name);
+ Log.i(TAG, "Successfully switched to connectivity mode on iface=" + iface);
+ return true;
+ }
+ }
+
+ /**
*
* Check if the interface is up or down.
*
@@ -1188,6 +1274,17 @@ public class WifiNative {
}
/**
+ * Get names of all the client interfaces.
+ *
+ * @return List of interface name of all active client interfaces.
+ */
+ public Set<String> getClientInterfaceNames() {
+ synchronized (mLock) {
+ return mIfaceMgr.findAllStaIfaceNames();
+ }
+ }
+
+ /**
* Get name of the softap interface.
*
* This is mainly used by external modules that needs to perform some
@@ -1522,9 +1619,9 @@ public class WifiNative {
void onFailure();
/**
- * Invoked when the number of associated stations changes.
+ * Invoked when the associated stations changes.
*/
- void onNumAssociatedStationsChanged(int numStations);
+ void onConnectedClientsChanged(List<NativeWifiClient> clients);
/**
* Invoked when the channel switch event happens.
@@ -1889,7 +1986,7 @@ public class WifiNative {
* @return true if succeeds, false otherwise.
*/
public boolean simAuthResponse(
- @NonNull String ifaceName, int id, String type, String response) {
+ @NonNull String ifaceName, String type, String response) {
if (SIM_AUTH_RESP_TYPE_GSM_AUTH.equals(type)) {
return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(
ifaceName, response);
@@ -1910,7 +2007,7 @@ public class WifiNative {
* @param ifaceName Name of the interface.
* @return true if succeeds, false otherwise.
*/
- public boolean simAuthFailedResponse(@NonNull String ifaceName, int id) {
+ public boolean simAuthFailedResponse(@NonNull String ifaceName) {
return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure(ifaceName);
}
@@ -1920,7 +2017,7 @@ public class WifiNative {
* @param ifaceName Name of the interface.
* @return true if succeeds, false otherwise.
*/
- public boolean umtsAuthFailedResponse(@NonNull String ifaceName, int id) {
+ public boolean umtsAuthFailedResponse(@NonNull String ifaceName) {
return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure(ifaceName);
}
@@ -1932,8 +2029,8 @@ public class WifiNative {
* @param encryptedResponse String to send.
* @return true if succeeds, false otherwise.
*/
- public boolean simIdentityResponse(@NonNull String ifaceName, int id,
- String unencryptedResponse, String encryptedResponse) {
+ public boolean simIdentityResponse(@NonNull String ifaceName, String unencryptedResponse,
+ String encryptedResponse) {
return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(ifaceName,
unencryptedResponse, encryptedResponse);
}
@@ -2089,21 +2186,6 @@ public class WifiNative {
}
/**
- * Migrate all the configured networks from wpa_supplicant.
- *
- * @param ifaceName Name of the interface.
- * @param configs Map of configuration key to configuration objects corresponding to all
- * the networks.
- * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
- * @return Max priority of all the configs.
- */
- public boolean migrateNetworksFromSupplicant(
- @NonNull String ifaceName, Map<String, WifiConfiguration> configs,
- SparseArray<Map<String, String>> networkExtras) {
- return mSupplicantStaIfaceHal.loadNetworks(ifaceName, configs, networkExtras);
- }
-
- /**
* Add the provided network configuration to wpa_supplicant and initiate connection to it.
* This method does the following:
* 1. Abort any ongoing scan to unblock the connection request.
@@ -2216,14 +2298,13 @@ public class WifiNative {
return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken(ifaceName);
}
- /** Remove the request |networkId| from supplicant if it's the current network,
- * if the current configured network matches |networkId|.
+ /**
+ * Clean HAL cached data for |networkId|.
*
- * @param ifaceName Name of the interface.
* @param networkId network id of the network to be removed from supplicant.
*/
- public void removeNetworkIfCurrent(@NonNull String ifaceName, int networkId) {
- mSupplicantStaIfaceHal.removeNetworkIfCurrent(ifaceName, networkId);
+ public void removeNetworkCachedData(int networkId) {
+ mSupplicantStaIfaceHal.removeNetworkCachedData(networkId);
}
/*
@@ -2649,6 +2730,16 @@ public class WifiNative {
}
/**
+ * Get the connection Wifi technology
+ *
+ * @param ifaceName Name of the interface.
+ * @return Wifi technology for connection on this interface
+ */
+ public @WifiInfo.WifiTechnology int getWifiTechnology(@NonNull String ifaceName) {
+ return mSupplicantStaIfaceHal.getWifiTechnology(ifaceName);
+ }
+
+ /**
* Set the MAC OUI during scanning.
* An OUI {Organizationally Unique Identifier} is a 24-bit number that
* uniquely identifies a vendor or manufacturer.
@@ -3261,8 +3352,8 @@ public class WifiNative {
********************************************************/
/* Register native functions */
static {
- /* Native functions are defined in libwifi-service.so */
- System.loadLibrary("wifi-service");
+ /* Native functions are defined in libwifi-jni.so */
+ System.loadLibrary("wifi-jni");
registerNatives();
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 4b5866b445..bea181ce3f 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -33,19 +33,18 @@ import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
+import android.net.wifi.IActionListener;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.INetworkRequestUserSelectionCallback;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.SecurityType;
-import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiScanner;
+import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
import android.os.PatternMatcher;
import android.os.Process;
import android.os.RemoteException;
@@ -121,7 +120,6 @@ public class WifiNetworkFactory extends NetworkFactory {
private final PeriodicScanAlarmListener mPeriodicScanTimerListener;
private final ConnectionTimeoutAlarmListener mConnectionTimeoutAlarmListener;
private final ExternalCallbackTracker<INetworkRequestMatchCallback> mRegisteredCallbacks;
- private final Messenger mSrcMessenger;
// Store all user approved access points for apps.
@VisibleForTesting
public final Map<String, LinkedHashSet<AccessPoint>> mUserApprovedAccessPointMap;
@@ -299,23 +297,20 @@ public class WifiNetworkFactory extends NetworkFactory {
}
}
- private final Handler.Callback mNetworkConnectionTriggerCallback = (Message msg) -> {
- switch (msg.what) {
- // Success here means that an attempt to connect to the network has been initiated.
- case WifiManager.CONNECT_NETWORK_SUCCEEDED:
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "Triggered network connection");
- }
- break;
- case WifiManager.CONNECT_NETWORK_FAILED:
- Log.e(TAG, "Failed to trigger network connection");
- handleNetworkConnectionFailure(mUserSelectedNetwork);
- break;
- default:
- Log.e(TAG, "Unknown message " + msg.what);
+ private final class ConnectActionListener extends IActionListener.Stub {
+ @Override
+ public void onSuccess() {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Triggered network connection");
+ }
}
- return true;
- };
+
+ @Override
+ public void onFailure(int reason) {
+ Log.e(TAG, "Failed to trigger network connection");
+ handleNetworkConnectionFailure(mUserSelectedNetwork);
+ }
+ }
/**
* Module to interact with the wifi config store.
@@ -376,7 +371,6 @@ public class WifiNetworkFactory extends NetworkFactory {
mPeriodicScanTimerListener = new PeriodicScanAlarmListener();
mConnectionTimeoutAlarmListener = new ConnectionTimeoutAlarmListener();
mRegisteredCallbacks = new ExternalCallbackTracker<INetworkRequestMatchCallback>(mHandler);
- mSrcMessenger = new Messenger(new Handler(looper, mNetworkConnectionTriggerCallback));
mUserApprovedAccessPointMap = new HashMap<>();
// register the data store for serializing/deserializing data.
@@ -735,7 +729,8 @@ public class WifiNetworkFactory extends NetworkFactory {
// Remove the network if it was added previously by an app's specifier request.
if (wcmNetwork.ephemeral && wcmNetwork.fromWifiNetworkSpecifier) {
boolean success =
- mWifiConfigManager.removeNetwork(wcmNetwork.networkId, wcmNetwork.creatorUid);
+ mWifiConfigManager.removeNetwork(
+ wcmNetwork.networkId, wcmNetwork.creatorUid, wcmNetwork.creatorName);
if (!success) {
Log.e(TAG, "Failed to remove network from config manager");
} else if (mVerboseLoggingEnabled) {
@@ -761,11 +756,10 @@ public class WifiNetworkFactory extends NetworkFactory {
// Send the connect request to ClientModeImpl.
// TODO(b/117601161): Refactor this.
- Message msg = Message.obtain();
- msg.what = WifiManager.CONNECT_NETWORK;
- msg.arg1 = networkId;
- msg.replyTo = mSrcMessenger;
- mWifiInjector.getClientModeImpl().sendMessage(msg);
+ ConnectActionListener connectActionListener = new ConnectActionListener();
+ mWifiInjector.getClientModeImpl().connect(null, networkId, new Binder(),
+ connectActionListener, connectActionListener.hashCode(),
+ mActiveSpecificNetworkRequestSpecifier.requestorUid);
// Post an alarm to handle connection timeout.
scheduleConnectionTimeout();
@@ -1102,11 +1096,10 @@ public class WifiNetworkFactory extends NetworkFactory {
if (!bssid.matches(matchBaseAddress, matchMask)) {
return false;
}
- if (ScanResultMatchInfo.getNetworkType(wns.wifiConfiguration)
- != ScanResultMatchInfo.getNetworkType(scanResult)) {
- return false;
- }
- return true;
+ ScanResultMatchInfo fromScanResult = ScanResultMatchInfo.fromScanResult(scanResult);
+ ScanResultMatchInfo fromWifiConfiguration =
+ ScanResultMatchInfo.fromWifiConfiguration(wns.wifiConfiguration);
+ return fromScanResult.networkTypeEquals(fromWifiConfiguration);
}
// Loops through the scan results and finds scan results matching the active network
@@ -1167,7 +1160,7 @@ public class WifiNetworkFactory extends NetworkFactory {
ApplicationInfo applicationInfo = null;
try {
applicationInfo = mContext.getPackageManager().getApplicationInfoAsUser(
- packageName, 0, UserHandle.getUserId(uid));
+ packageName, 0, UserHandle.getUserHandleForUid(uid));
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Failed to find app name for " + packageName);
return "";
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 85bd9174a5..0395500143 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -482,36 +482,6 @@ public class WifiNetworkSelector {
}
/**
- * This returns a list of ScanDetails that were filtered in the process of network selection.
- * The list is further filtered for only carrier unsaved networks with EAP encryption.
- *
- * @param carrierConfig CarrierNetworkConfig used to filter carrier networks
- * @return the list of ScanDetails for carrier unsaved networks that do not have invalid SSIDS,
- * blacklisted BSSIDS, or low signal strength, and with EAP encryption. This will return an
- * empty list when there are no such networks, or when network selection has not been run.
- */
- public List<ScanDetail> getFilteredScanDetailsForCarrierUnsavedNetworks(
- CarrierNetworkConfig carrierConfig) {
- List<ScanDetail> carrierUnsavedNetworks = new ArrayList<>();
- for (ScanDetail scanDetail : mFilteredNetworks) {
- ScanResult scanResult = scanDetail.getScanResult();
-
- if (!ScanResultUtil.isScanResultForEapNetwork(scanResult)
- || !carrierConfig.isCarrierNetwork(scanResult.SSID)) {
- continue;
- }
-
- // Skip saved networks
- if (mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail) != null) {
- continue;
- }
-
- carrierUnsavedNetworks.add(scanDetail);
- }
- return carrierUnsavedNetworks;
- }
-
- /**
* @return the list of ScanDetails scored as potential candidates by the last run of
* selectNetwork, this will be empty if Network selector determined no selection was
* needed on last run. This includes scan details of sufficient signal strength, and
@@ -751,13 +721,12 @@ public class WifiNetworkSelector {
if (config != null) {
mConnectableNetworks.add(Pair.create(scanDetail, config));
mNetworkIds.add(config.networkId);
- if (config.networkId == lastUserSelectedNetworkId) {
- wifiCandidates.add(scanDetail, config,
- registeredEvaluator.getId(), score, lastSelectionWeight);
- } else {
- wifiCandidates.add(scanDetail, config,
- registeredEvaluator.getId(), score);
- }
+ wifiCandidates.add(scanDetail, config,
+ registeredEvaluator.getId(),
+ score,
+ (config.networkId == lastUserSelectedNetworkId)
+ ? lastSelectionWeight : 0.0,
+ WifiConfiguration.isMetered(config, wifiInfo));
mWifiMetrics.setNominatorForNetwork(config.networkId,
evaluatorIdToNominatorId(registeredEvaluator.getId()));
}
@@ -829,7 +798,7 @@ public class WifiNetworkSelector {
String chooses = " would choose ";
if (candidateScorer == activeScorer) {
chooses = " chooses ";
- legacyOverrideWanted = candidateScorer.userConnectChoiceOverrideWanted();
+ legacyOverrideWanted = choice.userConnectChoiceOverride;
selectedNetworkId = networkId;
}
String id = candidateScorer.getIdentifier();
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index 644eb65234..d530cdbfc9 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -235,6 +235,9 @@ public class WifiNetworkSuggestionsManager {
*/
private Set<ExtendedWifiNetworkSuggestion> mActiveNetworkSuggestionsMatchingConnection;
+ private final Map<String, Set<ExtendedWifiNetworkSuggestion>>
+ mPasspointInfo = new HashMap<>();
+
/**
* Intent filter for processing notification actions.
*/
@@ -307,7 +310,6 @@ public class WifiNetworkSuggestionsManager {
}
@Override
-
public void fromDeserialized(Map<String, PerAppInfo> networkSuggestionsMap) {
mActiveNetworkSuggestionsPerApp.putAll(networkSuggestionsMap);
// Build the scan cache.
@@ -320,7 +322,13 @@ public class WifiNetworkSuggestionsManager {
startTrackingAppOpsChange(packageName,
extNetworkSuggestions.iterator().next().wns.suggestorUid);
}
- addToScanResultMatchInfoMap(extNetworkSuggestions);
+ for (ExtendedWifiNetworkSuggestion ewns : extNetworkSuggestions) {
+ if (ewns.wns.wifiConfiguration.FQDN != null) {
+ addToPasspointInfoMap(ewns);
+ } else {
+ addToScanResultMatchInfoMap(ewns);
+ }
+ }
}
}
@@ -329,6 +337,7 @@ public class WifiNetworkSuggestionsManager {
mActiveNetworkSuggestionsPerApp.clear();
mActiveScanResultMatchInfoWithBssid.clear();
mActiveScanResultMatchInfoWithNoBssid.clear();
+ mPasspointInfo.clear();
}
@Override
@@ -362,7 +371,7 @@ public class WifiNetworkSuggestionsManager {
// Set the user approved flag.
setHasUserApprovedForApp(false, packageName);
// Take away CHANGE_WIFI_STATE app-ops from the app.
- mAppOps.setMode(AppOpsManager.OP_CHANGE_WIFI_STATE, uid, packageName,
+ mAppOps.setMode(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, uid, packageName,
MODE_IGNORED);
break;
case NOTIFICATION_USER_DISMISSED_INTENT_ACTION:
@@ -426,91 +435,118 @@ public class WifiNetworkSuggestionsManager {
}
private void addToScanResultMatchInfoMap(
- @NonNull Collection<ExtendedWifiNetworkSuggestion> extNetworkSuggestions) {
- for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) {
- ScanResultMatchInfo scanResultMatchInfo =
- ScanResultMatchInfo.fromWifiConfiguration(
- extNetworkSuggestion.wns.wifiConfiguration);
- Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsForScanResultMatchInfo;
- if (!TextUtils.isEmpty(extNetworkSuggestion.wns.wifiConfiguration.BSSID)) {
- Pair<ScanResultMatchInfo, MacAddress> lookupPair =
- Pair.create(scanResultMatchInfo,
- MacAddress.fromString(
- extNetworkSuggestion.wns.wifiConfiguration.BSSID));
- extNetworkSuggestionsForScanResultMatchInfo =
- mActiveScanResultMatchInfoWithBssid.get(lookupPair);
- if (extNetworkSuggestionsForScanResultMatchInfo == null) {
- extNetworkSuggestionsForScanResultMatchInfo = new HashSet<>();
- mActiveScanResultMatchInfoWithBssid.put(
- lookupPair, extNetworkSuggestionsForScanResultMatchInfo);
- }
- } else {
- extNetworkSuggestionsForScanResultMatchInfo =
- mActiveScanResultMatchInfoWithNoBssid.get(scanResultMatchInfo);
- if (extNetworkSuggestionsForScanResultMatchInfo == null) {
- extNetworkSuggestionsForScanResultMatchInfo = new HashSet<>();
- mActiveScanResultMatchInfoWithNoBssid.put(
- scanResultMatchInfo, extNetworkSuggestionsForScanResultMatchInfo);
- }
+ @NonNull ExtendedWifiNetworkSuggestion extNetworkSuggestion) {
+ ScanResultMatchInfo scanResultMatchInfo =
+ ScanResultMatchInfo.fromWifiConfiguration(
+ extNetworkSuggestion.wns.wifiConfiguration);
+ Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsForScanResultMatchInfo;
+ if (!TextUtils.isEmpty(extNetworkSuggestion.wns.wifiConfiguration.BSSID)) {
+ Pair<ScanResultMatchInfo, MacAddress> lookupPair =
+ Pair.create(scanResultMatchInfo,
+ MacAddress.fromString(
+ extNetworkSuggestion.wns.wifiConfiguration.BSSID));
+ extNetworkSuggestionsForScanResultMatchInfo =
+ mActiveScanResultMatchInfoWithBssid.get(lookupPair);
+ if (extNetworkSuggestionsForScanResultMatchInfo == null) {
+ extNetworkSuggestionsForScanResultMatchInfo = new HashSet<>();
+ mActiveScanResultMatchInfoWithBssid.put(
+ lookupPair, extNetworkSuggestionsForScanResultMatchInfo);
+ }
+ } else {
+ extNetworkSuggestionsForScanResultMatchInfo =
+ mActiveScanResultMatchInfoWithNoBssid.get(scanResultMatchInfo);
+ if (extNetworkSuggestionsForScanResultMatchInfo == null) {
+ extNetworkSuggestionsForScanResultMatchInfo = new HashSet<>();
+ mActiveScanResultMatchInfoWithNoBssid.put(
+ scanResultMatchInfo, extNetworkSuggestionsForScanResultMatchInfo);
}
- extNetworkSuggestionsForScanResultMatchInfo.add(extNetworkSuggestion);
}
+ extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion);
+ extNetworkSuggestionsForScanResultMatchInfo.add(extNetworkSuggestion);
}
private void removeFromScanResultMatchInfoMap(
- @NonNull Collection<ExtendedWifiNetworkSuggestion> extNetworkSuggestions) {
- for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) {
- ScanResultMatchInfo scanResultMatchInfo =
- ScanResultMatchInfo.fromWifiConfiguration(
- extNetworkSuggestion.wns.wifiConfiguration);
- Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsForScanResultMatchInfo;
- if (!TextUtils.isEmpty(extNetworkSuggestion.wns.wifiConfiguration.BSSID)) {
- Pair<ScanResultMatchInfo, MacAddress> lookupPair =
- Pair.create(scanResultMatchInfo,
- MacAddress.fromString(
- extNetworkSuggestion.wns.wifiConfiguration.BSSID));
- extNetworkSuggestionsForScanResultMatchInfo =
- mActiveScanResultMatchInfoWithBssid.get(lookupPair);
- // This should never happen because we should have done necessary error checks in
- // the parent method.
- if (extNetworkSuggestionsForScanResultMatchInfo == null) {
- Log.wtf(TAG, "No scan result match info found.");
- }
- extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion);
- // Remove the set from map if empty.
- if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) {
- mActiveScanResultMatchInfoWithBssid.remove(lookupPair);
- }
- } else {
- extNetworkSuggestionsForScanResultMatchInfo =
- mActiveScanResultMatchInfoWithNoBssid.get(scanResultMatchInfo);
- // This should never happen because we should have done necessary error checks in
- // the parent method.
- if (extNetworkSuggestionsForScanResultMatchInfo == null) {
- Log.wtf(TAG, "No scan result match info found.");
- }
- extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion);
- // Remove the set from map if empty.
- if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) {
- mActiveScanResultMatchInfoWithNoBssid.remove(scanResultMatchInfo);
- }
+ @NonNull ExtendedWifiNetworkSuggestion extNetworkSuggestion) {
+ ScanResultMatchInfo scanResultMatchInfo =
+ ScanResultMatchInfo.fromWifiConfiguration(
+ extNetworkSuggestion.wns.wifiConfiguration);
+ Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsForScanResultMatchInfo;
+ if (!TextUtils.isEmpty(extNetworkSuggestion.wns.wifiConfiguration.BSSID)) {
+ Pair<ScanResultMatchInfo, MacAddress> lookupPair =
+ Pair.create(scanResultMatchInfo,
+ MacAddress.fromString(
+ extNetworkSuggestion.wns.wifiConfiguration.BSSID));
+ extNetworkSuggestionsForScanResultMatchInfo =
+ mActiveScanResultMatchInfoWithBssid.get(lookupPair);
+ // This should never happen because we should have done necessary error checks in
+ // the parent method.
+ if (extNetworkSuggestionsForScanResultMatchInfo == null) {
+ Log.wtf(TAG, "No scan result match info found.");
+ return;
+ }
+ extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion);
+ // Remove the set from map if empty.
+ if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) {
+ mActiveScanResultMatchInfoWithBssid.remove(lookupPair);
}
+ } else {
+ extNetworkSuggestionsForScanResultMatchInfo =
+ mActiveScanResultMatchInfoWithNoBssid.get(scanResultMatchInfo);
+ // This should never happen because we should have done necessary error checks in
+ // the parent method.
+ if (extNetworkSuggestionsForScanResultMatchInfo == null) {
+ Log.wtf(TAG, "No scan result match info found.");
+ return;
+ }
+ extNetworkSuggestionsForScanResultMatchInfo.remove(extNetworkSuggestion);
+ // Remove the set from map if empty.
+ if (extNetworkSuggestionsForScanResultMatchInfo.isEmpty()) {
+ mActiveScanResultMatchInfoWithNoBssid.remove(scanResultMatchInfo);
+ }
+ }
+ }
+
+ private void addToPasspointInfoMap(ExtendedWifiNetworkSuggestion ewns) {
+ Set<ExtendedWifiNetworkSuggestion> extendedWifiNetworkSuggestions =
+ mPasspointInfo.get(ewns.wns.wifiConfiguration.FQDN);
+ if (extendedWifiNetworkSuggestions == null) {
+ extendedWifiNetworkSuggestions = new HashSet<>();
+ }
+ extendedWifiNetworkSuggestions.add(ewns);
+ mPasspointInfo.put(ewns.wns.wifiConfiguration.FQDN, extendedWifiNetworkSuggestions);
+ }
+
+ private void removeFromPassPointInfoMap(ExtendedWifiNetworkSuggestion ewns) {
+ Set<ExtendedWifiNetworkSuggestion> extendedWifiNetworkSuggestions =
+ mPasspointInfo.get(ewns.wns.wifiConfiguration.FQDN);
+ if (extendedWifiNetworkSuggestions == null
+ || !extendedWifiNetworkSuggestions.contains(ewns)) {
+ Log.wtf(TAG, "No Passpoint info found.");
+ return;
+ }
+ extendedWifiNetworkSuggestions.remove(ewns);
+ if (extendedWifiNetworkSuggestions.isEmpty()) {
+ mPasspointInfo.remove(ewns.wns.wifiConfiguration.FQDN);
}
}
+
// Issues a disconnect if the only serving network suggestion is removed.
- // TODO (b/115504887): What if there is also a saved network with the same credentials?
- private void triggerDisconnectIfServingNetworkSuggestionRemoved(
+ private void removeFromConfigManagerIfServingNetworkSuggestionRemoved(
Collection<ExtendedWifiNetworkSuggestion> extNetworkSuggestionsRemoved) {
if (mActiveNetworkSuggestionsMatchingConnection == null
|| mActiveNetworkSuggestionsMatchingConnection.isEmpty()) {
return;
}
+ WifiConfiguration activeWifiConfiguration =
+ mActiveNetworkSuggestionsMatchingConnection.iterator().next().wns.wifiConfiguration;
if (mActiveNetworkSuggestionsMatchingConnection.removeAll(extNetworkSuggestionsRemoved)) {
if (mActiveNetworkSuggestionsMatchingConnection.isEmpty()) {
Log.i(TAG, "Only network suggestion matching the connected network removed. "
- + "Disconnecting...");
- mWifiInjector.getClientModeImpl().disconnectCommand();
+ + "Removing from config manager...");
+ // will trigger a disconnect.
+ mWifiConfigManager.removeSuggestionConfiguredNetwork(
+ activeWifiConfiguration.configKey());
}
}
}
@@ -576,29 +612,42 @@ public class WifiNetworkSuggestionsManager {
}
Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions =
convertToExtendedWnsSet(networkSuggestions, perAppInfo);
- // check if the app is trying to in-place modify network suggestions.
- if (!Collections.disjoint(perAppInfo.extNetworkSuggestions, extNetworkSuggestions)) {
- Log.e(TAG, "Failed to add network suggestions for " + packageName
- + ". Modification of active network suggestions disallowed");
- return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE;
- }
if (perAppInfo.extNetworkSuggestions.size() + extNetworkSuggestions.size()
> WifiManager.NETWORK_SUGGESTIONS_MAX_PER_APP) {
- Log.e(TAG, "Failed to add network suggestions for " + packageName
- + ". Exceeds max per app, current list size: "
- + perAppInfo.extNetworkSuggestions.size()
- + ", new list size: "
- + extNetworkSuggestions.size());
- return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP;
+ Set<ExtendedWifiNetworkSuggestion> savedNetworkSuggestions =
+ new HashSet<>(perAppInfo.extNetworkSuggestions);
+ savedNetworkSuggestions.addAll(extNetworkSuggestions);
+ if (savedNetworkSuggestions.size() > WifiManager.NETWORK_SUGGESTIONS_MAX_PER_APP) {
+ Log.e(TAG, "Failed to add network suggestions for " + packageName
+ + ". Exceeds max per app, current list size: "
+ + perAppInfo.extNetworkSuggestions.size()
+ + ", new list size: "
+ + extNetworkSuggestions.size());
+ return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP;
+ }
}
if (perAppInfo.extNetworkSuggestions.isEmpty()) {
// Start tracking app-op changes from the app if they have active suggestions.
startTrackingAppOpsChange(packageName, uid);
}
- perAppInfo.extNetworkSuggestions.addAll(extNetworkSuggestions);
+ for (ExtendedWifiNetworkSuggestion ewns: extNetworkSuggestions) {
+ if (ewns.wns.passpointConfiguration == null) {
+ addToScanResultMatchInfoMap(ewns);
+ } else {
+ // Install Passpoint config, if failure, ignore that suggestion
+ if (!mWifiInjector.getPasspointManager().addOrUpdateProvider(
+ ewns.wns.passpointConfiguration, uid,
+ packageName, true)) {
+ Log.e(TAG, "Passpoint profile install failure.");
+ continue;
+ }
+ addToPasspointInfoMap(ewns);
+ }
+ perAppInfo.extNetworkSuggestions.remove(ewns);
+ perAppInfo.extNetworkSuggestions.add(ewns);
+ }
// Update the max size for this app.
perAppInfo.maxSize = Math.max(perAppInfo.extNetworkSuggestions.size(), perAppInfo.maxSize);
- addToScanResultMatchInfoMap(extNetworkSuggestions);
saveToStore();
mWifiMetrics.incrementNetworkSuggestionApiNumModification();
mWifiMetrics.noteNetworkSuggestionApiListSizeHistogram(getAllMaxSizes());
@@ -615,6 +664,10 @@ public class WifiNetworkSuggestionsManager {
mAppOps.stopWatchingMode(appOpsChangedListener);
}
+ /**
+ * Remove provided list from that App active list. If provided list is empty, will remove all.
+ * Will disconnect network if current connected network is in the remove list.
+ */
private void removeInternal(
@NonNull Collection<ExtendedWifiNetworkSuggestion> extNetworkSuggestions,
@NonNull String packageName,
@@ -634,8 +687,21 @@ public class WifiNetworkSuggestionsManager {
// Stop tracking app-op changes from the app if they don't have active suggestions.
stopTrackingAppOpsChange(packageName);
}
- // Clear the scan cache.
- removeFromScanResultMatchInfoMap(extNetworkSuggestions);
+ // Clear the cache.
+ for (ExtendedWifiNetworkSuggestion ewns : extNetworkSuggestions) {
+ if (ewns.wns.wifiConfiguration.FQDN != null) {
+ // Clear the Passpoint config.
+ mWifiInjector.getPasspointManager().removeProvider(
+ ewns.wns.suggestorUid,
+ false,
+ ewns.wns.wifiConfiguration.FQDN);
+ removeFromPassPointInfoMap(ewns);
+ } else {
+ removeFromScanResultMatchInfoMap(ewns);
+ }
+ }
+ // Disconnect suggested network if connected
+ removeFromConfigManagerIfServingNetworkSuggestionRemoved(extNetworkSuggestions);
}
/**
@@ -661,13 +727,6 @@ public class WifiNetworkSuggestionsManager {
+ ". Network suggestions not found in active network suggestions");
return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID;
}
- if (mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(uid)) {
- // empty list is used to clear everything for the app.
- if (extNetworkSuggestions.isEmpty()) {
- extNetworkSuggestions = new HashSet<>(perAppInfo.extNetworkSuggestions);
- }
- triggerDisconnectIfServingNetworkSuggestionRemoved(extNetworkSuggestions);
- }
removeInternal(extNetworkSuggestions, packageName, perAppInfo);
saveToStore();
mWifiMetrics.incrementNetworkSuggestionApiNumModification();
@@ -681,8 +740,6 @@ public class WifiNetworkSuggestionsManager {
public void removeApp(@NonNull String packageName) {
PerAppInfo perAppInfo = mActiveNetworkSuggestionsPerApp.get(packageName);
if (perAppInfo == null) return;
- // Disconnect from the current network, if the only suggestion for it was removed.
- triggerDisconnectIfServingNetworkSuggestionRemoved(perAppInfo.extNetworkSuggestions);
removeInternal(Collections.EMPTY_LIST, packageName, perAppInfo);
// Remove the package fully from the internal database.
mActiveNetworkSuggestionsPerApp.remove(packageName);
@@ -691,14 +748,27 @@ public class WifiNetworkSuggestionsManager {
}
/**
+ * Get all network suggestion for target App
+ * @return List of WifiNetworkSuggestions
+ */
+ public @NonNull List<WifiNetworkSuggestion> get(@NonNull String packageName) {
+ List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
+ PerAppInfo perAppInfo = mActiveNetworkSuggestionsPerApp.get(packageName);
+ // if App never suggested return empty list.
+ if (perAppInfo == null) return networkSuggestionList;
+ for (ExtendedWifiNetworkSuggestion extendedSuggestion : perAppInfo.extNetworkSuggestions) {
+ networkSuggestionList.add(extendedSuggestion.wns);
+ }
+ return networkSuggestionList;
+ }
+
+
+ /**
* Clear all internal state (for network settings reset).
*/
public void clear() {
Iterator<Map.Entry<String, PerAppInfo>> iter =
mActiveNetworkSuggestionsPerApp.entrySet().iterator();
- // Disconnect if we're connected to one of the suggestions.
- triggerDisconnectIfServingNetworkSuggestionRemoved(
- mActiveNetworkSuggestionsMatchingConnection);
while (iter.hasNext()) {
Map.Entry<String, PerAppInfo> entry = iter.next();
removeInternal(Collections.EMPTY_LIST, entry.getKey(), entry.getValue());
@@ -754,7 +824,7 @@ public class WifiNetworkSuggestionsManager {
private PendingIntent getPrivateBroadcast(@NonNull String action, @NonNull String packageName,
int uid) {
Intent intent = new Intent(action)
- .setPackage("android")
+ .setPackage(mWifiInjector.getWifiStackPackageName())
.putExtra(EXTRA_PACKAGE_NAME, packageName)
.putExtra(EXTRA_UID, uid);
return mFrameworkFacade.getBroadcast(mContext, 0, intent,
@@ -765,7 +835,7 @@ public class WifiNetworkSuggestionsManager {
ApplicationInfo applicationInfo = null;
try {
applicationInfo = mContext.getPackageManager().getApplicationInfoAsUser(
- packageName, 0, UserHandle.getUserId(uid));
+ packageName, 0, UserHandle.getUserHandleForUid(uid));
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Failed to find app name for " + packageName);
return "";
@@ -813,15 +883,26 @@ public class WifiNetworkSuggestionsManager {
mUserApprovalNotificationPackageName = packageName;
}
- private boolean sendUserApprovalNotificationIfNotApproved(
- @NonNull PerAppInfo perAppInfo,
- @NonNull WifiNetworkSuggestion matchingSuggestion) {
- if (perAppInfo.hasUserApproved) {
+ /**
+ * Send user approval notification if the app is not approved
+ * @param packageName app package name
+ * @param uid app UID
+ * @return true if app is not approved and send notification.
+ */
+ public boolean sendUserApprovalNotificationIfNotApproved(
+ @NonNull String packageName, @NonNull int uid) {
+ if (!mActiveNetworkSuggestionsPerApp.containsKey(packageName)) {
+ Log.wtf(TAG, "AppInfo is missing for " + packageName);
+ return false;
+ }
+ if (mActiveNetworkSuggestionsPerApp.get(packageName).hasUserApproved) {
return false; // already approved.
}
- Log.i(TAG, "Sending user approval notification for " + perAppInfo.packageName);
- sendUserApprovalNotification(perAppInfo.packageName, matchingSuggestion.suggestorUid);
+ Log.i(TAG, "Sending user approval notification for " + packageName);
+ if (!mUserApprovalNotificationActive) {
+ sendUserApprovalNotification(packageName, uid);
+ }
return true;
}
@@ -848,6 +929,14 @@ public class WifiNetworkSuggestionsManager {
return extNetworkSuggestions;
}
+ private @Nullable Set<ExtendedWifiNetworkSuggestion> getNetworkSuggestionsForFqdnMatch(
+ @Nullable String fqdn) {
+ if (TextUtils.isEmpty(fqdn)) {
+ return null;
+ }
+ return mPasspointInfo.get(fqdn);
+ }
+
/**
* Returns a set of all network suggestions matching the provided scan detail.
*/
@@ -882,7 +971,8 @@ public class WifiNetworkSuggestionsManager {
&& approvedExtNetworkSuggestions.size() != extNetworkSuggestions.size()) {
for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) {
if (sendUserApprovalNotificationIfNotApproved(
- extNetworkSuggestion.perAppInfo, extNetworkSuggestion.wns)) {
+ extNetworkSuggestion.perAppInfo.packageName,
+ extNetworkSuggestion.wns.suggestorUid)) {
break;
}
}
@@ -901,18 +991,22 @@ public class WifiNetworkSuggestionsManager {
/**
* Returns a set of all network suggestions matching the provided the WifiConfiguration.
*/
- private @Nullable Set<ExtendedWifiNetworkSuggestion> getNetworkSuggestionsForWifiConfiguration(
+ public @Nullable Set<ExtendedWifiNetworkSuggestion> getNetworkSuggestionsForWifiConfiguration(
@NonNull WifiConfiguration wifiConfiguration, @Nullable String bssid) {
Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions = null;
- try {
- ScanResultMatchInfo scanResultMatchInfo =
- ScanResultMatchInfo.fromWifiConfiguration(wifiConfiguration);
- extNetworkSuggestions = getNetworkSuggestionsForScanResultMatchInfo(
- scanResultMatchInfo, bssid == null ? null : MacAddress.fromString(bssid));
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Failed to lookup network from scan result match info map", e);
+ if (wifiConfiguration.isPasspoint()) {
+ extNetworkSuggestions = getNetworkSuggestionsForFqdnMatch(wifiConfiguration.FQDN);
+ } else {
+ try {
+ ScanResultMatchInfo scanResultMatchInfo =
+ ScanResultMatchInfo.fromWifiConfiguration(wifiConfiguration);
+ extNetworkSuggestions = getNetworkSuggestionsForScanResultMatchInfo(
+ scanResultMatchInfo, bssid == null ? null : MacAddress.fromString(bssid));
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Failed to lookup network from scan result match info map", e);
+ }
}
- if (extNetworkSuggestions == null) {
+ if (extNetworkSuggestions == null || extNetworkSuggestions.isEmpty()) {
return null;
}
Set<ExtendedWifiNetworkSuggestion> approvedExtNetworkSuggestions =
@@ -926,7 +1020,7 @@ public class WifiNetworkSuggestionsManager {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "getNetworkSuggestionsFoWifiConfiguration Found "
+ approvedExtNetworkSuggestions + " for " + wifiConfiguration.SSID
- + "[" + wifiConfiguration.allowedKeyManagement + "]");
+ + wifiConfiguration.FQDN + "[" + wifiConfiguration.allowedKeyManagement + "]");
}
return approvedExtNetworkSuggestions;
}
@@ -993,7 +1087,8 @@ public class WifiNetworkSuggestionsManager {
private void handleConnectionSuccess(
@NonNull WifiConfiguration connectedNetwork, @NonNull String connectedBssid) {
Set<ExtendedWifiNetworkSuggestion> matchingExtNetworkSuggestions =
- getNetworkSuggestionsForWifiConfiguration(connectedNetwork, connectedBssid);
+ getNetworkSuggestionsForWifiConfiguration(connectedNetwork, connectedBssid);
+
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Network suggestions matching the connection "
+ matchingExtNetworkSuggestions);
diff --git a/service/java/com/android/server/wifi/WifiScoreCard.java b/service/java/com/android/server/wifi/WifiScoreCard.java
index 973c06dc9f..af995fd62c 100644
--- a/service/java/com/android/server/wifi/WifiScoreCard.java
+++ b/service/java/com/android/server/wifi/WifiScoreCard.java
@@ -46,6 +46,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
@@ -67,6 +68,8 @@ public class WifiScoreCard {
private static final String TAG = "WifiScoreCard";
private static final boolean DBG = false;
+ private static final int TARGET_IN_MEMORY_ENTRIES = 50;
+
private final Clock mClock;
private final String mL2KeySeed;
private MemoryStore mMemoryStore;
@@ -251,6 +254,7 @@ public class WifiScoreCard {
if (mValidated) return; // Only once per connection
update(Event.VALIDATION_SUCCESS, wifiInfo);
mValidated = true;
+ doWrites();
}
/**
@@ -369,6 +373,8 @@ public class WifiScoreCard {
public final String ssid;
public final MacAddress bssid;
public boolean changed;
+ public boolean referenced;
+
private SecurityType mSecurityType = null;
private int mNetworkAgentId = Integer.MIN_VALUE;
private int mNetworkConfigId = Integer.MIN_VALUE;
@@ -381,6 +387,7 @@ public class WifiScoreCard {
this.l2Key = l2KeyFromLong(hash);
this.id = idFromLong(hash);
this.changed = false;
+ this.referenced = false;
}
void updateEventStats(Event event, int frequency, int rssi, int linkspeed) {
PerSignal perSignal = lookupSignal(event, frequency);
@@ -513,6 +520,8 @@ public class WifiScoreCard {
private final PerBssid mDummyPerBssid;
private final Map<MacAddress, PerBssid> mApForBssid = new ArrayMap<>();
+ private int mApForBssidTargetSize = TARGET_IN_MEMORY_ENTRIES;
+ private int mApForBssidReferenced = 0;
// TODO should be private, but WifiCandidates needs it
@NonNull PerBssid lookupBssid(String ssid, String bssid) {
@@ -531,9 +540,15 @@ public class WifiScoreCard {
PerBssid old = mApForBssid.put(mac, ans);
if (old != null) {
Log.i(TAG, "Discarding stats for score card (ssid changed) ID: " + old.id);
+ if (old.referenced) mApForBssidReferenced--;
}
requestReadForPerBssid(ans);
}
+ if (!ans.referenced) {
+ ans.referenced = true;
+ mApForBssidReferenced++;
+ clean();
+ }
return ans;
}
@@ -580,6 +595,34 @@ public class WifiScoreCard {
return count;
}
+ /**
+ * Evicts older entries from memory.
+ *
+ * This uses an approximate least-recently-used method. When the number of
+ * referenced entries exceeds the target value, any items that have not been
+ * referenced since the last round are evicted, and the remaining entries
+ * are marked as unreferenced. The total count varies between the target
+ * value and twice the target value.
+ */
+ private void clean() {
+ if (mMemoryStore == null) return;
+ if (mApForBssidReferenced >= mApForBssidTargetSize) {
+ doWrites(); // Do not want to evict changed items
+ // Evict the unreferenced ones, and clear all the referenced bits for the next round.
+ Iterator<Map.Entry<MacAddress, PerBssid>> it = mApForBssid.entrySet().iterator();
+ while (it.hasNext()) {
+ PerBssid perBssid = it.next().getValue();
+ if (perBssid.referenced) {
+ perBssid.referenced = false;
+ } else {
+ it.remove();
+ if (DBG) Log.v(TAG, "Evict " + perBssid.id);
+ }
+ }
+ mApForBssidReferenced = 0;
+ }
+ }
+
private long computeHashLong(String ssid, MacAddress mac) {
byte[][] parts = {
// Our seed keeps the L2Keys specific to this device
@@ -789,6 +832,7 @@ public class WifiScoreCard {
* @param obfuscate - if true, ssids and bssids are omitted (short id only)
*/
public byte[] getNetworkListByteArray(boolean obfuscate) {
+ // These are really grouped by ssid, ignoring the security type.
Map<String, Network.Builder> networks = new ArrayMap<>();
for (PerBssid perBssid: mApForBssid.values()) {
String key = perBssid.ssid;
@@ -799,15 +843,12 @@ public class WifiScoreCard {
if (!obfuscate) {
network.setSsid(perBssid.ssid);
}
- if (perBssid.mSecurityType != null) {
- network.setSecurityType(perBssid.mSecurityType);
- }
- if (perBssid.mNetworkAgentId >= network.getNetworkAgentId()) {
- network.setNetworkAgentId(perBssid.mNetworkAgentId);
- }
- if (perBssid.mNetworkConfigId >= network.getNetworkConfigId()) {
- network.setNetworkConfigId(perBssid.mNetworkConfigId);
- }
+ }
+ if (perBssid.mNetworkAgentId >= network.getNetworkAgentId()) {
+ network.setNetworkAgentId(perBssid.mNetworkAgentId);
+ }
+ if (perBssid.mNetworkConfigId >= network.getNetworkConfigId()) {
+ network.setNetworkConfigId(perBssid.mNetworkConfigId);
}
network.addAccessPoints(perBssid.toAccessPoint(obfuscate));
}
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index 33cc15058a..63321b3430 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -293,7 +293,7 @@ public class WifiScoreReport {
synchronized (mLinkMetricsHistory) {
history = new LinkedList<>(mLinkMetricsHistory);
}
- pw.println("time,session,netid,rssi,filtered_rssi,rssi_threshold, freq,txLinkSpeed,"
+ pw.println("time,session,netid,rssi,filtered_rssi,rssi_threshold,freq,txLinkSpeed,"
+ "rxLinkSpeed,tx_good,tx_retry,tx_bad,rx_pps,nudrq,nuds,s1,s2,score");
for (String line : history) {
pw.println(line);
diff --git a/service/java/com/android/server/wifi/WifiService.java b/service/java/com/android/server/wifi/WifiService.java
index b934ea108a..aaf9b19893 100644
--- a/service/java/com/android/server/wifi/WifiService.java
+++ b/service/java/com/android/server/wifi/WifiService.java
@@ -17,34 +17,30 @@
package com.android.server.wifi;
import android.content.Context;
+import android.os.Binder;
import android.util.Log;
-import com.android.server.SystemService;
import com.android.server.wifi.util.WifiAsyncChannel;
-public final class WifiService extends SystemService {
+/**
+ * Manages the wifi service instance.
+ */
+public final class WifiService implements WifiServiceBase {
private static final String TAG = "WifiService";
final WifiServiceImpl mImpl;
public WifiService(Context context) {
- super(context);
- mImpl = new WifiServiceImpl(context, new WifiInjector(context), new WifiAsyncChannel(TAG));
+ mImpl = new WifiServiceImpl(context, WifiInjector.getInstance(), new WifiAsyncChannel(TAG));
}
@Override
public void onStart() {
- Log.i(TAG, "Registering " + Context.WIFI_SERVICE);
- publishBinderService(Context.WIFI_SERVICE, mImpl);
- }
+ Log.i(TAG, "Starting " + Context.WIFI_SERVICE);
+ mImpl.checkAndStartWifi();
- @Override
- public void onBootPhase(int phase) {
- if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
- mImpl.checkAndStartWifi();
- } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
- mImpl.handleBootCompleted();
- }
+ // Trigger all the necessary boot completed actions, since we are starting late now.
+ mImpl.handleBootCompleted();
}
@Override
@@ -61,4 +57,9 @@ public final class WifiService extends SystemService {
public void onStopUser(int userId) {
mImpl.handleUserStop(userId);
}
+
+ @Override
+ public Binder retrieveImpl() {
+ return mImpl;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiServiceBase.java b/service/java/com/android/server/wifi/WifiServiceBase.java
new file mode 100644
index 0000000000..8cf8add6d8
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiServiceBase.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 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.os.Binder;
+
+/**
+ * Base class for all the wifi services. This is used to manage the lifetime of the services.
+ * Each service should override the methods corresponding to the lifetime events they care about.
+ *
+ * Note: Services can listen to these system broadcasts on their own, but they're explicitly listed
+ * here to better manage inter-service dependencies. (For ex: wifi aware service needs wifi service
+ * to initialize the HAL first).
+ */
+public interface WifiServiceBase {
+ /**
+ * Invoked when the APK service is bound. Should bed used to publish
+ * it's binder service & perform necessary initialization. This should happen very close to
+ * bootup phase {@link SystemService#PHASE_BOOT_COMPLETED} in system_server.
+ */
+ void onStart();
+
+ /**
+ * Invoked when the user switches.
+ *
+ * @param userId Id for the new user.
+ */
+ default void onSwitchUser(int userId) {}
+
+ /**
+ * Invoked when the user unlocks.
+ *
+ * @param userId Id for the user.
+ */
+ default void onUnlockUser(int userId) {}
+
+ /**
+ * Invoked when the user stops.
+ *
+ * @param userId Id for the user.
+ */
+ default void onStopUser(int userId) {}
+
+ /**
+ * Retrieve the underlying binder service implementation.
+ */
+ Binder retrieveImpl();
+}
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 4dbf71fd76..9d3f422cbd 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -18,34 +18,20 @@ package com.android.server.wifi;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.wifi.WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_FAILURE_REASON;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
-import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
+import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
+import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
import static android.net.wifi.WifiManager.WIFI_FEATURE_INFRA_5G;
-import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
-import static com.android.server.wifi.WifiController.CMD_AIRPLANE_TOGGLED;
-import static com.android.server.wifi.WifiController.CMD_EMERGENCY_CALL_STATE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_EMERGENCY_MODE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_SCAN_ALWAYS_MODE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_SET_AP;
-import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED;
-
-import android.Manifest;
import android.annotation.CheckResult;
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningAppProcessInfo;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.AppOpsManager;
-import android.app.admin.DeviceAdminInfo;
-import android.app.admin.DevicePolicyManagerInternal;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -58,23 +44,31 @@ import android.database.ContentObserver;
import android.net.DhcpInfo;
import android.net.DhcpResults;
import android.net.Network;
+import android.net.NetworkStack;
import android.net.NetworkUtils;
import android.net.Uri;
import android.net.ip.IpClientUtil;
+import android.net.wifi.IActionListener;
import android.net.wifi.IDppCallback;
+import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.IOnWifiUsabilityStatsListener;
+import android.net.wifi.IScanResultsListener;
import android.net.wifi.ISoftApCallback;
import android.net.wifi.ITrafficStateCallback;
+import android.net.wifi.ITxPacketCountListener;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiActivityEnergyInfo;
+import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.DeviceMobilityState;
import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
import android.net.wifi.WifiNetworkSuggestion;
+import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
+import android.net.wifi.WifiStackClient;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
@@ -84,11 +78,9 @@ import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
-import android.os.Messenger;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -101,8 +93,7 @@ import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
-import android.util.MutableInt;
-import android.util.Slog;
+import android.util.MutableBoolean;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -111,9 +102,9 @@ import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.AsyncChannel;
+import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.hotspot2.PasspointProvider;
import com.android.server.wifi.util.ExternalCallbackTracker;
-import com.android.server.wifi.util.GeneralUtil.Mutable;
import com.android.server.wifi.util.WifiHandler;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -134,35 +125,31 @@ import java.security.cert.PKIXParameters;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
/**
* WifiService handles remote WiFi operation requests by implementing
* the IWifiManager interface.
- *
- * @hide
*/
public class WifiServiceImpl extends BaseWifiService {
private static final String TAG = "WifiService";
+ private static final int APP_INFO_FLAGS_SYSTEM_APP =
+ ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
private static final boolean VDBG = false;
- // Default scan background throttling interval if not overriden in settings
- private static final long DEFAULT_SCAN_BACKGROUND_THROTTLE_INTERVAL_MS = 30 * 60 * 1000;
-
- // Apps with importance higher than this value is considered as background app.
- private static final int BACKGROUND_IMPORTANCE_CUTOFF =
- RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
-
- // Max wait time for posting blocking runnables
+ /** Max wait time for posting blocking runnables */
private static final int RUN_WITH_SCISSORS_TIMEOUT_MILLIS = 4000;
- final ClientModeImpl mClientModeImpl;
- final ActiveModeWarden mActiveModeWarden;
- final ScanRequestProxy mScanRequestProxy;
+ private final ClientModeImpl mClientModeImpl;
+ private final ActiveModeWarden mActiveModeWarden;
+ private final ScanRequestProxy mScanRequestProxy;
private final Context mContext;
private final FrameworkFacade mFacade;
@@ -171,24 +158,22 @@ public class WifiServiceImpl extends BaseWifiService {
private final PowerManager mPowerManager;
private final AppOpsManager mAppOps;
private final UserManager mUserManager;
- private final ActivityManager mActivityManager;
private final WifiCountryCode mCountryCode;
- // Debug counter tracking scan requests sent by WifiManager
- private int scanRequestCounter = 0;
-
- /* Polls traffic stats and notifies clients */
- private WifiTrafficPoller mWifiTrafficPoller;
- /* Tracks the persisted states for wi-fi & airplane mode */
- final WifiSettingsStore mSettingsStore;
- /* Logs connection events and some general router and scan stats */
+
+ /** Polls traffic stats and notifies clients */
+ private final WifiTrafficPoller mWifiTrafficPoller;
+ /** Tracks the persisted states for wi-fi & airplane mode */
+ private final WifiSettingsStore mSettingsStore;
+ /** Logs connection events and some general router and scan stats */
private final WifiMetrics mWifiMetrics;
private final WifiInjector mWifiInjector;
- /* Backup/Restore Module */
+ /** Backup/Restore Module */
private final WifiBackupRestore mWifiBackupRestore;
private final WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
-
- private WifiLog mLog;
+ private final WifiConfigManager mWifiConfigManager;
+ private final PasspointManager mPasspointManager;
+ private final WifiLog mLog;
/**
* Verbose logging flag. Toggled by developer options.
*/
@@ -202,42 +187,21 @@ public class WifiServiceImpl extends BaseWifiService {
private final FrameworkFacade mFrameworkFacade;
- private WifiPermissionsUtil mWifiPermissionsUtil;
-
- @GuardedBy("mLocalOnlyHotspotRequests")
- private final HashMap<Integer, LocalOnlyHotspotRequestInfo> mLocalOnlyHotspotRequests;
- @GuardedBy("mLocalOnlyHotspotRequests")
- private WifiConfiguration mLocalOnlyHotspotConfig = null;
- @GuardedBy("mLocalOnlyHotspotRequests")
- private final ConcurrentHashMap<String, Integer> mIfaceIpModes;
-
- private final ExternalCallbackTracker<ISoftApCallback> mRegisteredSoftApCallbacks;
-
- /**
- * One of: {@link WifiManager#WIFI_AP_STATE_DISABLED},
- * {@link WifiManager#WIFI_AP_STATE_DISABLING},
- * {@link WifiManager#WIFI_AP_STATE_ENABLED},
- * {@link WifiManager#WIFI_AP_STATE_ENABLING},
- * {@link WifiManager#WIFI_AP_STATE_FAILED}
- *
- * Access/maintenance MUST be done on the wifi service thread
- */
- // TODO: (b/71714381) Remove mWifiApState and broadcast mechanism, keep mSoftApState as the only
- // field to store soft AP state. Then rename mSoftApState and mSoftApNumClients to
- // mWifiApState and mWifiApNumClients, to match the constants (i.e. WIFI_AP_STATE_*)
- private int mWifiApState = WifiManager.WIFI_AP_STATE_DISABLED;
- private int mSoftApState = WifiManager.WIFI_AP_STATE_DISABLED;
- private int mSoftApNumClients = 0;
+ private final WifiPermissionsUtil mWifiPermissionsUtil;
/**
* Power profile
*/
- PowerProfile mPowerProfile;
+ private final PowerProfile mPowerProfile;
+
+ private final TetheredSoftApTracker mTetheredSoftApTracker;
+
+ private final LohsSoftApTracker mLohsSoftApTracker;
+
+ private WifiScanner mWifiScanner;
/**
* Callback for use with LocalOnlyHotspot to unregister requesting applications upon death.
- *
- * @hide
*/
public final class LocalOnlyRequestorCallback
implements LocalOnlyHotspotRequestInfo.RequestingApplicationDeathCallback {
@@ -246,159 +210,11 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public void onLocalOnlyHotspotRequestorDeath(LocalOnlyHotspotRequestInfo requestor) {
- unregisterCallingAppAndStopLocalOnlyHotspot(requestor);
- };
- }
-
- /**
- * Handles client connections
- */
- private class AsyncChannelExternalClientHandler extends WifiHandler {
-
- AsyncChannelExternalClientHandler(String tag, Looper looper) {
- super(tag, looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- switch (msg.what) {
- case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
- AsyncChannel ac = mFrameworkFacade.makeWifiAsyncChannel(TAG);
- ac.connect(mContext, this, msg.replyTo);
- break;
- }
- case WifiManager.CONNECT_NETWORK: {
- if (checkPrivilegedPermissionsAndReplyIfNotAuthorized(
- msg, WifiManager.CONNECT_NETWORK_FAILED)) {
- WifiConfiguration config = (WifiConfiguration) msg.obj;
- int networkId = msg.arg1;
- Slog.d(TAG, "CONNECT "
- + " nid=" + Integer.toString(networkId)
- + " config=" + config
- + " uid=" + msg.sendingUid
- + " name="
- + mContext.getPackageManager().getNameForUid(msg.sendingUid));
- if (config != null) {
- /* Command is forwarded to state machine */
- mClientModeImpl.sendMessage(Message.obtain(msg));
- } else if (config == null
- && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
- mClientModeImpl.sendMessage(Message.obtain(msg));
- } else {
- Slog.e(TAG, "AsyncChannelExternalClientHandler.handleMessage "
- + "ignoring invalid msg=" + msg);
- replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED,
- WifiManager.INVALID_ARGS);
- }
- }
- break;
- }
- case WifiManager.SAVE_NETWORK: {
- if (checkPrivilegedPermissionsAndReplyIfNotAuthorized(
- msg, WifiManager.SAVE_NETWORK_FAILED)) {
- WifiConfiguration config = (WifiConfiguration) msg.obj;
- int networkId = msg.arg1;
- Slog.d(TAG, "SAVE"
- + " nid=" + Integer.toString(networkId)
- + " config=" + config
- + " uid=" + msg.sendingUid
- + " name="
- + mContext.getPackageManager().getNameForUid(msg.sendingUid));
- if (config != null) {
- /* Command is forwarded to state machine */
- mClientModeImpl.sendMessage(Message.obtain(msg));
- } else {
- Slog.e(TAG, "AsyncChannelExternalClientHandler.handleMessage "
- + "ignoring invalid msg=" + msg);
- replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED,
- WifiManager.INVALID_ARGS);
- }
- }
- break;
- }
- case WifiManager.FORGET_NETWORK:
- if (checkPrivilegedPermissionsAndReplyIfNotAuthorized(
- msg, WifiManager.FORGET_NETWORK_FAILED)) {
- mClientModeImpl.sendMessage(Message.obtain(msg));
- }
- break;
- case WifiManager.DISABLE_NETWORK:
- if (checkPrivilegedPermissionsAndReplyIfNotAuthorized(
- msg, WifiManager.DISABLE_NETWORK_FAILED)) {
- mClientModeImpl.sendMessage(Message.obtain(msg));
- }
- break;
- case WifiManager.RSSI_PKTCNT_FETCH: {
- if (checkChangePermissionAndReplyIfNotAuthorized(
- msg, WifiManager.RSSI_PKTCNT_FETCH_FAILED)) {
- mClientModeImpl.sendMessage(Message.obtain(msg));
- }
- break;
- }
- default: {
- Slog.d(TAG, "AsyncChannelExternalClientHandler.handleMessage "
- + "ignoring msg=" + msg);
- break;
- }
- }
- }
-
- /**
- * Helper method to check if the sender of the message holds the
- * {@link Manifest.permission#CHANGE_WIFI_STATE} permission, and reply with a failure if it
- * doesn't
- *
- * @param msg Incoming message.
- * @param replyWhat Param to be filled in the {@link Message#what} field of the failure
- * reply.
- * @return true if the sender holds the permission, false otherwise.
- */
- private boolean checkChangePermissionAndReplyIfNotAuthorized(Message msg, int replyWhat) {
- if (!mWifiPermissionsUtil.checkChangePermission(msg.sendingUid)) {
- Slog.e(TAG, "AsyncChannelExternalClientHandler.handleMessage "
- + "ignoring unauthorized msg=" + msg);
- replyFailed(msg, replyWhat, WifiManager.NOT_AUTHORIZED);
- return false;
- }
- return true;
- }
-
- /**
- * Helper method to check if the sender of the message holds one of
- * {@link Manifest.permission#NETWORK_SETTINGS},
- * {@link Manifest.permission#NETWORK_SETUP_WIZARD} or
- * {@link Manifest.permission#NETWORK_STACK} permission, and reply with a failure if it
- * doesn't
- *
- * @param msg Incoming message.
- * @param replyWhat Param to be filled in the {@link Message#what} field of the failure
- * reply.
- * @return true if the sender holds the permission, false otherwise.
- */
- private boolean checkPrivilegedPermissionsAndReplyIfNotAuthorized(
- Message msg, int replyWhat) {
- if (!isPrivileged(-1, msg.sendingUid)) {
- Slog.e(TAG, "ClientHandler.handleMessage ignoring unauthorized msg=" + msg);
- replyFailed(msg, replyWhat, WifiManager.NOT_AUTHORIZED);
- return false;
- }
- return true;
- }
-
- private void replyFailed(Message msg, int what, int why) {
- if (msg.replyTo == null) return;
- Message reply = Message.obtain();
- reply.what = what;
- reply.arg1 = why;
- try {
- msg.replyTo.send(reply);
- } catch (RemoteException e) {
- // There's not much we can do if reply can't be sent!
- }
+ mLog.trace("onLocalOnlyHotspotRequestorDeath pid=%")
+ .c(requestor.getPid()).flush();
+ mLohsSoftApTracker.stopByRequest(requestor);
}
}
- private AsyncChannelExternalClientHandler mAsyncChannelExternalClientHandler;
/**
* Handles interaction with ClientModeImpl
@@ -420,33 +236,32 @@ public class WifiServiceImpl extends BaseWifiService {
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
mClientModeImplChannel = mCmiChannel;
} else {
- Slog.e(TAG, "ClientModeImpl connection failure, error=" + msg.arg1);
+ Log.e(TAG, "ClientModeImpl connection failure, error=" + msg.arg1);
mClientModeImplChannel = null;
}
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
- Slog.e(TAG, "ClientModeImpl channel lost, msg.arg1 =" + msg.arg1);
+ Log.e(TAG, "ClientModeImpl channel lost, msg.arg1 =" + msg.arg1);
mClientModeImplChannel = null;
//Re-establish connection to state machine
mCmiChannel.connect(mContext, this, mClientModeImpl.getHandler());
break;
}
default: {
- Slog.d(TAG, "ClientModeImplHandler.handleMessage ignoring msg=" + msg);
+ Log.d(TAG, "ClientModeImplHandler.handleMessage ignoring msg=" + msg);
break;
}
}
}
}
- ClientModeImplHandler mClientModeImplHandler;
- private WifiController mWifiController;
+ private final ClientModeImplHandler mClientModeImplHandler;
private final WifiLockManager mWifiLockManager;
private final WifiMulticastLockManager mWifiMulticastLockManager;
private final DppManager mDppManager;
-
- private WifiApConfigStore mWifiApConfigStore;
+ private final WifiApConfigStore mWifiApConfigStore;
+ private final WifiThreadRunner mWifiThreadRunner;
public WifiServiceImpl(Context context, WifiInjector wifiInjector, AsyncChannel asyncChannel) {
mContext = context;
@@ -460,44 +275,31 @@ public class WifiServiceImpl extends BaseWifiService {
mCountryCode = mWifiInjector.getWifiCountryCode();
mClientModeImpl = mWifiInjector.getClientModeImpl();
mActiveModeWarden = mWifiInjector.getActiveModeWarden();
- mClientModeImpl.enableRssiPolling(true);
+ mClientModeImpl.enableRssiPolling(true); //TODO(b/65033024) strange startup
mScanRequestProxy = mWifiInjector.getScanRequestProxy();
mSettingsStore = mWifiInjector.getWifiSettingsStore();
mPowerManager = mContext.getSystemService(PowerManager.class);
mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
- mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
mWifiLockManager = mWifiInjector.getWifiLockManager();
mWifiMulticastLockManager = mWifiInjector.getWifiMulticastLockManager();
- HandlerThread wifiServiceHandlerThread = mWifiInjector.getWifiServiceHandlerThread();
- mAsyncChannelExternalClientHandler =
- new AsyncChannelExternalClientHandler(TAG, wifiServiceHandlerThread.getLooper());
mClientModeImplHandler = new ClientModeImplHandler(TAG,
- wifiServiceHandlerThread.getLooper(), asyncChannel);
- mWifiController = mWifiInjector.getWifiController();
+ mWifiInjector.getAsyncChannelHandlerThread().getLooper(), asyncChannel);
mWifiBackupRestore = mWifiInjector.getWifiBackupRestore();
mWifiApConfigStore = mWifiInjector.getWifiApConfigStore();
mWifiPermissionsUtil = mWifiInjector.getWifiPermissionsUtil();
mLog = mWifiInjector.makeLog(TAG);
mFrameworkFacade = wifiInjector.getFrameworkFacade();
- mIfaceIpModes = new ConcurrentHashMap<>();
- mLocalOnlyHotspotRequests = new HashMap<>();
enableVerboseLoggingInternal(getVerboseLoggingLevel());
- mRegisteredSoftApCallbacks =
- new ExternalCallbackTracker<ISoftApCallback>(mClientModeImplHandler);
-
- mWifiInjector.getActiveModeWarden().registerSoftApCallback(new SoftApCallbackImpl());
+ mTetheredSoftApTracker = new TetheredSoftApTracker();
+ mActiveModeWarden.registerSoftApCallback(mTetheredSoftApTracker);
+ mLohsSoftApTracker = new LohsSoftApTracker();
+ mActiveModeWarden.registerLohsCallback(mLohsSoftApTracker);
mPowerProfile = mWifiInjector.getPowerProfile();
mWifiNetworkSuggestionsManager = mWifiInjector.getWifiNetworkSuggestionsManager();
mDppManager = mWifiInjector.getDppManager();
- }
-
- /**
- * Provide a way for unit tests to set valid log object in the WifiHandler
- * @param log WifiLog object to assign to the clientHandler
- */
- @VisibleForTesting
- public void setWifiHandlerLogForTest(WifiLog log) {
- mAsyncChannelExternalClientHandler.setWifiLog(log);
+ mWifiThreadRunner = mWifiInjector.getWifiThreadRunner();
+ mWifiConfigManager = mWifiInjector.getWifiConfigManager();
+ mPasspointManager = mWifiInjector.getPasspointManager();
}
/**
@@ -509,16 +311,9 @@ public class WifiServiceImpl extends BaseWifiService {
* This function is used only at boot time.
*/
public void checkAndStartWifi() {
- // First check if we will end up restarting WifiService
- if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
- Log.d(TAG, "Device still encrypted. Need to restart SystemServer. Do not start wifi.");
- return;
- }
-
// Check if wi-fi needs to be enabled
boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
- Slog.i(TAG, "WifiService starting up with Wi-Fi " +
- (wifiEnabled ? "enabled" : "disabled"));
+ Log.i(TAG, "WifiService starting up with Wi-Fi " + (wifiEnabled ? "enabled" : "disabled"));
registerForScanModeChange();
mContext.registerReceiver(
@@ -526,7 +321,7 @@ public class WifiServiceImpl extends BaseWifiService {
@Override
public void onReceive(Context context, Intent intent) {
if (mSettingsStore.handleAirplaneModeToggled()) {
- mWifiController.sendMessage(CMD_AIRPLANE_TOGGLED);
+ mActiveModeWarden.airplaneModeToggled();
}
}
},
@@ -548,25 +343,6 @@ public class WifiServiceImpl extends BaseWifiService {
},
new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED));
- mContext.registerReceiver(
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final int currState = intent.getIntExtra(EXTRA_WIFI_AP_STATE,
- WIFI_AP_STATE_DISABLED);
- final int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_AP_STATE,
- WIFI_AP_STATE_DISABLED);
- final int errorCode = intent.getIntExtra(EXTRA_WIFI_AP_FAILURE_REASON,
- HOTSPOT_NO_ERROR);
- final String ifaceName =
- intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
- final int mode = intent.getIntExtra(EXTRA_WIFI_AP_MODE,
- WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- handleWifiApStateChange(currState, prevState, errorCode, ifaceName, mode);
- }
- },
- new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION));
-
// Adding optimizations of only receiving broadcasts when wifi is enabled
// can result in race conditions when apps toggle wifi in the background
// without active user involvement. Always receive broadcasts.
@@ -576,33 +352,35 @@ public class WifiServiceImpl extends BaseWifiService {
if (!mClientModeImpl.syncInitialize(mClientModeImplChannel)) {
Log.wtf(TAG, "Failed to initialize ClientModeImpl");
}
- mWifiController.start();
-
- // If we are already disabled (could be due to airplane mode), avoid changing persist
- // state here
- if (wifiEnabled) {
- setWifiEnabled(mContext.getPackageName(), wifiEnabled);
- }
+ mActiveModeWarden.start();
}
public void handleBootCompleted() {
Log.d(TAG, "Handle boot completed");
+ mWifiThreadRunner.post(() -> {
+ new MemoryStoreImpl(mContext, mWifiInjector, mWifiInjector.getWifiScoreCard()).start();
+ if (!mWifiConfigManager.loadFromStore()) {
+ Log.e(TAG, "Failed to load from config store");
+ }
+ mPasspointManager.initializeProvisioner(
+ mWifiInjector.getPasspointProvisionerHandlerThread().getLooper());
+ });
mClientModeImpl.handleBootCompleted();
}
public void handleUserSwitch(int userId) {
Log.d(TAG, "Handle user switch " + userId);
- mClientModeImpl.handleUserSwitch(userId);
+ mWifiThreadRunner.post(() -> mWifiConfigManager.handleUserSwitch(userId));
}
public void handleUserUnlock(int userId) {
Log.d(TAG, "Handle user unlock " + userId);
- mClientModeImpl.handleUserUnlock(userId);
+ mWifiThreadRunner.post(() -> mWifiConfigManager.handleUserUnlock(userId));
}
public void handleUserStop(int userId) {
Log.d(TAG, "Handle user stop " + userId);
- mClientModeImpl.handleUserStop(userId);
+ mWifiThreadRunner.post(() -> mWifiConfigManager.handleUserStop(userId));
}
/**
@@ -635,22 +413,18 @@ public class WifiServiceImpl extends BaseWifiService {
}
try {
mWifiPermissionsUtil.enforceCanAccessScanResults(packageName, callingUid);
- Mutable<Boolean> scanSuccess = new Mutable<>();
- boolean runWithScissorsSuccess = mWifiInjector.getClientModeImplHandler()
- .runWithScissors(() -> {
- scanSuccess.value = mScanRequestProxy.startScan(callingUid, packageName);
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- if (!runWithScissorsSuccess) {
- Log.e(TAG, "Failed to post runnable to start scan");
+ Boolean scanSuccess = mWifiThreadRunner.call(() ->
+ mScanRequestProxy.startScan(callingUid, packageName), null);
+ if (scanSuccess == null) {
sendFailedScanBroadcast();
return false;
}
- if (!scanSuccess.value) {
+ if (!scanSuccess) {
Log.e(TAG, "Failed to start scan");
return false;
}
} catch (SecurityException e) {
- Slog.e(TAG, "Permission violation - startScan not allowed for"
+ Log.e(TAG, "Permission violation - startScan not allowed for"
+ " uid=" + callingUid + ", packageName=" + packageName + ", reason=" + e);
return false;
} finally {
@@ -689,10 +463,10 @@ public class WifiServiceImpl extends BaseWifiService {
return null;
}
- boolean mInIdleMode;
- boolean mScanPending;
+ private boolean mInIdleMode;
+ private boolean mScanPending;
- void handleIdleModeChanged() {
+ private void handleIdleModeChanged() {
boolean doScan = false;
synchronized (this) {
boolean idle = mPowerManager.isDeviceIdleMode();
@@ -729,34 +503,44 @@ public class WifiServiceImpl extends BaseWifiService {
== PackageManager.PERMISSION_GRANTED;
}
+ private boolean checkMainlineWifiStackPermission(int pid, int uid) {
+ return mContext.checkPermission(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK, pid, uid)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
private boolean checkNetworkManagedProvisioningPermission(int pid, int uid) {
return mContext.checkPermission(android.Manifest.permission.NETWORK_MANAGED_PROVISIONING,
pid, uid) == PackageManager.PERMISSION_GRANTED;
}
- // Helper method to check if the entity initiating the binder call has any of the signature only
- // permissions.
+ /**
+ * Helper method to check if the entity initiating the binder call has any of the signature only
+ * permissions.
+ */
private boolean isPrivileged(int pid, int uid) {
return checkNetworkSettingsPermission(pid, uid)
|| checkNetworkSetupWizardPermission(pid, uid)
|| checkNetworkStackPermission(pid, uid)
- || checkNetworkManagedProvisioningPermission(pid, uid);
+ || checkNetworkManagedProvisioningPermission(pid, uid)
+ || checkMainlineWifiStackPermission(pid, uid);
}
- // Helper method to check if the entity initiating the binder call has setup wizard or settings
- // permissions.
+ /**
+ * Helper method to check if the entity initiating the binder call has setup wizard or settings
+ * permissions.
+ */
private boolean isSettingsOrSuw(int pid, int uid) {
return checkNetworkSettingsPermission(pid, uid)
|| checkNetworkSetupWizardPermission(pid, uid);
}
- // Helper method to check if the entity initiating the binder call is a system app.
+ /** Helper method to check if the entity initiating the binder call is a system app. */
private boolean isSystem(String packageName, int uid) {
long ident = Binder.clearCallingIdentity();
try {
ApplicationInfo info = mContext.getPackageManager().getApplicationInfoAsUser(
- packageName, 0, UserHandle.getUserId(uid));
- return info.isSystemApp() || info.isUpdatedSystemApp();
+ packageName, 0, UserHandle.getUserHandleForUid(uid));
+ return (info.flags & APP_INFO_FLAGS_SYSTEM_APP) != 0;
} catch (PackageManager.NameNotFoundException e) {
// In case of exception, assume unknown app (more strict checking)
// Note: This case will never happen since checkPackage is
@@ -767,13 +551,10 @@ public class WifiServiceImpl extends BaseWifiService {
return false;
}
- // Helper method to check if the entity initiating the binder call is a DO/PO app.
- private boolean isDeviceOrProfileOwner(int uid) {
- final DevicePolicyManagerInternal dpmi =
- mWifiInjector.getWifiPermissionsWrapper().getDevicePolicyManagerInternal();
- if (dpmi == null) return false;
- return dpmi.isActiveAdminWithPolicy(uid, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER)
- || dpmi.isActiveAdminWithPolicy(uid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ /** Helper method to check if the entity initiating the binder call is a DO/PO app. */
+ private boolean isDeviceOrProfileOwner(int uid, String packageName) {
+ return mWifiPermissionsUtil.isDeviceOwner(uid, packageName)
+ || mWifiPermissionsUtil.isProfileOwner(uid, packageName);
}
private void enforceNetworkSettingsPermission() {
@@ -782,8 +563,15 @@ public class WifiServiceImpl extends BaseWifiService {
}
private void enforceNetworkStackPermission() {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK,
- "WifiService");
+ // TODO(b/142554155): Only check for MAINLINE_NETWORK_STACK permission
+ boolean granted = mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.NETWORK_STACK)
+ == PackageManager.PERMISSION_GRANTED;
+ if (granted) {
+ return;
+ }
+ mContext.enforceCallingOrSelfPermission(
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "WifiService");
}
private void enforceAccessPermission() {
@@ -812,22 +600,11 @@ public class WifiServiceImpl extends BaseWifiService {
AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Binder.getCallingUid(), callingPackage);
}
- private void enforceLocationHardwarePermission() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE,
- "LocationHardware");
- }
-
private void enforceReadCredentialPermission() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_WIFI_CREDENTIAL,
"WifiService");
}
- private void enforceWorkSourcePermission() {
- mContext.enforceCallingPermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
- "WifiService");
-
- }
-
private void enforceMulticastChangePermission() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE,
@@ -853,7 +630,7 @@ public class WifiServiceImpl extends BaseWifiService {
return mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q, uid)
|| isPrivileged(pid, uid)
// DO/PO apps should be able to add/modify saved networks.
- || isDeviceOrProfileOwner(uid)
+ || isDeviceOrProfileOwner(uid, packageName)
// TODO: Remove this system app bypass once Q is released.
|| isSystem(packageName, uid)
|| mWifiPermissionsUtil.checkSystemAlertWindowPermission(uid, packageName);
@@ -871,7 +648,7 @@ public class WifiServiceImpl extends BaseWifiService {
return false;
}
boolean isPrivileged = isPrivileged(Binder.getCallingPid(), Binder.getCallingUid());
- if (!isPrivileged && !isDeviceOrProfileOwner(Binder.getCallingUid())
+ if (!isPrivileged && !isDeviceOrProfileOwner(Binder.getCallingUid(), packageName)
&& !mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q,
Binder.getCallingUid())
&& !isSystem(packageName, Binder.getCallingUid())) {
@@ -886,14 +663,8 @@ public class WifiServiceImpl extends BaseWifiService {
}
// If SoftAp is enabled, only privileged apps are allowed to toggle wifi
- boolean apEnabled = mWifiApState == WifiManager.WIFI_AP_STATE_ENABLED;
- if (apEnabled && !isPrivileged) {
- mLog.err("setWifiEnabled SoftAp enabled: only Settings can toggle wifi").flush();
- return false;
- }
-
- // If we're in crypt debounce, ignore any wifi state change APIs.
- if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
+ if (!isPrivileged && mTetheredSoftApTracker.getState() == WIFI_AP_STATE_ENABLED) {
+ mLog.err("setWifiEnabled with SoftAp enabled: only Settings can toggle wifi").flush();
return false;
}
@@ -909,7 +680,7 @@ public class WifiServiceImpl extends BaseWifiService {
Binder.restoreCallingIdentity(ident);
}
mWifiMetrics.incrementNumWifiToggles(isPrivileged, enable);
- mWifiController.sendMessage(CMD_WIFI_TOGGLED);
+ mActiveModeWarden.wifiToggled();
return true;
}
@@ -944,13 +715,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("getWifiApEnabledState uid=%").c(Binder.getCallingUid()).flush();
}
-
- // hand off work to our handler thread
- MutableInt apState = new MutableInt(WifiManager.WIFI_AP_STATE_DISABLED);
- mWifiInjector.getClientModeImplHandler().runWithScissors(() -> {
- apState.value = mWifiApState;
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- return apState.value;
+ return mTetheredSoftApTracker.getState();
}
/**
@@ -972,71 +737,7 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("updateInterfaceIpState uid=%").c(Binder.getCallingUid()).flush();
// hand off the work to our handler thread
- mWifiInjector.getClientModeImplHandler().post(() -> {
- updateInterfaceIpStateInternal(ifaceName, mode);
- });
- }
-
- private void updateInterfaceIpStateInternal(String ifaceName, int mode) {
- // update interface IP state related to tethering and hotspot
- synchronized (mLocalOnlyHotspotRequests) {
- // update the mode tracker here - we clear out state below
- Integer previousMode = WifiManager.IFACE_IP_MODE_UNSPECIFIED;
- if (ifaceName != null) {
- previousMode = mIfaceIpModes.put(ifaceName, mode);
- }
- Slog.d(TAG, "updateInterfaceIpState: ifaceName=" + ifaceName + " mode=" + mode
- + " previous mode= " + previousMode);
-
- switch (mode) {
- case WifiManager.IFACE_IP_MODE_LOCAL_ONLY:
- // first make sure we have registered requests.. otherwise clean up
- if (mLocalOnlyHotspotRequests.isEmpty()) {
- // we don't have requests... stop the hotspot
- stopSoftAp();
- updateInterfaceIpStateInternal(null, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- return;
- }
- // LOHS is ready to go! Call our registered requestors!
- sendHotspotStartedMessageToAllLOHSRequestInfoEntriesLocked();
- break;
- case WifiManager.IFACE_IP_MODE_TETHERED:
- if (!isConcurrentLohsAndTetheringSupported()) {
- /* We have tethered an interface. We don't really act on this now other than
- * if we have LOHS requests, and this is an issue. Return incompatible mode
- * for onFailed for the registered requestors since this can result from a
- * race between a tether request and a hotspot request (tethering wins). */
- sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
- LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE);
- }
- break;
- case WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR:
- Slog.d(TAG, "IP mode config error - need to clean up");
- if (mLocalOnlyHotspotRequests.isEmpty()) {
- Slog.d(TAG, "no LOHS requests, stop softap");
- stopSoftAp();
- } else {
- Slog.d(TAG, "we have LOHS requests, clean them up");
- // there was an error setting up the hotspot... trigger onFailed for the
- // registered LOHS requestors
- sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
- LocalOnlyHotspotCallback.ERROR_GENERIC);
- }
- updateInterfaceIpStateInternal(null, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- break;
- case WifiManager.IFACE_IP_MODE_UNSPECIFIED:
- if (ifaceName == null) {
- // interface name is null, this is due to softap teardown. clear all
- // entries for now.
- // TODO: Deal with individual interfaces when we receive updates for them
- mIfaceIpModes.clear();
- return;
- }
- break;
- default:
- mLog.warn("updateInterfaceIpStateInternal: unknown mode %").c(mode).flush();
- }
- }
+ mWifiThreadRunner.post(() -> mLohsSoftApTracker.updateInterfaceIpState(ifaceName, mode));
}
/**
@@ -1049,27 +750,18 @@ public class WifiServiceImpl extends BaseWifiService {
public boolean startSoftAp(WifiConfiguration wifiConfig) {
// NETWORK_STACK is a signature only permission.
enforceNetworkStackPermission();
- // If we're in crypt debounce, ignore any wifi state change APIs.
- if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
- return false;
- }
mLog.info("startSoftAp uid=%").c(Binder.getCallingUid()).flush();
- synchronized (mLocalOnlyHotspotRequests) {
- // If a tethering request comes in while we have an existing tethering session, return
- // error.
- if (mIfaceIpModes.contains(WifiManager.IFACE_IP_MODE_TETHERED)) {
- mLog.err("Tethering is already active.").flush();
- return false;
- }
- // If a tethering request comes in while we have LOHS running (or requested), call stop
- // for softap mode and restart softap with the tethering config.
- if (!isConcurrentLohsAndTetheringSupported() && !mLocalOnlyHotspotRequests.isEmpty()) {
- stopSoftApInternal(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ if (mTetheredSoftApTracker.setEnablingIfAllowed()) {
+ if (!isConcurrentLohsAndTetheringSupported()) {
+ // Take down LOHS if it is up.
+ mLohsSoftApTracker.stopAll();
}
return startSoftApInternal(wifiConfig, WifiManager.IFACE_IP_MODE_TETHERED);
}
+ mLog.err("Tethering is already active.").flush();
+ return false;
}
/**
@@ -1083,10 +775,10 @@ public class WifiServiceImpl extends BaseWifiService {
// null wifiConfig is a meaningful input for CMD_SET_AP
if (wifiConfig == null || WifiApConfigStore.validateApWifiConfiguration(wifiConfig)) {
SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(mode, wifiConfig);
- mWifiController.sendMessage(CMD_SET_AP, 1, 0, softApConfig);
+ mActiveModeWarden.startSoftAp(softApConfig);
return true;
}
- Slog.e(TAG, "Invalid WifiConfiguration");
+ Log.e(TAG, "Invalid WifiConfiguration");
return false;
}
@@ -1099,46 +791,80 @@ public class WifiServiceImpl extends BaseWifiService {
public boolean stopSoftAp() {
// NETWORK_STACK is a signature only permission.
enforceNetworkStackPermission();
- // If we're in crypt debounce, ignore any wifi state change APIs.
- if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
- return false;
- }
// only permitted callers are allowed to this point - they must have gone through
// connectivity service since this method is protected with the NETWORK_STACK PERMISSION
mLog.info("stopSoftAp uid=%").c(Binder.getCallingUid()).flush();
- synchronized (mLocalOnlyHotspotRequests) {
- // If a tethering request comes in while we have LOHS running (or requested), call stop
- // for softap mode and restart softap with the tethering config.
- if (!mLocalOnlyHotspotRequests.isEmpty()) {
- // This shouldn't affect devices that support concurrent LOHS and tethering
- mLog.trace("Call to stop Tethering while LOHS is active,"
- + " Registered LOHS callers will be updated when softap stopped.").flush();
- }
-
- return stopSoftApInternal(WifiManager.IFACE_IP_MODE_TETHERED);
- }
+ stopSoftApInternal(WifiManager.IFACE_IP_MODE_TETHERED);
+ return true;
}
/**
- * Internal method to stop softap mode. Callers of this method should have already checked
+ * Internal method to stop softap mode.
+ *
+ * Callers of this method should have already checked
* proper permissions beyond the NetworkStack permission.
+ *
+ * @param mode the operating mode of APs to bring down (ex,
+ * {@link WifiManager.IFACE_IP_MODE_TETHERED} or
+ * {@link WifiManager.IFACE_IP_MODE_LOCAL_ONLY}).
+ * Use {@link WifiManager.IFACE_IP_MODE_UNSPECIFIED} to stop all APs.
*/
- private boolean stopSoftApInternal(int mode) {
- mLog.trace("stopSoftApInternal uid=%").c(Binder.getCallingUid()).flush();
+ private void stopSoftApInternal(int mode) {
+ mLog.trace("stopSoftApInternal uid=% mode=%").c(Binder.getCallingUid()).c(mode).flush();
- mWifiController.sendMessage(CMD_SET_AP, 0, mode);
- return true;
+ mActiveModeWarden.stopSoftAp(mode);
}
/**
- * Callback to use with ClientModeImpl to receive events from ClientModeImpl
- *
- * @hide
+ * SoftAp callback
*/
- private final class SoftApCallbackImpl implements WifiManager.SoftApCallback {
+ private final class TetheredSoftApTracker implements WifiManager.SoftApCallback {
+ /**
+ * State of tethered SoftAP
+ * One of: {@link WifiManager#WIFI_AP_STATE_DISABLED},
+ * {@link WifiManager#WIFI_AP_STATE_DISABLING},
+ * {@link WifiManager#WIFI_AP_STATE_ENABLED},
+ * {@link WifiManager#WIFI_AP_STATE_ENABLING},
+ * {@link WifiManager#WIFI_AP_STATE_FAILED}
+ */
+ private final Object mLock = new Object();
+ private int mTetheredSoftApState = WIFI_AP_STATE_DISABLED;
+ private List<WifiClient> mTetheredSoftApConnectedClients = new ArrayList<>();
+
+ public int getState() {
+ synchronized (mLock) {
+ return mTetheredSoftApState;
+ }
+ }
+
+ public boolean setEnablingIfAllowed() {
+ synchronized (mLock) {
+ if (mTetheredSoftApState == WIFI_AP_STATE_ENABLING) return false;
+ if (mTetheredSoftApState == WIFI_AP_STATE_ENABLED) return false;
+ mTetheredSoftApState = WIFI_AP_STATE_ENABLING;
+ return true;
+ }
+ }
+
+ public List<WifiClient> getConnectedClients() {
+ return mTetheredSoftApConnectedClients;
+ }
+
+ private final ExternalCallbackTracker<ISoftApCallback> mRegisteredSoftApCallbacks =
+ new ExternalCallbackTracker<>(mClientModeImplHandler);
+
+ public boolean registerSoftApCallback(IBinder binder, ISoftApCallback callback,
+ int callbackIdentifier) {
+ return mRegisteredSoftApCallbacks.add(binder, callback, callbackIdentifier);
+ }
+
+ public void unregisterSoftApCallback(int callbackIdentifier) {
+ mRegisteredSoftApCallbacks.remove(callbackIdentifier);
+ }
+
/**
* Called when soft AP state changes.
*
@@ -1150,7 +876,9 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public void onStateChanged(int state, int failureReason) {
- mSoftApState = state;
+ synchronized (mLock) {
+ mTetheredSoftApState = state;
+ }
Iterator<ISoftApCallback> iterator =
mRegisteredSoftApCallbacks.getCallbacks().iterator();
@@ -1160,28 +888,30 @@ public class WifiServiceImpl extends BaseWifiService {
callback.onStateChanged(state, failureReason);
} catch (RemoteException e) {
Log.e(TAG, "onStateChanged: remote exception -- " + e);
+ // TODO(b/138863863) remove does nothing, getCallbacks() returns a copy
iterator.remove();
}
}
}
/**
- * Called when number of connected clients to soft AP changes.
+ * Called when the connected clients to soft AP changes.
*
- * @param numClients number of connected clients to soft AP
+ * @param clients connected clients to soft AP
*/
@Override
- public void onNumClientsChanged(int numClients) {
- mSoftApNumClients = numClients;
+ public void onConnectedClientsChanged(List<WifiClient> clients) {
+ mTetheredSoftApConnectedClients = new ArrayList<>(clients);
Iterator<ISoftApCallback> iterator =
mRegisteredSoftApCallbacks.getCallbacks().iterator();
while (iterator.hasNext()) {
ISoftApCallback callback = iterator.next();
try {
- callback.onNumClientsChanged(numClients);
+ callback.onConnectedClientsChanged(mTetheredSoftApConnectedClients);
} catch (RemoteException e) {
- Log.e(TAG, "onNumClientsChanged: remote exception -- " + e);
+ Log.e(TAG, "onConnectedClientsChanged: remote exception -- " + e);
+ // TODO(b/138863863) remove does nothing, getCallbacks() returns a copy
iterator.remove();
}
}
@@ -1189,6 +919,306 @@ public class WifiServiceImpl extends BaseWifiService {
}
/**
+ * Lohs callback
+ */
+ private final class LohsSoftApTracker implements WifiManager.SoftApCallback {
+ @GuardedBy("mLocalOnlyHotspotRequests")
+ private final HashMap<Integer, LocalOnlyHotspotRequestInfo>
+ mLocalOnlyHotspotRequests = new HashMap<>();
+
+ @GuardedBy("mLocalOnlyHotspotRequests")
+ private WifiConfiguration mLocalOnlyHotspotConfig = null;
+
+ @GuardedBy("mLocalOnlyHotspotRequests")
+ private String mLohsInterfaceName;
+
+ /**
+ * State of local-only hotspot
+ * One of: {@link WifiManager#WIFI_AP_STATE_DISABLED},
+ * {@link WifiManager#WIFI_AP_STATE_DISABLING},
+ * {@link WifiManager#WIFI_AP_STATE_ENABLED},
+ * {@link WifiManager#WIFI_AP_STATE_ENABLING},
+ * {@link WifiManager#WIFI_AP_STATE_FAILED}
+ */
+ @GuardedBy("mLocalOnlyHotspotRequests")
+ private int mLohsState = WIFI_AP_STATE_DISABLED;
+
+ @GuardedBy("mLocalOnlyHotspotRequests")
+ private int mLohsInterfaceMode = WifiManager.IFACE_IP_MODE_UNSPECIFIED;
+
+ public void updateInterfaceIpState(String ifaceName, int mode) {
+ // update interface IP state related to local-only hotspot
+ synchronized (mLocalOnlyHotspotRequests) {
+ Log.d(TAG, "updateInterfaceIpState: ifaceName=" + ifaceName + " mode=" + mode
+ + " previous LOHS mode= " + mLohsInterfaceMode);
+
+ switch (mode) {
+ case WifiManager.IFACE_IP_MODE_LOCAL_ONLY:
+ // first make sure we have registered requests.
+ if (mLocalOnlyHotspotRequests.isEmpty()) {
+ // we don't have requests... stop the hotspot
+ Log.wtf(TAG, "Starting LOHS without any requests?");
+ stopSoftApInternal(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ return;
+ }
+ // LOHS is ready to go! Call our registered requestors!
+ mLohsInterfaceName = ifaceName;
+ mLohsInterfaceMode = mode;
+ sendHotspotStartedMessageToAllLOHSRequestInfoEntriesLocked();
+ break;
+ case WifiManager.IFACE_IP_MODE_TETHERED:
+ if (mLohsInterfaceName != null
+ && mLohsInterfaceName.equals(ifaceName)) {
+ /* This shouldn't happen except in a race, but if it does, tear down
+ * the LOHS and let tethering win.
+ *
+ * If concurrent SAPs are allowed, the interface names will differ,
+ * so we don't have to check the config here.
+ */
+ Log.e(TAG, "Unexpected IP mode change on " + ifaceName);
+ mLohsInterfaceName = null;
+ mLohsInterfaceMode = WifiManager.IFACE_IP_MODE_UNSPECIFIED;
+ sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
+ LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE);
+ }
+ break;
+ case WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR:
+ if (ifaceName == null) {
+ // All softAps
+ mLohsInterfaceName = null;
+ mLohsInterfaceMode = mode;
+ sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
+ LocalOnlyHotspotCallback.ERROR_GENERIC);
+ stopSoftApInternal(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
+ } else if (ifaceName.equals(mLohsInterfaceName)) {
+ mLohsInterfaceName = null;
+ mLohsInterfaceMode = mode;
+ sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
+ LocalOnlyHotspotCallback.ERROR_GENERIC);
+ stopSoftApInternal(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ } else {
+ // Not for LOHS. This is the wrong place to do this, but...
+ stopSoftApInternal(WifiManager.IFACE_IP_MODE_TETHERED);
+ }
+ break;
+ case WifiManager.IFACE_IP_MODE_UNSPECIFIED:
+ if (ifaceName == null || ifaceName.equals(mLohsInterfaceName)) {
+ mLohsInterfaceName = null;
+ mLohsInterfaceMode = mode;
+ }
+ break;
+ default:
+ mLog.warn("updateInterfaceIpState: unknown mode %").c(mode).flush();
+ }
+ }
+ }
+
+ /**
+ * Helper method to send a HOTSPOT_FAILED message to all registered LocalOnlyHotspotRequest
+ * callers and clear the registrations.
+ *
+ * Callers should already hold the mLocalOnlyHotspotRequests lock.
+ */
+ @GuardedBy("mLocalOnlyHotspotRequests")
+ private void sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(int reason) {
+ for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
+ try {
+ requestor.sendHotspotFailedMessage(reason);
+ requestor.unlinkDeathRecipient();
+ } catch (RemoteException e) {
+ // This will be cleaned up by binder death handling
+ }
+ }
+
+ // Since all callers were notified, now clear the registrations.
+ mLocalOnlyHotspotRequests.clear();
+ }
+
+ /**
+ * Helper method to send a HOTSPOT_STOPPED message to all registered LocalOnlyHotspotRequest
+ * callers and clear the registrations.
+ *
+ * Callers should already hold the mLocalOnlyHotspotRequests lock.
+ */
+ @GuardedBy("mLocalOnlyHotspotRequests")
+ private void sendHotspotStoppedMessageToAllLOHSRequestInfoEntriesLocked() {
+ for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
+ try {
+ requestor.sendHotspotStoppedMessage();
+ requestor.unlinkDeathRecipient();
+ } catch (RemoteException e) {
+ // This will be cleaned up by binder death handling
+ }
+ }
+
+ // Since all callers were notified, now clear the registrations.
+ mLocalOnlyHotspotRequests.clear();
+ }
+
+ /**
+ * Add a new LOHS client
+ */
+ private int start(int pid, LocalOnlyHotspotRequestInfo request) {
+ synchronized (mLocalOnlyHotspotRequests) {
+ // does this caller already have a request?
+ if (mLocalOnlyHotspotRequests.get(pid) != null) {
+ mLog.trace("caller already has an active request").flush();
+ throw new IllegalStateException(
+ "Caller already has an active LocalOnlyHotspot request");
+ }
+
+ // check current operating state and take action if needed
+ if (mLohsInterfaceMode == WifiManager.IFACE_IP_MODE_LOCAL_ONLY) {
+ // LOHS is already active, send out what is running
+ try {
+ mLog.trace("LOHS already up, trigger onStarted callback").flush();
+ request.sendHotspotStartedMessage(mLocalOnlyHotspotConfig);
+ } catch (RemoteException e) {
+ return LocalOnlyHotspotCallback.ERROR_GENERIC;
+ }
+ } else if (mLocalOnlyHotspotRequests.isEmpty()) {
+ // this is the first request, then set up our config and start LOHS
+ boolean is5Ghz = hasAutomotiveFeature(mContext)
+ && mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_wifi_local_only_hotspot_5ghz)
+ && is5GhzSupported();
+
+ mLocalOnlyHotspotConfig =
+ WifiApConfigStore.generateLocalOnlyHotspotConfig(mContext,
+ is5Ghz ? WifiConfiguration.AP_BAND_5GHZ
+ : WifiConfiguration.AP_BAND_2GHZ);
+
+ startSoftApInternal(mLocalOnlyHotspotConfig,
+ WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ }
+
+ mLocalOnlyHotspotRequests.put(pid, request);
+ return LocalOnlyHotspotCallback.REQUEST_REGISTERED;
+ }
+ }
+
+ /**
+ * Requests that any local-only hotspot be stopped.
+ */
+ public void stopAll() {
+ synchronized (mLocalOnlyHotspotRequests) {
+ if (!mLocalOnlyHotspotRequests.isEmpty()) {
+ // This is used to take down LOHS when tethering starts, and in that
+ // case we send failed instead of stopped.
+ // TODO check if that is right. Calling onFailed instead of onStopped when the
+ // hotspot is already started does not seem to match the documentation
+ sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
+ LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE);
+ stopIfEmptyLocked();
+ }
+ }
+ }
+
+ /**
+ * Unregisters the LOHS request from the given process and stops LOHS if no other clients.
+ */
+ public void stopByPid(int pid) {
+ synchronized (mLocalOnlyHotspotRequests) {
+ LocalOnlyHotspotRequestInfo requestInfo = mLocalOnlyHotspotRequests.remove(pid);
+ if (requestInfo == null) return;
+ requestInfo.unlinkDeathRecipient();
+ stopIfEmptyLocked();
+ }
+ }
+
+ /**
+ * Unregisters LocalOnlyHotspot request and stops the hotspot if needed.
+ */
+ public void stopByRequest(LocalOnlyHotspotRequestInfo request) {
+
+ synchronized (mLocalOnlyHotspotRequests) {
+ if (mLocalOnlyHotspotRequests.remove(request.getPid()) == null) {
+ mLog.trace("LocalOnlyHotspotRequestInfo not found to remove").flush();
+ return;
+ }
+ stopIfEmptyLocked();
+ }
+ }
+
+ @GuardedBy("mLocalOnlyHotspotRequests")
+ private void stopIfEmptyLocked() {
+ if (mLocalOnlyHotspotRequests.isEmpty()) {
+ mLocalOnlyHotspotConfig = null;
+ mLohsInterfaceName = null;
+ mLohsInterfaceMode = WifiManager.IFACE_IP_MODE_UNSPECIFIED;
+ stopSoftApInternal(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ }
+ }
+
+
+ /**
+ * Helper method to send a HOTSPOT_STARTED message to all registered LocalOnlyHotspotRequest
+ * callers.
+ *
+ * Callers should already hold the mLocalOnlyHotspotRequests lock.
+ */
+ @GuardedBy("mLocalOnlyHotspotRequests")
+ private void sendHotspotStartedMessageToAllLOHSRequestInfoEntriesLocked() {
+ for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
+ try {
+ requestor.sendHotspotStartedMessage(mLocalOnlyHotspotConfig);
+ } catch (RemoteException e) {
+ // This will be cleaned up by binder death handling
+ }
+ }
+ }
+
+ @Override
+ public void onStateChanged(int state, int failureReason) {
+ // The AP state update from ClientModeImpl for softap
+ synchronized (mLocalOnlyHotspotRequests) {
+ Log.d(TAG, "lohs.onStateChanged: currentState=" + state
+ + " previousState=" + mLohsState + " errorCode= " + failureReason
+ + " ifaceName=" + mLohsInterfaceName);
+
+ // check if we have a failure - since it is possible (worst case scenario where
+ // WifiController and ClientModeImpl are out of sync wrt modes) to get two FAILED
+ // notifications in a row, we need to handle this first.
+ if (state == WIFI_AP_STATE_FAILED) {
+ // update registered LOHS callbacks if we see a failure
+ int errorToReport = ERROR_GENERIC;
+ if (failureReason == SAP_START_FAILURE_NO_CHANNEL) {
+ errorToReport = ERROR_NO_CHANNEL;
+ }
+ // holding the required lock: send message to requestors and clear the list
+ sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(errorToReport);
+ // also need to clear interface ip state
+ updateInterfaceIpState(mLohsInterfaceName,
+ WifiManager.IFACE_IP_MODE_UNSPECIFIED);
+ } else if (state == WIFI_AP_STATE_DISABLING || state == WIFI_AP_STATE_DISABLED) {
+ // softap is shutting down or is down... let requestors know via the
+ // onStopped call
+ // if we are currently in hotspot mode, then trigger onStopped for registered
+ // requestors, otherwise something odd happened and we should clear state
+ if (mLohsInterfaceName != null
+ && mLohsInterfaceMode == WifiManager.IFACE_IP_MODE_LOCAL_ONLY) {
+ // holding the required lock: send message to requestors and clear the list
+ sendHotspotStoppedMessageToAllLOHSRequestInfoEntriesLocked();
+ } else if (!isConcurrentLohsAndTetheringSupported()) {
+ // LOHS not active: report an error (still holding the required lock)
+ sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(ERROR_GENERIC);
+ }
+ // also clear interface ip state
+ updateInterfaceIpState(mLohsInterfaceName,
+ WifiManager.IFACE_IP_MODE_UNSPECIFIED);
+ }
+ // For enabling and enabled, just record the new state
+ mLohsState = state;
+ }
+ }
+
+ @Override
+ public void onConnectedClientsChanged(List<WifiClient> clients) {
+ // Nothing to do
+ }
+ }
+
+ /**
* see {@link android.net.wifi.WifiManager#registerSoftApCallback(SoftApCallback, Handler)}
*
* @param binder IBinder instance to allow cleanup if the app dies
@@ -1217,19 +1247,19 @@ public class WifiServiceImpl extends BaseWifiService {
}
// post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(() -> {
- if (!mRegisteredSoftApCallbacks.add(binder, callback, callbackIdentifier)) {
+ mWifiThreadRunner.post(() -> {
+ if (!mTetheredSoftApTracker.registerSoftApCallback(binder, callback,
+ callbackIdentifier)) {
Log.e(TAG, "registerSoftApCallback: Failed to add callback");
return;
}
// Update the client about the current state immediately after registering the callback
try {
- callback.onStateChanged(mSoftApState, 0);
- callback.onNumClientsChanged(mSoftApNumClients);
+ callback.onStateChanged(mTetheredSoftApTracker.getState(), 0);
+ callback.onConnectedClientsChanged(mTetheredSoftApTracker.getConnectedClients());
} catch (RemoteException e) {
Log.e(TAG, "registerSoftApCallback: remote exception -- " + e);
}
-
});
}
@@ -1242,143 +1272,24 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public void unregisterSoftApCallback(int callbackIdentifier) {
-
enforceNetworkSettingsPermission();
if (mVerboseLoggingEnabled) {
mLog.info("unregisterSoftApCallback uid=%").c(Binder.getCallingUid()).flush();
}
// post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(() -> {
- mRegisteredSoftApCallbacks.remove(callbackIdentifier);
- });
+ mWifiThreadRunner.post(() ->
+ mTetheredSoftApTracker.unregisterSoftApCallback(callbackIdentifier));
}
/**
- * Private method to handle SoftAp state changes
- *
- * <p> MUST be called from the ClientModeImpl thread.
- */
- private void handleWifiApStateChange(
- int currentState, int previousState, int errorCode, String ifaceName, int mode) {
- // The AP state update from ClientModeImpl for softap
- Slog.d(TAG, "handleWifiApStateChange: currentState=" + currentState
- + " previousState=" + previousState + " errorCode= " + errorCode
- + " ifaceName=" + ifaceName + " mode=" + mode);
-
- // update the tracking ap state variable
- mWifiApState = currentState;
-
- // check if we have a failure - since it is possible (worst case scenario where
- // WifiController and ClientModeImpl are out of sync wrt modes) to get two FAILED
- // notifications in a row, we need to handle this first.
- if (currentState == WIFI_AP_STATE_FAILED) {
- // update registered LOHS callbacks if we see a failure
- synchronized (mLocalOnlyHotspotRequests) {
- int errorToReport = ERROR_GENERIC;
- if (errorCode == SAP_START_FAILURE_NO_CHANNEL) {
- errorToReport = ERROR_NO_CHANNEL;
- }
- // holding the required lock: send message to requestors and clear the list
- sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
- errorToReport);
- // also need to clear interface ip state - send null for now since we don't know
- // what interface (and we have one anyway)
- updateInterfaceIpStateInternal(null, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- }
- return;
- }
-
- if (currentState == WIFI_AP_STATE_DISABLING || currentState == WIFI_AP_STATE_DISABLED) {
- // softap is shutting down or is down... let requestors know via the onStopped call
- synchronized (mLocalOnlyHotspotRequests) {
- // if we are currently in hotspot mode, then trigger onStopped for registered
- // requestors, otherwise something odd happened and we should clear state
- if (mIfaceIpModes.getOrDefault(ifaceName, WifiManager.IFACE_IP_MODE_UNSPECIFIED)
- == WifiManager.IFACE_IP_MODE_LOCAL_ONLY) {
- // holding the required lock: send message to requestors and clear the list
- sendHotspotStoppedMessageToAllLOHSRequestInfoEntriesLocked();
- } else if (!isConcurrentLohsAndTetheringSupported()) {
- // LOHS not active: report an error (still holding the required lock)
- sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(ERROR_GENERIC);
- }
- // also clear interface ip state - send null for now since we don't know what
- // interface (and we only have one anyway)
- updateInterfaceIpState(null, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- }
- return;
- }
-
- // remaining states are enabling or enabled... those are not used for the callbacks
- }
-
- /**
- * Helper method to send a HOTSPOT_FAILED message to all registered LocalOnlyHotspotRequest
- * callers and clear the registrations.
- *
- * Callers should already hold the mLocalOnlyHotspotRequests lock.
- */
- @GuardedBy("mLocalOnlyHotspotRequests")
- private void sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(int arg1) {
- for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
- try {
- requestor.sendHotspotFailedMessage(arg1);
- requestor.unlinkDeathRecipient();
- } catch (RemoteException e) {
- // This will be cleaned up by binder death handling
- }
- }
-
- // Since all callers were notified, now clear the registrations.
- mLocalOnlyHotspotRequests.clear();
- }
-
- /**
- * Helper method to send a HOTSPOT_STOPPED message to all registered LocalOnlyHotspotRequest
- * callers and clear the registrations.
- *
- * Callers should already hold the mLocalOnlyHotspotRequests lock.
- */
- @GuardedBy("mLocalOnlyHotspotRequests")
- private void sendHotspotStoppedMessageToAllLOHSRequestInfoEntriesLocked() {
- for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
- try {
- requestor.sendHotspotStoppedMessage();
- requestor.unlinkDeathRecipient();
- } catch (RemoteException e) {
- // This will be cleaned up by binder death handling
- }
- }
-
- // Since all callers were notified, now clear the registrations.
- mLocalOnlyHotspotRequests.clear();
- }
-
- /**
- * Helper method to send a HOTSPOT_STARTED message to all registered LocalOnlyHotspotRequest
- * callers.
- *
- * Callers should already hold the mLocalOnlyHotspotRequests lock.
- */
- @GuardedBy("mLocalOnlyHotspotRequests")
- private void sendHotspotStartedMessageToAllLOHSRequestInfoEntriesLocked() {
- for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
- try {
- requestor.sendHotspotStartedMessage(mLocalOnlyHotspotConfig);
- } catch (RemoteException e) {
- // This will be cleaned up by binder death handling
- }
- }
- }
-
- /**
- * Temporary method used for testing while startLocalOnlyHotspot is not fully implemented. This
+ * Temporary method used for testing while start is not fully implemented. This
* method allows unit tests to register callbacks directly for testing mechanisms triggered by
* softap mode changes.
*/
@VisibleForTesting
void registerLOHSForTest(int pid, LocalOnlyHotspotRequestInfo request) {
- mLocalOnlyHotspotRequests.put(pid, request);
+ mLohsSoftApTracker.start(pid, request);
}
/**
@@ -1391,8 +1302,7 @@ public class WifiServiceImpl extends BaseWifiService {
*
* see {@link WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback)}
*
- * @param messenger Messenger to send messages to the corresponding WifiManager.
- * @param binder IBinder instance to allow cleanup if the app dies
+ * @param callback Callback to communicate with WifiManager and allow cleanup if the app dies.
* @param packageName String name of the calling package
*
* @return int return code for attempt to start LocalOnlyHotspot.
@@ -1403,24 +1313,21 @@ public class WifiServiceImpl extends BaseWifiService {
* have an outstanding request.
*/
@Override
- public int startLocalOnlyHotspot(Messenger messenger, IBinder binder, String packageName) {
+ public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName) {
// first check if the caller has permission to start a local only hotspot
// need to check for WIFI_STATE_CHANGE and location permission
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
+ mLog.info("start uid=% pid=%").c(uid).c(pid).flush();
+
if (enforceChangePermission(packageName) != MODE_ALLOWED) {
return LocalOnlyHotspotCallback.ERROR_GENERIC;
}
enforceLocationPermission(packageName, uid);
- long ident = Binder.clearCallingIdentity();
- try {
- // also need to verify that Locations services are enabled.
- if (!mWifiPermissionsUtil.isLocationModeEnabled()) {
- throw new SecurityException("Location mode is not enabled.");
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
+ // also need to verify that Locations services are enabled.
+ if (!Binder.withCleanCallingIdentity(() -> mWifiPermissionsUtil.isLocationModeEnabled())) {
+ throw new SecurityException("Location mode is not enabled.");
}
// verify that tethering is not disabled
@@ -1429,63 +1336,26 @@ public class WifiServiceImpl extends BaseWifiService {
}
// the app should be in the foreground
- if (!mFrameworkFacade.isAppForeground(uid)) {
+ if (!Binder.withCleanCallingIdentity(
+ () -> mFrameworkFacade.isAppForeground(mContext, uid))) {
return LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
}
- if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
+ // check if we are currently tethering
+ // TODO(b/123227116): handle all interface combinations just by changing the HAL.
+ if (!isConcurrentLohsAndTetheringSupported()
+ && mTetheredSoftApTracker.getState() == WIFI_AP_STATE_ENABLED) {
+ // Tethering is enabled, cannot start LocalOnlyHotspot
+ mLog.info("Cannot start localOnlyHotspot when WiFi Tethering is active.")
+ .flush();
return LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
}
- mLog.info("startLocalOnlyHotspot uid=% pid=%").c(uid).c(pid).flush();
-
- synchronized (mLocalOnlyHotspotRequests) {
- // check if we are currently tethering
- // TODO(b/123227116): handle all interface combinations just by changing the HAL.
- if (!isConcurrentLohsAndTetheringSupported()
- && mIfaceIpModes.contains(WifiManager.IFACE_IP_MODE_TETHERED)) {
- // Tethering is enabled, cannot start LocalOnlyHotspot
- mLog.info("Cannot start localOnlyHotspot when WiFi Tethering is active.").flush();
- return LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
- }
-
- // does this caller already have a request?
- LocalOnlyHotspotRequestInfo request = mLocalOnlyHotspotRequests.get(pid);
- if (request != null) {
- mLog.trace("caller already has an active request").flush();
- throw new IllegalStateException(
- "Caller already has an active LocalOnlyHotspot request");
- }
+ // now create the new LOHS request info object
+ LocalOnlyHotspotRequestInfo request = new LocalOnlyHotspotRequestInfo(callback,
+ new LocalOnlyRequestorCallback());
- // now create the new LOHS request info object
- request = new LocalOnlyHotspotRequestInfo(binder, messenger,
- new LocalOnlyRequestorCallback());
-
- // check current operating state and take action if needed
- if (mIfaceIpModes.contains(WifiManager.IFACE_IP_MODE_LOCAL_ONLY)) {
- // LOHS is already active, send out what is running
- try {
- mLog.trace("LOHS already up, trigger onStarted callback").flush();
- request.sendHotspotStartedMessage(mLocalOnlyHotspotConfig);
- } catch (RemoteException e) {
- return LocalOnlyHotspotCallback.ERROR_GENERIC;
- }
- } else if (mLocalOnlyHotspotRequests.isEmpty()) {
- // this is the first request, then set up our config and start LOHS
- boolean is5Ghz = hasAutomotiveFeature(mContext)
- && mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_wifi_local_only_hotspot_5ghz)
- && is5GhzSupported();
-
- mLocalOnlyHotspotConfig = WifiApConfigStore.generateLocalOnlyHotspotConfig(mContext,
- is5Ghz ? WifiConfiguration.AP_BAND_5GHZ : WifiConfiguration.AP_BAND_2GHZ);
-
- startSoftApInternal(mLocalOnlyHotspotConfig, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
- }
-
- mLocalOnlyHotspotRequests.put(pid, request);
- return LocalOnlyHotspotCallback.REQUEST_REGISTERED;
- }
+ return mLohsSoftApTracker.start(pid, request);
}
/**
@@ -1505,41 +1375,7 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("stopLocalOnlyHotspot uid=% pid=%").c(uid).c(pid).flush();
- synchronized (mLocalOnlyHotspotRequests) {
- // was the caller already registered? check request tracker - return false if not
- LocalOnlyHotspotRequestInfo requestInfo = mLocalOnlyHotspotRequests.get(pid);
- if (requestInfo == null) {
- return;
- }
- requestInfo.unlinkDeathRecipient();
- unregisterCallingAppAndStopLocalOnlyHotspot(requestInfo);
- } // end synchronized
- }
-
- /**
- * Helper method to unregister LocalOnlyHotspot requestors and stop the hotspot if needed.
- */
- private void unregisterCallingAppAndStopLocalOnlyHotspot(LocalOnlyHotspotRequestInfo request) {
- mLog.trace("unregisterCallingAppAndStopLocalOnlyHotspot pid=%").c(request.getPid()).flush();
-
- synchronized (mLocalOnlyHotspotRequests) {
- if (mLocalOnlyHotspotRequests.remove(request.getPid()) == null) {
- mLog.trace("LocalOnlyHotspotRequestInfo not found to remove").flush();
- return;
- }
-
- if (mLocalOnlyHotspotRequests.isEmpty()) {
- mLocalOnlyHotspotConfig = null;
- updateInterfaceIpStateInternal(null, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- // if that was the last caller, then call stopSoftAp as WifiService
- long identity = Binder.clearCallingIdentity();
- try {
- stopSoftApInternal(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
+ mLohsSoftApTracker.stopByPid(pid);
}
/**
@@ -1547,8 +1383,7 @@ public class WifiServiceImpl extends BaseWifiService {
*
* This call requires the android.permission.NETWORK_SETTINGS permission.
*
- * @param messenger Messenger to send messages to the corresponding WifiManager.
- * @param binder IBinder instance to allow cleanup if the app dies
+ * @param callback Callback to communicate with WifiManager and allow cleanup if the app dies.
*
* @throws SecurityException if the caller does not have permission to watch Local Only Hotspot
* status updates.
@@ -1556,7 +1391,7 @@ public class WifiServiceImpl extends BaseWifiService {
* an existing subscription.
*/
@Override
- public void startWatchLocalOnlyHotspot(Messenger messenger, IBinder binder) {
+ public void startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback callback) {
// NETWORK_SETTINGS is a signature only permission.
enforceNetworkSettingsPermission();
@@ -1589,19 +1424,15 @@ public class WifiServiceImpl extends BaseWifiService {
throw new SecurityException("App not allowed to read or update stored WiFi Ap config "
+ "(uid = " + uid + ")");
}
- mLog.info("getWifiApConfiguration uid=%").c(uid).flush();
+
+ if (mVerboseLoggingEnabled) {
+ 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
- final Mutable<WifiConfiguration> config = new Mutable();
- boolean success = mWifiInjector.getClientModeImplHandler().runWithScissors(() -> {
- config.value = mWifiApConfigStore.getApConfiguration();
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- if (success) {
- return config.value;
- }
- Log.e(TAG, "Failed to post runnable to fetch ap config");
- return new WifiConfiguration();
+ return mWifiThreadRunner.call(mWifiApConfigStore::getApConfiguration,
+ new WifiConfiguration());
}
/**
@@ -1626,12 +1457,10 @@ public class WifiServiceImpl extends BaseWifiService {
if (wifiConfig == null)
return false;
if (WifiApConfigStore.validateApWifiConfiguration(wifiConfig)) {
- mClientModeImplHandler.post(() -> {
- mWifiApConfigStore.setApConfiguration(wifiConfig);
- });
+ mWifiThreadRunner.post(() -> mWifiApConfigStore.setApConfiguration(wifiConfig));
return true;
} else {
- Slog.e(TAG, "Invalid WifiConfiguration");
+ Log.e(TAG, "Invalid WifiConfiguration");
return false;
}
}
@@ -1784,19 +1613,18 @@ public class WifiServiceImpl extends BaseWifiService {
rxIdleTime * rxIdleCurrent) * voltage);
if (VDBG || rxIdleTime < 0 || stats.on_time < 0 || stats.tx_time < 0 ||
stats.rx_time < 0 || stats.on_time_scan < 0 || energyUsed < 0) {
- StringBuilder sb = new StringBuilder();
- sb.append(" rxIdleCur=" + rxIdleCurrent);
- sb.append(" rxCur=" + rxCurrent);
- sb.append(" txCur=" + txCurrent);
- sb.append(" voltage=" + voltage);
- sb.append(" on_time=" + stats.on_time);
- sb.append(" tx_time=" + stats.tx_time);
- sb.append(" tx_time_per_level=" + Arrays.toString(txTimePerLevel));
- sb.append(" rx_time=" + stats.rx_time);
- sb.append(" rxIdleTime=" + rxIdleTime);
- sb.append(" scan_time=" + stats.on_time_scan);
- sb.append(" energy=" + energyUsed);
- Log.d(TAG, " reportActivityInfo: " + sb.toString());
+ String sb = " rxIdleCur=" + rxIdleCurrent
+ + " rxCur=" + rxCurrent
+ + " txCur=" + txCurrent
+ + " voltage=" + voltage
+ + " on_time=" + stats.on_time
+ + " tx_time=" + stats.tx_time
+ + " tx_time_per_level=" + Arrays.toString(txTimePerLevel)
+ + " rx_time=" + stats.rx_time
+ + " rxIdleTime=" + rxIdleTime
+ + " scan_time=" + stats.on_time_scan
+ + " energy=" + energyUsed;
+ Log.d(TAG, " reportActivityInfo: " + sb);
}
// Convert the LinkLayerStats into EnergyActivity
@@ -1810,7 +1638,7 @@ public class WifiServiceImpl extends BaseWifiService {
return null;
}
} else {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
+ Log.e(TAG, "mClientModeImplChannel is not initialized");
return null;
}
}
@@ -1831,7 +1659,7 @@ public class WifiServiceImpl extends BaseWifiService {
try {
mWifiPermissionsUtil.enforceCanAccessScanResults(packageName, callingUid);
} catch (SecurityException e) {
- Slog.e(TAG, "Permission violation - getConfiguredNetworks not allowed for uid="
+ Log.e(TAG, "Permission violation - getConfiguredNetworks not allowed for uid="
+ callingUid + ", packageName=" + packageName + ", reason=" + e);
return new ParceledListSlice<>(new ArrayList<>());
} finally {
@@ -1853,32 +1681,27 @@ public class WifiServiceImpl extends BaseWifiService {
}
int targetConfigUid = Process.INVALID_UID; // don't expose any MAC addresses
- if (isPrivileged(getCallingPid(), callingUid) || isDeviceOrProfileOwner(callingUid)) {
+ if (isPrivileged(getCallingPid(), callingUid)
+ || isDeviceOrProfileOwner(callingUid, packageName)) {
targetConfigUid = Process.WIFI_UID; // expose all MAC addresses
} else if (isCarrierApp) {
targetConfigUid = callingUid; // expose only those configs created by the Carrier App
}
-
- if (mClientModeImplChannel != null) {
- List<WifiConfiguration> configs = mClientModeImpl.syncGetConfiguredNetworks(
- callingUid, mClientModeImplChannel, targetConfigUid);
- if (configs != null) {
- if (isTargetSdkLessThanQOrPrivileged) {
- return new ParceledListSlice<WifiConfiguration>(configs);
- } else { // Carrier app: should only get its own configs
- List<WifiConfiguration> creatorConfigs = new ArrayList<>();
- for (WifiConfiguration config : configs) {
- if (config.creatorUid == callingUid) {
- creatorConfigs.add(config);
- }
- }
- return new ParceledListSlice<WifiConfiguration>(creatorConfigs);
- }
+ int finalTargetConfigUid = targetConfigUid;
+ List<WifiConfiguration> configs = mWifiThreadRunner.call(
+ () -> mWifiConfigManager.getSavedNetworks(finalTargetConfigUid),
+ Collections.emptyList());
+ if (isTargetSdkLessThanQOrPrivileged) {
+ return new ParceledListSlice<>(configs);
+ }
+ // Carrier app: should only get its own configs
+ List<WifiConfiguration> creatorConfigs = new ArrayList<>();
+ for (WifiConfiguration config : configs) {
+ if (config.creatorUid == callingUid) {
+ creatorConfigs.add(config);
}
- } else {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
}
- return null;
+ return new ParceledListSlice<>(creatorConfigs);
}
/**
@@ -1888,8 +1711,8 @@ public class WifiServiceImpl extends BaseWifiService {
* @return the list of configured networks with real preSharedKey
*/
@Override
- public ParceledListSlice<WifiConfiguration>
- getPrivilegedConfiguredNetworks(String packageName) {
+ public ParceledListSlice<WifiConfiguration> getPrivilegedConfiguredNetworks(
+ String packageName) {
enforceReadCredentialPermission();
enforceAccessPermission();
int callingUid = Binder.getCallingUid();
@@ -1897,7 +1720,7 @@ public class WifiServiceImpl extends BaseWifiService {
try {
mWifiPermissionsUtil.enforceCanAccessScanResults(packageName, callingUid);
} catch (SecurityException e) {
- Slog.e(TAG, "Permission violation - getPrivilegedConfiguredNetworks not allowed for"
+ Log.e(TAG, "Permission violation - getPrivilegedConfiguredNetworks not allowed for"
+ " uid=" + callingUid + ", packageName=" + packageName + ", reason=" + e);
return null;
} finally {
@@ -1906,16 +1729,10 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("getPrivilegedConfiguredNetworks uid=%").c(callingUid).flush();
}
- if (mClientModeImplChannel != null) {
- List<WifiConfiguration> configs =
- mClientModeImpl.syncGetPrivilegedConfiguredNetwork(mClientModeImplChannel);
- if (configs != null) {
- return new ParceledListSlice<WifiConfiguration>(configs);
- }
- } else {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
- }
- return null;
+ List<WifiConfiguration> configs = mWifiThreadRunner.call(
+ () -> mWifiConfigManager.getConfiguredNetworksWithPasswords(),
+ Collections.emptyList());
+ return new ParceledListSlice<>(configs);
}
/**
@@ -1938,11 +1755,9 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("getMatchingPasspointConfigurations uid=%").c(Binder.getCallingUid()).flush();
}
- if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)) {
- return new HashMap<>();
- }
- return mClientModeImpl.syncGetAllMatchingFqdnsForScanResults(scanResults,
- mClientModeImplChannel);
+ return mWifiThreadRunner.call(
+ () -> mPasspointManager.getAllMatchingFqdnsForScanResults(scanResults),
+ Collections.emptyMap());
}
/**
@@ -1960,10 +1775,8 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("getMatchingOsuProviders uid=%").c(Binder.getCallingUid()).flush();
}
- if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)) {
- return new HashMap<>();
- }
- return mClientModeImpl.syncGetMatchingOsuProviders(scanResults, mClientModeImplChannel);
+ return mWifiThreadRunner.call(
+ () -> mPasspointManager.getMatchingOsuProviders(scanResults), Collections.emptyMap());
}
/**
@@ -1982,15 +1795,13 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("getMatchingPasspointConfigsForOsuProviders uid=%").c(
Binder.getCallingUid()).flush();
}
- if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)) {
- return new HashMap<>();
- }
if (osuProviders == null) {
Log.e(TAG, "Attempt to retrieve Passpoint configuration with null osuProviders");
return new HashMap<>();
}
- return mClientModeImpl.syncGetMatchingPasspointConfigsForOsuProviders(osuProviders,
- mClientModeImplChannel);
+ return mWifiThreadRunner.call(
+ () -> mPasspointManager.getMatchingPasspointConfigsForOsuProviders(osuProviders),
+ Collections.emptyMap());
}
/**
@@ -2011,15 +1822,13 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("getWifiConfigsForPasspointProfiles uid=%").c(
Binder.getCallingUid()).flush();
}
- if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)) {
- return new ArrayList<>();
- }
if (fqdnList == null) {
Log.e(TAG, "Attempt to retrieve WifiConfiguration with null fqdn List");
return new ArrayList<>();
}
- return mClientModeImpl.syncGetWifiConfigsForPasspointProfiles(fqdnList,
- mClientModeImplChannel);
+ return mWifiThreadRunner.call(
+ () -> mPasspointManager.getWifiConfigsForPasspointProfiles(fqdnList),
+ Collections.emptyList());
}
/**
@@ -2032,8 +1841,9 @@ public class WifiServiceImpl extends BaseWifiService {
if (enforceChangePermission(packageName) != MODE_ALLOWED) {
return -1;
}
+ int callingUid = Binder.getCallingUid();
if (!isTargetSdkLessThanQOrPrivileged(
- packageName, Binder.getCallingPid(), Binder.getCallingUid())) {
+ packageName, Binder.getCallingPid(), callingUid)) {
mLog.info("addOrUpdateNetwork not allowed for uid=%")
.c(Binder.getCallingUid()).flush();
return -1;
@@ -2041,7 +1851,7 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("addOrUpdateNetwork uid=%").c(Binder.getCallingUid()).flush();
if (config == null) {
- Slog.e(TAG, "bad network configuration");
+ Log.e(TAG, "bad network configuration");
return -1;
}
mWifiMetrics.incrementNumAddOrUpdateNetworkCalls();
@@ -2051,8 +1861,8 @@ public class WifiServiceImpl extends BaseWifiService {
if (config.isPasspoint()) {
PasspointConfiguration passpointConfig =
PasspointProvider.convertFromWifiConfig(config);
- if (passpointConfig.getCredential() == null) {
- Slog.e(TAG, "Missing credential for Passpoint profile");
+ if (passpointConfig == null || passpointConfig.getCredential() == null) {
+ Log.e(TAG, "Missing credential for Passpoint profile");
return -1;
}
@@ -2068,28 +1878,20 @@ public class WifiServiceImpl extends BaseWifiService {
passpointConfig.getCredential().setClientPrivateKey(
config.enterpriseConfig.getClientPrivateKey());
if (!addOrUpdatePasspointConfiguration(passpointConfig, packageName)) {
- Slog.e(TAG, "Failed to add Passpoint profile");
+ Log.e(TAG, "Failed to add Passpoint profile");
return -1;
}
// There is no network ID associated with a Passpoint profile.
return 0;
}
- //TODO: pass the Uid the ClientModeImpl as a message parameter
- Slog.i("addOrUpdateNetwork", " uid = " + Integer.toString(Binder.getCallingUid())
+ Log.i("addOrUpdateNetwork", " uid = " + Binder.getCallingUid()
+ " SSID " + config.SSID
- + " nid=" + Integer.toString(config.networkId));
- if (config.networkId == WifiConfiguration.INVALID_NETWORK_ID) {
- config.creatorUid = Binder.getCallingUid();
- } else {
- config.lastUpdateUid = Binder.getCallingUid();
- }
- if (mClientModeImplChannel != null) {
- return mClientModeImpl.syncAddOrUpdateNetwork(mClientModeImplChannel, config);
- } else {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
- return -1;
- }
+ + " nid=" + config.networkId);
+ return mWifiThreadRunner.call(
+ () -> mWifiConfigManager.addOrUpdateNetwork(config, callingUid, packageName)
+ .getNetworkId(),
+ WifiConfiguration.INVALID_NETWORK_ID);
}
public static void verifyCert(X509Certificate caCert)
@@ -2123,14 +1925,42 @@ public class WifiServiceImpl extends BaseWifiService {
.c(Binder.getCallingUid()).flush();
return false;
}
- mLog.info("removeNetwork uid=%").c(Binder.getCallingUid()).flush();
- // TODO Add private logging for netId b/33807876
- if (mClientModeImplChannel != null) {
- return mClientModeImpl.syncRemoveNetwork(mClientModeImplChannel, netId);
- } else {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
- return false;
+ int callingUid = Binder.getCallingUid();
+ mLog.info("removeNetwork uid=%").c(callingUid).flush();
+ return mWifiThreadRunner.call(
+ () -> mWifiConfigManager.removeNetwork(netId, callingUid, packageName), false);
+ }
+
+ /**
+ * Trigger a connect request and wait for the callback to return status.
+ * This preserves the legacy connect API behavior, i.e. {@link WifiManager#enableNetwork(
+ * int, true)}
+ * @return
+ */
+ private boolean triggerConnectAndReturnStatus(int netId, int callingUid) {
+ final CountDownLatch countDownLatch = new CountDownLatch(1);
+ final MutableBoolean success = new MutableBoolean(false);
+ IActionListener.Stub connectListener = new IActionListener.Stub() {
+ @Override
+ public void onSuccess() {
+ success.value = true;
+ countDownLatch.countDown();
+ }
+ @Override
+ public void onFailure(int reason) {
+ success.value = false;
+ countDownLatch.countDown();
+ }
+ };
+ mClientModeImpl.connect(null, netId, new Binder(), connectListener,
+ connectListener.hashCode(), callingUid);
+ // now wait for response.
+ try {
+ countDownLatch.await(RUN_WITH_SCISSORS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Failed to retrieve connect status");
}
+ return success.value;
}
/**
@@ -2151,18 +1981,19 @@ public class WifiServiceImpl extends BaseWifiService {
.c(Binder.getCallingUid()).flush();
return false;
}
+ int callingUid = Binder.getCallingUid();
// TODO b/33807876 Log netId
mLog.info("enableNetwork uid=% disableOthers=%")
- .c(Binder.getCallingUid())
+ .c(callingUid)
.c(disableOthers).flush();
mWifiMetrics.incrementNumEnableNetworkCalls();
- if (mClientModeImplChannel != null) {
- return mClientModeImpl.syncEnableNetwork(mClientModeImplChannel, netId,
- disableOthers);
+ if (disableOthers) {
+ return triggerConnectAndReturnStatus(netId, callingUid);
} else {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
- return false;
+ return mWifiThreadRunner.call(
+ () -> mWifiConfigManager.enableNetwork(netId, false, callingUid, packageName),
+ false);
}
}
@@ -2183,15 +2014,25 @@ public class WifiServiceImpl extends BaseWifiService {
.c(Binder.getCallingUid()).flush();
return false;
}
- // TODO b/33807876 Log netId
- mLog.info("disableNetwork uid=%").c(Binder.getCallingUid()).flush();
+ int callingUid = Binder.getCallingUid();
+ mLog.info("disableNetwork uid=%").c(callingUid).flush();
+ return mWifiThreadRunner.call(
+ () -> mWifiConfigManager.disableNetwork(netId, callingUid, packageName), false);
+ }
- if (mClientModeImplChannel != null) {
- return mClientModeImpl.syncDisableNetwork(mClientModeImplChannel, netId);
- } else {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
- return false;
- }
+ /**
+ * See {@link android.net.wifi.WifiManager#allowAutojoin(int, boolean)}
+ * @param netId the integer that identifies the network configuration
+ * @param choice the user's choice to allow auto-join
+ */
+ @Override
+ public void allowAutojoin(int netId, boolean choice) {
+ enforceNetworkSettingsPermission();
+
+ int callingUid = Binder.getCallingUid();
+ mLog.info("allowAutojoin=% uid=%").c(choice).c(callingUid).flush();
+ mWifiThreadRunner.post(
+ () -> mWifiConfigManager.allowAutojoin(netId, choice));
}
/**
@@ -2218,9 +2059,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
mWifiPermissionsUtil.enforceCanAccessScanResults(callingPackage, uid);
hideBssidSsidAndNetworkId = false;
- } catch (RemoteException e) {
- Log.e(TAG, "Error checking receiver permission", e);
- } catch (SecurityException e) {
+ } catch (SecurityException ignored) {
}
if (hideDefaultMacAddress) {
result.setMacAddress(WifiInfo.DEFAULT_MAC_ADDRESS);
@@ -2257,19 +2096,13 @@ public class WifiServiceImpl extends BaseWifiService {
}
try {
mWifiPermissionsUtil.enforceCanAccessScanResults(callingPackage, uid);
- final List<ScanResult> scanResults = new ArrayList<>();
- boolean success = mWifiInjector.getClientModeImplHandler().runWithScissors(() -> {
- scanResults.addAll(mScanRequestProxy.getScanResults());
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- if (!success) {
- Log.e(TAG, "Failed to post runnable to fetch scan results");
- return new ArrayList<ScanResult>();
- }
+ List<ScanResult> scanResults = mWifiThreadRunner.call(
+ mScanRequestProxy::getScanResults, Collections.emptyList());
return scanResults;
} catch (SecurityException e) {
- Slog.e(TAG, "Permission violation - getScanResults not allowed for uid="
+ Log.e(TAG, "Permission violation - getScanResults not allowed for uid="
+ uid + ", packageName=" + callingPackage + ", reason=" + e);
- return new ArrayList<ScanResult>();
+ return new ArrayList<>();
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -2287,13 +2120,11 @@ public class WifiServiceImpl extends BaseWifiService {
if (enforceChangePermission(packageName) != MODE_ALLOWED) {
return false;
}
- mLog.info("addorUpdatePasspointConfiguration uid=%").c(Binder.getCallingUid()).flush();
- if (!mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_PASSPOINT)) {
- return false;
- }
- return mClientModeImpl.syncAddOrUpdatePasspointConfig(mClientModeImplChannel, config,
- Binder.getCallingUid(), packageName);
+ int callingUid = Binder.getCallingUid();
+ mLog.info("addorUpdatePasspointConfiguration uid=%").c(callingUid).flush();
+ return mWifiThreadRunner.call(
+ () -> mPasspointManager.addOrUpdateProvider(config, callingUid, packageName, false),
+ false);
}
/**
@@ -2311,10 +2142,9 @@ public class WifiServiceImpl extends BaseWifiService {
privileged = true;
}
mLog.info("removePasspointConfiguration uid=%").c(Binder.getCallingUid()).flush();
- if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)) {
- return false;
- }
- return mClientModeImpl.syncRemovePasspointConfig(mClientModeImplChannel, privileged, fqdn);
+ final boolean privilegedFinal = privileged;
+ return mWifiThreadRunner.call(
+ () -> mPasspointManager.removeProvider(uid, privilegedFinal, fqdn), false);
}
/**
@@ -2335,11 +2165,10 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("getPasspointConfigurations uid=%").c(Binder.getCallingUid()).flush();
}
- if (!mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_PASSPOINT)) {
- return new ArrayList<>();
- }
- return mClientModeImpl.syncGetPasspointConfigs(mClientModeImplChannel, privileged);
+ final boolean privilegedFinal = privileged;
+ return mWifiThreadRunner.call(
+ () -> mPasspointManager.getProviderConfigs(uid, privilegedFinal),
+ Collections.emptyList());
}
/**
@@ -2351,10 +2180,6 @@ public class WifiServiceImpl extends BaseWifiService {
public void queryPasspointIcon(long bssid, String fileName) {
enforceAccessPermission();
mLog.info("queryPasspointIcon uid=%").c(Binder.getCallingUid()).flush();
- if (!mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_PASSPOINT)) {
- throw new UnsupportedOperationException("Passpoint not enabled");
- }
mClientModeImpl.syncQueryPasspointIcon(mClientModeImplChannel, bssid, fileName);
}
@@ -2366,7 +2191,7 @@ public class WifiServiceImpl extends BaseWifiService {
@Override
public int matchProviderWithCurrentNetwork(String fqdn) {
mLog.info("matchProviderWithCurrentNetwork uid=%").c(Binder.getCallingUid()).flush();
- return mClientModeImpl.matchProviderWithCurrentNetwork(mClientModeImplChannel, fqdn);
+ return 0;
}
/**
@@ -2380,21 +2205,6 @@ public class WifiServiceImpl extends BaseWifiService {
mClientModeImpl.deauthenticateNetwork(mClientModeImplChannel, holdoff, ess);
}
- /**
- * Set the country code
- * @param countryCode ISO 3166 country code.
- *
- */
- @Override
- public void setCountryCode(String countryCode) {
- Slog.i(TAG, "WifiService trying to set country code to " + countryCode);
- enforceConnectivityInternalPermission();
- mLog.info("setCountryCode uid=%").c(Binder.getCallingUid()).flush();
- final long token = Binder.clearCallingIdentity();
- mCountryCode.setCountryCode(countryCode);
- Binder.restoreCallingIdentity(token);
- }
-
/**
* Get the country code
* @return Get the best choice country code for wifi, regardless of if it was set or
@@ -2407,8 +2217,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("getCountryCode uid=%").c(Binder.getCallingUid()).flush();
}
- String country = mCountryCode.getCountryCode();
- return country;
+ return mCountryCode.getCountryCode();
}
@Override
@@ -2503,31 +2312,28 @@ public class WifiServiceImpl extends BaseWifiService {
* so we need to do additional work to find it from remote IP address
*/
- class TdlsTaskParams {
- public String remoteIpAddress;
- public boolean enable;
+ private static class TdlsTaskParams {
+ String mRemoteIpAddress;
+ boolean mEnable;
}
- class TdlsTask extends AsyncTask<TdlsTaskParams, Integer, Integer> {
+ private class TdlsTask extends AsyncTask<TdlsTaskParams, Integer, Integer> {
@Override
protected Integer doInBackground(TdlsTaskParams... params) {
// Retrieve parameters for the call
TdlsTaskParams param = params[0];
- String remoteIpAddress = param.remoteIpAddress.trim();
- boolean enable = param.enable;
+ String remoteIpAddress = param.mRemoteIpAddress.trim();
+ boolean enable = param.mEnable;
// Get MAC address of Remote IP
String macAddress = null;
- BufferedReader reader = null;
-
- try {
- reader = new BufferedReader(new FileReader("/proc/net/arp"));
-
- // Skip over the line bearing colum titles
- String line = reader.readLine();
+ try (BufferedReader reader = new BufferedReader(new FileReader("/proc/net/arp"))) {
+ // Skip over the line bearing column titles
+ reader.readLine();
+ String line;
while ((line = reader.readLine()) != null) {
String[] tokens = line.split("[ ]+");
if (tokens.length < 6) {
@@ -2546,27 +2352,17 @@ public class WifiServiceImpl extends BaseWifiService {
}
if (macAddress == null) {
- Slog.w(TAG, "Did not find remoteAddress {" + remoteIpAddress + "} in " +
- "/proc/net/arp");
+ Log.w(TAG, "Did not find remoteAddress {" + remoteIpAddress + "} in "
+ + "/proc/net/arp");
} else {
enableTdlsWithMacAddress(macAddress, enable);
}
} catch (FileNotFoundException e) {
- Slog.e(TAG, "Could not open /proc/net/arp to lookup mac address");
+ Log.e(TAG, "Could not open /proc/net/arp to lookup mac address");
} catch (IOException e) {
- Slog.e(TAG, "Could not read /proc/net/arp to lookup mac address");
- } finally {
- try {
- if (reader != null) {
- reader.close();
- }
- }
- catch (IOException e) {
- // Do nothing
- }
+ Log.e(TAG, "Could not read /proc/net/arp to lookup mac address");
}
-
return 0;
}
}
@@ -2578,8 +2374,8 @@ public class WifiServiceImpl extends BaseWifiService {
}
mLog.info("enableTdls uid=% enable=%").c(Binder.getCallingUid()).c(enable).flush();
TdlsTaskParams params = new TdlsTaskParams();
- params.remoteIpAddress = remoteAddress;
- params.enable = enable;
+ params.mRemoteIpAddress = remoteAddress;
+ params.mEnable = enable;
new TdlsTask().execute(params);
}
@@ -2598,22 +2394,6 @@ public class WifiServiceImpl extends BaseWifiService {
}
/**
- * Get a reference to handler. This is used by a client to establish
- * an AsyncChannel communication with WifiService
- */
- @Override
- public Messenger getWifiServiceMessenger(String packageName) {
- enforceAccessPermission();
- if (enforceChangePermission(packageName) != MODE_ALLOWED) {
- // We don't have a good way of creating a fake Messenger, and returning null would
- // immediately break callers.
- throw new SecurityException("Could not create wifi service messenger");
- }
- mLog.info("getWifiServiceMessenger uid=%").c(Binder.getCallingUid()).flush();
- return new Messenger(mAsyncChannelExternalClientHandler);
- }
-
- /**
* Disable an ephemeral network, i.e. network that is created thru a WiFi Scorer
*/
@Override
@@ -2626,7 +2406,7 @@ public class WifiServiceImpl extends BaseWifiService {
return;
}
mLog.info("disableEphemeralNetwork uid=%").c(Binder.getCallingUid()).flush();
- mClientModeImpl.disableEphemeralNetwork(SSID);
+ mWifiThreadRunner.post(() -> mWifiConfigManager.disableEphemeralNetwork(SSID));
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -2635,17 +2415,19 @@ public class WifiServiceImpl extends BaseWifiService {
String action = intent.getAction();
if (action.equals(Intent.ACTION_USER_REMOVED)) {
int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
- mClientModeImpl.removeUserConfigs(userHandle);
+ mWifiThreadRunner.post(() -> mWifiConfigManager.removeNetworksForUser(userHandle));
} else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
BluetoothAdapter.STATE_DISCONNECTED);
mClientModeImpl.sendBluetoothAdapterStateChange(state);
} else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
- boolean emergencyMode = intent.getBooleanExtra("phoneinECMState", false);
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, emergencyMode ? 1 : 0, 0);
+ boolean emergencyMode =
+ intent.getBooleanExtra(PhoneConstants.PHONE_IN_ECM_STATE, false);
+ mActiveModeWarden.emergencyCallbackModeChanged(emergencyMode);
} else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED)) {
- boolean inCall = intent.getBooleanExtra(PhoneConstants.PHONE_IN_EMERGENCY_CALL, false);
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, inCall ? 1 : 0, 0);
+ boolean inCall =
+ intent.getBooleanExtra(PhoneConstants.PHONE_IN_EMERGENCY_CALL, false);
+ mActiveModeWarden.emergencyCallStateChanged(inCall);
} else if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
handleIdleModeChanged();
}
@@ -2660,7 +2442,7 @@ public class WifiServiceImpl extends BaseWifiService {
@Override
public void onChange(boolean selfChange) {
mSettingsStore.handleWifiScanAlwaysAvailableToggled();
- mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
+ mActiveModeWarden.scanAlwaysModeChanged();
}
};
mFrameworkFacade.registerContentObserver(mContext,
@@ -2698,10 +2480,13 @@ public class WifiServiceImpl extends BaseWifiService {
return;
}
String pkgName = uri.getSchemeSpecificPart();
- mClientModeImpl.removeAppConfigs(pkgName, uid);
- // Call the method in ClientModeImpl thread.
- mWifiInjector.getClientModeImplHandler().post(() -> {
+ // Call the method in the main Wifi thread.
+ mWifiThreadRunner.post(() -> {
+ ApplicationInfo ai = new ApplicationInfo();
+ ai.packageName = pkgName;
+ ai.uid = uid;
+ mWifiConfigManager.removeNetworksForApp(ai);
mScanRequestProxy.clearScanRequestTimestampsForApp(pkgName, uid);
// Remove all suggestions from the package.
@@ -2711,7 +2496,6 @@ public class WifiServiceImpl extends BaseWifiService {
// Remove all Passpoint profiles from package.
mWifiInjector.getPasspointManager().removePasspointProviderWithPackage(
pkgName);
-
});
}
}
@@ -2736,7 +2520,11 @@ public class WifiServiceImpl extends BaseWifiService {
}
if (args != null && args.length > 0 && WifiMetrics.PROTO_DUMP_ARG.equals(args[0])) {
// WifiMetrics proto bytes were requested. Dump only these.
- mClientModeImpl.updateWifiMetrics();
+ mWifiThreadRunner.run(() -> {
+ mWifiMetrics.updateSavedNetworks(
+ mWifiConfigManager.getSavedNetworks(Process.WIFI_UID));
+ mPasspointManager.updateMetrics();
+ });
mWifiMetrics.dump(fd, pw, args);
} else if (args != null && args.length > 0 && IpClientUtil.DUMP_ARG.equals(args[0])) {
// IpClient dump was requested. Pass it along and take no further action.
@@ -2747,12 +2535,10 @@ public class WifiServiceImpl extends BaseWifiService {
WifiScoreReport wifiScoreReport = mClientModeImpl.getWifiScoreReport();
if (wifiScoreReport != null) wifiScoreReport.dump(fd, pw, args);
} else if (args != null && args.length > 0 && WifiScoreCard.DUMP_ARG.equals(args[0])) {
- mWifiInjector.getClientModeImplHandler().runWithScissors(() -> {
- WifiScoreCard wifiScoreCard = mWifiInjector.getWifiScoreCard();
- if (wifiScoreCard != null) {
- pw.println(wifiScoreCard.getNetworkListBase64(true));
- }
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
+ WifiScoreCard wifiScoreCard = mWifiInjector.getWifiScoreCard();
+ String networkListBase64 = mWifiThreadRunner.call(() ->
+ wifiScoreCard.getNetworkListBase64(true), "");
+ pw.println(networkListBase64);
} else {
// Polls link layer stats and RSSI. This allows the stats to show up in
// WifiScoreReport's dump() output when taking a bug report even if the screen is off.
@@ -2764,7 +2550,6 @@ public class WifiServiceImpl extends BaseWifiService {
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0));
pw.println("mInIdleMode " + mInIdleMode);
pw.println("mScanPending " + mScanPending);
- mWifiController.dump(fd, pw, args);
mSettingsStore.dump(fd, pw, args);
mWifiTrafficPoller.dump(fd, pw, args);
pw.println();
@@ -2777,35 +2562,31 @@ public class WifiServiceImpl extends BaseWifiService {
pw.println();
mClientModeImpl.dump(fd, pw, args);
pw.println();
- mWifiInjector.getClientModeImplHandler().runWithScissors(() -> {
- WifiScoreCard wifiScoreCard = mWifiInjector.getWifiScoreCard();
- if (wifiScoreCard != null) {
- pw.println("WifiScoreCard:");
- pw.println(wifiScoreCard.getNetworkListBase64(true));
- }
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- mClientModeImpl.updateWifiMetrics();
+ WifiScoreCard wifiScoreCard = mWifiInjector.getWifiScoreCard();
+ String networkListBase64 = mWifiThreadRunner.call(() ->
+ wifiScoreCard.getNetworkListBase64(true), "");
+ pw.println("WifiScoreCard:");
+ pw.println(networkListBase64);
+ mWifiThreadRunner.run(() -> {
+ mWifiMetrics.updateSavedNetworks(
+ mWifiConfigManager.getSavedNetworks(Process.WIFI_UID));
+ mPasspointManager.updateMetrics();
+ });
mWifiMetrics.dump(fd, pw, args);
pw.println();
- mWifiInjector.getClientModeImplHandler().runWithScissors(() -> {
- mWifiNetworkSuggestionsManager.dump(fd, pw, args);
- pw.println();
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
+ mWifiThreadRunner.run(() -> mWifiNetworkSuggestionsManager.dump(fd, pw, args));
+ pw.println();
mWifiBackupRestore.dump(fd, pw, args);
pw.println();
pw.println("ScoringParams: settings put global " + Settings.Global.WIFI_SCORE_PARAMS
+ " " + mWifiInjector.getScoringParams());
pw.println();
+ pw.println("WifiScoreReport:");
WifiScoreReport wifiScoreReport = mClientModeImpl.getWifiScoreReport();
- if (wifiScoreReport != null) {
- pw.println("WifiScoreReport:");
- wifiScoreReport.dump(fd, pw, args);
- }
+ wifiScoreReport.dump(fd, pw, args);
pw.println();
SarManager sarManager = mWifiInjector.getSarManager();
- if (sarManager != null) {
- sarManager.dump(fd, pw, args);
- }
+ sarManager.dump(fd, pw, args);
pw.println();
}
}
@@ -2823,18 +2604,8 @@ public class WifiServiceImpl extends BaseWifiService {
WorkSource updatedWs = (ws == null || ws.isEmpty())
? new WorkSource(Binder.getCallingUid()) : ws;
- Mutable<Boolean> lockSuccess = new Mutable<>();
- boolean runWithScissorsSuccess = mWifiInjector.getClientModeImplHandler().runWithScissors(
- () -> {
- lockSuccess.value = mWifiLockManager.acquireWifiLock(
- lockMode, tag, binder, updatedWs);
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- if (!runWithScissorsSuccess) {
- Log.e(TAG, "Failed to post runnable to acquireWifiLock");
- return false;
- }
-
- return lockSuccess.value;
+ return mWifiThreadRunner.call(() ->
+ mWifiLockManager.acquireWifiLock(lockMode, tag, binder, updatedWs), false);
}
@Override
@@ -2849,13 +2620,8 @@ public class WifiServiceImpl extends BaseWifiService {
WorkSource updatedWs = (ws == null || ws.isEmpty())
? new WorkSource(Binder.getCallingUid()) : ws;
- boolean runWithScissorsSuccess = mWifiInjector.getClientModeImplHandler().runWithScissors(
- () -> {
- mWifiLockManager.updateWifiLockWorkSource(binder, updatedWs);
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- if (!runWithScissorsSuccess) {
- Log.e(TAG, "Failed to post runnable to updateWifiLockWorkSource");
- }
+ mWifiThreadRunner.run(() ->
+ mWifiLockManager.updateWifiLockWorkSource(binder, updatedWs));
}
@Override
@@ -2864,16 +2630,9 @@ public class WifiServiceImpl extends BaseWifiService {
// Check on permission to make this call
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
- Mutable<Boolean> lockSuccess = new Mutable<>();
- boolean runWithScissorsSuccess = mWifiInjector.getClientModeImplHandler().runWithScissors(
- () -> {
- lockSuccess.value = mWifiLockManager.releaseWifiLock(binder);
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- if (!runWithScissorsSuccess) {
- Log.e(TAG, "Failed to post runnable to releaseWifiLock");
- return false;
- }
- return lockSuccess.value;
+
+ return mWifiThreadRunner.call(() ->
+ mWifiLockManager.releaseWifiLock(binder), false);
}
@Override
@@ -2918,7 +2677,7 @@ public class WifiServiceImpl extends BaseWifiService {
enableVerboseLoggingInternal(verbose);
}
- void enableVerboseLoggingInternal(int verbose) {
+ private void enableVerboseLoggingInternal(int verbose) {
mVerboseLoggingEnabled = verbose > 0;
mClientModeImpl.enableVerboseLogging(verbose);
mWifiLockManager.enableVerboseLogging(verbose);
@@ -2945,44 +2704,35 @@ public class WifiServiceImpl extends BaseWifiService {
if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
return;
}
-
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
// Turn mobile hotspot off
stopSoftApInternal(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
}
- if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI)) {
- if (mClientModeImplChannel != null) {
- // Delete all Wifi SSIDs
- List<WifiConfiguration> networks = mClientModeImpl.syncGetConfiguredNetworks(
- Binder.getCallingUid(), mClientModeImplChannel, Process.WIFI_UID);
- if (networks != null) {
- for (WifiConfiguration config : networks) {
- removeNetwork(config.networkId, packageName);
- }
- }
-
- // Delete all Passpoint configurations
- if (mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_PASSPOINT)) {
- List<PasspointConfiguration> configs = mClientModeImpl.syncGetPasspointConfigs(
- mClientModeImplChannel, true);
- if (configs != null) {
- for (PasspointConfiguration config : configs) {
- removePasspointConfiguration(config.getHomeSp().getFqdn(), packageName);
- }
- }
- }
- }
-
- mWifiInjector.getClientModeImplHandler().post(() -> {
- mWifiInjector.getWifiConfigManager().clearDeletedEphemeralNetworks();
- mClientModeImpl.clearNetworkRequestUserApprovedAccessPoints();
- mWifiNetworkSuggestionsManager.clear();
- mWifiInjector.getWifiScoreCard().clear();
- });
- notifyFactoryReset();
+ if (mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI)) {
+ return;
}
+ // Delete all Wifi SSIDs
+ List<WifiConfiguration> networks = mWifiThreadRunner.call(
+ () -> mWifiConfigManager.getSavedNetworks(Process.WIFI_UID),
+ Collections.emptyList());
+ for (WifiConfiguration network : networks) {
+ removeNetwork(network.networkId, packageName);
+ }
+ // Delete all Passpoint configurations
+ List<PasspointConfiguration> configs = mWifiThreadRunner.call(
+ () -> mPasspointManager.getProviderConfigs(Process.WIFI_UID /* ignored */, true),
+ Collections.emptyList());
+ for (PasspointConfiguration config : configs) {
+ removePasspointConfiguration(config.getHomeSp().getFqdn(), packageName);
+ }
+ mWifiThreadRunner.post(() -> {
+ mWifiConfigManager.clearDeletedEphemeralNetworks();
+ mClientModeImpl.clearNetworkRequestUserApprovedAccessPoints();
+ mWifiNetworkSuggestionsManager.clear();
+ mWifiInjector.getWifiScoreCard().clear();
+ notifyFactoryReset();
+ });
}
/**
@@ -2995,12 +2745,6 @@ public class WifiServiceImpl extends BaseWifiService {
android.Manifest.permission.NETWORK_CARRIER_PROVISIONING);
}
- /* private methods */
- static boolean logAndReturnFalse(String s) {
- Log.d(TAG, s);
- return false;
- }
-
@Override
public Network getCurrentNetwork() {
enforceAccessPermission();
@@ -3046,16 +2790,16 @@ public class WifiServiceImpl extends BaseWifiService {
enforceNetworkSettingsPermission();
mLog.info("retrieveBackupData uid=%").c(Binder.getCallingUid()).flush();
if (mClientModeImplChannel == null) {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
+ Log.e(TAG, "mClientModeImplChannel is not initialized");
return null;
}
- Slog.d(TAG, "Retrieving backup data");
- List<WifiConfiguration> wifiConfigurations =
- mClientModeImpl.syncGetPrivilegedConfiguredNetwork(mClientModeImplChannel);
+ Log.d(TAG, "Retrieving backup data");
+ List<WifiConfiguration> wifiConfigurations = mWifiThreadRunner.call(
+ () -> mWifiConfigManager.getConfiguredNetworksWithPasswords(), null);
byte[] backupData =
mWifiBackupRestore.retrieveBackupDataFromConfigurations(wifiConfigurations);
- Slog.d(TAG, "Retrieved backup data");
+ Log.d(TAG, "Retrieved backup data");
return backupData;
}
@@ -3066,19 +2810,24 @@ public class WifiServiceImpl extends BaseWifiService {
*/
private void restoreNetworks(List<WifiConfiguration> configurations) {
if (configurations == null) {
- Slog.e(TAG, "Backup data parse failed");
+ Log.e(TAG, "Backup data parse failed");
return;
}
- for (WifiConfiguration configuration : configurations) {
- int networkId = mClientModeImpl.syncAddOrUpdateNetwork(
- mClientModeImplChannel, configuration);
- if (networkId == WifiConfiguration.INVALID_NETWORK_ID) {
- Slog.e(TAG, "Restore network failed: " + configuration.configKey());
- continue;
- }
- // Enable all networks restored.
- mClientModeImpl.syncEnableNetwork(mClientModeImplChannel, networkId, false);
- }
+ int callingUid = Binder.getCallingUid();
+ mWifiThreadRunner.run(
+ () -> {
+ for (WifiConfiguration configuration : configurations) {
+ int networkId =
+ mWifiConfigManager.addOrUpdateNetwork(configuration, callingUid)
+ .getNetworkId();
+ if (networkId == WifiConfiguration.INVALID_NETWORK_ID) {
+ Log.e(TAG, "Restore network failed: " + configuration.configKey());
+ continue;
+ }
+ // Enable all networks restored.
+ mWifiConfigManager.enableNetwork(networkId, false, callingUid, null);
+ }
+ });
}
/**
@@ -3091,15 +2840,15 @@ public class WifiServiceImpl extends BaseWifiService {
enforceNetworkSettingsPermission();
mLog.info("restoreBackupData uid=%").c(Binder.getCallingUid()).flush();
if (mClientModeImplChannel == null) {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
+ Log.e(TAG, "mClientModeImplChannel is not initialized");
return;
}
- Slog.d(TAG, "Restoring backup data");
+ Log.d(TAG, "Restoring backup data");
List<WifiConfiguration> wifiConfigurations =
mWifiBackupRestore.retrieveConfigurationsFromBackupData(data);
restoreNetworks(wifiConfigurations);
- Slog.d(TAG, "Restored backup data");
+ Log.d(TAG, "Restored backup data");
}
/**
@@ -3113,16 +2862,16 @@ public class WifiServiceImpl extends BaseWifiService {
enforceNetworkSettingsPermission();
mLog.trace("restoreSupplicantBackupData uid=%").c(Binder.getCallingUid()).flush();
if (mClientModeImplChannel == null) {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
+ Log.e(TAG, "mClientModeImplChannel is not initialized");
return;
}
- Slog.d(TAG, "Restoring supplicant backup data");
+ Log.d(TAG, "Restoring supplicant backup data");
List<WifiConfiguration> wifiConfigurations =
mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
supplicantData, ipConfigData);
restoreNetworks(wifiConfigurations);
- Slog.d(TAG, "Restored supplicant backup data");
+ Log.d(TAG, "Restored supplicant backup data");
}
/**
@@ -3143,10 +2892,6 @@ public class WifiServiceImpl extends BaseWifiService {
if (!isSettingsOrSuw(Binder.getCallingPid(), Binder.getCallingUid())) {
throw new SecurityException(TAG + ": Permission denied");
}
- if (!mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_PASSPOINT)) {
- throw new UnsupportedOperationException("Passpoint not enabled");
- }
final int uid = Binder.getCallingUid();
mLog.trace("startSubscriptionProvisioning uid=%").c(uid).flush();
if (mClientModeImpl.syncStartSubscriptionProvisioning(uid, provider,
@@ -3184,9 +2929,8 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("registerTrafficStateCallback uid=%").c(Binder.getCallingUid()).flush();
}
// Post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(() -> {
- mWifiTrafficPoller.addCallback(binder, callback, callbackIdentifier);
- });
+ mWifiThreadRunner.post(() ->
+ mWifiTrafficPoller.addCallback(binder, callback, callbackIdentifier));
}
/**
@@ -3204,9 +2948,8 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("unregisterTrafficStateCallback uid=%").c(Binder.getCallingUid()).flush();
}
// Post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(() -> {
- mWifiTrafficPoller.removeCallback(callbackIdentifier);
- });
+ mWifiThreadRunner.post(() ->
+ mWifiTrafficPoller.removeCallback(callbackIdentifier));
}
private boolean is5GhzSupported() {
@@ -3218,7 +2961,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (channel != null) {
return mClientModeImpl.syncGetSupportedFeatures(channel);
} else {
- Slog.e(TAG, "mClientModeImplChannel is not initialized");
+ Log.e(TAG, "mClientModeImplChannel is not initialized");
return 0;
}
}
@@ -3258,9 +3001,8 @@ public class WifiServiceImpl extends BaseWifiService {
.c(Binder.getCallingUid()).flush();
}
// Post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(() -> {
- mClientModeImpl.addNetworkRequestMatchCallback(binder, callback, callbackIdentifier);
- });
+ mWifiThreadRunner.post(() -> mClientModeImpl.addNetworkRequestMatchCallback(
+ binder, callback, callbackIdentifier));
}
/**
@@ -3279,9 +3021,8 @@ public class WifiServiceImpl extends BaseWifiService {
.c(Binder.getCallingUid()).flush();
}
// Post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(() -> {
- mClientModeImpl.removeNetworkRequestMatchCallback(callbackIdentifier);
- });
+ mWifiThreadRunner.post(() ->
+ mClientModeImpl.removeNetworkRequestMatchCallback(callbackIdentifier));
}
/**
@@ -3302,20 +3043,14 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("addNetworkSuggestions uid=%").c(Binder.getCallingUid()).flush();
}
int callingUid = Binder.getCallingUid();
- Mutable<Integer> success = new Mutable<>();
- boolean runWithScissorsSuccess = mWifiInjector.getClientModeImplHandler().runWithScissors(
- () -> {
- success.value = mWifiNetworkSuggestionsManager.add(
- networkSuggestions, callingUid, callingPackageName);
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- if (!runWithScissorsSuccess) {
- Log.e(TAG, "Failed to post runnable to add network suggestions");
- return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL;
- }
- if (success.value != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
+
+ int success = mWifiThreadRunner.call(() -> mWifiNetworkSuggestionsManager.add(
+ networkSuggestions, callingUid, callingPackageName),
+ WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL);
+ if (success != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
Log.e(TAG, "Failed to add network suggestions");
}
- return success.value;
+ return success;
}
/**
@@ -3336,20 +3071,29 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("removeNetworkSuggestions uid=%").c(Binder.getCallingUid()).flush();
}
int callingUid = Binder.getCallingUid();
- Mutable<Integer> success = new Mutable<>();
- boolean runWithScissorsSuccess = mWifiInjector.getClientModeImplHandler().runWithScissors(
- () -> {
- success.value = mWifiNetworkSuggestionsManager.remove(
- networkSuggestions, callingUid, callingPackageName);
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- if (!runWithScissorsSuccess) {
- Log.e(TAG, "Failed to post runnable to remove network suggestions");
- return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL;
- }
- if (success.value != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
+
+ int success = mWifiThreadRunner.call(() -> mWifiNetworkSuggestionsManager.remove(
+ networkSuggestions, callingUid, callingPackageName),
+ WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL);
+ if (success != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
Log.e(TAG, "Failed to remove network suggestions");
}
- return success.value;
+ return success;
+ }
+
+ /**
+ * See {@link android.net.wifi.WifiManager#getNetworkSuggestions()}
+ * @param callingPackageName Package Name of the app getting the suggestions.
+ * @return a list of network suggestions suggested by this app
+ */
+ public List<WifiNetworkSuggestion> getNetworkSuggestions(String callingPackageName) {
+ mAppOps.checkPackage(Binder.getCallingUid(), callingPackageName);
+ enforceAccessPermission();
+ if (mVerboseLoggingEnabled) {
+ mLog.info("getNetworkSuggestionList uid=%").c(Binder.getCallingUid()).flush();
+ }
+ return mWifiThreadRunner.call(() ->
+ mWifiNetworkSuggestionsManager.get(callingPackageName), Collections.emptyList());
}
/**
@@ -3364,17 +3108,14 @@ public class WifiServiceImpl extends BaseWifiService {
throw new SecurityException("App not allowed to get Wi-Fi factory MAC address "
+ "(uid = " + uid + ")");
}
- final List<String> result = new ArrayList<>();
- boolean success = mWifiInjector.getClientModeImplHandler().runWithScissors(() -> {
- final String mac = mClientModeImpl.getFactoryMacAddress();
- if (mac != null) {
- result.add(mac);
- }
- }, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
- if (success) {
- return result.isEmpty() ? null : result.stream().toArray(String[]::new);
+ String result = mWifiThreadRunner.call(mClientModeImpl::getFactoryMacAddress, null);
+ // result can be null if either: WifiThreadRunner.call() timed out, or
+ // ClientModeImpl.getFactoryMacAddress() returned null.
+ // In this particular instance, we don't differentiate the two types of nulls.
+ if (result == null) {
+ return null;
}
- return null;
+ return new String[]{result};
}
/**
@@ -3393,8 +3134,7 @@ public class WifiServiceImpl extends BaseWifiService {
.flush();
}
// Post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(
- () -> mClientModeImpl.setDeviceMobilityState(state));
+ mWifiThreadRunner.post(() -> mClientModeImpl.setDeviceMobilityState(state));
}
/**
@@ -3438,10 +3178,8 @@ public class WifiServiceImpl extends BaseWifiService {
throw new SecurityException(TAG + ": Permission denied");
}
- mDppManager.mHandler.post(() -> {
- mDppManager.startDppAsConfiguratorInitiator(uid, binder, enrolleeUri,
- selectedNetworkId, netRole, callback);
- });
+ mWifiThreadRunner.post(() -> mDppManager.startDppAsConfiguratorInitiator(
+ uid, binder, enrolleeUri, selectedNetworkId, netRole, callback));
}
/**
@@ -3472,24 +3210,21 @@ public class WifiServiceImpl extends BaseWifiService {
throw new SecurityException(TAG + ": Permission denied");
}
- mDppManager.mHandler.post(() -> {
- mDppManager.startDppAsEnrolleeInitiator(uid, binder, configuratorUri, callback);
- });
+ mWifiThreadRunner.post(() ->
+ mDppManager.startDppAsEnrolleeInitiator(uid, binder, configuratorUri, callback));
}
/**
* Stop or abort a current DPP session.
*/
@Override
- public void stopDppSession() throws android.os.RemoteException {
+ public void stopDppSession() throws RemoteException {
if (!isSettingsOrSuw(Binder.getCallingPid(), Binder.getCallingUid())) {
throw new SecurityException(TAG + ": Permission denied");
}
final int uid = getMockableCallingUid();
- mDppManager.mHandler.post(() -> {
- mDppManager.stopDppSession(uid);
- });
+ mWifiThreadRunner.post(() -> mDppManager.stopDppSession(uid));
}
/**
@@ -3522,9 +3257,8 @@ public class WifiServiceImpl extends BaseWifiService {
.c(Binder.getCallingUid()).flush();
}
// Post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(() -> {
- mWifiMetrics.addOnWifiUsabilityListener(binder, listener, listenerIdentifier);
- });
+ mWifiThreadRunner.post(() ->
+ mWifiMetrics.addOnWifiUsabilityListener(binder, listener, listenerIdentifier));
}
/**
@@ -3544,9 +3278,8 @@ public class WifiServiceImpl extends BaseWifiService {
.c(Binder.getCallingUid()).flush();
}
// Post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(() -> {
- mWifiMetrics.removeOnWifiUsabilityListener(listenerIdentifier);
- });
+ mWifiThreadRunner.post(() ->
+ mWifiMetrics.removeOnWifiUsabilityListener(listenerIdentifier));
}
/**
@@ -3569,8 +3302,116 @@ public class WifiServiceImpl extends BaseWifiService {
.flush();
}
// Post operation to handler thread
- mWifiInjector.getClientModeImplHandler().post(
- () -> mClientModeImpl.updateWifiUsabilityScore(seqNum, score,
- predictionHorizonSec));
+ mWifiThreadRunner.post(() ->
+ mClientModeImpl.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec));
+ }
+
+ /**
+ * see {@link android.net.wifi.WifiManager#connect(int, WifiManager.ActionListener)}
+ */
+ @Override
+ public void connect(WifiConfiguration config, int netId, IBinder binder,
+ @Nullable IActionListener callback, int callbackIdentifier) {
+ if (!isPrivileged(Binder.getCallingPid(), Binder.getCallingUid())) {
+ throw new SecurityException(TAG + ": Permission denied");
+ }
+ if (mVerboseLoggingEnabled) {
+ mLog.info("connect uid=%").c(Binder.getCallingUid()).flush();
+ }
+ mClientModeImpl.connect(
+ config, netId, binder, callback, callbackIdentifier, Binder.getCallingUid());
+ }
+
+ /**
+ * see {@link android.net.wifi.WifiManager#save(WifiConfiguration,
+ * WifiManager.ActionListener)}
+ */
+ @Override
+ public void save(WifiConfiguration config, IBinder binder, @Nullable IActionListener callback,
+ int callbackIdentifier) {
+ if (!isPrivileged(Binder.getCallingPid(), Binder.getCallingUid())) {
+ throw new SecurityException(TAG + ": Permission denied");
+ }
+ if (mVerboseLoggingEnabled) {
+ mLog.info("connect uid=%").c(Binder.getCallingUid()).flush();
+ }
+ mClientModeImpl.save(
+ config, binder, callback, callbackIdentifier, Binder.getCallingUid());
+ }
+
+ /**
+ * see {@link android.net.wifi.WifiManager#forget(int, WifiManager.ActionListener)}
+ */
+ @Override
+ public void forget(int netId, IBinder binder, @Nullable IActionListener callback,
+ int callbackIdentifier) {
+ if (!isPrivileged(Binder.getCallingPid(), Binder.getCallingUid())) {
+ throw new SecurityException(TAG + ": Permission denied");
+ }
+ if (mVerboseLoggingEnabled) {
+ mLog.info("connect uid=%").c(Binder.getCallingUid()).flush();
+ }
+ mClientModeImpl.forget(
+ netId, binder, callback, callbackIdentifier, Binder.getCallingUid());
+ }
+
+ /**
+ * see {@link android.net.wifi.WifiManager#getTxPacketCount(WifiManager.TxPacketCountListener)}
+ */
+ @Override
+ public void getTxPacketCount(String packageName, IBinder binder,
+ @NonNull ITxPacketCountListener callback, int callbackIdentifier) {
+ // verify arguments
+ if (binder == null) {
+ throw new IllegalArgumentException("Binder must not be null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("Callback must not be null");
+ }
+ enforceChangePermission(packageName);
+ if (mVerboseLoggingEnabled) {
+ mLog.info("connect uid=%").c(Binder.getCallingUid()).flush();
+ }
+ mClientModeImpl.getTxPacketCount(
+ binder, callback, callbackIdentifier, Binder.getCallingUid());
+ }
+
+ /**
+ * See {@link WifiManager#addScanResultsListener(Executor, WifiManager.ScanResultsListener)}
+ */
+ public void registerScanResultsListener(IBinder binder, IScanResultsListener listener,
+ int listenerIdentifier) {
+ if (binder == null) {
+ throw new IllegalArgumentException("Binder must not be null");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+ enforceAccessPermission();
+
+ if (mVerboseLoggingEnabled) {
+ mLog.info("registerScanResultListener uid=%").c(Binder.getCallingUid()).flush();
+ }
+ mWifiThreadRunner.post(() -> {
+ if (!mWifiInjector.getScanRequestProxy().registerScanResultsListener(binder, listener,
+ listenerIdentifier)) {
+ Log.e(TAG, "registerScanResultListener: Failed to add callback");
+ }
+ });
+ }
+
+ /**
+ * See {@link WifiManager#removeScanResultsListener(WifiManager.ScanResultsListener)}
+ */
+ public void unregisterScanResultsListener(int listenerIdentifier) {
+ if (mVerboseLoggingEnabled) {
+ mLog.info("unregisterScanResultCallback uid=%").c(Binder.getCallingUid()).flush();
+ }
+ enforceAccessPermission();
+ // post operation to handler thread
+ mWifiThreadRunner.post(() ->
+ mWifiInjector.getScanRequestProxy()
+ .unregisterScanResultsListener(listenerIdentifier));
+
}
}
diff --git a/service/java/com/android/server/wifi/WifiSettingsStore.java b/service/java/com/android/server/wifi/WifiSettingsStore.java
index 8d8d587b5c..a2f962f620 100644
--- a/service/java/com/android/server/wifi/WifiSettingsStore.java
+++ b/service/java/com/android/server/wifi/WifiSettingsStore.java
@@ -45,9 +45,6 @@ public class WifiSettingsStore {
private final Context mContext;
- /* Tracks if we have checked the saved wi-fi state after boot */
- private boolean mCheckSavedStateAtBoot = false;
-
WifiSettingsStore(Context context) {
mContext = context;
mAirplaneModeOn = getPersistedAirplaneModeOn();
@@ -56,11 +53,6 @@ public class WifiSettingsStore {
}
public synchronized boolean isWifiToggleEnabled() {
- if (!mCheckSavedStateAtBoot) {
- mCheckSavedStateAtBoot = true;
- if (testAndClearWifiSavedState()) return true;
- }
-
if (mAirplaneModeOn) {
return mPersistWifiState == WIFI_ENABLED_AIRPLANE_OVERRIDE;
} else {
@@ -116,8 +108,7 @@ public class WifiSettingsStore {
}
} else {
/* On airplane mode disable, restore wifi state if necessary */
- if (testAndClearWifiSavedState() ||
- mPersistWifiState == WIFI_ENABLED_AIRPLANE_OVERRIDE
+ if (mPersistWifiState == WIFI_ENABLED_AIRPLANE_OVERRIDE
|| mPersistWifiState == WIFI_DISABLED_AIRPLANE_ON) {
persistWifiState(WIFI_ENABLED);
}
@@ -156,55 +147,6 @@ public class WifiSettingsStore {
&& toggleableRadios.contains(Settings.Global.RADIO_WIFI);
}
- /**
- * After a reboot, we restore wi-fi to be on if it was turned off temporarily for tethering.
- * The settings app tracks the saved state, but the framework has to check it at boot to
- * make sure the wi-fi is turned on in case it was turned off for the purpose of tethering.
- *
- * Note that this is not part of the regular WIFI_ON setting because this only needs to
- * be controlled through the settings app and not the Wi-Fi public API.
- */
- private boolean testAndClearWifiSavedState() {
- int wifiSavedState = getWifiSavedState();
- if (wifiSavedState == WIFI_ENABLED) {
- setWifiSavedState(WIFI_DISABLED);
- }
- return (wifiSavedState == WIFI_ENABLED);
- }
-
- /**
- * Allow callers to set the Settings.Global.WIFI_SAVED_STATE property.
- *
- * When changing states, we need to remember what the wifi state was before switching. An
- * example of this is when WiFiController switches to APEnabledState. Before swtiching to the
- * new state, WifiController sets the current WiFi enabled/disabled state. When the AP is
- * turned off, the WIFI_SAVED_STATE setting is used to restore the previous wifi state.
- *
- * @param state WiFi state to store with the Settings.Global.WIFI_SAVED_STATE property.
- */
- public void setWifiSavedState(int state) {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.WIFI_SAVED_STATE, state);
- }
-
- /**
- * Allow callers to get the Settings.Global.WIFI_SAVED_STATE property.
- *
- * When changing states we remember what the wifi state was before switching. This function is
- * used to get the saved state.
- *
- * @return int Value for the previously saved state.
- */
- public int getWifiSavedState() {
- try {
- return Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.WIFI_SAVED_STATE);
- } catch (Settings.SettingNotFoundException e) {
- // If we have an error, return wifiSavedState off.
- return WIFI_DISABLED;
- }
- }
-
private int getPersistedWifiState() {
final ContentResolver cr = mContext.getContentResolver();
try {
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index b2289a8323..8a7bd75813 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -16,8 +16,6 @@
package com.android.server.wifi;
-import android.app.AppGlobals;
-import android.content.pm.IPackageManager;
import android.net.wifi.WifiScanner;
import android.os.Binder;
import android.os.ShellCommand;
@@ -50,20 +48,20 @@ public class WifiShellCommand extends ShellCommand {
private final WifiLockManager mWifiLockManager;
private final WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
private final WifiConfigManager mWifiConfigManager;
- private final IPackageManager mPM;
private final WifiNative mWifiNative;
private final HostapdHal mHostapdHal;
private final WifiCountryCode mWifiCountryCode;
+ private final WifiLastResortWatchdog mWifiLastResortWatchdog;
WifiShellCommand(WifiInjector wifiInjector) {
mClientModeImpl = wifiInjector.getClientModeImpl();
mWifiLockManager = wifiInjector.getWifiLockManager();
mWifiNetworkSuggestionsManager = wifiInjector.getWifiNetworkSuggestionsManager();
mWifiConfigManager = wifiInjector.getWifiConfigManager();
- mPM = AppGlobals.getPackageManager();
mHostapdHal = wifiInjector.getHostapdHal();
mWifiNative = wifiInjector.getWifiNative();
mWifiCountryCode = wifiInjector.getWifiCountryCode();
+ mWifiLastResortWatchdog = wifiInjector.getWifiLastResortWatchdog();
}
@Override
@@ -245,6 +243,27 @@ public class WifiShellCommand extends ShellCommand {
+ mWifiCountryCode.getCountryCode());
return 0;
}
+ case "set-wifi-watchdog": {
+ boolean enabled;
+ String nextArg = getNextArgRequired();
+ if ("enabled".equals(nextArg)) {
+ enabled = true;
+ } else if ("disabled".equals(nextArg)) {
+ enabled = false;
+ } else {
+ pw.println(
+ "Invalid argument to 'set-wifi-watchdog' - must be 'enabled'"
+ + " or 'disabled'");
+ return -1;
+ }
+ mWifiLastResortWatchdog.setWifiWatchdogFeature(enabled);
+ return 0;
+ }
+ case "get-wifi-watchdog": {
+ pw.println("wifi watchdog state is "
+ + mWifiLastResortWatchdog.getWifiWatchdogFeature());
+ return 0;
+ }
default:
return handleDefaultCommands(cmd);
}
@@ -344,6 +363,10 @@ public class WifiShellCommand extends ShellCommand {
pw.println(" Sets country code to <two-letter code> or left for normal value");
pw.println(" get-country-code");
pw.println(" Gets country code as a two-letter string");
+ pw.println(" set-wifi-watchdog enabled|disabled");
+ pw.println(" Sets whether wifi watchdog should trigger recovery");
+ pw.println(" get-wifi-watchdog");
+ pw.println(" Gets setting of wifi watchdog trigger recovery.");
pw.println();
}
}
diff --git a/service/java/com/android/server/wifi/WifiStackService.java b/service/java/com/android/server/wifi/WifiStackService.java
new file mode 100644
index 0000000000..214f85bca7
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiStackService.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import static com.android.internal.notification.SystemNotificationChannels.NETWORK_ALERTS;
+import static com.android.internal.notification.SystemNotificationChannels.NETWORK_AVAILABLE;
+import static com.android.internal.notification.SystemNotificationChannels.NETWORK_STATUS;
+
+import android.annotation.NonNull;
+import android.app.ActivityManager;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.wifi.IWifiStackConnector;
+import android.net.wifi.WifiApiServiceInfo;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.os.storage.StorageManager;
+import android.util.Log;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.wifi.aware.WifiAwareService;
+import com.android.server.wifi.p2p.WifiP2pService;
+import com.android.server.wifi.rtt.RttService;
+import com.android.server.wifi.scanner.WifiScanningService;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Android service used to start the wifi stack when bound to via an intent.
+ */
+public class WifiStackService extends Service {
+ private static final String TAG = WifiStackService.class.getSimpleName();
+ // Ordered list of wifi services. The ordering determines the order in which the events
+ // are delivered to the services.
+ @GuardedBy("mApiServices")
+ private final LinkedHashMap<String, WifiServiceBase> mApiServices = new LinkedHashMap<>();
+ private static WifiStackConnector sConnector;
+
+ private class WifiStackConnector extends IWifiStackConnector.Stub {
+ private final Context mContext;
+
+ WifiStackConnector(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public List<WifiApiServiceInfo> getWifiApiServiceInfos() {
+ // Ensure this is being invoked from system_server only.
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.NETWORK_STACK, "WifiStackService");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mApiServices) {
+ return mApiServices.entrySet().stream()
+ .map(entry -> {
+ WifiApiServiceInfo service = new WifiApiServiceInfo();
+ service.name = entry.getKey();
+ service.binder = entry.getValue().retrieveImpl();
+ return service;
+ })
+ .collect(Collectors.toList());
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ private class WifiBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i(TAG, "Received " + intent + " broadcast");
+ final String action = intent.getAction();
+ if (action == null) {
+ Log.w(TAG, "Received null action for broadcast.");
+ return;
+ }
+ int userId;
+ switch (action) {
+ case Intent.ACTION_USER_SWITCHED:
+ userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ synchronized (mApiServices) {
+ for (WifiServiceBase service : mApiServices.values()) {
+ service.onSwitchUser(userId);
+ }
+ }
+ break;
+ case Intent.ACTION_USER_STOPPED:
+ userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ synchronized (mApiServices) {
+ for (WifiServiceBase service : mApiServices.values()) {
+ service.onStopUser(userId);
+ }
+ }
+ break;
+ case Intent.ACTION_USER_UNLOCKED:
+ userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ synchronized (mApiServices) {
+ for (WifiServiceBase service : mApiServices.values()) {
+ service.onUnlockUser(userId);
+ }
+ }
+ break;
+ default:
+ Log.e(TAG, "Received unexpected action for broadcast.");
+ break;
+ }
+ }
+ }
+
+ // Create notification channels used by wifi.
+ private void createNotificationChannels() {
+ final NotificationManager nm = getSystemService(NotificationManager.class);
+ List<NotificationChannel> channelsList = new ArrayList<>();
+ final NotificationChannel networkStatusChannel = new NotificationChannel(
+ NETWORK_STATUS,
+ getString(R.string.notification_channel_network_status),
+ NotificationManager.IMPORTANCE_LOW);
+ channelsList.add(networkStatusChannel);
+
+ final NotificationChannel networkAlertsChannel = new NotificationChannel(
+ NETWORK_ALERTS,
+ getString(R.string.notification_channel_network_alerts),
+ NotificationManager.IMPORTANCE_HIGH);
+ networkAlertsChannel.setBlockableSystem(true);
+ channelsList.add(networkAlertsChannel);
+
+ final NotificationChannel networkAvailable = new NotificationChannel(
+ NETWORK_AVAILABLE,
+ getString(R.string.notification_channel_network_available),
+ NotificationManager.IMPORTANCE_LOW);
+ networkAvailable.setBlockableSystem(true);
+ channelsList.add(networkAvailable);
+
+ nm.createNotificationChannels(channelsList);
+ }
+
+
+ private synchronized boolean initializeServices(Context context) {
+ if (UserHandle.myUserId() != 0) {
+ Log.w(TAG, "Wifi stack can only be bound from primary user");
+ return false;
+ }
+ // Don't start wifi services if we're in crypt bounce state.
+ if (StorageManager.inCryptKeeperBounce()) {
+ Log.d(TAG, "Device still encrypted. Need to restart SystemServer."
+ + " Do not start wifi.");
+ return false;
+ }
+
+ // BootCompleteReceiver is registered in AndroidManifest.xml and here. The receiver
+ // registered here is triggered earlier, while the receiver registered in the manifest
+ // is more reliable since it is registered earlier, so we are guaranteed to get the
+ // broadcast (if we register too late the broadcast may have already triggered and we
+ // would have missed it). Register in both places and BootCompleteReceiver will ensure that
+ // callbacks are called exactly once.
+ Log.d(TAG, "Registering BootCompleteReceiver to listen for ACTION_LOCKED_BOOT_COMPLETED");
+ context.registerReceiver(new BootCompleteReceiver(),
+ new IntentFilter(Intent.ACTION_LOCKED_BOOT_COMPLETED));
+
+ synchronized (mApiServices) {
+ // Top level wifi feature flag.
+ if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+ Log.w(TAG, "Wifi not supported on the device");
+ return false;
+ }
+
+ // initialize static instance of WifiInjector
+ new WifiInjector(this);
+ // Ordering of wifi services.
+ // wifiscanner service
+ mApiServices.put(Context.WIFI_SCANNING_SERVICE, new WifiScanningService(this));
+ // wifi service
+ mApiServices.put(Context.WIFI_SERVICE, new WifiService(this));
+ // wifi-p2p service
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
+ mApiServices.put(Context.WIFI_P2P_SERVICE, new WifiP2pService(this));
+ }
+ // wifi-aware service
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)) {
+ mApiServices.put(Context.WIFI_AWARE_SERVICE, new WifiAwareService(this));
+ }
+ // wifirtt service
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)) {
+ mApiServices.put(Context.WIFI_RTT_RANGING_SERVICE, new RttService(this));
+ }
+ }
+
+ Handler handler = new Handler(Looper.myLooper());
+ // register callback to start Wifi services after boot completes
+ BootCompleteReceiver.registerCallback(() -> handler.post(() -> {
+ int currentUser = ActivityManager.getCurrentUser();
+ synchronized (mApiServices) {
+ for (WifiServiceBase service : mApiServices.values()) {
+ service.onStart();
+ // The current active user might have switched before the wifi services started
+ // up. So, send a onSwitchUser callback just after onStart callback is invoked.
+ if (currentUser != UserHandle.USER_SYSTEM) {
+ service.onSwitchUser(currentUser);
+ }
+ }
+ }
+ }));
+
+ // Register broadcast receiver for system events.
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+ intentFilter.addAction(Intent.ACTION_USER_STOPPED);
+ intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
+ registerReceiver(new WifiBroadcastReceiver(), intentFilter);
+
+ // Create notification channels.
+ createNotificationChannels();
+
+ return true;
+ }
+
+ /**
+ * Create a binder connector for the system server to communicate with the network stack.
+ *
+ * <p>On platforms where the network stack runs in the system server process, this method may
+ * be called directly instead of obtaining the connector by binding to the service.
+ */
+ private synchronized IBinder makeConnectorAndInitializeServices(Context context) {
+ if (sConnector == null) {
+ if (!initializeServices(context)) {
+ Log.w(TAG, "Failed to initialize services");
+ return null;
+ }
+ sConnector = new WifiStackConnector(context);
+ }
+ return sConnector;
+ }
+
+ @NonNull
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.i(TAG, "WifiStack Service onBind");
+ return makeConnectorAndInitializeServices(this);
+ }
+}
diff --git a/service/java/com/android/server/wifi/WifiThreadRunner.java b/service/java/com/android/server/wifi/WifiThreadRunner.java
new file mode 100644
index 0000000000..3a0fd048ee
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiThreadRunner.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.server.wifi.util.GeneralUtil.Mutable;
+
+import java.util.function.Supplier;
+
+import javax.annotation.concurrent.ThreadSafe;
+
+/**
+ * Runs code on the main Wifi thread from another thread, in order to prevent race conditions.
+ */
+@ThreadSafe
+public class WifiThreadRunner {
+ private static final String TAG = "WifiThreadRunner";
+
+ /** Max wait time for posting blocking runnables */
+ private static final int RUN_WITH_SCISSORS_TIMEOUT_MILLIS = 4000;
+
+ private final Handler mHandler;
+
+ public WifiThreadRunner(Handler handler) {
+ mHandler = handler;
+ }
+
+ /**
+ * Synchronously runs code on the main Wifi thread and return a value.
+ * <b>Blocks</b> the calling thread until the callable completes execution on the main Wifi
+ * thread.
+ *
+ * BEWARE OF DEADLOCKS!!!
+ *
+ * @param <T> the return type
+ * @param supplier the lambda that should be run on the main Wifi thread
+ * e.g. wifiThreadRunner.call(() -> mWifiApConfigStore.getApConfiguration())
+ * or wifiThreadRunner.call(mWifiApConfigStore::getApConfiguration)
+ * @param valueToReturnOnTimeout If the lambda provided could not be run within the timeout (
+ * {@link #RUN_WITH_SCISSORS_TIMEOUT_MILLIS}), will return this provided value
+ * instead.
+ * @return value retrieved from Wifi thread, or |valueToReturnOnTimeout| if the call failed.
+ * Beware of NullPointerExceptions when expecting a primitive (e.g. int, long) return
+ * type, it may still return null and throw a NullPointerException when auto-unboxing!
+ * Recommend capturing the return value in an Integer or Long instead and explicitly
+ * handling nulls.
+ */
+ @Nullable
+ public <T> T call(@NonNull Supplier<T> supplier, T valueToReturnOnTimeout) {
+ Mutable<T> result = new Mutable<>();
+ boolean runWithScissorsSuccess = runWithScissors(mHandler,
+ () -> result.value = supplier.get(),
+ RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
+ if (runWithScissorsSuccess) {
+ return result.value;
+ } else {
+ Log.e(TAG, "WifiThreadRunner.call() timed out!", new Throwable("Stack trace:"));
+ return valueToReturnOnTimeout;
+ }
+ }
+
+ /**
+ * Runs a Runnable on the main Wifi thread and <b>blocks</b> the calling thread until the
+ * Runnable completes execution on the main Wifi thread.
+ *
+ * BEWARE OF DEADLOCKS!!!
+ *
+ * @return true if the runnable executed successfully, false otherwise
+ */
+ public boolean run(@NonNull Runnable runnable) {
+ boolean runWithScissorsSuccess =
+ runWithScissors(mHandler, runnable, RUN_WITH_SCISSORS_TIMEOUT_MILLIS);
+ if (runWithScissorsSuccess) {
+ return true;
+ } else {
+ Log.e(TAG, "WifiThreadRunner.run() timed out!", new Throwable("Stack trace:"));
+ return false;
+ }
+ }
+
+ /**
+ * Asynchronously runs a Runnable on the main Wifi thread.
+ *
+ * @return true if the runnable was successfully posted <b>(not executed)</b> to the main Wifi
+ * thread, false otherwise
+ */
+ public boolean post(@NonNull Runnable runnable) {
+ return mHandler.post(runnable);
+ }
+
+ // Note: @hide methods copied from android.os.Handler
+ /**
+ * Runs the specified task synchronously.
+ * <p>
+ * If the current thread is the same as the handler thread, then the runnable
+ * runs immediately without being enqueued. Otherwise, posts the runnable
+ * to the handler and waits for it to complete before returning.
+ * </p><p>
+ * This method is dangerous! Improper use can result in deadlocks.
+ * Never call this method while any locks are held or use it in a
+ * possibly re-entrant manner.
+ * </p><p>
+ * This method is occasionally useful in situations where a background thread
+ * must synchronously await completion of a task that must run on the
+ * handler's thread. However, this problem is often a symptom of bad design.
+ * Consider improving the design (if possible) before resorting to this method.
+ * </p><p>
+ * One example of where you might want to use this method is when you just
+ * set up a Handler thread and need to perform some initialization steps on
+ * it before continuing execution.
+ * </p><p>
+ * If timeout occurs then this method returns <code>false</code> but the runnable
+ * will remain posted on the handler and may already be in progress or
+ * complete at a later time.
+ * </p><p>
+ * When using this method, be sure to use {@link Looper#quitSafely} when
+ * quitting the looper. Otherwise {@link #runWithScissors} may hang indefinitely.
+ * (TODO: We should fix this by making MessageQueue aware of blocking runnables.)
+ * </p>
+ *
+ * @param r The Runnable that will be executed synchronously.
+ * @param timeout The timeout in milliseconds, or 0 to wait indefinitely.
+ *
+ * @return Returns true if the Runnable was successfully executed.
+ * Returns false on failure, usually because the
+ * looper processing the message queue is exiting.
+ *
+ * @hide This method is prone to abuse and should probably not be in the API.
+ * If we ever do make it part of the API, we might want to rename it to something
+ * less funny like runUnsafe().
+ */
+ private static boolean runWithScissors(@NonNull Handler handler, @NonNull Runnable r,
+ long timeout) {
+ if (r == null) {
+ throw new IllegalArgumentException("runnable must not be null");
+ }
+ if (timeout < 0) {
+ throw new IllegalArgumentException("timeout must be non-negative");
+ }
+
+ if (Looper.myLooper() == handler.getLooper()) {
+ r.run();
+ return true;
+ }
+
+ BlockingRunnable br = new BlockingRunnable(r);
+ return br.postAndWait(handler, timeout);
+ }
+
+ private static final class BlockingRunnable implements Runnable {
+ private final Runnable mTask;
+ private boolean mDone;
+
+ BlockingRunnable(Runnable task) {
+ mTask = task;
+ }
+
+ @Override
+ public void run() {
+ try {
+ mTask.run();
+ } finally {
+ synchronized (this) {
+ mDone = true;
+ notifyAll();
+ }
+ }
+ }
+
+ public boolean postAndWait(Handler handler, long timeout) {
+ if (!handler.post(this)) {
+ return false;
+ }
+
+ synchronized (this) {
+ if (timeout > 0) {
+ final long expirationTime = SystemClock.uptimeMillis() + timeout;
+ while (!mDone) {
+ long delay = expirationTime - SystemClock.uptimeMillis();
+ if (delay <= 0) {
+ return false; // timeout
+ }
+ try {
+ wait(delay);
+ } catch (InterruptedException ex) {
+ }
+ }
+ } else {
+ while (!mDone) {
+ try {
+ wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ }
+ }
+ return true;
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/WifiTrafficPoller.java b/service/java/com/android/server/wifi/WifiTrafficPoller.java
index 90bdb13113..4491449e28 100644
--- a/service/java/com/android/server/wifi/WifiTrafficPoller.java
+++ b/service/java/com/android/server/wifi/WifiTrafficPoller.java
@@ -21,7 +21,6 @@ import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
@@ -44,9 +43,8 @@ public class WifiTrafficPoller {
private final ExternalCallbackTracker<ITrafficStateCallback> mRegisteredCallbacks;
- WifiTrafficPoller(@NonNull Looper looper) {
- mRegisteredCallbacks = new ExternalCallbackTracker<ITrafficStateCallback>(
- new Handler(looper));
+ WifiTrafficPoller(@NonNull Handler handler) {
+ mRegisteredCallbacks = new ExternalCallbackTracker<>(handler);
}
/**
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index 464a34007b..a1d98061b3 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -53,7 +53,6 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.os.Handler;
-import android.os.Looper;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
@@ -248,14 +247,11 @@ public class WifiVendorHal {
// Being final fields, they can be accessed without synchronization under
// some reasonable assumptions. See
// https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5
- private final Looper mLooper;
private final Handler mHalEventHandler;
- public WifiVendorHal(HalDeviceManager halDeviceManager,
- Looper looper) {
+ public WifiVendorHal(HalDeviceManager halDeviceManager, Handler handler) {
mHalDeviceManager = halDeviceManager;
- mLooper = looper;
- mHalEventHandler = new Handler(looper);
+ mHalEventHandler = handler;
mHalDeviceManagerStatusCallbacks = new HalDeviceManagerStatusListener();
mIWifiStaIfaceEventCallback = new StaIfaceEventCallback();
mIWifiChipEventCallback = new ChipEventCallback();
@@ -1295,17 +1291,23 @@ public class WifiVendorHal {
byte[] macByteArray = mac.toByteArray();
synchronized (sLock) {
try {
- android.hardware.wifi.V1_2.IWifiStaIface ifaceV12 =
+ android.hardware.wifi.V1_2.IWifiStaIface sta12 =
getWifiStaIfaceForV1_2Mockable(ifaceName);
- if (ifaceV12 == null) return boolResult(false);
- WifiStatus status = ifaceV12.setMacAddress(macByteArray);
- if (!ok(status)) return false;
- return true;
+ if (sta12 != null) {
+ return ok(sta12.setMacAddress(macByteArray));
+ }
+
+ android.hardware.wifi.V1_4.IWifiApIface ap14 =
+ getWifiApIfaceForV1_4Mockable(ifaceName);
+ if (ap14 != null) {
+ return ok(ap14.setMacAddress(macByteArray));
+ }
} catch (RemoteException e) {
handleRemoteException(e);
return false;
}
}
+ return boolResult(false);
}
/**
@@ -1320,20 +1322,33 @@ public class WifiVendorHal {
}
synchronized (sLock) {
try {
- android.hardware.wifi.V1_3.IWifiStaIface ifaceV13 =
- getWifiStaIfaceForV1_3Mockable(ifaceName);
- if (ifaceV13 == null) return null;
AnswerBox box = new AnswerBox();
- ifaceV13.getFactoryMacAddress((status, macBytes) -> {
- if (!ok(status)) return;
- box.mac = MacAddress.fromBytes(macBytes);
- });
- return box.mac;
+
+ android.hardware.wifi.V1_3.IWifiStaIface sta13 =
+ getWifiStaIfaceForV1_3Mockable(ifaceName);
+ if (sta13 != null) {
+ sta13.getFactoryMacAddress((status, macBytes) -> {
+ if (!ok(status)) return;
+ box.mac = MacAddress.fromBytes(macBytes);
+ });
+ return box.mac;
+ }
+
+ android.hardware.wifi.V1_4.IWifiApIface ap14 =
+ getWifiApIfaceForV1_4Mockable(ifaceName);
+ if (ap14 != null) {
+ ap14.getFactoryMacAddress((status, macBytes) -> {
+ if (!ok(status)) return;
+ box.mac = MacAddress.fromBytes(macBytes);
+ });
+ return box.mac;
+ }
} catch (RemoteException e) {
handleRemoteException(e);
return null;
}
}
+ return null;
}
/**
@@ -2311,6 +2326,13 @@ public class WifiVendorHal {
return android.hardware.wifi.V1_3.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);
+ }
+
/**
* sarPowerBackoffRequired_1_1()
* This method checks if we need to backoff wifi Tx power due to SAR requirements.
diff --git a/service/java/com/android/server/wifi/WificondControl.java b/service/java/com/android/server/wifi/WificondControl.java
index bd756f6439..0fc151bb85 100644
--- a/service/java/com/android/server/wifi/WificondControl.java
+++ b/service/java/com/android/server/wifi/WificondControl.java
@@ -20,21 +20,12 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
import android.annotation.NonNull;
import android.app.AlarmManager;
-import android.net.wifi.IApInterface;
-import android.net.wifi.IApInterfaceEventCallback;
-import android.net.wifi.IClientInterface;
-import android.net.wifi.IPnoScanEvent;
-import android.net.wifi.IScanEvent;
-import android.net.wifi.ISendMgmtFrameEvent;
-import android.net.wifi.IWifiScannerImpl;
-import android.net.wifi.IWificond;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
@@ -46,18 +37,30 @@ import com.android.server.wifi.util.NativeUtil;
import com.android.server.wifi.util.ScanResultUtil;
import com.android.server.wifi.wificond.ChannelSettings;
import com.android.server.wifi.wificond.HiddenNetwork;
+import com.android.server.wifi.wificond.IApInterface;
+import com.android.server.wifi.wificond.IApInterfaceEventCallback;
+import com.android.server.wifi.wificond.IClientInterface;
+import com.android.server.wifi.wificond.IPnoScanEvent;
+import com.android.server.wifi.wificond.IScanEvent;
+import com.android.server.wifi.wificond.ISendMgmtFrameEvent;
+import com.android.server.wifi.wificond.IWifiScannerImpl;
+import com.android.server.wifi.wificond.IWificond;
import com.android.server.wifi.wificond.NativeScanResult;
+import com.android.server.wifi.wificond.NativeWifiClient;
import com.android.server.wifi.wificond.PnoNetwork;
import com.android.server.wifi.wificond.PnoSettings;
import com.android.server.wifi.wificond.RadioChainInfo;
import com.android.server.wifi.wificond.SingleScanSettings;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Stream;
/**
* This class provides methods for WifiNative to send control commands to wificond.
@@ -129,13 +132,13 @@ public class WificondControl implements IBinder.DeathRecipient {
}
WificondControl(WifiInjector wifiInjector, WifiMonitor wifiMonitor,
- CarrierNetworkConfig carrierNetworkConfig, AlarmManager alarmManager, Looper looper,
+ CarrierNetworkConfig carrierNetworkConfig, AlarmManager alarmManager, Handler handler,
Clock clock) {
mWifiInjector = wifiInjector;
mWifiMonitor = wifiMonitor;
mCarrierNetworkConfig = carrierNetworkConfig;
mAlarmManager = alarmManager;
- mEventHandler = new Handler(looper);
+ mEventHandler = handler;
mClock = clock;
}
@@ -158,18 +161,6 @@ public class WificondControl implements IBinder.DeathRecipient {
Log.d(TAG, "Pno Scan failed event");
mWifiInjector.getWifiMetrics().incrementPnoScanFailedCount();
}
-
- @Override
- public void OnPnoScanOverOffloadStarted() {
- Log.d(TAG, "Pno scan over offload started");
- mWifiInjector.getWifiMetrics().incrementPnoScanStartedOverOffloadCount();
- }
-
- @Override
- public void OnPnoScanOverOffloadFailed(int reason) {
- Log.d(TAG, "Pno scan over offload failed");
- mWifiInjector.getWifiMetrics().incrementPnoScanFailedOverOffloadCount();
- }
}
/**
@@ -183,8 +174,15 @@ public class WificondControl implements IBinder.DeathRecipient {
}
@Override
- public void onNumAssociatedStationsChanged(int numStations) {
- mSoftApListener.onNumAssociatedStationsChanged(numStations);
+ public void onConnectedClientsChanged(NativeWifiClient[] clients) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "onConnectedClientsChanged called with " + clients.length + " clients");
+ for (int i = 0; i < clients.length; i++) {
+ Log.d(TAG, " mac " + clients[i].macAddress);
+ }
+ }
+
+ mSoftApListener.onConnectedClientsChanged(Arrays.asList(clients));
}
@Override
@@ -385,6 +383,11 @@ public class WificondControl implements IBinder.DeathRecipient {
return false;
}
+ if (mWificond == null) {
+ Log.e(TAG, "Reference to wifiCond is null");
+ return false;
+ }
+
boolean success;
try {
success = mWificond.tearDownClientInterface(ifaceName);
@@ -444,6 +447,12 @@ public class WificondControl implements IBinder.DeathRecipient {
Log.e(TAG, "No valid wificond ap interface handler");
return false;
}
+
+ if (mWificond == null) {
+ Log.e(TAG, "Reference to wifiCond is null");
+ return false;
+ }
+
boolean success;
try {
success = mWificond.tearDownApInterface(ifaceName);
@@ -559,6 +568,18 @@ public class WificondControl implements IBinder.DeathRecipient {
return mWificondScanners.get(ifaceName);
}
+ private static final int CAPABILITY_SIZE = 16;
+
+ private static BitSet capabilityIntToBitset(int capabilityInt) {
+ BitSet capabilityBitSet = new BitSet(CAPABILITY_SIZE);
+ for (int i = 0; i < CAPABILITY_SIZE; i++) {
+ if ((capabilityInt & (1 << i)) != 0) {
+ capabilityBitSet.set(i);
+ }
+ }
+ return capabilityBitSet;
+ }
+
/**
* Fetch the latest scan result from kernel via wificond.
* @param ifaceName Name of the interface.
@@ -596,7 +617,8 @@ public class WificondControl implements IBinder.DeathRecipient {
InformationElementUtil.parseInformationElements(result.infoElement);
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(ies, result.capability, isEnhancedOpenSupported());
+ capabilities.from(ies, capabilityIntToBitset(result.capability),
+ isEnhancedOpenSupported());
String flags = capabilities.generateCapabilitiesString();
NetworkDetail networkDetail;
try {
@@ -607,7 +629,8 @@ public class WificondControl implements IBinder.DeathRecipient {
}
ScanDetail scanDetail = new ScanDetail(networkDetail, wifiSsid, bssid, flags,
- result.signalMbm / 100, result.frequency, result.tsf, ies, null);
+ result.signalMbm / 100, result.frequency, result.tsf, ies, null,
+ result.infoElement);
ScanResult scanResult = scanDetail.getScanResult();
// Update carrier network info if this AP's SSID is associated with a carrier Wi-Fi
// network and it uses EAP.
@@ -622,7 +645,7 @@ public class WificondControl implements IBinder.DeathRecipient {
// Fill up the radio chain info.
if (result.radioChainInfos != null) {
scanResult.radioChainInfos =
- new ScanResult.RadioChainInfo[result.radioChainInfos.size()];
+ new ScanResult.RadioChainInfo[result.radioChainInfos.length];
int idx = 0;
for (RadioChainInfo nativeRadioChainInfo : result.radioChainInfos) {
scanResult.radioChainInfos[idx] = new ScanResult.RadioChainInfo();
@@ -660,6 +683,33 @@ public class WificondControl implements IBinder.DeathRecipient {
}
/**
+ * HiddenNetwork is an AIDL generated classes, create a wrapper around it to implement a custom
+ * equals() method.
+ */
+ private static final class HiddenNetworkWrapper {
+ HiddenNetwork mHiddenNetwork;
+
+ HiddenNetworkWrapper(HiddenNetwork hiddenNetwork) {
+ mHiddenNetwork = hiddenNetwork;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof HiddenNetworkWrapper) {
+ HiddenNetworkWrapper that = (HiddenNetworkWrapper) o;
+ return Arrays.equals(this.mHiddenNetwork.ssid, that.mHiddenNetwork.ssid);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(mHiddenNetwork.ssid);
+ }
+ }
+
+ /**
* Start a scan using wificond for the given parameters.
* @param ifaceName Name of the interface.
* @param scanType Type of scan to perform.
@@ -683,31 +733,39 @@ public class WificondControl implements IBinder.DeathRecipient {
Log.e(TAG, "Invalid scan type ", e);
return false;
}
- settings.channelSettings = new ArrayList<>();
- settings.hiddenNetworks = new ArrayList<>();
- if (freqs != null) {
- for (Integer freq : freqs) {
- ChannelSettings channel = new ChannelSettings();
- channel.frequency = freq;
- settings.channelSettings.add(channel);
- }
- }
- if (hiddenNetworkSSIDs != null) {
- for (String ssid : hiddenNetworkSSIDs) {
- HiddenNetwork network = new HiddenNetwork();
- try {
- network.ssid = NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(ssid));
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Illegal argument " + ssid, e);
- continue;
- }
- // settings.hiddenNetworks is expected to be very small, so this shouldn't cause
- // any performance issues.
- if (!settings.hiddenNetworks.contains(network)) {
- settings.hiddenNetworks.add(network);
- }
- }
+ if (freqs == null) {
+ settings.channelSettings = new ChannelSettings[0];
+ } else {
+ settings.channelSettings = freqs.stream()
+ .map(freq -> {
+ ChannelSettings channel = new ChannelSettings();
+ channel.frequency = freq;
+ return channel;
+ })
+ .toArray(ChannelSettings[]::new);
+ }
+
+ if (hiddenNetworkSSIDs == null) {
+ settings.hiddenNetworks = new HiddenNetwork[0];
+ } else {
+ settings.hiddenNetworks = hiddenNetworkSSIDs.stream()
+ .flatMap(ssid -> {
+ HiddenNetwork network = new HiddenNetwork();
+ try {
+ network.ssid = NativeUtil.byteArrayFromArrayList(
+ NativeUtil.decodeSsid(ssid));
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Illegal argument " + ssid, e);
+ return Stream.empty();
+ }
+ // wrap so that we can use custom equals() method
+ HiddenNetworkWrapper wrapper = new HiddenNetworkWrapper(network);
+ return Stream.of(wrapper);
+ })
+ .distinct() // use custom equals() method to dedupe
+ .map(wrapper -> wrapper.mHiddenNetwork) // unwrap
+ .toArray(HiddenNetwork[]::new);
}
try {
@@ -731,25 +789,28 @@ public class WificondControl implements IBinder.DeathRecipient {
return false;
}
PnoSettings settings = new PnoSettings();
- settings.pnoNetworks = new ArrayList<>();
settings.intervalMs = pnoSettings.periodInMs;
settings.min2gRssi = pnoSettings.min24GHzRssi;
settings.min5gRssi = pnoSettings.min5GHzRssi;
- if (pnoSettings.networkList != null) {
- for (WifiNative.PnoNetwork network : pnoSettings.networkList) {
- PnoNetwork condNetwork = new PnoNetwork();
- condNetwork.isHidden = (network.flags
- & WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN) != 0;
- try {
- condNetwork.ssid =
- NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(network.ssid));
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Illegal argument " + network.ssid, e);
- continue;
- }
- condNetwork.frequencies = network.frequencies;
- settings.pnoNetworks.add(condNetwork);
- }
+ if (pnoSettings.networkList == null) {
+ settings.pnoNetworks = new PnoNetwork[0];
+ } else {
+ settings.pnoNetworks = Arrays.stream(pnoSettings.networkList)
+ .flatMap(network -> {
+ PnoNetwork condNetwork = new PnoNetwork();
+ condNetwork.isHidden = (network.flags
+ & WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN) != 0;
+ try {
+ condNetwork.ssid = NativeUtil.byteArrayFromArrayList(
+ NativeUtil.decodeSsid(network.ssid));
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Illegal argument " + network.ssid, e);
+ return Stream.empty();
+ }
+ condNetwork.frequencies = network.frequencies;
+ return Stream.of(condNetwork);
+ })
+ .toArray(PnoNetwork[]::new);
}
try {
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
index 5832ee8981..5267c4c175 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
@@ -16,6 +16,8 @@
package com.android.server.wifi.aware;
+import static android.net.RouteInfo.RTN_UNICAST;
+
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -1532,7 +1534,8 @@ public class WifiAwareDataPathStateManager {
linkProperties.setInterfaceName(nnri.interfaceName);
linkProperties.addLinkAddress(new LinkAddress(linkLocal, 64));
linkProperties.addRoute(
- new RouteInfo(new IpPrefix("fe80::/64"), null, nnri.interfaceName));
+ new RouteInfo(new IpPrefix("fe80::/64"), null, nnri.interfaceName,
+ RTN_UNICAST));
return true;
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java b/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java
index 2f072c06f0..b47f0a3091 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareMetrics.java
@@ -234,7 +234,7 @@ public class WifiAwareMetrics {
*/
public void recordAttachStatus(int status) {
synchronized (mLock) {
- mAttachStatusData.put(status, mAttachStatusData.get(status) + 1);
+ addNanHalStatusToHistogram(status, mAttachStatusData);
}
}
@@ -354,9 +354,9 @@ public class WifiAwareMetrics {
public void recordDiscoveryStatus(int uid, int status, boolean isPublish) {
synchronized (mLock) {
if (isPublish) {
- mPublishStatusData.put(status, mPublishStatusData.get(status) + 1);
+ addNanHalStatusToHistogram(status, mPublishStatusData);
} else {
- mSubscribeStatusData.put(status, mSubscribeStatusData.get(status) + 1);
+ addNanHalStatusToHistogram(status, mSubscribeStatusData);
}
if (status == NanStatusType.NO_RESOURCES_AVAILABLE) {
@@ -463,9 +463,9 @@ public class WifiAwareMetrics {
public void recordNdpStatus(int status, boolean isOutOfBand, long startTimestamp) {
synchronized (mLock) {
if (isOutOfBand) {
- mOutOfBandNdpStatusData.put(status, mOutOfBandNdpStatusData.get(status) + 1);
+ addNanHalStatusToHistogram(status, mOutOfBandNdpStatusData);
} else {
- mInBandNdpStatusData.put(status, mOutOfBandNdpStatusData.get(status) + 1);
+ addNanHalStatusToHistogram(status, mInBandNdpStatusData);
}
if (status == NanStatusType.SUCCESS) {
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
index 366af13f35..7cb6e84c87 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
@@ -26,13 +26,16 @@ 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.IWifiNanIfaceEventCallback;
+import android.hardware.wifi.V1_2.NanDataPathChannelInfo;
import android.hardware.wifi.V1_2.NanDataPathScheduleUpdateInd;
import android.os.ShellCommand;
import android.util.Log;
+import android.util.SparseArray;
import android.util.SparseIntArray;
import libcore.util.HexEncoding;
+import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -75,13 +78,14 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
private static final int CB_EV_DATA_PATH_SCHED_UPDATE = 11;
private SparseIntArray mCallbackCounter = new SparseIntArray();
+ private SparseArray<ArrayList<NanDataPathChannelInfo>> mChannelInfoPerNdp = new SparseArray<>();
private void incrementCbCount(int callbackId) {
mCallbackCounter.put(callbackId, mCallbackCounter.get(callbackId) + 1);
}
/**
- * Interpreter of adb shell command 'adb shell wifiaware native_cb ...'.
+ * Interpreter of adb shell command 'adb shell cmd wifiaware native_cb ...'.
*
* @return -1 if parameter not recognized or invalid value, 0 otherwise.
*/
@@ -121,6 +125,17 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
}
return 0;
}
+ case "get_channel_info": {
+ String option = parentShell.getNextOption();
+ if (VDBG) Log.v(TAG, "option='" + option + "'");
+ if (option != null) {
+ pwe.println("Unknown option to 'get_channel_info'");
+ return -1;
+ }
+ String channelInfoString = convertChannelInfoToJsonString();
+ pwo.println(channelInfoString);
+ return 0;
+ }
default:
pwe.println("Unknown 'wifiaware native_cb <cmd>'");
}
@@ -140,6 +155,7 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
pw.println(" " + command);
pw.println(" get_cb_count [--reset]: gets the number of callbacks (and optionally reset "
+ "count)");
+ pw.println(" get_channel_info: prints out existing NDP channel info as a JSON String");
}
@Override
@@ -502,13 +518,15 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
+ ", 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());
+ + ", 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;
}
incrementCbCount(CB_EV_DATA_PATH_CONFIRM);
+ mChannelInfoPerNdp.put(event.V1_0.ndpInstanceId, event.channelInfo);
mWifiAwareStateManager.onDataPathConfirmNotification(event.V1_0.ndpInstanceId,
event.V1_0.peerNdiMacAddr, event.V1_0.dataPathSetupSuccess,
@@ -526,6 +544,9 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
return;
}
incrementCbCount(CB_EV_DATA_PATH_SCHED_UPDATE);
+ for (int ndpInstanceId : event.ndpInstanceIds) {
+ mChannelInfoPerNdp.put(ndpInstanceId, event.channelInfo);
+ }
mWifiAwareStateManager.onDataPathScheduleUpdateNotification(event.peerDiscoveryAddress,
event.ndpInstanceIds, event.channelInfo);
@@ -535,16 +556,25 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
public void eventDataPathTerminated(int ndpInstanceId) {
if (mDbg) Log.v(TAG, "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId);
incrementCbCount(CB_EV_DATA_PATH_TERMINATED);
+ mChannelInfoPerNdp.remove(ndpInstanceId);
mWifiAwareStateManager.onDataPathEndNotification(ndpInstanceId);
}
/**
+ * Reset the channel info when Aware is down.
+ */
+ /* package */ void resetChannelInfo() {
+ mChannelInfoPerNdp.clear();
+ }
+
+ /**
* Dump the internal state of the class.
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("WifiAwareNativeCallback:");
pw.println(" mCallbackCounter: " + mCallbackCounter);
+ pw.println(" mChannelInfoPerNdp: " + mChannelInfoPerNdp);
}
@@ -577,4 +607,30 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
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}]}"
+ * @return Json String.
+ */
+ private String convertChannelInfoToJsonString() {
+ JSONObject channelInfoJson = new JSONObject();
+ try {
+ for (int i = 0; i < mChannelInfoPerNdp.size(); i++) {
+ JSONArray infoJsonArray = new JSONArray();
+ for (NanDataPathChannelInfo info : mChannelInfoPerNdp.valueAt(i)) {
+ JSONObject j = new JSONObject();
+ j.put("channelFreq", info.channelFreq);
+ j.put("channelBandwidth", info.channelBandwidth);
+ j.put("numSpatialStreams", info.numSpatialStreams);
+ infoJsonArray.put(j);
+ }
+ channelInfoJson.put(Integer.toString(mChannelInfoPerNdp.keyAt(i)), infoJsonArray);
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, "onCommand: get_channel_info e=" + e);
+ }
+ return channelInfoJson.toString();
+ }
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
index 6556bb084b..e3361bfc0a 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
@@ -51,6 +51,7 @@ public class WifiAwareNativeManager {
private InterfaceAvailableForRequestListener mInterfaceAvailableForRequestListener =
new InterfaceAvailableForRequestListener();
private int mReferenceCount = 0;
+ private volatile boolean mAwareNativeAvailable = false;
WifiAwareNativeManager(WifiAwareStateManager awareStateManager,
HalDeviceManager halDeviceManager,
@@ -101,6 +102,13 @@ public class WifiAwareNativeManager {
}
/**
+ * Return the Availability of WifiAware native HAL
+ */
+ public boolean isAwareNativeAvailable() {
+ return mAwareNativeAvailable;
+ }
+
+ /**
* Returns the native HAL WifiNanIface through which commands to the NAN HAL are dispatched.
* Return may be null if not initialized/available.
*/
@@ -194,6 +202,7 @@ public class WifiAwareNativeManager {
mInterfaceDestroyedListener = null;
mHalDeviceManager.removeIface(mWifiNanIface);
mWifiNanIface = null;
+ mWifiAwareNativeCallback.resetChannelInfo();
}
}
@@ -205,6 +214,7 @@ public class WifiAwareNativeManager {
}
mWifiNanIface = null;
mReferenceCount = 0;
+ mAwareNativeAvailable = false;
mWifiAwareStateManager.disableUsage();
}
}
@@ -235,8 +245,10 @@ public class WifiAwareNativeManager {
}
synchronized (mLock) {
if (isAvailable) {
+ mAwareNativeAvailable = true;
mWifiAwareStateManager.enableUsage();
} else if (mWifiNanIface == null) { // not available could mean already have NAN
+ mAwareNativeAvailable = false;
mWifiAwareStateManager.disableUsage();
}
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareService.java b/service/java/com/android/server/wifi/aware/WifiAwareService.java
index f38c373163..e4b1e443c0 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareService.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareService.java
@@ -17,64 +17,63 @@
package com.android.server.wifi.aware;
import android.content.Context;
+import android.os.Binder;
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.WifiServiceBase;
/**
* Service implementing Wi-Fi Aware functionality. Delegates actual interface
* implementation to WifiAwareServiceImpl.
*/
-public final class WifiAwareService extends SystemService {
+public final class WifiAwareService implements WifiServiceBase {
private static final String TAG = "WifiAwareService";
final WifiAwareServiceImpl mImpl;
public WifiAwareService(Context context) {
- super(context);
mImpl = new WifiAwareServiceImpl(context);
}
@Override
public void onStart() {
- Log.i(TAG, "Registering " + Context.WIFI_AWARE_SERVICE);
- publishBinderService(Context.WIFI_AWARE_SERVICE, mImpl);
- }
+ Log.i(TAG, "Starting " + Context.WIFI_AWARE_SERVICE);
+ WifiInjector wifiInjector = WifiInjector.getInstance();
+ if (wifiInjector == null) {
+ Log.e(TAG, "NULL injector!");
+ return;
+ }
- @Override
- public void onBootPhase(int phase) {
- if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
- WifiInjector wifiInjector = WifiInjector.getInstance();
- if (wifiInjector == null) {
- Log.e(TAG, "onBootPhase(PHASE_SYSTEM_SERVICES_READY): NULL injector!");
- return;
- }
+ HalDeviceManager halDeviceManager = wifiInjector.getHalDeviceManager();
- HalDeviceManager halDeviceManager = wifiInjector.getHalDeviceManager();
+ WifiAwareStateManager wifiAwareStateManager = new WifiAwareStateManager();
+ WifiAwareNativeCallback wifiAwareNativeCallback = new WifiAwareNativeCallback(
+ wifiAwareStateManager);
+ WifiAwareNativeManager wifiAwareNativeManager = new WifiAwareNativeManager(
+ wifiAwareStateManager, halDeviceManager, wifiAwareNativeCallback);
+ WifiAwareNativeApi wifiAwareNativeApi = new WifiAwareNativeApi(wifiAwareNativeManager);
+ wifiAwareStateManager.setNative(wifiAwareNativeManager, wifiAwareNativeApi);
+ WifiAwareShellCommand wifiAwareShellCommand = new WifiAwareShellCommand();
+ wifiAwareShellCommand.register("native_api", wifiAwareNativeApi);
+ wifiAwareShellCommand.register("native_cb", wifiAwareNativeCallback);
+ wifiAwareShellCommand.register("state_mgr", wifiAwareStateManager);
- WifiAwareStateManager wifiAwareStateManager = new WifiAwareStateManager();
- WifiAwareNativeCallback wifiAwareNativeCallback = new WifiAwareNativeCallback(
- wifiAwareStateManager);
- WifiAwareNativeManager wifiAwareNativeManager = new WifiAwareNativeManager(
- wifiAwareStateManager, halDeviceManager, wifiAwareNativeCallback);
- WifiAwareNativeApi wifiAwareNativeApi = new WifiAwareNativeApi(wifiAwareNativeManager);
- wifiAwareStateManager.setNative(wifiAwareNativeManager, wifiAwareNativeApi);
- WifiAwareShellCommand wifiAwareShellCommand = new WifiAwareShellCommand();
- wifiAwareShellCommand.register("native_api", wifiAwareNativeApi);
- wifiAwareShellCommand.register("native_cb", wifiAwareNativeCallback);
- wifiAwareShellCommand.register("state_mgr", wifiAwareStateManager);
+ HandlerThread awareHandlerThread = wifiInjector.getWifiAwareHandlerThread();
+ mImpl.start(awareHandlerThread, wifiAwareStateManager, wifiAwareShellCommand,
+ wifiInjector.getWifiMetrics().getWifiAwareMetrics(),
+ wifiInjector.getWifiPermissionsUtil(),
+ wifiInjector.getWifiPermissionsWrapper(), wifiInjector.getFrameworkFacade(),
+ wifiAwareNativeManager, wifiAwareNativeApi, wifiAwareNativeCallback);
- HandlerThread awareHandlerThread = wifiInjector.getWifiAwareHandlerThread();
- mImpl.start(awareHandlerThread, wifiAwareStateManager, wifiAwareShellCommand,
- wifiInjector.getWifiMetrics().getWifiAwareMetrics(),
- wifiInjector.getWifiPermissionsUtil(),
- wifiInjector.getWifiPermissionsWrapper(), wifiInjector.getFrameworkFacade(),
- wifiAwareNativeManager, wifiAwareNativeApi, wifiAwareNativeCallback);
- } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
- mImpl.startLate();
- }
+ // TODO: This 2 step initialization is no longer necessary because of service ordering in
+ // WifiStackService.
+ mImpl.startLate();
}
-}
+ @Override
+ public Binder retrieveImpl() {
+ return mImpl;
+ }
+}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
index e6e961d690..a0f937d33b 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java
@@ -418,7 +418,7 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub {
+ ", retryCount=" + retryCount);
}
- mStateManager.sendMessage(clientId, sessionId, peerId, message, messageId, retryCount);
+ mStateManager.sendMessage(uid, clientId, sessionId, peerId, message, messageId, retryCount);
}
@Override
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index 9b096e525a..072788081b 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -673,8 +673,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
* Place a request to send a message on a discovery session on the state
* machine queue.
*/
- public void sendMessage(int clientId, int sessionId, int peerId, byte[] message, int messageId,
- int retryCount) {
+ public void sendMessage(int uid, int clientId, int sessionId, int peerId, byte[] message,
+ int messageId, int retryCount) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_ENQUEUE_SEND_MESSAGE;
msg.arg2 = clientId;
@@ -683,6 +683,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message);
msg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID, messageId);
msg.getData().putInt(MESSAGE_BUNDLE_KEY_RETRY_COUNT, retryCount);
+ msg.getData().putInt(MESSAGE_BUNDLE_KEY_UID, uid);
mSm.sendMessage(msg);
}
@@ -704,6 +705,10 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
if (mDbg) Log.d(TAG, "enableUsage(): while Wi-Fi is disabled - ignoring");
return;
}
+ if (!mWifiAwareNativeManager.isAwareNativeAvailable()) {
+ if (mDbg) Log.d(TAG, "enableUsage(): while Aware Native isn't Available - ignoring");
+ return;
+ }
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_ENABLE_USAGE;
mSm.sendMessage(msg);
@@ -1196,6 +1201,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
private short mCurrentTransactionId = TRANSACTION_ID_IGNORE;
private static final long AWARE_SEND_MESSAGE_TIMEOUT = 10_000;
+ private static final int MESSAGE_QUEUE_DEPTH_PER_UID = 50;
private int mSendArrivalSequenceCounter = 0;
private boolean mSendQueueBlocked = false;
private final SparseArray<Message> mHostQueuedSendMessages = new SparseArray<>();
@@ -1633,6 +1639,17 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
+ msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID)
+ ", mSendArrivalSequenceCounter=" + mSendArrivalSequenceCounter);
}
+ int uid = msg.getData().getInt(MESSAGE_BUNDLE_KEY_UID);
+ if (isUidExceededMessageQueueDepthLimit(uid)) {
+ if (mDbg) {
+ Log.v(TAG, "message queue limit exceeded for uid=" + uid
+ + " at messageId="
+ + msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID));
+ }
+ onMessageSendFailLocal(msg, NanStatusType.INTERNAL_FAILURE);
+ waitForResponse = false;
+ break;
+ }
Message sendMsg = obtainMessage(msg.what);
sendMsg.copyFrom(msg);
sendMsg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ,
@@ -2103,6 +2120,24 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
transmitNextMessage();
}
+ private boolean isUidExceededMessageQueueDepthLimit(int uid) {
+ int size = mHostQueuedSendMessages.size();
+ int numOfMessages = 0;
+ if (size < MESSAGE_QUEUE_DEPTH_PER_UID) {
+ return false;
+ }
+ for (int i = 0; i < size; ++i) {
+ if (mHostQueuedSendMessages.valueAt(i).getData()
+ .getInt(MESSAGE_BUNDLE_KEY_UID) == uid) {
+ numOfMessages++;
+ if (numOfMessages >= MESSAGE_QUEUE_DEPTH_PER_UID) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
@Override
protected String getLogRecString(Message msg) {
StringBuilder sb = new StringBuilder(WifiAwareStateManager.messageToString(msg));
@@ -2542,6 +2577,10 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
if (completedCommand.arg1 == COMMAND_TYPE_CONNECT) {
+ if (mCurrentAwareConfiguration == null) { // enabled (as opposed to re-configured)
+ createAllDataPathInterfaces();
+ }
+
Bundle data = completedCommand.getData();
int clientId = completedCommand.arg2;
@@ -2580,9 +2619,6 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
return;
}
- if (mCurrentAwareConfiguration == null) { // enabled (as opposed to re-configured)
- createAllDataPathInterfaces();
- }
mCurrentAwareConfiguration = mergeConfigRequests(null);
if (mCurrentAwareConfiguration == null) {
Log.wtf(TAG, "onConfigCompletedLocal: got a null merged configuration after config!?");
diff --git a/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java b/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java
index d95ab38312..825164bacc 100644
--- a/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java
+++ b/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java
@@ -292,7 +292,7 @@ public class ANQPMatcher {
*/
private static boolean matchMccMnc(String mccMnc, IMSIParameter imsiParam,
List<String> simImsiList) {
- if (imsiParam == null || simImsiList == null) {
+ if (imsiParam == null || simImsiList == null || mccMnc == null) {
return false;
}
// Match against the IMSI parameter in the provider.
diff --git a/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java b/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java
index edee2da1a1..36ed8592e0 100644
--- a/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java
+++ b/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java
@@ -258,17 +258,28 @@ public class NetworkDetail {
mANQPElements = null;
//set up channel info
mPrimaryFreq = freq;
+ int channelWidth = ScanResult.UNSPECIFIED;
+ int centerFreq0 = 0;
+ int centerFreq1 = 0;
+
+ if (vhtOperation.isPresent()) {
+ channelWidth = vhtOperation.getChannelWidth();
+ if (channelWidth != ScanResult.UNSPECIFIED) {
+ centerFreq0 = vhtOperation.getCenterFreq0();
+ centerFreq1 = vhtOperation.getCenterFreq1();
+ }
+ }
- if (vhtOperation.isValid()) {
- // 80 or 160 MHz
- mChannelWidth = vhtOperation.getChannelWidth();
- mCenterfreq0 = vhtOperation.getCenterFreq0();
- mCenterfreq1 = vhtOperation.getCenterFreq1();
- } else {
- mChannelWidth = htOperation.getChannelWidth();
- mCenterfreq0 = htOperation.getCenterFreq0(mPrimaryFreq);
- mCenterfreq1 = 0;
+ if (channelWidth == ScanResult.UNSPECIFIED) {
+ //Either no vht, or vht shows BW is 40/20 MHz
+ if (htOperation.isPresent()) {
+ channelWidth = htOperation.getChannelWidth();
+ centerFreq0 = htOperation.getCenterFreq0(mPrimaryFreq);
+ }
}
+ mChannelWidth = channelWidth;
+ mCenterfreq0 = centerFreq0;
+ mCenterfreq1 = centerFreq1;
// If trafficIndicationMap is not valid, mDtimPeriod will be negative
if (trafficIndicationMap.isValid()) {
@@ -287,8 +298,7 @@ public class NetworkDetail {
maxRateA = supportedRates.mRates.get(supportedRates.mRates.size() - 1);
mMaxRate = maxRateA > maxRateB ? maxRateA : maxRateB;
mWifiMode = InformationElementUtil.WifiMode.determineMode(mPrimaryFreq, mMaxRate,
- vhtOperation.isValid(),
- iesFound.contains(ScanResult.InformationElement.EID_HT_OPERATION),
+ vhtOperation.isPresent(), htOperation.isPresent(),
iesFound.contains(ScanResult.InformationElement.EID_ERP));
} else {
mWifiMode = 0;
@@ -303,9 +313,8 @@ public class NetworkDetail {
+ ", WifiMode: " + InformationElementUtil.WifiMode.toString(mWifiMode)
+ ", Freq: " + mPrimaryFreq
+ ", mMaxRate: " + mMaxRate
- + ", VHT: " + String.valueOf(vhtOperation.isValid())
- + ", HT: " + String.valueOf(
- iesFound.contains(ScanResult.InformationElement.EID_HT_OPERATION))
+ + ", VHT: " + String.valueOf(vhtOperation.isPresent())
+ + ", HT: " + String.valueOf(htOperation.isPresent())
+ ", ERP: " + String.valueOf(
iesFound.contains(ScanResult.InformationElement.EID_ERP))
+ ", SupportedRates: " + supportedRates.toString()
diff --git a/service/java/com/android/server/wifi/hotspot2/OsuNetworkConnection.java b/service/java/com/android/server/wifi/hotspot2/OsuNetworkConnection.java
index 08899ae283..b3bab6432e 100644
--- a/service/java/com/android/server/wifi/hotspot2/OsuNetworkConnection.java
+++ b/service/java/com/android/server/wifi/hotspot2/OsuNetworkConnection.java
@@ -28,6 +28,7 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
@@ -192,9 +193,12 @@ public class OsuNetworkConnection {
if (TextUtils.isEmpty(nai)) {
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
} else {
- // TODO: Handle OSEN.
- Log.w(TAG, "OSEN not supported");
- return false;
+ // Setup OSEN connection with Unauthenticated user TLS and WFA Root certs
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OSEN);
+ config.allowedProtocols.set(WifiConfiguration.Protocol.OSEN);
+ config.enterpriseConfig.setDomainSuffixMatch(nai);
+ config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.UNAUTH_TLS);
+ config.enterpriseConfig.setCaPath(WfaKeyStore.DEFAULT_WFA_CERT_DIR);
}
mNetworkId = mWifiManager.addNetwork(config);
if (mNetworkId < 0) {
diff --git a/service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java b/service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java
index 92560932c2..e096b144bf 100644
--- a/service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java
+++ b/service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java
@@ -411,11 +411,25 @@ public class OsuServerConnection {
}
X509Certificate certificate = getCert(certInfo.getKey());
- if (certificate == null || !ServiceProviderVerifier.verifyCertFingerprint(
+ if (certificate == null) {
+ // In case of an invalid cert, clear all of retrieved CA certs so that
+ // PasspointProvisioner aborts current flow. getCert already logs the error.
+ trustRootCertificates.clear();
+ break;
+ }
+
+ // Verify that the certificate's fingerprint matches the one provided in the PPS-MO
+ // profile, in accordance with section 7.3.1 of the HS2.0 specification.
+ if (!ServiceProviderVerifier.verifyCertFingerprint(
certificate, certInfo.getValue())) {
- // If any failure happens, clear all of retrieved CA certs so that
+ // If fingerprint does not match, clear all of retrieved CA certs so that
// PasspointProvisioner aborts current flow.
trustRootCertificates.clear();
+ String certName = "";
+ if (certificate.getSubjectDN() != null) {
+ certName = certificate.getSubjectDN().getName();
+ }
+ Log.e(TAG, "Fingerprint does not match the certificate " + certName);
break;
}
certificates.add(certificate);
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
index 0114cfb211..f2d7388a06 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
@@ -71,6 +71,7 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData {
"RemediationCaCertificateAlias";
private static final String XML_TAG_HAS_EVER_CONNECTED = "HasEverConnected";
+ private static final String XML_TAG_IS_FROM_SUGGESTION = "IsFromSuggestion";
private final WifiKeyStore mKeyStore;
private final SIMAccessor mSimAccessor;
@@ -200,6 +201,7 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData {
XmlUtil.writeNextValue(out, XML_TAG_CLIENT_PRIVATE_KEY_ALIAS,
provider.getClientPrivateKeyAlias());
XmlUtil.writeNextValue(out, XML_TAG_HAS_EVER_CONNECTED, provider.getHasEverConnected());
+ XmlUtil.writeNextValue(out, XML_TAG_IS_FROM_SUGGESTION, provider.isFromSuggestion());
if (provider.getConfig() != null) {
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION);
PasspointXmlUtils.serializePasspointConfiguration(out, provider.getConfig());
@@ -272,6 +274,7 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData {
String remediationCaCertificateAlias = null;
String packageName = null;
boolean hasEverConnected = false;
+ boolean isFromSuggestion = false;
boolean shared = false;
PasspointConfiguration config = null;
while (XmlUtils.nextElementWithin(in, outerTagDepth)) {
@@ -309,6 +312,9 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData {
case XML_TAG_HAS_EVER_CONNECTED:
hasEverConnected = (boolean) value;
break;
+ case XML_TAG_IS_FROM_SUGGESTION:
+ isFromSuggestion = (boolean) value;
+ break;
}
} else {
if (!TextUtils.equals(in.getName(),
@@ -338,8 +344,8 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData {
throw new XmlPullParserException("Missing Passpoint configuration");
}
return new PasspointProvider(config, mKeyStore, mSimAccessor, providerId, creatorUid,
- packageName, caCertificateAliases, clientCertificateAlias, clientPrivateKeyAlias,
- remediationCaCertificateAlias, hasEverConnected, shared);
+ packageName, isFromSuggestion, caCertificateAliases, clientCertificateAlias,
+ clientPrivateKeyAlias, remediationCaCertificateAlias, hasEverConnected, shared);
}
}
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
index c468737613..af4a6c883d 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java
@@ -98,7 +98,7 @@ import java.util.stream.Collectors;
* The provider matching requires obtaining additional information from the AP (ANQP elements).
* The ANQP elements will be cached using {@link AnqpCache} to avoid unnecessary requests.
*
- * NOTE: These API's are not thread safe and should only be used from ClientModeImpl thread.
+ * NOTE: These API's are not thread safe and should only be used from the main Wifi thread.
*/
public class PasspointManager {
private static final String TAG = "PasspointManager";
@@ -364,7 +364,9 @@ public class PasspointManager {
}
/**
- * Initializes the provisioning flow with a looper
+ * Initializes the provisioning flow with a looper.
+ * This looper should be tied to a background worker thread since PasspointProvisioner has a
+ * heavy workload.
*/
public void initializeProvisioner(Looper looper) {
mPasspointProvisioner.init(looper);
@@ -390,7 +392,8 @@ public class PasspointManager {
* @param packageName Package name of the app adding/Updating {@code config}
* @return true if provider is added, false otherwise
*/
- public boolean addOrUpdateProvider(PasspointConfiguration config, int uid, String packageName) {
+ public boolean addOrUpdateProvider(PasspointConfiguration config, int uid,
+ String packageName, boolean isFromSuggestion) {
mWifiMetrics.incrementNumPasspointProviderInstallation();
if (config == null) {
Log.e(TAG, "Configuration not provided");
@@ -419,8 +422,8 @@ public class PasspointManager {
}
// Create a provider and install the necessary certificates and keys.
- PasspointProvider newProvider = mObjectFactory.makePasspointProvider(
- config, mKeyStore, mSimAccessor, mProviderIndex++, uid, packageName);
+ PasspointProvider newProvider = mObjectFactory.makePasspointProvider(config, mKeyStore,
+ mSimAccessor, mProviderIndex++, uid, packageName, isFromSuggestion);
if (!newProvider.installCertsAndKeys()) {
Log.e(TAG, "Failed to install certificates and keys to keystore");
@@ -429,13 +432,26 @@ public class PasspointManager {
// Remove existing provider with the same FQDN.
if (mProviders.containsKey(config.getHomeSp().getFqdn())) {
+ PasspointProvider old = mProviders.get(config.getHomeSp().getFqdn());
+ // If new profile is from suggestion and from a different App, ignore new profile,
+ // return true.
+ // If from same app, update it.
+ if (isFromSuggestion && !old.getPackageName().equals(packageName)) {
+ newProvider.uninstallCertsAndKeys();
+ return false;
+ }
Log.d(TAG, "Replacing configuration for " + config.getHomeSp().getFqdn());
- mProviders.get(config.getHomeSp().getFqdn()).uninstallCertsAndKeys();
+ old.uninstallCertsAndKeys();
mProviders.remove(config.getHomeSp().getFqdn());
+ // New profile changes the credential, remove the related WifiConfig.
+ if (!old.equals(newProvider)) {
+ mWifiConfigManager.removePasspointConfiguredNetwork(
+ newProvider.getWifiConfig().configKey());
+ }
}
mProviders.put(config.getHomeSp().getFqdn(), newProvider);
mWifiConfigManager.saveToStore(true /* forceWrite */);
- if (newProvider.getPackageName() != null) {
+ if (!isFromSuggestion && newProvider.getPackageName() != null) {
startTrackingAppOpsChange(newProvider.getPackageName(), uid);
}
Log.d(TAG, "Added/updated Passpoint configuration: " + config.getHomeSp().getFqdn()
@@ -646,7 +662,7 @@ public class PasspointManager {
// Create a provider and install the necessary certificates and keys.
PasspointProvider newProvider = mObjectFactory.makePasspointProvider(
- config, mKeyStore, mSimAccessor, mProviderIndex++, Process.WIFI_UID, null);
+ config, mKeyStore, mSimAccessor, mProviderIndex++, Process.WIFI_UID, null, false);
newProvider.setEphemeral(true);
Log.d(TAG, "installed PasspointConfiguration for carrier : "
+ config.getHomeSp().getFriendlyName());
@@ -665,7 +681,6 @@ public class PasspointManager {
*/
public boolean removeProvider(int callingUid, boolean privileged, String fqdn) {
mWifiMetrics.incrementNumPasspointProviderUninstallation();
- String packageName;
PasspointProvider provider = mProviders.get(fqdn);
if (provider == null) {
Log.e(TAG, "Config doesn't exist");
@@ -677,7 +692,10 @@ public class PasspointManager {
return false;
}
provider.uninstallCertsAndKeys();
- packageName = provider.getPackageName();
+ String packageName = provider.getPackageName();
+ // Remove any configs corresponding to the profile in WifiConfigManager.
+ mWifiConfigManager.removePasspointConfiguredNetwork(
+ provider.getWifiConfig().configKey());
mProviders.remove(fqdn);
mWifiConfigManager.saveToStore(true /* forceWrite */);
@@ -707,18 +725,21 @@ public class PasspointManager {
/**
* Return the installed Passpoint provider configurations.
- *
* An empty list will be returned when no provider is installed.
*
* @param callingUid Calling UID.
* @param privileged Whether the caller is a privileged entity
* @return A list of {@link PasspointConfiguration}
*/
- public List<PasspointConfiguration> getProviderConfigs(int callingUid, boolean privileged) {
+ public List<PasspointConfiguration> getProviderConfigs(int callingUid,
+ boolean privileged) {
List<PasspointConfiguration> configs = new ArrayList<>();
for (Map.Entry<String, PasspointProvider> entry : mProviders.entrySet()) {
PasspointProvider provider = entry.getValue();
if (privileged || callingUid == provider.getCreatorUid()) {
+ if (provider.isEphemeral() || provider.isFromSuggestion()) {
+ continue;
+ }
configs.add(provider.getConfig());
}
}
@@ -746,12 +767,14 @@ public class PasspointManager {
}
Pair<PasspointProvider, PasspointMatch> bestMatch = null;
for (Pair<PasspointProvider, PasspointMatch> match : allMatches) {
- if (match.second == PasspointMatch.HomeProvider) {
- bestMatch = match;
- break;
- }
- if (match.second == PasspointMatch.RoamingProvider && bestMatch == null) {
- bestMatch = match;
+ if (!isExpired(match.first.getConfig())) {
+ if (match.second == PasspointMatch.HomeProvider) {
+ bestMatch = match;
+ break;
+ }
+ if (match.second == PasspointMatch.RoamingProvider && bestMatch == null) {
+ bestMatch = match;
+ }
}
}
if (bestMatch != null) {
@@ -808,6 +831,15 @@ public class PasspointManager {
roamingConsortium);
if (matchStatus == PasspointMatch.HomeProvider
|| matchStatus == PasspointMatch.RoamingProvider) {
+ // If provider is from network suggestion, check user approval.
+ // Send user approval notification if need.
+ // If not approved, will be ignored in this matching.
+ if (provider.isFromSuggestion()
+ && mWifiInjector.getWifiNetworkSuggestionsManager()
+ .sendUserApprovalNotificationIfNotApproved(
+ provider.getPackageName(), provider.getCreatorUid())) {
+ continue;
+ }
allMatches.add(Pair.create(provider, matchStatus));
}
}
@@ -1020,13 +1052,12 @@ public class PasspointManager {
public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(
List<OsuProvider> osuProviders) {
Map<OsuProvider, PasspointConfiguration> matchingPasspointConfigs = new HashMap<>();
- List<PasspointConfiguration> passpointConfigurations =
- getProviderConfigs(Process.WIFI_UID /* ignored */, true);
for (OsuProvider osuProvider : osuProviders) {
Map<String, String> friendlyNamesForOsuProvider = osuProvider.getFriendlyNameList();
if (friendlyNamesForOsuProvider == null) continue;
- for (PasspointConfiguration passpointConfiguration : passpointConfigurations) {
+ for (PasspointProvider provider : mProviders.values()) {
+ PasspointConfiguration passpointConfiguration = provider.getConfig();
Map<String, String> serviceFriendlyNamesForPpsMo =
passpointConfiguration.getServiceFriendlyNames();
if (serviceFriendlyNamesForPpsMo == null) continue;
@@ -1161,7 +1192,7 @@ public class PasspointManager {
// Note that for legacy configuration, the alias for client private key is the same as the
// alias for the client certificate.
PasspointProvider provider = new PasspointProvider(passpointConfig, mKeyStore,
- mSimAccessor, mProviderIndex++, wifiConfig.creatorUid, null,
+ mSimAccessor, mProviderIndex++, wifiConfig.creatorUid, null, false,
Arrays.asList(enterpriseConfig.getCaCertificateAlias()),
enterpriseConfig.getClientCertificateAlias(),
enterpriseConfig.getClientCertificateAlias(), null, false, false);
@@ -1180,4 +1211,28 @@ public class PasspointManager {
IProvisioningCallback callback) {
return mPasspointProvisioner.startSubscriptionProvisioning(callingUid, provider, callback);
}
+
+ /**
+ * Check if a Passpoint configuration is expired
+ *
+ * @param config {@link PasspointConfiguration} Passpoint configuration
+ * @return True if the configuration is expired, false if not or expiration is unset
+ */
+ private boolean isExpired(@NonNull PasspointConfiguration config) {
+ long expirationTime = config.getSubscriptionExpirationTimeInMillis();
+
+ if (expirationTime != Long.MIN_VALUE) {
+ long curTime = System.currentTimeMillis();
+
+ // Check expiration and return true for expired profiles
+ if (curTime >= expirationTime) {
+ Log.d(TAG, "Profile for " + config.getServiceFriendlyName() + " has expired, "
+ + "expiration time: " + expirationTime + ", current time: "
+ + curTime);
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java
index ec8a009d98..2d98a9d719 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java
@@ -244,13 +244,18 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva
}
// Add the newly created WifiConfiguration to WifiConfigManager.
- NetworkUpdateResult result =
- mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
+ NetworkUpdateResult result;
+ if (config.fromWifiNetworkSuggestion) {
+ result = mWifiConfigManager.addOrUpdateNetwork(
+ config, config.creatorUid, config.creatorName);
+ } else {
+ result = mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
+ }
if (!result.isSuccess()) {
localLog("Failed to add passpoint network");
return null;
}
- mWifiConfigManager.enableNetwork(result.getNetworkId(), false, Process.WIFI_UID);
+ mWifiConfigManager.enableNetwork(result.getNetworkId(), false, Process.WIFI_UID, null);
mWifiConfigManager.setNetworkCandidateScanResult(result.getNetworkId(),
networkInfo.mScanDetail.getScanResult(), 0);
mWifiConfigManager.updateScanDetailForNetwork(
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java b/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java
index c083b86cc6..94be270e2b 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointObjectFactory.java
@@ -59,9 +59,9 @@ public class PasspointObjectFactory{
*/
public PasspointProvider makePasspointProvider(PasspointConfiguration config,
WifiKeyStore keyStore, SIMAccessor simAccessor, long providerId, int creatorUid,
- String packageName) {
+ String packageName, boolean isFromSuggestion) {
return new PasspointProvider(config, keyStore, simAccessor, providerId, creatorUid,
- packageName);
+ packageName, isFromSuggestion);
}
/**
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
index ca9814aa6a..70ea738ac5 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
@@ -30,6 +30,7 @@ import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
+import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.IMSIParameter;
import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiKeyStore;
@@ -69,6 +70,8 @@ public class PasspointProvider {
private static final String ALIAS_HS_TYPE = "HS2_";
private static final String ALIAS_ALIAS_REMEDIATION_TYPE = "REMEDIATION_";
+ private static final String SYSTEM_CA_STORE_PATH = "/system/etc/security/cacerts";
+
private final PasspointConfiguration mConfig;
private final WifiKeyStore mKeyStore;
@@ -95,6 +98,8 @@ public class PasspointProvider {
private boolean mHasEverConnected;
private boolean mIsShared;
+ private boolean mIsFromSuggestion;
+
/**
* This is a flag to indicate if the Provider is created temporarily.
@@ -103,14 +108,15 @@ public class PasspointProvider {
private boolean mIsEphemeral = false;
public PasspointProvider(PasspointConfiguration config, WifiKeyStore keyStore,
- SIMAccessor simAccessor, long providerId, int creatorUid, String packageName) {
- this(config, keyStore, simAccessor, providerId, creatorUid, packageName, null, null, null,
- null, false, false);
+ SIMAccessor simAccessor, long providerId, int creatorUid, String packageName,
+ boolean isFromSuggestion) {
+ this(config, keyStore, simAccessor, providerId, creatorUid, packageName, isFromSuggestion,
+ null, null, null, null, false, false);
}
public PasspointProvider(PasspointConfiguration config, WifiKeyStore keyStore,
SIMAccessor simAccessor, long providerId, int creatorUid, String packageName,
- List<String> caCertificateAliases,
+ boolean isFromSuggestion, List<String> caCertificateAliases,
String clientCertificateAlias, String clientPrivateKeyAlias,
String remediationCaCertificateAlias,
boolean hasEverConnected, boolean isShared) {
@@ -126,6 +132,7 @@ public class PasspointProvider {
mRemediationCaCertificateAlias = remediationCaCertificateAlias;
mHasEverConnected = hasEverConnected;
mIsShared = isShared;
+ mIsFromSuggestion = isFromSuggestion;
// Setup EAP method and authentication parameter based on the credential.
if (mConfig.getCredential().getUserCredential() != null) {
@@ -202,6 +209,10 @@ public class PasspointProvider {
return mImsiParameter;
}
+ public boolean isFromSuggestion() {
+ return mIsFromSuggestion;
+ }
+
/**
* Install certificates and key based on current configuration.
* Note: the certificates and keys in the configuration will get cleared once
@@ -407,8 +418,26 @@ public class PasspointProvider {
buildEnterpriseConfigForSimCredential(enterpriseConfig,
mConfig.getCredential().getSimCredential());
}
+ // If AAA server trusted names are specified, use it to replace HOME SP FQDN
+ // and use system CA regardless of provisioned CA certificate.
+ if (!ArrayUtils.isEmpty(mConfig.getAaaServerTrustedNames())) {
+ enterpriseConfig.setDomainSuffixMatch(
+ String.join(";", mConfig.getAaaServerTrustedNames()));
+ enterpriseConfig.setCaCertificateAliases(new String[] {SYSTEM_CA_STORE_PATH});
+ }
wifiConfig.enterpriseConfig = enterpriseConfig;
+ // PPS MO Credential/CheckAAAServerCertStatus node contains a flag which indicates
+ // if the mobile device needs to check the AAA server certificate's revocation status
+ // during EAP authentication.
+ if (mConfig.getCredential().getCheckAaaServerCertStatus()) {
+ // Check server certificate using OCSP (Online Certificate Status Protocol).
+ wifiConfig.enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
+ }
wifiConfig.shared = mIsShared;
+ wifiConfig.fromWifiNetworkSuggestion = mIsFromSuggestion;
+ wifiConfig.ephemeral = mIsFromSuggestion;
+ wifiConfig.creatorName = mPackageName;
+ wifiConfig.creatorUid = mCreatorUid;
return wifiConfig;
}
@@ -519,6 +548,9 @@ public class PasspointProvider {
builder.append("Configuration Begin ---\n");
builder.append(mConfig);
builder.append("Configuration End ---\n");
+ builder.append("WifiConfiguration Begin ---\n");
+ builder.append(getWifiConfig());
+ builder.append("WifiConfiguration End ---\n");
return builder.toString();
}
@@ -622,7 +654,11 @@ public class PasspointProvider {
config.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
config.setIdentity(credential.getUsername());
config.setPassword(decodedPassword);
- config.setCaCertificateAliases(mCaCertificateAliases.toArray(new String[0]));
+ if (!ArrayUtils.isEmpty(mCaCertificateAliases)) {
+ config.setCaCertificateAliases(mCaCertificateAliases.toArray(new String[0]));
+ } else {
+ config.setCaCertificateAliases(new String[] {SYSTEM_CA_STORE_PATH});
+ }
int phase2Method = WifiEnterpriseConfig.Phase2.NONE;
switch (credential.getNonEapInnerMethod()) {
case Credential.UserCredential.AUTH_METHOD_PAP:
@@ -651,7 +687,11 @@ public class PasspointProvider {
private void buildEnterpriseConfigForCertCredential(WifiEnterpriseConfig config) {
config.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
config.setClientCertificateAlias(mClientCertificateAlias);
- config.setCaCertificateAliases(mCaCertificateAliases.toArray(new String[0]));
+ if (!ArrayUtils.isEmpty(mCaCertificateAliases)) {
+ config.setCaCertificateAliases(mCaCertificateAliases.toArray(new String[0]));
+ } else {
+ config.setCaCertificateAliases(new String[] {SYSTEM_CA_STORE_PATH});
+ }
}
/**
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
index 137d9fa19c..b9afb0bac2 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
@@ -789,7 +789,8 @@ public class PasspointProvisioner {
// Verify that the intent will resolve to an activity
if (intent.resolveActivity(mContext.getPackageManager()) != null) {
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ // TODO (b/142234604): This will not work on multi-user device scenarios.
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
invokeProvisioningCallback(PROVISIONING_STATUS,
ProvisioningCallback.OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE);
changeState(STATE_WAITING_FOR_REDIRECT_RESPONSE);
diff --git a/service/java/com/android/server/wifi/hotspot2/ServiceProviderVerifier.java b/service/java/com/android/server/wifi/hotspot2/ServiceProviderVerifier.java
index d0f6dd5410..bae7b70194 100644
--- a/service/java/com/android/server/wifi/hotspot2/ServiceProviderVerifier.java
+++ b/service/java/com/android/server/wifi/hotspot2/ServiceProviderVerifier.java
@@ -22,12 +22,13 @@ import android.util.Log;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.org.bouncycastle.asn1.ASN1Encodable;
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
-import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.org.bouncycastle.asn1.DERTaggedObject;
-import com.android.org.bouncycastle.asn1.DERUTF8String;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.DERUTF8String;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
diff --git a/service/java/com/android/server/wifi/hotspot2/WfaKeyStore.java b/service/java/com/android/server/wifi/hotspot2/WfaKeyStore.java
index 342ce1cd88..c85f7f9639 100644
--- a/service/java/com/android/server/wifi/hotspot2/WfaKeyStore.java
+++ b/service/java/com/android/server/wifi/hotspot2/WfaKeyStore.java
@@ -34,7 +34,7 @@ public class WfaKeyStore {
private static final String TAG = "PasspointWfaKeyStore";
// The WFA Root certs are checked in to /system/ca-certificates/cacerts_wfa
// The location on device is configured in the corresponding Android.mk
- private static final String DEFAULT_WFA_CERT_DIR =
+ /* package */ static final String DEFAULT_WFA_CERT_DIR =
Environment.getRootDirectory() + "/etc/security/cacerts_wfa";
private boolean mVerboseLoggingEnabled = false;
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pService.java b/service/java/com/android/server/wifi/p2p/WifiP2pService.java
index 6137c3cd95..97da28b3e9 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pService.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pService.java
@@ -17,36 +17,34 @@
package com.android.server.wifi.p2p;
import android.content.Context;
+import android.os.Binder;
import android.util.Log;
-import com.android.server.SystemService;
import com.android.server.wifi.WifiInjector;
+import com.android.server.wifi.WifiServiceBase;
/**
* Wifi P2p Service class, instantiates P2p service
- * Overrides onStart() and onBootPhase() methods in
+ * Overrides onStart() and onBootCompleted() methods in
* the super class.
*/
-public final class WifiP2pService extends SystemService {
+public final class WifiP2pService implements WifiServiceBase {
private static final String TAG = "WifiP2pService";
final WifiP2pServiceImpl mImpl;
public WifiP2pService(Context context) {
- super(context);
mImpl = new WifiP2pServiceImpl(context, WifiInjector.getInstance());
}
@Override
public void onStart() {
- Log.i(TAG, "Registering " + Context.WIFI_P2P_SERVICE);
- publishBinderService(Context.WIFI_P2P_SERVICE, mImpl);
+ Log.i(TAG, "Starting " + Context.WIFI_P2P_SERVICE);
+ mImpl.connectivityServiceReady();
}
@Override
- public void onBootPhase(int phase) {
- if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
- mImpl.connectivityServiceReady();
- }
+ public Binder retrieveImpl() {
+ return mImpl;
}
}
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 3f37456641..dfbc45f8ac 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -72,7 +72,6 @@ import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Slog;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -397,7 +396,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mP2pStateMachine.sendMessage(Message.obtain(msg));
break;
default:
- Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
+ Log.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
break;
}
}
@@ -462,6 +461,25 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
/**
+ * If wifi p2p interface name pattern is defined,
+ * {@link com.android.server.connectivity.Tethering} listens to
+ * {@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}
+ * events and takes over the DHCP server management automatically.
+ */
+ private boolean isDhcpServerHostedByDnsmasq() {
+ try {
+ String[] tetherableWifiP2pRegexs = mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_tether_wifi_p2p_regexs);
+ return (tetherableWifiP2pRegexs == null || tetherableWifiP2pRegexs.length == 0);
+ } catch (Resources.NotFoundException e404) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "No P2P tetherable interface pattern");
+ }
+ }
+ return true;
+ }
+
+ /**
* Obtains the service interface for Managements services
*/
public void connectivityServiceReady() {
@@ -2490,9 +2508,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
dialog.setCanceledOnTouchOutside(false);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
- attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- dialog.getWindow().setAttributes(attrs);
+ dialog.getWindow().addSystemFlags(
+ WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
dialog.show();
mFrequencyConflictDialog = dialog;
}
@@ -3017,6 +3034,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
private void startDhcpServer(String intf) {
+ if (!isDhcpServerHostedByDnsmasq()) return;
+
InterfaceConfiguration ifcg = null;
try {
ifcg = mNwService.getInterfaceConfig(intf);
@@ -3043,6 +3062,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
private void stopDhcpServer(String intf) {
+ if (!isDhcpServerHostedByDnsmasq()) return;
+
try {
mNwService.untetherInterface(intf);
for (String temp : mNwService.listTetheredInterfaces()) {
@@ -3070,9 +3091,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
.create();
dialog.setCanceledOnTouchOutside(false);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
- attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- dialog.getWindow().setAttributes(attrs);
+ dialog.getWindow().addSystemFlags(
+ WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
dialog.show();
}
@@ -3102,9 +3122,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
.create();
dialog.setCanceledOnTouchOutside(false);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
- attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- dialog.getWindow().setAttributes(attrs);
+ dialog.getWindow().addSystemFlags(
+ WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
dialog.show();
}
@@ -3128,9 +3147,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
.create();
dialog.setCanceledOnTouchOutside(false);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
- attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- dialog.getWindow().setAttributes(attrs);
+ dialog.getWindow().addSystemFlags(
+ WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
dialog.show();
}
@@ -3212,9 +3230,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes();
- attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
- dialog.getWindow().setAttributes(attrs);
+ dialog.getWindow().addSystemFlags(
+ WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
dialog.show();
}
@@ -3784,12 +3801,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
@Override
protected void logd(String s) {
- Slog.d(TAG, s);
+ Log.d(TAG, s);
}
@Override
protected void loge(String s) {
- Slog.e(TAG, s);
+ Log.e(TAG, s);
}
/**
diff --git a/service/java/com/android/server/wifi/rtt/RttService.java b/service/java/com/android/server/wifi/rtt/RttService.java
index 74370516e2..e4ce9235fd 100644
--- a/service/java/com/android/server/wifi/rtt/RttService.java
+++ b/service/java/com/android/server/wifi/rtt/RttService.java
@@ -18,57 +18,53 @@ package com.android.server.wifi.rtt;
import android.content.Context;
import android.net.wifi.aware.IWifiAwareManager;
+import android.os.Binder;
import android.os.HandlerThread;
import android.os.ServiceManager;
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.WifiServiceBase;
import com.android.server.wifi.util.WifiPermissionsUtil;
/**
* TBD.
*/
-public class RttService extends SystemService {
+public class RttService implements WifiServiceBase {
private static final String TAG = "RttService";
private Context mContext;
private RttServiceImpl mImpl;
public RttService(Context context) {
- super(context);
mContext = context;
mImpl = new RttServiceImpl(context);
}
@Override
public void onStart() {
- Log.i(TAG, "Registering " + Context.WIFI_RTT_RANGING_SERVICE);
- publishBinderService(Context.WIFI_RTT_RANGING_SERVICE, mImpl);
- }
-
- @Override
- public void onBootPhase(int phase) {
- if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
- Log.i(TAG, "Starting " + Context.WIFI_RTT_RANGING_SERVICE);
+ Log.i(TAG, "Starting " + Context.WIFI_RTT_RANGING_SERVICE);
+ WifiInjector wifiInjector = WifiInjector.getInstance();
+ if (wifiInjector == null) {
+ Log.e(TAG, "onBootPhase(PHASE_SYSTEM_SERVICES_READY): NULL injector!");
+ return;
+ }
- WifiInjector wifiInjector = WifiInjector.getInstance();
- if (wifiInjector == null) {
- Log.e(TAG, "onBootPhase(PHASE_SYSTEM_SERVICES_READY): NULL injector!");
- return;
- }
+ HalDeviceManager halDeviceManager = wifiInjector.getHalDeviceManager();
+ HandlerThread handlerThread = wifiInjector.getRttHandlerThread();
+ WifiPermissionsUtil wifiPermissionsUtil = wifiInjector.getWifiPermissionsUtil();
+ RttMetrics rttMetrics = wifiInjector.getWifiMetrics().getRttMetrics();
- HalDeviceManager halDeviceManager = wifiInjector.getHalDeviceManager();
- HandlerThread handlerThread = wifiInjector.getRttHandlerThread();
- WifiPermissionsUtil wifiPermissionsUtil = wifiInjector.getWifiPermissionsUtil();
- RttMetrics rttMetrics = wifiInjector.getWifiMetrics().getRttMetrics();
+ IWifiAwareManager awareBinder = (IWifiAwareManager) ServiceManager.getService(
+ Context.WIFI_AWARE_SERVICE);
- IWifiAwareManager awareBinder = (IWifiAwareManager) ServiceManager.getService(
- Context.WIFI_AWARE_SERVICE);
+ RttNative rttNative = new RttNative(mImpl, halDeviceManager);
+ mImpl.start(handlerThread.getLooper(), wifiInjector.getClock(), awareBinder, rttNative,
+ rttMetrics, wifiPermissionsUtil, wifiInjector.getFrameworkFacade());
+ }
- RttNative rttNative = new RttNative(mImpl, halDeviceManager);
- mImpl.start(handlerThread.getLooper(), wifiInjector.getClock(), awareBinder, rttNative,
- rttMetrics, wifiPermissionsUtil, wifiInjector.getFrameworkFacade());
- }
+ @Override
+ public Binder retrieveImpl() {
+ return mImpl;
}
}
diff --git a/service/java/com/android/server/wifi/rtt/RttServiceImpl.java b/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
index d69ce8f00a..ce64d2e4a6 100644
--- a/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
+++ b/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
@@ -399,7 +399,7 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
public boolean isAvailable() {
long ident = Binder.clearCallingIdentity();
try {
- return mRttNative.isReady() && !mPowerManager.isDeviceIdleMode()
+ return mRttNative != null && mRttNative.isReady() && !mPowerManager.isDeviceIdleMode()
&& mWifiPermissionsUtil.isLocationModeEnabled();
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/service/java/com/android/server/wifi/scanner/BackgroundScanScheduler.java b/service/java/com/android/server/wifi/scanner/BackgroundScanScheduler.java
index 01d64e9f51..2749aedf37 100644
--- a/service/java/com/android/server/wifi/scanner/BackgroundScanScheduler.java
+++ b/service/java/com/android/server/wifi/scanner/BackgroundScanScheduler.java
@@ -23,9 +23,9 @@ import android.net.wifi.WifiScanner;
import android.net.wifi.WifiScanner.ScanData;
import android.net.wifi.WifiScanner.ScanSettings;
import android.util.ArraySet;
+import android.util.Log;
import android.util.Pair;
import android.util.Rational;
-import android.util.Slog;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection;
@@ -425,7 +425,7 @@ public class BackgroundScanScheduler {
if (maxScheduledBucket != null) {
return maxScheduledBucket.bucketId;
} else {
- Slog.wtf(TAG, "No bucket found for settings");
+ Log.wtf(TAG, "No bucket found for settings");
return -1;
}
}
@@ -474,7 +474,7 @@ public class BackgroundScanScheduler {
}
if (gcd < PERIOD_MIN_GCD_MS) {
- Slog.wtf(TAG, "found gcd less than min gcd");
+ Log.wtf(TAG, "found gcd less than min gcd");
gcd = PERIOD_MIN_GCD_MS;
}
@@ -517,7 +517,7 @@ public class BackgroundScanScheduler {
}
}
if (index == -1) {
- Slog.wtf(TAG, "Could not find best bucket for period " + requestedPeriod + " in "
+ Log.wtf(TAG, "Could not find best bucket for period " + requestedPeriod + " in "
+ maxNumBuckets + " buckets");
}
return index;
diff --git a/service/java/com/android/server/wifi/scanner/ChannelHelper.java b/service/java/com/android/server/wifi/scanner/ChannelHelper.java
index 6a01f0c83d..c2d651daba 100644
--- a/service/java/com/android/server/wifi/scanner/ChannelHelper.java
+++ b/service/java/com/android/server/wifi/scanner/ChannelHelper.java
@@ -56,6 +56,15 @@ public abstract class ChannelHelper {
public abstract WifiScanner.ChannelSpec[] getAvailableScanChannels(int band);
/**
+ * Compares the channels / bands available from this helper with the channels / bands available
+ * from the other channel helper.
+ *
+ * @return true if the all the channels available from the other channel helper is also
+ * available in this helper.
+ */
+ public abstract boolean satisfies(ChannelHelper otherChannelHelper);
+
+ /**
* Estimates the duration that the chip will spend scanning with the given settings
*/
public abstract int estimateScanDuration(WifiScanner.ScanSettings settings);
diff --git a/service/java/com/android/server/wifi/scanner/HalWifiScannerImpl.java b/service/java/com/android/server/wifi/scanner/HalWifiScannerImpl.java
index ce92956b9b..12f65958de 100644
--- a/service/java/com/android/server/wifi/scanner/HalWifiScannerImpl.java
+++ b/service/java/com/android/server/wifi/scanner/HalWifiScannerImpl.java
@@ -39,18 +39,17 @@ public class HalWifiScannerImpl extends WifiScannerImpl implements Handler.Callb
private static final String TAG = "HalWifiScannerImpl";
private static final boolean DBG = false;
- private final String mIfaceName;
private final WifiNative mWifiNative;
private final ChannelHelper mChannelHelper;
private final WificondScannerImpl mWificondScannerDelegate;
public HalWifiScannerImpl(Context context, String ifaceName, WifiNative wifiNative,
WifiMonitor wifiMonitor, Looper looper, Clock clock) {
- mIfaceName = ifaceName;
+ super(ifaceName);
mWifiNative = wifiNative;
mChannelHelper = new WificondChannelHelper(wifiNative);
mWificondScannerDelegate =
- new WificondScannerImpl(context, mIfaceName, wifiNative, wifiMonitor,
+ new WificondScannerImpl(context, getIfaceName(), wifiNative, wifiMonitor,
mChannelHelper, looper, clock);
}
@@ -68,7 +67,7 @@ public class HalWifiScannerImpl extends WifiScannerImpl implements Handler.Callb
@Override
public boolean getScanCapabilities(WifiNative.ScanCapabilities capabilities) {
return mWifiNative.getBgScanCapabilities(
- mIfaceName, capabilities);
+ getIfaceName(), capabilities);
}
@Override
@@ -95,27 +94,27 @@ public class HalWifiScannerImpl extends WifiScannerImpl implements Handler.Callb
return false;
}
return mWifiNative.startBgScan(
- mIfaceName, settings, eventHandler);
+ getIfaceName(), settings, eventHandler);
}
@Override
public void stopBatchedScan() {
- mWifiNative.stopBgScan(mIfaceName);
+ mWifiNative.stopBgScan(getIfaceName());
}
@Override
public void pauseBatchedScan() {
- mWifiNative.pauseBgScan(mIfaceName);
+ mWifiNative.pauseBgScan(getIfaceName());
}
@Override
public void restartBatchedScan() {
- mWifiNative.restartBgScan(mIfaceName);
+ mWifiNative.restartBgScan(getIfaceName());
}
@Override
public WifiScanner.ScanData[] getLatestBatchedScanResults(boolean flush) {
- return mWifiNative.getBgScanResults(mIfaceName);
+ return mWifiNative.getBgScanResults(getIfaceName());
}
@Override
diff --git a/service/java/com/android/server/wifi/scanner/KnownBandsChannelHelper.java b/service/java/com/android/server/wifi/scanner/KnownBandsChannelHelper.java
index 33cce1c080..7aeefce0fe 100644
--- a/service/java/com/android/server/wifi/scanner/KnownBandsChannelHelper.java
+++ b/service/java/com/android/server/wifi/scanner/KnownBandsChannelHelper.java
@@ -16,12 +16,24 @@
package com.android.server.wifi.scanner;
+import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ;
+import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS;
+import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ;
+import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY;
+import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS;
+import static android.net.wifi.WifiScanner.WIFI_BAND_BOTH;
+import static android.net.wifi.WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
+import static android.net.wifi.WifiScanner.WIFI_BAND_MAX;
+import static android.net.wifi.WifiScanner.WIFI_BAND_UNSPECIFIED;
+
import android.net.wifi.WifiScanner;
import android.util.ArraySet;
import com.android.server.wifi.WifiNative;
+import java.util.Arrays;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* ChannelHelper that offers channel manipulation utilities when the channels in a band are known.
@@ -32,36 +44,45 @@ public class KnownBandsChannelHelper extends ChannelHelper {
private WifiScanner.ChannelSpec[][] mBandsToChannels;
protected void setBandChannels(int[] channels2G, int[] channels5G, int[] channelsDfs) {
- mBandsToChannels = new WifiScanner.ChannelSpec[8][];
-
- mBandsToChannels[0] = NO_CHANNELS;
-
- mBandsToChannels[1] = new WifiScanner.ChannelSpec[channels2G.length];
- copyChannels(mBandsToChannels[1], 0, channels2G);
-
- mBandsToChannels[2] = new WifiScanner.ChannelSpec[channels5G.length];
- copyChannels(mBandsToChannels[2], 0, channels5G);
-
- mBandsToChannels[3] = new WifiScanner.ChannelSpec[channels2G.length + channels5G.length];
- copyChannels(mBandsToChannels[3], 0, channels2G);
- copyChannels(mBandsToChannels[3], channels2G.length, channels5G);
-
- mBandsToChannels[4] = new WifiScanner.ChannelSpec[channelsDfs.length];
- copyChannels(mBandsToChannels[4], 0, channelsDfs);
-
- mBandsToChannels[5] = new WifiScanner.ChannelSpec[channels2G.length + channelsDfs.length];
- copyChannels(mBandsToChannels[5], 0, channels2G);
- copyChannels(mBandsToChannels[5], channels2G.length, channelsDfs);
-
- mBandsToChannels[6] = new WifiScanner.ChannelSpec[channels5G.length + channelsDfs.length];
- copyChannels(mBandsToChannels[6], 0, channels5G);
- copyChannels(mBandsToChannels[6], channels5G.length, channelsDfs);
-
- mBandsToChannels[7] = new WifiScanner.ChannelSpec[
- channels2G.length + channels5G.length + channelsDfs.length];
- copyChannels(mBandsToChannels[7], 0, channels2G);
- copyChannels(mBandsToChannels[7], channels2G.length, channels5G);
- copyChannels(mBandsToChannels[7], channels2G.length + channels5G.length, channelsDfs);
+ mBandsToChannels = new WifiScanner.ChannelSpec[WIFI_BAND_MAX][];
+
+ mBandsToChannels[WIFI_BAND_UNSPECIFIED] = NO_CHANNELS;
+
+ mBandsToChannels[WIFI_BAND_24_GHZ] = new WifiScanner.ChannelSpec[channels2G.length];
+ copyChannels(mBandsToChannels[WIFI_BAND_24_GHZ], 0, channels2G);
+
+ mBandsToChannels[WIFI_BAND_5_GHZ] = new WifiScanner.ChannelSpec[channels5G.length];
+ copyChannels(mBandsToChannels[WIFI_BAND_5_GHZ], 0, channels5G);
+
+ mBandsToChannels[WIFI_BAND_BOTH] =
+ new WifiScanner.ChannelSpec[channels2G.length + channels5G.length];
+ copyChannels(mBandsToChannels[WIFI_BAND_BOTH], 0, channels2G);
+ copyChannels(mBandsToChannels[WIFI_BAND_BOTH], channels2G.length, channels5G);
+
+ mBandsToChannels[WIFI_BAND_5_GHZ_DFS_ONLY] =
+ new WifiScanner.ChannelSpec[channelsDfs.length];
+ copyChannels(mBandsToChannels[WIFI_BAND_5_GHZ_DFS_ONLY], 0, channelsDfs);
+
+ // No constant for 2G + DFS available.
+ mBandsToChannels[WIFI_BAND_24_GHZ_WITH_5GHZ_DFS] =
+ new WifiScanner.ChannelSpec[channels2G.length + channelsDfs.length];
+ copyChannels(mBandsToChannels[WIFI_BAND_24_GHZ_WITH_5GHZ_DFS], 0, channels2G);
+ copyChannels(mBandsToChannels[WIFI_BAND_24_GHZ_WITH_5GHZ_DFS], channels2G.length,
+ channelsDfs);
+
+ mBandsToChannels[WIFI_BAND_5_GHZ_WITH_DFS] =
+ new WifiScanner.ChannelSpec[channels5G.length + channelsDfs.length];
+ copyChannels(mBandsToChannels[WIFI_BAND_5_GHZ_WITH_DFS], 0, channels5G);
+ copyChannels(mBandsToChannels[WIFI_BAND_5_GHZ_WITH_DFS], channels5G.length,
+ channelsDfs);
+
+ mBandsToChannels[WIFI_BAND_BOTH_WITH_DFS] =
+ new WifiScanner.ChannelSpec[channels2G.length + channels5G.length
+ + channelsDfs.length];
+ copyChannels(mBandsToChannels[WIFI_BAND_BOTH_WITH_DFS], 0, channels2G);
+ copyChannels(mBandsToChannels[WIFI_BAND_BOTH_WITH_DFS], channels2G.length, channels5G);
+ copyChannels(mBandsToChannels[WIFI_BAND_BOTH_WITH_DFS],
+ channels2G.length + channels5G.length, channelsDfs);
}
private static void copyChannels(
@@ -73,7 +94,7 @@ public class KnownBandsChannelHelper extends ChannelHelper {
@Override
public WifiScanner.ChannelSpec[] getAvailableScanChannels(int band) {
- if (band < WifiScanner.WIFI_BAND_24_GHZ || band > WifiScanner.WIFI_BAND_BOTH_WITH_DFS) {
+ if (band < WIFI_BAND_UNSPECIFIED || band >= WIFI_BAND_MAX) {
// invalid value for band
return NO_CHANNELS;
} else {
@@ -82,8 +103,29 @@ public class KnownBandsChannelHelper extends ChannelHelper {
}
@Override
+ public boolean satisfies(ChannelHelper otherChannelHelper) {
+ if (!(otherChannelHelper instanceof KnownBandsChannelHelper)) return false;
+ KnownBandsChannelHelper otherKnownBandsChannelHelper =
+ (KnownBandsChannelHelper) otherChannelHelper;
+ // Compare all the channels in every band
+ for (int i = WIFI_BAND_UNSPECIFIED; i < WIFI_BAND_MAX; i++) {
+ Set<Integer> thisFrequencies = Arrays.stream(mBandsToChannels[i])
+ .map(spec -> spec.frequency)
+ .collect(Collectors.toSet());
+ Set<Integer> otherFrequencies = Arrays.stream(
+ otherKnownBandsChannelHelper.mBandsToChannels[i])
+ .map(spec -> spec.frequency)
+ .collect(Collectors.toSet());
+ if (!thisFrequencies.containsAll(otherFrequencies)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
public int estimateScanDuration(WifiScanner.ScanSettings settings) {
- if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
+ if (settings.band == WIFI_BAND_UNSPECIFIED) {
return settings.channels.length * SCAN_PERIOD_PER_CHANNEL_MS;
} else {
return getAvailableScanChannels(settings.band).length * SCAN_PERIOD_PER_CHANNEL_MS;
@@ -103,20 +145,20 @@ public class KnownBandsChannelHelper extends ChannelHelper {
// TODO this should be rewritten to be based on the input data instead of hardcoded ranges
private int getBandFromChannel(int frequency) {
if (2400 <= frequency && frequency < 2500) {
- return WifiScanner.WIFI_BAND_24_GHZ;
+ return WIFI_BAND_24_GHZ;
} else if (isDfsChannel(frequency)) {
return WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY;
} else if (5100 <= frequency && frequency < 6000) {
- return WifiScanner.WIFI_BAND_5_GHZ;
+ return WIFI_BAND_5_GHZ;
} else {
- return WifiScanner.WIFI_BAND_UNSPECIFIED;
+ return WIFI_BAND_UNSPECIFIED;
}
}
@Override
public boolean settingsContainChannel(WifiScanner.ScanSettings settings, int channel) {
WifiScanner.ChannelSpec[] settingsChannels;
- if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) {
+ if (settings.band == WIFI_BAND_UNSPECIFIED) {
settingsChannels = settings.channels;
} else {
settingsChannels = getAvailableScanChannels(settings.band);
@@ -199,8 +241,7 @@ public class KnownBandsChannelHelper extends ChannelHelper {
@Override
public boolean isAllChannels() {
- return getAvailableScanChannels(WifiScanner.WIFI_BAND_BOTH_WITH_DFS).length ==
- mChannels.size();
+ return getAvailableScanChannels(WIFI_BAND_BOTH_WITH_DFS).length == mChannels.size();
}
@Override
@@ -251,7 +292,7 @@ public class KnownBandsChannelHelper extends ChannelHelper {
bucketSettings.num_channels = 0;
bucketSettings.channels = null;
} else {
- bucketSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED;
+ bucketSettings.band = WIFI_BAND_UNSPECIFIED;
bucketSettings.num_channels = mChannels.size();
bucketSettings.channels = new WifiNative.ChannelSettings[mChannels.size()];
for (int i = 0; i < mChannels.size(); ++i) {
@@ -264,7 +305,7 @@ public class KnownBandsChannelHelper extends ChannelHelper {
@Override
public Set<Integer> getScanFreqs() {
- if (mExactBands == WifiScanner.WIFI_BAND_BOTH_WITH_DFS) {
+ if (mExactBands == WIFI_BAND_BOTH_WITH_DFS) {
return null;
} else {
return new ArraySet<Integer>(mChannels);
diff --git a/service/java/com/android/server/wifi/scanner/WifiScannerImpl.java b/service/java/com/android/server/wifi/scanner/WifiScannerImpl.java
index c08baf536d..c99117fdb9 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScannerImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScannerImpl.java
@@ -16,6 +16,7 @@
package com.android.server.wifi.scanner;
+import android.annotation.NonNull;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiScanner;
@@ -40,7 +41,11 @@ public abstract class WifiScannerImpl {
* A factory that create a {@link com.android.server.wifi.scanner.WifiScannerImpl}
*/
public static interface WifiScannerImplFactory {
- WifiScannerImpl create(Context context, Looper looper, Clock clock);
+ /**
+ * Create instance of {@link WifiScannerImpl}.
+ */
+ WifiScannerImpl create(Context context, Looper looper, Clock clock,
+ @NonNull String ifaceName);
}
/**
@@ -48,10 +53,10 @@ public abstract class WifiScannerImpl {
* This factory should only ever be used once.
*/
public static final WifiScannerImplFactory DEFAULT_FACTORY = new WifiScannerImplFactory() {
- public WifiScannerImpl create(Context context, Looper looper, Clock clock) {
+ public WifiScannerImpl create(Context context, Looper looper, Clock clock,
+ @NonNull String ifaceName) {
WifiNative wifiNative = WifiInjector.getInstance().getWifiNative();
WifiMonitor wifiMonitor = WifiInjector.getInstance().getWifiMonitor();
- String ifaceName = wifiNative.getClientInterfaceName();
if (TextUtils.isEmpty(ifaceName)) {
return null;
}
@@ -76,6 +81,19 @@ public abstract class WifiScannerImpl {
}
};
+ private final String mIfaceName;
+
+ WifiScannerImpl(@NonNull String ifaceName) {
+ mIfaceName = ifaceName;
+ }
+
+ /**
+ * Get the interface name used by this instance of {@link WifiScannerImpl}
+ */
+ public @NonNull String getIfaceName() {
+ return mIfaceName;
+ }
+
/**
* Cleanup any ongoing operations. This may be called when the driver is unloaded.
* There is no expectation that failure events are returned for ongoing operations.
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningService.java b/service/java/com/android/server/wifi/scanner/WifiScanningService.java
index 93ac722529..d8dec0fb82 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningService.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningService.java
@@ -17,40 +17,40 @@
package com.android.server.wifi.scanner;
import android.content.Context;
+import android.os.Binder;
import android.os.HandlerThread;
import android.util.Log;
-import com.android.server.SystemService;
import com.android.server.am.BatteryStatsService;
import com.android.server.wifi.WifiInjector;
+import com.android.server.wifi.WifiServiceBase;
-public class WifiScanningService extends SystemService {
+/**
+ * Manages the wifi scanner service instance.
+ */
+public class WifiScanningService implements WifiServiceBase {
static final String TAG = "WifiScanningService";
private final WifiScanningServiceImpl mImpl;
private final HandlerThread mHandlerThread;
public WifiScanningService(Context context) {
- super(context);
Log.i(TAG, "Creating " + Context.WIFI_SCANNING_SERVICE);
mHandlerThread = new HandlerThread("WifiScanningService");
mHandlerThread.start();
- mImpl = new WifiScanningServiceImpl(getContext(), mHandlerThread.getLooper(),
+ mImpl = new WifiScanningServiceImpl(context, mHandlerThread.getLooper(),
WifiScannerImpl.DEFAULT_FACTORY, BatteryStatsService.getService(),
WifiInjector.getInstance());
}
@Override
public void onStart() {
- Log.i(TAG, "Publishing " + Context.WIFI_SCANNING_SERVICE);
- publishBinderService(Context.WIFI_SCANNING_SERVICE, mImpl);
+ Log.i(TAG, "Starting " + Context.WIFI_SCANNING_SERVICE);
+ mImpl.startService();
}
@Override
- public void onBootPhase(int phase) {
- if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
- Log.i(TAG, "Starting " + Context.WIFI_SCANNING_SERVICE);
- mImpl.startService();
- }
+ public Binder retrieveImpl() {
+ return mImpl;
}
}
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 442faa13e1..4d21ac6551 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -16,10 +16,10 @@
package com.android.server.wifi.scanner;
-import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.AlarmManager;
import android.content.Context;
import android.net.wifi.IWifiScanner;
@@ -29,6 +29,8 @@ import android.net.wifi.WifiScanner.ChannelSpec;
import android.net.wifi.WifiScanner.PnoSettings;
import android.net.wifi.WifiScanner.ScanData;
import android.net.wifi.WifiScanner.ScanSettings;
+import android.net.wifi.WifiScanner.WifiBand;
+import android.net.wifi.WifiStackClient;
import android.os.Binder;
import android.os.Bundle;
import android.os.Looper;
@@ -37,6 +39,7 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.WorkSource;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;
@@ -69,6 +72,8 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class WifiScanningServiceImpl extends IWifiScanner.Stub {
@@ -95,8 +100,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
mLocalLog.log(message);
}
- private WifiScannerImpl mScannerImpl;
-
@Override
public Messenger getMessenger() {
if (mClientHandler != null) {
@@ -108,10 +111,12 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
@Override
- public Bundle getAvailableChannels(int band) {
+ public Bundle getAvailableChannels(@WifiBand int band, String packageName) {
+ enforcePermission(Binder.getCallingUid(), packageName, false, false, false);
+
mChannelHelper.updateChannels();
ChannelSpec[] channelSpecs = mChannelHelper.getAvailableScanChannels(band);
- ArrayList<Integer> list = new ArrayList<Integer>(channelSpecs.length);
+ ArrayList<Integer> list = new ArrayList<>(channelSpecs.length);
for (ChannelSpec channelSpec : channelSpecs) {
list.add(channelSpec.frequency);
}
@@ -121,11 +126,16 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
return b;
}
- private void enforceNetworkStack(int uid) {
+ private void enforceWifiStackPermission(int uid) {
mContext.enforcePermission(
- Manifest.permission.NETWORK_STACK,
+ WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK,
UNKNOWN_PID, uid,
- "NetworkStack");
+ "MainlineWifiStack");
+ }
+
+ private boolean checkWifiStackPermission(int uid) {
+ return mContext.checkPermission(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK,
+ UNKNOWN_PID, uid) == PERMISSION_GRANTED;
}
// Helper method to check if the incoming message is for a privileged request.
@@ -166,29 +176,39 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
/**
+ * @see #enforcePermission(int, String, boolean, boolean, boolean)
+ */
+ private void enforcePermission(int uid, Message msg) throws SecurityException {
+ enforcePermission(uid, getPackageName(msg), isPrivilegedMessage(msg.what),
+ shouldIgnoreLocationSettingsForSingleScan(msg),
+ shouldHideFromAppsForSingleScan(msg));
+ }
+
+ /**
* Enforce the necessary client permissions for WifiScanner.
* If the client has NETWORK_STACK permission, then it can "always" send "any" request.
* If the client has only LOCATION_HARDWARE permission, then it can
* a) Only make scan related requests when location is turned on.
* b) Can never make one of the privileged requests.
- *
- * @param uid Uid of the client.
- * @param msg {@link Message} of the incoming request.
- * @throws {@link SecurityException} if the client does not have the necessary permissions.
+ * @param uid uid of the client
+ * @param packageName package name of the client
+ * @param isPrivilegedRequest whether we are checking for a privileged request
+ * @param shouldIgnoreLocationSettings override to ignore location settings
+ * @param shouldHideFromApps override to hide request from AppOps
*/
- private void enforcePermission(int uid, Message msg) throws SecurityException {
+ private void enforcePermission(int uid, String packageName, boolean isPrivilegedRequest,
+ boolean shouldIgnoreLocationSettings, boolean shouldHideFromApps) {
try {
- /** Wifi stack issued requests.*/
- enforceNetworkStack(uid);
+ // Wifi stack issued requests.
+ enforceWifiStackPermission(uid);
} catch (SecurityException e) {
- /** System-app issued requests. */
- if (isPrivilegedMessage(msg.what)) {
+ // System-app issued requests
+ if (isPrivilegedRequest) {
// Privileged message, only requests from clients with NETWORK_STACK allowed!
throw e;
}
- mWifiPermissionsUtil.enforceCanAccessScanResultsForWifiScanner(
- getPackageName(msg), uid, shouldIgnoreLocationSettingsForSingleScan(msg),
- shouldHideFromAppsForSingleScan(msg));
+ mWifiPermissionsUtil.enforceCanAccessScanResultsForWifiScanner(packageName, uid,
+ shouldIgnoreLocationSettings, shouldHideFromApps);
}
}
@@ -276,14 +296,16 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
switch (msg.what) {
case WifiScanner.CMD_ENABLE:
- mBackgroundScanStateMachine.sendMessage(CMD_DRIVER_LOADED);
- mSingleScanStateMachine.sendMessage(CMD_DRIVER_LOADED);
- mPnoScanStateMachine.sendMessage(CMD_DRIVER_LOADED);
+ setupScannerImpls();
+ mBackgroundScanStateMachine.sendMessage(Message.obtain(msg));
+ mSingleScanStateMachine.sendMessage(Message.obtain(msg));
+ mPnoScanStateMachine.sendMessage(Message.obtain(msg));
break;
case WifiScanner.CMD_DISABLE:
- mBackgroundScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
- mSingleScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
- mPnoScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
+ teardownScannerImpls();
+ mBackgroundScanStateMachine.sendMessage(Message.obtain(msg));
+ mSingleScanStateMachine.sendMessage(Message.obtain(msg));
+ mPnoScanStateMachine.sendMessage(Message.obtain(msg));
break;
case WifiScanner.CMD_START_BACKGROUND_SCAN:
case WifiScanner.CMD_STOP_BACKGROUND_SCAN:
@@ -317,8 +339,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private static final int CMD_SCAN_RESULTS_AVAILABLE = BASE + 0;
private static final int CMD_FULL_SCAN_RESULTS = BASE + 1;
- private static final int CMD_DRIVER_LOADED = BASE + 6;
- private static final int CMD_DRIVER_UNLOADED = BASE + 7;
private static final int CMD_SCAN_PAUSED = BASE + 8;
private static final int CMD_SCAN_RESTARTED = BASE + 9;
private static final int CMD_SCAN_FAILED = BASE + 10;
@@ -329,6 +349,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private final Looper mLooper;
private final WifiScannerImpl.WifiScannerImplFactory mScannerImplFactory;
private final ArrayMap<Messenger, ClientInfo> mClients;
+ private final Map<String, WifiScannerImpl> mScannerImpls;
+
private final RequestList<Void> mSingleScanListeners = new RequestList<>();
@@ -347,6 +369,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private final Clock mClock;
private final FrameworkFacade mFrameworkFacade;
private final WifiPermissionsUtil mWifiPermissionsUtil;
+ private final WifiNative mWifiNative;
WifiScanningServiceImpl(Context context, Looper looper,
WifiScannerImpl.WifiScannerImplFactory scannerImplFactory, IBatteryStats batteryStats,
@@ -356,12 +379,14 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
mScannerImplFactory = scannerImplFactory;
mBatteryStats = batteryStats;
mClients = new ArrayMap<>();
+ mScannerImpls = new ArrayMap<>();
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mWifiMetrics = wifiInjector.getWifiMetrics();
mClock = wifiInjector.getClock();
mLog = wifiInjector.makeLog(TAG);
mFrameworkFacade = wifiInjector.getFrameworkFacade();
mWifiPermissionsUtil = wifiInjector.getWifiPermissionsUtil();
+ mWifiNative = wifiInjector.getWifiNative();
mPreviousSchedule = null;
}
@@ -379,6 +404,81 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
/**
+ * Checks if all the channels provided by the new impl is already satisfied by an existing impl.
+ *
+ * Note: This only handles the cases where the 2 ifaces are on different chips with
+ * distinctly different bands supported on both. If there are cases where
+ * the 2 ifaces support overlapping bands, then we probably need to rework this.
+ * For example: wlan0 supports 2.4G only, wlan1 supports 2.4G + 5G + DFS.
+ * In the above example, we should teardown wlan0 impl when wlan1 impl is created
+ * because wlan1 impl can already handle all the supported bands.
+ * Ignoring this for now since we don't foresee this requirement in the near future.
+ */
+ private boolean doesAnyExistingImplSatisfy(WifiScannerImpl newImpl) {
+ for (WifiScannerImpl existingImpl : mScannerImpls.values()) {
+ if (existingImpl.getChannelHelper().satisfies(newImpl.getChannelHelper())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void setupScannerImpls() {
+ Set<String> ifaceNames = mWifiNative.getClientInterfaceNames();
+ if (ArrayUtils.isEmpty(ifaceNames)) {
+ loge("Failed to retrieve client interface names");
+ return;
+ }
+ Set<String> ifaceNamesOfImplsAlreadySetup = mScannerImpls.keySet();
+ if (ifaceNames.equals(ifaceNamesOfImplsAlreadySetup)) {
+ // Scanner Impls already exist for all ifaces (back to back CMD_ENABLE sent?).
+ Log.i(TAG, "scanner impls already exists");
+ return;
+ }
+ // set of impls to teardown.
+ Set<String> ifaceNamesOfImplsToTeardown = new ArraySet<>(ifaceNamesOfImplsAlreadySetup);
+ ifaceNamesOfImplsToTeardown.removeAll(ifaceNames);
+ // set of impls to be considered for setup.
+ Set<String> ifaceNamesOfImplsToSetup = new ArraySet<>(ifaceNames);
+ ifaceNamesOfImplsToSetup.removeAll(ifaceNamesOfImplsAlreadySetup);
+
+ for (String ifaceName : ifaceNamesOfImplsToTeardown) {
+ WifiScannerImpl impl = mScannerImpls.remove(ifaceName);
+ if (impl == null) continue; // should never happen
+ impl.cleanup();
+ Log.i(TAG, "Removed an impl for " + ifaceName);
+ }
+ for (String ifaceName : ifaceNamesOfImplsToSetup) {
+ WifiScannerImpl impl = mScannerImplFactory.create(mContext, mLooper, mClock, ifaceName);
+ if (impl == null) {
+ loge("Failed to create scanner impl for " + ifaceName);
+ continue;
+ }
+ // If this new scanner impl does not offer any new bands to scan, then we should
+ // ignore it.
+ if (!doesAnyExistingImplSatisfy(impl)) {
+ mScannerImpls.put(ifaceName, impl);
+ Log.i(TAG, "Created a new impl for " + ifaceName);
+ } else {
+ Log.i(TAG, "All the channels on the new impl for iface " + ifaceName
+ + " are already satisfied by an existing impl. Skipping..");
+ impl.cleanup(); // cleanup the impl before discarding.
+ }
+ }
+ }
+
+ private void teardownScannerImpls() {
+ for (Map.Entry<String, WifiScannerImpl> entry : mScannerImpls.entrySet()) {
+ WifiScannerImpl impl = entry.getValue();
+ String ifaceName = entry.getKey();
+ if (impl == null) continue; // should never happen
+ impl.cleanup();
+ Log.i(TAG, "Removed an impl for " + ifaceName);
+ }
+ mScannerImpls.clear();
+ }
+
+ /**
* Provide a way for unit tests to set valid log object in the WifiHandler
* @param log WifiLog object to assign to the clientHandler
*/
@@ -491,7 +591,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
* ScanningState. Any requests queued while scanning will be placed in the pending queue and
* executed after transitioning back to IdleState.
*/
- class WifiSingleScanStateMachine extends StateMachine implements WifiNative.ScanEventHandler {
+ class WifiSingleScanStateMachine extends StateMachine {
/**
* Maximum age of results that we return from our cache via
* {@link WifiScanner#getScanResults()}.
@@ -513,9 +613,14 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
// Scan results cached from the last full single scan request.
private final List<ScanResult> mCachedScanResults = new ArrayList<>();
+ // Tracks scan requests across multiple scanner impls.
+ private final ScannerImplsTracker mScannerImplsTracker;
+
WifiSingleScanStateMachine(Looper looper) {
super("WifiSingleScanStateMachine", looper);
+ mScannerImplsTracker = new ScannerImplsTracker();
+
setLogRecSize(128);
setLogOnlyTransitions(false);
@@ -530,46 +635,150 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
/**
- * Called to indicate a change in state for the current scan.
- * Will dispatch a coresponding event to the state machine
+ * Tracks a single scan request across all the available scanner impls.
+ *
+ * a) Initiates the scan using the same ScanSettings across all the available impls.
+ * b) Waits for all the impls to report the status of the scan request (success or failure).
+ * c) Calculates a consolidated scan status and sends the results if successful.
+ * Note: If there are failures on some of the scanner impls, we ignore them since we will
+ * get some scan results from the other successful impls. We don't declare total scan
+ * failures, unless all the scanner impls fail.
*/
- @Override
- public void onScanStatus(int event) {
- if (DBG) localLog("onScanStatus event received, event=" + event);
- switch(event) {
- case WifiNative.WIFI_SCAN_RESULTS_AVAILABLE:
- case WifiNative.WIFI_SCAN_THRESHOLD_NUM_SCANS:
- case WifiNative.WIFI_SCAN_THRESHOLD_PERCENT:
- sendMessage(CMD_SCAN_RESULTS_AVAILABLE);
- break;
- case WifiNative.WIFI_SCAN_FAILED:
- sendMessage(CMD_SCAN_FAILED);
- break;
- default:
- Log.e(TAG, "Unknown scan status event: " + event);
- break;
+ private final class ScannerImplsTracker {
+ private final class ScanEventHandler implements WifiNative.ScanEventHandler {
+ private final String mImplIfaceName;
+ ScanEventHandler(@NonNull String implIfaceName) {
+ mImplIfaceName = implIfaceName;
+ }
+
+ /**
+ * Called to indicate a change in state for the current scan.
+ * Will dispatch a corresponding event to the state machine
+ */
+ @Override
+ public void onScanStatus(int event) {
+ if (DBG) localLog("onScanStatus event received, event=" + event);
+ switch (event) {
+ case WifiNative.WIFI_SCAN_RESULTS_AVAILABLE:
+ case WifiNative.WIFI_SCAN_THRESHOLD_NUM_SCANS:
+ case WifiNative.WIFI_SCAN_THRESHOLD_PERCENT:
+ reportScanStatusForImpl(mImplIfaceName, STATUS_SUCCEEDED);
+ break;
+ case WifiNative.WIFI_SCAN_FAILED:
+ reportScanStatusForImpl(mImplIfaceName, STATUS_FAILED);
+ break;
+ default:
+ Log.e(TAG, "Unknown scan status event: " + event);
+ break;
+ }
+ }
+
+ /**
+ * Called for each full scan result if requested
+ */
+ @Override
+ public void onFullScanResult(ScanResult fullScanResult, int bucketsScanned) {
+ if (DBG) localLog("onFullScanResult received");
+ reportFullScanResultForImpl(mImplIfaceName, fullScanResult, bucketsScanned);
+ }
+
+ @Override
+ public void onScanPaused(ScanData[] scanData) {
+ // should not happen for single scan
+ Log.e(TAG, "Got scan paused for single scan");
+ }
+
+ @Override
+ public void onScanRestarted() {
+ // should not happen for single scan
+ Log.e(TAG, "Got scan restarted for single scan");
+ }
}
- }
- /**
- * Called for each full scan result if requested
- */
- @Override
- public void onFullScanResult(ScanResult fullScanResult, int bucketsScanned) {
- if (DBG) localLog("onFullScanResult received");
- sendMessage(CMD_FULL_SCAN_RESULTS, 0, bucketsScanned, fullScanResult);
- }
+ private static final int STATUS_PENDING = 0;
+ private static final int STATUS_SUCCEEDED = 1;
+ private static final int STATUS_FAILED = 2;
- @Override
- public void onScanPaused(ScanData[] scanData) {
- // should not happen for single scan
- Log.e(TAG, "Got scan paused for single scan");
- }
+ // Tracks scan status per impl.
+ Map<String, Integer> mStatusPerImpl = new ArrayMap<>();
- @Override
- public void onScanRestarted() {
- // should not happen for single scan
- Log.e(TAG, "Got scan restarted for single scan");
+ /**
+ * Triggers a new scan on all the available scanner impls.
+ * @return true if the scan succeeded on any of the impl, false otherwise.
+ */
+ public boolean startSingleScan(WifiNative.ScanSettings scanSettings) {
+ mStatusPerImpl.clear();
+ boolean anySuccess = false;
+ for (Map.Entry<String, WifiScannerImpl> entry : mScannerImpls.entrySet()) {
+ String ifaceName = entry.getKey();
+ WifiScannerImpl impl = entry.getValue();
+ boolean success = impl.startSingleScan(
+ scanSettings, new ScanEventHandler(ifaceName));
+ if (!success) {
+ Log.e(TAG, "Failed to start single scan on " + ifaceName);
+ continue;
+ }
+ mStatusPerImpl.put(ifaceName, STATUS_PENDING);
+ anySuccess = true;
+ }
+ return anySuccess;
+ }
+
+ /**
+ * Returns the latest scan results from all the available scanner impls.
+ * @return Consolidated list of scan results from all the impl.
+ */
+ public @Nullable ScanData getLatestSingleScanResults() {
+ ScanData consolidatedScanData = null;
+ for (WifiScannerImpl impl : mScannerImpls.values()) {
+ ScanData scanData = impl.getLatestSingleScanResults();
+ if (consolidatedScanData == null) {
+ consolidatedScanData = new ScanData(scanData);
+ } else {
+ consolidatedScanData.addResults(scanData.getResults());
+ }
+ }
+ return consolidatedScanData;
+ }
+
+ private void reportFullScanResultForImpl(@NonNull String implIfaceName,
+ ScanResult fullScanResult, int bucketsScanned) {
+ Integer status = mStatusPerImpl.get(implIfaceName);
+ if (status != null && status == STATUS_PENDING) {
+ sendMessage(CMD_FULL_SCAN_RESULTS, 0, bucketsScanned, fullScanResult);
+ }
+ }
+
+ private int getConsolidatedStatus() {
+ boolean anyPending = mStatusPerImpl.values().stream()
+ .anyMatch(status -> status == STATUS_PENDING);
+ // at-least one impl status is still pending.
+ if (anyPending) return STATUS_PENDING;
+
+ boolean anySuccess = mStatusPerImpl.values().stream()
+ .anyMatch(status -> status == STATUS_SUCCEEDED);
+ // one success is good enough to declare consolidated success.
+ if (anySuccess) {
+ return STATUS_SUCCEEDED;
+ } else {
+ // all failed.
+ return STATUS_FAILED;
+ }
+ }
+
+ private void reportScanStatusForImpl(@NonNull String implIfaceName, int newStatus) {
+ Integer currentStatus = mStatusPerImpl.get(implIfaceName);
+ if (currentStatus != null && currentStatus == STATUS_PENDING) {
+ mStatusPerImpl.put(implIfaceName, newStatus);
+ }
+ // Now check if all the scanner impls scan status is available.
+ int consolidatedStatus = getConsolidatedStatus();
+ if (consolidatedStatus == STATUS_SUCCEEDED) {
+ sendMessage(CMD_SCAN_RESULTS_AVAILABLE);
+ } else if (consolidatedStatus == STATUS_FAILED) {
+ sendMessage(CMD_SCAN_FAILED);
+ }
+ }
}
class DefaultState extends State {
@@ -581,15 +790,15 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
- case CMD_DRIVER_LOADED:
- if (mScannerImpl == null) {
+ case WifiScanner.CMD_ENABLE:
+ if (mScannerImpls.isEmpty()) {
loge("Failed to start single scan state machine because scanner impl"
+ " is null");
return HANDLED;
}
transitionTo(mIdleState);
return HANDLED;
- case CMD_DRIVER_UNLOADED:
+ case WifiScanner.CMD_DISABLE:
transitionTo(mDefaultState);
return HANDLED;
case WifiScanner.CMD_START_SINGLE_SCAN:
@@ -653,7 +862,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
ClientInfo ci = mClients.get(msg.replyTo);
switch (msg.what) {
- case CMD_DRIVER_LOADED:
+ case WifiScanner.CMD_ENABLE:
// Ignore if we're already in driver loaded state.
return HANDLED;
case WifiScanner.CMD_START_SINGLE_SCAN:
@@ -761,11 +970,17 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_SCAN_RESULTS_AVAILABLE:
- mWifiMetrics.incrementScanReturnEntry(
- WifiMetricsProto.WifiLog.SCAN_SUCCESS,
- mActiveScans.size());
- reportScanResults(mScannerImpl.getLatestSingleScanResults());
- mActiveScans.clear();
+ ScanData latestScanResults =
+ mScannerImplsTracker.getLatestSingleScanResults();
+ if (latestScanResults != null) {
+ mWifiMetrics.incrementScanReturnEntry(
+ WifiMetricsProto.WifiLog.SCAN_SUCCESS,
+ mActiveScans.size());
+ reportScanResults(latestScanResults);
+ mActiveScans.clear();
+ } else {
+ Log.e(TAG, "latest scan results null unexpectedly");
+ }
transitionTo(mIdleState);
return HANDLED;
case CMD_FULL_SCAN_RESULTS:
@@ -804,9 +1019,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
Log.e(TAG, "Invalid scan type " + settings.type);
return false;
}
- if (mContext.checkPermission(
- Manifest.permission.NETWORK_STACK, UNKNOWN_PID, ci.getUid())
- == PERMISSION_DENIED) {
+ if (!checkWifiStackPermission(ci.getUid())) {
if (!ArrayUtils.isEmpty(settings.hiddenNetworks)) {
Log.e(TAG, "Failing single scan because app " + ci.getUid()
+ " does not have permission to set hidden networks");
@@ -974,7 +1187,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
channels.fillBucketSettings(bucketSettings, Integer.MAX_VALUE);
settings.buckets = new WifiNative.BucketSettings[] {bucketSettings};
- if (mScannerImpl.startSingleScan(settings, this)) {
+ if (mScannerImplsTracker.startSingleScan(settings)) {
// store the active scan settings
mActiveScanSettings = settings;
// swap pending and active scan requests
@@ -1004,7 +1217,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
clientHandlers.clear();
}
- void reportFullScanResult(ScanResult result, int bucketsScanned) {
+ void reportFullScanResult(@NonNull ScanResult result, int bucketsScanned) {
for (RequestInfo<ScanSettings> entry : mActiveScans) {
if (ScanScheduleUtil.shouldReportFullScanResultForSettings(mChannelHelper,
result, bucketsScanned, entry.settings, -1)) {
@@ -1017,7 +1230,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
- void reportScanResults(ScanData results) {
+ void reportScanResults(@NonNull ScanData results) {
if (results != null && results.getResults() != null) {
if (results.getResults().length > 0) {
mWifiMetrics.incrementNonEmptyScanResultCount();
@@ -1059,8 +1272,9 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
- class WifiBackgroundScanStateMachine extends StateMachine
- implements WifiNative.ScanEventHandler {
+ // TODO(b/71855918): Remove this bg scan state machine and its dependencies.
+ // Note: bgscan will not support multiple scanner impls (will pick any).
+ class WifiBackgroundScanStateMachine extends StateMachine {
private final DefaultState mDefaultState = new DefaultState();
private final StartedState mStartedState = new StartedState();
@@ -1068,6 +1282,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private final RequestList<ScanSettings> mActiveBackgroundScans = new RequestList<>();
+ private WifiScannerImpl mScannerImpl;
+
WifiBackgroundScanStateMachine(Looper looper) {
super("WifiBackgroundScanStateMachine", looper);
@@ -1092,40 +1308,48 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
updateSchedule();
}
- @Override
- public void onScanStatus(int event) {
- if (DBG) localLog("onScanStatus event received, event=" + event);
- switch(event) {
- case WifiNative.WIFI_SCAN_RESULTS_AVAILABLE:
- case WifiNative.WIFI_SCAN_THRESHOLD_NUM_SCANS:
- case WifiNative.WIFI_SCAN_THRESHOLD_PERCENT:
- sendMessage(CMD_SCAN_RESULTS_AVAILABLE);
- break;
- case WifiNative.WIFI_SCAN_FAILED:
- sendMessage(CMD_SCAN_FAILED);
- break;
- default:
- Log.e(TAG, "Unknown scan status event: " + event);
- break;
+ private final class ScanEventHandler implements WifiNative.ScanEventHandler {
+ private final String mImplIfaceName;
+
+ ScanEventHandler(@NonNull String implIfaceName) {
+ mImplIfaceName = implIfaceName;
}
- }
- @Override
- public void onFullScanResult(ScanResult fullScanResult, int bucketsScanned) {
- if (DBG) localLog("onFullScanResult received");
- sendMessage(CMD_FULL_SCAN_RESULTS, 0, bucketsScanned, fullScanResult);
- }
+ @Override
+ public void onScanStatus(int event) {
+ if (DBG) localLog("onScanStatus event received, event=" + event);
+ switch (event) {
+ case WifiNative.WIFI_SCAN_RESULTS_AVAILABLE:
+ case WifiNative.WIFI_SCAN_THRESHOLD_NUM_SCANS:
+ case WifiNative.WIFI_SCAN_THRESHOLD_PERCENT:
+ sendMessage(CMD_SCAN_RESULTS_AVAILABLE);
+ break;
+ case WifiNative.WIFI_SCAN_FAILED:
+ sendMessage(CMD_SCAN_FAILED);
+ break;
+ default:
+ Log.e(TAG, "Unknown scan status event: " + event);
+ break;
+ }
+ }
- @Override
- public void onScanPaused(ScanData scanData[]) {
- if (DBG) localLog("onScanPaused received");
- sendMessage(CMD_SCAN_PAUSED, scanData);
- }
+ @Override
+ public void onFullScanResult(ScanResult fullScanResult, int bucketsScanned) {
+ if (DBG) localLog("onFullScanResult received");
+ sendMessage(CMD_FULL_SCAN_RESULTS, 0, bucketsScanned, fullScanResult);
+ }
- @Override
- public void onScanRestarted() {
- if (DBG) localLog("onScanRestarted received");
- sendMessage(CMD_SCAN_RESTARTED);
+ @Override
+ public void onScanPaused(ScanData[] scanData) {
+ if (DBG) localLog("onScanPaused received");
+ sendMessage(CMD_SCAN_PAUSED, scanData);
+ }
+
+ @Override
+ public void onScanRestarted() {
+ if (DBG) localLog("onScanRestarted received");
+ sendMessage(CMD_SCAN_RESTARTED);
+ }
}
class DefaultState extends State {
@@ -1138,16 +1362,14 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
- case CMD_DRIVER_LOADED:
- // TODO this should be moved to a common location since it is used outside
- // of this state machine. It is ok right now because the driver loaded event
- // is sent to this state machine first.
- mScannerImpl = mScannerImplFactory.create(mContext, mLooper, mClock);
- if (mScannerImpl == null) {
+ case WifiScanner.CMD_ENABLE:
+ if (mScannerImpls.isEmpty()) {
loge("Failed to start bgscan scan state machine because scanner impl"
+ " is null");
return HANDLED;
}
+ // Pick any impl available and stick to it until disable.
+ mScannerImpl = mScannerImpls.entrySet().iterator().next().getValue();
mChannelHelper = mScannerImpl.getChannelHelper();
mBackgroundScheduler = new BackgroundScanScheduler(mChannelHelper);
@@ -1171,7 +1393,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
transitionTo(mStartedState);
return HANDLED;
- case CMD_DRIVER_UNLOADED:
+ case WifiScanner.CMD_DISABLE:
Log.i(TAG, "wifi driver unloaded");
transitionTo(mDefaultState);
break;
@@ -1204,15 +1426,18 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
@Override
public void enter() {
if (DBG) localLog("StartedState");
+ if (mScannerImpl == null) {
+ // should never happen
+ Log.wtf(TAG, "Scanner impl unexpectedly null");
+ transitionTo(mDefaultState);
+ }
}
@Override
public void exit() {
sendBackgroundScanFailedToAllAndClear(
WifiScanner.REASON_UNSPECIFIED, "Scan was interrupted");
- if (mScannerImpl != null) {
- mScannerImpl.cleanup();
- }
+ mScannerImpl = null; // reset impl
}
@Override
@@ -1220,11 +1445,11 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
ClientInfo ci = mClients.get(msg.replyTo);
switch (msg.what) {
- case CMD_DRIVER_LOADED:
+ case WifiScanner.CMD_ENABLE:
Log.e(TAG, "wifi driver loaded received while already loaded");
// Ignore if we're already in driver loaded state.
return HANDLED;
- case CMD_DRIVER_UNLOADED:
+ case WifiScanner.CMD_DISABLE:
return NOT_HANDLED;
case WifiScanner.CMD_START_BACKGROUND_SCAN: {
mWifiMetrics.incrementBackgroundScanCount();
@@ -1392,7 +1617,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
+ ChannelHelper.toString(bucket));
}
- if (mScannerImpl.startBatchedScan(schedule, this)) {
+ if (mScannerImpl.startBatchedScan(schedule,
+ new ScanEventHandler(mScannerImpl.getIfaceName()))) {
if (DBG) {
Log.d(TAG, "scan restarted with " + schedule.num_buckets
+ " bucket(s) and base period: " + schedule.base_period_ms);
@@ -1505,7 +1731,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
* multiple requests at the same time, so will need non-trivial changes to support (if at all
* possible) in WifiScanningService.
*/
- class WifiPnoScanStateMachine extends StateMachine implements WifiNative.PnoEventHandler {
+ class WifiPnoScanStateMachine extends StateMachine {
private final DefaultState mDefaultState = new DefaultState();
private final StartedState mStartedState = new StartedState();
@@ -1515,10 +1741,14 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private final RequestList<Pair<PnoSettings, ScanSettings>> mActivePnoScans =
new RequestList<>();
+ // Tracks scan requests across multiple scanner impls.
+ private final ScannerImplsTracker mScannerImplsTracker;
WifiPnoScanStateMachine(Looper looper) {
super("WifiPnoScanStateMachine", looper);
+ mScannerImplsTracker = new ScannerImplsTracker();
+
setLogRecSize(256);
setLogOnlyTransitions(false);
@@ -1537,16 +1767,125 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
transitionTo(mStartedState);
}
- @Override
- public void onPnoNetworkFound(ScanResult[] results) {
- if (DBG) localLog("onWifiPnoNetworkFound event received");
- sendMessage(CMD_PNO_NETWORK_FOUND, 0, 0, results);
- }
+ /**
+ * Tracks a PNO scan request across all the available scanner impls.
+ *
+ * Note: If there are failures on some of the scanner impls, we ignore them since we can
+ * get a PNO match from the other successful impls. We don't declare total scan
+ * failures, unless all the scanner impls fail.
+ */
+ private final class ScannerImplsTracker {
+ private final class PnoEventHandler implements WifiNative.PnoEventHandler {
+ private final String mImplIfaceName;
- @Override
- public void onPnoScanFailed() {
- if (DBG) localLog("onWifiPnoScanFailed event received");
- sendMessage(CMD_PNO_SCAN_FAILED, 0, 0, null);
+ PnoEventHandler(@NonNull String implIfaceName) {
+ mImplIfaceName = implIfaceName;
+ }
+
+ @Override
+ public void onPnoNetworkFound(ScanResult[] results) {
+ if (DBG) localLog("onWifiPnoNetworkFound event received");
+ reportPnoNetworkFoundForImpl(mImplIfaceName, results);
+ }
+
+ @Override
+ public void onPnoScanFailed() {
+ if (DBG) localLog("onWifiPnoScanFailed event received");
+ reportPnoScanFailedForImpl(mImplIfaceName);
+ }
+ }
+
+ private static final int STATUS_PENDING = 0;
+ private static final int STATUS_FAILED = 2;
+
+ // Tracks scan status per impl.
+ Map<String, Integer> mStatusPerImpl = new ArrayMap<>();
+
+ /**
+ * Triggers a new PNO with the specified settings on all the available scanner impls.
+ * @return true if the PNO succeeded on any of the impl, false otherwise.
+ */
+ public boolean setHwPnoList(WifiNative.PnoSettings pnoSettings) {
+ mStatusPerImpl.clear();
+ boolean anySuccess = false;
+ for (Map.Entry<String, WifiScannerImpl> entry : mScannerImpls.entrySet()) {
+ String ifaceName = entry.getKey();
+ WifiScannerImpl impl = entry.getValue();
+ boolean success = impl.setHwPnoList(
+ pnoSettings, new PnoEventHandler(ifaceName));
+ if (!success) {
+ Log.e(TAG, "Failed to start pno on " + ifaceName);
+ continue;
+ }
+ mStatusPerImpl.put(ifaceName, STATUS_PENDING);
+ anySuccess = true;
+ }
+ return anySuccess;
+ }
+
+ /**
+ * Resets any ongoing PNO on all the available scanner impls.
+ * @return true if the PNO stop succeeded on all of the impl, false otherwise.
+ */
+ public boolean resetHwPnoList() {
+ boolean allSuccess = true;
+ for (String ifaceName : mStatusPerImpl.keySet()) {
+ WifiScannerImpl impl = mScannerImpls.get(ifaceName);
+ if (impl == null) continue;
+ boolean success = impl.resetHwPnoList();
+ if (!success) {
+ Log.e(TAG, "Failed to stop pno on " + ifaceName);
+ allSuccess = false;
+ }
+ }
+ mStatusPerImpl.clear();
+ return allSuccess;
+ }
+
+ /**
+ * @return true if HW PNO is supported on all the available scanner impls,
+ * false otherwise.
+ */
+ public boolean isHwPnoSupported(boolean isConnected) {
+ for (WifiScannerImpl impl : mScannerImpls.values()) {
+ if (!impl.isHwPnoSupported(isConnected)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void reportPnoNetworkFoundForImpl(@NonNull String implIfaceName,
+ ScanResult[] results) {
+ Integer status = mStatusPerImpl.get(implIfaceName);
+ if (status != null && status == STATUS_PENDING) {
+ sendMessage(CMD_PNO_NETWORK_FOUND, 0, 0, results);
+ }
+ }
+
+ private int getConsolidatedStatus() {
+ boolean anyPending = mStatusPerImpl.values().stream()
+ .anyMatch(status -> status == STATUS_PENDING);
+ // at-least one impl status is still pending.
+ if (anyPending) {
+ return STATUS_PENDING;
+ } else {
+ // all failed.
+ return STATUS_FAILED;
+ }
+ }
+
+ private void reportPnoScanFailedForImpl(@NonNull String implIfaceName) {
+ Integer currentStatus = mStatusPerImpl.get(implIfaceName);
+ if (currentStatus != null && currentStatus == STATUS_PENDING) {
+ mStatusPerImpl.put(implIfaceName, STATUS_FAILED);
+ }
+ // Now check if all the scanner impls scan status is available.
+ int consolidatedStatus = getConsolidatedStatus();
+ if (consolidatedStatus == STATUS_FAILED) {
+ sendMessage(CMD_PNO_SCAN_FAILED);
+ }
+ }
}
class DefaultState extends State {
@@ -1558,15 +1897,15 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
- case CMD_DRIVER_LOADED:
- if (mScannerImpl == null) {
+ case WifiScanner.CMD_ENABLE:
+ if (mScannerImpls.isEmpty()) {
loge("Failed to start pno scan state machine because scanner impl"
+ " is null");
return HANDLED;
}
transitionTo(mStartedState);
break;
- case CMD_DRIVER_UNLOADED:
+ case WifiScanner.CMD_DISABLE:
transitionTo(mDefaultState);
break;
case WifiScanner.CMD_START_PNO_SCAN:
@@ -1602,7 +1941,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
public boolean processMessage(Message msg) {
ClientInfo ci = mClients.get(msg.replyTo);
switch (msg.what) {
- case CMD_DRIVER_LOADED:
+ case WifiScanner.CMD_ENABLE:
// Ignore if we're already in driver loaded state.
return HANDLED;
case WifiScanner.CMD_START_PNO_SCAN:
@@ -1614,7 +1953,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
pnoParams.setDefusable(true);
PnoSettings pnoSettings =
pnoParams.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY);
- if (mScannerImpl.isHwPnoSupported(pnoSettings.isConnected)) {
+ if (mScannerImplsTracker.isHwPnoSupported(pnoSettings.isConnected)) {
deferMessage(msg);
transitionTo(mHwPnoScanState);
} else {
@@ -1640,7 +1979,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
@Override
public void exit() {
// Reset PNO scan in ScannerImpl before we exit.
- mScannerImpl.resetHwPnoList();
+ mScannerImplsTracker.resetHwPnoList();
removeInternalClient();
}
@@ -1806,7 +2145,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
WifiNative.PnoSettings nativePnoSettings =
convertSettingsToPnoNative(scanSettings, pnoSettings);
- if (!mScannerImpl.setHwPnoList(nativePnoSettings, mPnoScanStateMachine)) {
+ if (!mScannerImplsTracker.setHwPnoList(nativePnoSettings)) {
return false;
}
logScanRequest("addHwPnoScanRequest", ci, handler, null, scanSettings, pnoSettings);
@@ -2182,8 +2521,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
ScanResultUtil.dumpScanResults(pw, scanResults, nowMs);
pw.println();
}
- if (mScannerImpl != null) {
- mScannerImpl.dump(fd, pw, args);
+ for (WifiScannerImpl impl : mScannerImpls.values()) {
+ impl.dump(fd, pw, args);
}
}
diff --git a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
index e3bd207dfb..c8319c6ec5 100644
--- a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
@@ -31,6 +31,7 @@ import com.android.server.wifi.ScanDetail;
import com.android.server.wifi.WifiMonitor;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection;
+import com.android.server.wifi.util.NativeUtil;
import com.android.server.wifi.util.ScanResultUtil;
import java.io.FileDescriptor;
@@ -60,7 +61,6 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
private static final int MAX_SCAN_BUCKETS = 16;
private final Context mContext;
- private final String mIfaceName;
private final WifiNative mWifiNative;
private final WifiMonitor mWifiMonitor;
private final AlarmManager mAlarmManager;
@@ -96,8 +96,8 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
public WificondScannerImpl(Context context, String ifaceName, WifiNative wifiNative,
WifiMonitor wifiMonitor, ChannelHelper channelHelper,
Looper looper, Clock clock) {
+ super(ifaceName);
mContext = context;
- mIfaceName = ifaceName;
mWifiNative = wifiNative;
mWifiMonitor = wifiMonitor;
mChannelHelper = channelHelper;
@@ -109,11 +109,11 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
mHwPnoScanSupported = mContext.getResources().getBoolean(
R.bool.config_wifi_background_scan_support);
- wifiMonitor.registerHandler(mIfaceName,
+ wifiMonitor.registerHandler(getIfaceName(),
WifiMonitor.SCAN_FAILED_EVENT, mEventHandler);
- wifiMonitor.registerHandler(mIfaceName,
+ wifiMonitor.registerHandler(getIfaceName(),
WifiMonitor.PNO_SCAN_RESULTS_EVENT, mEventHandler);
- wifiMonitor.registerHandler(mIfaceName,
+ wifiMonitor.registerHandler(getIfaceName(),
WifiMonitor.SCAN_RESULTS_EVENT, mEventHandler);
}
@@ -123,11 +123,11 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
stopHwPnoScan();
mLastScanSettings = null; // finally clear any active scan
mLastPnoScanSettings = null; // finally clear any active scan
- mWifiMonitor.deregisterHandler(mIfaceName,
+ mWifiMonitor.deregisterHandler(getIfaceName(),
WifiMonitor.SCAN_FAILED_EVENT, mEventHandler);
- mWifiMonitor.deregisterHandler(mIfaceName,
+ mWifiMonitor.deregisterHandler(getIfaceName(),
WifiMonitor.PNO_SCAN_RESULTS_EVENT, mEventHandler);
- mWifiMonitor.deregisterHandler(mIfaceName,
+ mWifiMonitor.deregisterHandler(getIfaceName(),
WifiMonitor.SCAN_RESULTS_EVENT, mEventHandler);
}
}
@@ -190,7 +190,7 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
if (!allFreqs.isEmpty()) {
freqs = allFreqs.getScanFreqs();
success = mWifiNative.scan(
- mIfaceName, settings.scanType, freqs, hiddenNetworkSSIDSet);
+ getIfaceName(), settings.scanType, freqs, hiddenNetworkSSIDSet);
if (!success) {
Log.e(TAG, "Failed to start scan, freqs=" + freqs);
}
@@ -321,7 +321,7 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
// got a scan before we started scanning or after scan was canceled
return;
}
- mNativePnoScanResults = mWifiNative.getPnoScanResults(mIfaceName);
+ mNativePnoScanResults = mWifiNative.getPnoScanResults(getIfaceName());
List<ScanResult> hwPnoScanResults = new ArrayList<>();
int numFilteredScanResults = 0;
for (int i = 0; i < mNativePnoScanResults.size(); ++i) {
@@ -373,7 +373,7 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
return;
}
- mNativeScanResults = mWifiNative.getScanResults(mIfaceName);
+ mNativeScanResults = mWifiNative.getScanResults(getIfaceName());
List<ScanResult> singleScanResults = new ArrayList<>();
int numFilteredScanResults = 0;
for (int i = 0; i < mNativeScanResults.size(); ++i) {
@@ -419,11 +419,11 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
}
private boolean startHwPnoScan(WifiNative.PnoSettings pnoSettings) {
- return mWifiNative.startPnoScan(mIfaceName, pnoSettings);
+ return mWifiNative.startPnoScan(getIfaceName(), pnoSettings);
}
private void stopHwPnoScan() {
- mWifiNative.stopPnoScan(mIfaceName);
+ mWifiNative.stopPnoScan(getIfaceName());
}
/**
@@ -498,6 +498,16 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
}).collect(Collectors.toList());
ScanResultUtil.dumpScanResults(pw, pnoScanResults, nowMs);
}
+ pw.println("Latest native scan results IEs:");
+ if (mNativeScanResults != null) {
+ for (ScanDetail detail : mNativeScanResults) {
+ if (detail.getInformationElementRawData() != null) {
+ pw.println(NativeUtil.hexStringFromByteArray(
+ detail.getInformationElementRawData()));
+ }
+ }
+ }
+ pw.println("");
}
}
diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
index c3a4c0c95f..2ca0641c36 100644
--- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
+++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
@@ -44,6 +44,7 @@ public class ApConfigUtil {
/**
* Convert frequency to channel.
+ * Note: the utility does not perform any regulatory domain compliance.
* @param frequency frequency to convert
* @return channel number associated with given frequency, -1 if no match
*/
@@ -52,7 +53,7 @@ public class ApConfigUtil {
return (frequency - 2412) / 5 + 1;
} else if (frequency == 2484) {
return 14;
- } else if (frequency >= 5170 && frequency <= 5825) {
+ } else if (frequency >= 5170 && frequency <= 5865) {
/* DFS is included. */
return (frequency - 5170) / 5 + 34;
}
diff --git a/service/java/com/android/server/wifi/util/EncryptedData.java b/service/java/com/android/server/wifi/util/EncryptedData.java
index 91342d3356..0b29099f8a 100644
--- a/service/java/com/android/server/wifi/util/EncryptedData.java
+++ b/service/java/com/android/server/wifi/util/EncryptedData.java
@@ -29,10 +29,11 @@ public class EncryptedData {
private final byte[] mIv;
public EncryptedData(byte[] encryptedData, byte[] iv) {
- Preconditions.checkNotNull(encryptedData, iv);
- Preconditions.checkState(encryptedData.length == ENCRYPTED_DATA_LENGTH,
+ Preconditions.checkNotNull(encryptedData);
+ Preconditions.checkNotNull(iv);
+ Preconditions.checkArgument(encryptedData.length == ENCRYPTED_DATA_LENGTH,
"encryptedData.length=" + encryptedData.length);
- Preconditions.checkState(iv.length == IV_LENGTH, "iv.length=" + iv.length);
+ Preconditions.checkArgument(iv.length == IV_LENGTH, "iv.length=" + iv.length);
mEncryptedData = encryptedData;
mIv = iv;
}
diff --git a/service/java/com/android/server/wifi/util/Environment.java b/service/java/com/android/server/wifi/util/Environment.java
new file mode 100644
index 0000000000..9ce90f8f05
--- /dev/null
+++ b/service/java/com/android/server/wifi/util/Environment.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.util;
+
+import java.io.File;
+
+/**
+ * Provides access to environment variables.
+ *
+ * Note: @hide methods copied from android.os.Environment
+ */
+public class Environment {
+ /**
+ * Get data/misc directory
+ */
+ public static File getDataMiscDirectory() {
+ return new File(android.os.Environment.getDataDirectory(), "misc");
+ }
+
+ /**
+ * Get data/misc_ce/<userId> directory
+ */
+ public static File getDataMiscCeDirectory(int userId) {
+ return buildPath(android.os.Environment.getDataDirectory(), "misc_ce",
+ String.valueOf(userId));
+ }
+
+ /**
+ * Append path segments to given base path, returning result.
+ */
+ public static File buildPath(File base, String... segments) {
+ File cur = base;
+ for (String segment : segments) {
+ if (cur == null) {
+ cur = new File(segment);
+ } else {
+ cur = new File(cur, segment);
+ }
+ }
+ return cur;
+ }
+
+}
diff --git a/service/java/com/android/server/wifi/util/ExternalCallbackTracker.java b/service/java/com/android/server/wifi/util/ExternalCallbackTracker.java
index 8f92da4315..225e68ac44 100644
--- a/service/java/com/android/server/wifi/util/ExternalCallbackTracker.java
+++ b/service/java/com/android/server/wifi/util/ExternalCallbackTracker.java
@@ -17,6 +17,7 @@
package com.android.server.wifi.util;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
@@ -72,11 +73,11 @@ public class ExternalCallbackTracker<T> {
* @return an instance of {@link ExternalCallbackHolder} if there are no failures, otherwise
* null.
*/
- public static <T> ExternalCallbackHolder createAndLinkToDeath(
+ public static <T> ExternalCallbackHolder<T> createAndLinkToDeath(
@NonNull IBinder binder, @NonNull T callbackObject,
@NonNull DeathCallback deathCallback) {
ExternalCallbackHolder<T> externalCallback =
- new ExternalCallbackHolder<T>(binder, callbackObject, deathCallback);
+ new ExternalCallbackHolder<>(binder, callbackObject, deathCallback);
try {
binder.linkToDeath(externalCallback, 0);
} catch (RemoteException e) {
@@ -131,8 +132,9 @@ public class ExternalCallbackTracker<T> {
});
});
if (externalCallback == null) return false;
- if (mCallbacks.containsKey(callbackIdentifier) && remove(callbackIdentifier)) {
+ if (mCallbacks.containsKey(callbackIdentifier)) {
Log.d(TAG, "Replacing callback " + callbackIdentifier);
+ remove(callbackIdentifier);
}
mCallbacks.put(callbackIdentifier, externalCallback);
if (mCallbacks.size() > NUM_CALLBACKS_WTF_LIMIT) {
@@ -145,16 +147,16 @@ public class ExternalCallbackTracker<T> {
/**
* Remove a callback object to tracker.
- * @return true on success, false on failure.
+ * @return Removed object instance on success, null on failure.
*/
- public boolean remove(int callbackIdentifier) {
+ public @Nullable T remove(int callbackIdentifier) {
ExternalCallbackHolder<T> externalCallback = mCallbacks.remove(callbackIdentifier);
if (externalCallback == null) {
Log.w(TAG, "Unknown external callback " + callbackIdentifier);
- return false;
+ return null;
}
externalCallback.reset();
- return true;
+ return externalCallback.getCallback();
}
/**
diff --git a/service/java/com/android/server/wifi/util/FileUtils.java b/service/java/com/android/server/wifi/util/FileUtils.java
new file mode 100644
index 0000000000..07b1155c33
--- /dev/null
+++ b/service/java/com/android/server/wifi/util/FileUtils.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.util;
+
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.Log;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Utility methods useful for working with files.
+ *
+ * Note: @hide methods copied from android.os.FileUtils
+ */
+public final class FileUtils {
+ private static final String TAG = "FileUtils";
+
+ /**
+ * Set owner and mode of of given path.
+ *
+ * @param mode to apply through {@code chmod}
+ * @param uid to apply through {@code chown}, or -1 to leave unchanged
+ * @param gid to apply through {@code chown}, or -1 to leave unchanged
+ * @return 0 on success, otherwise errno.
+ */
+ public static int setPermissions(String path, int mode, int uid, int gid) {
+ try {
+ Os.chmod(path, mode);
+ } catch (ErrnoException e) {
+ Log.w(TAG, "Failed to chmod(" + path + "): " + e);
+ return e.errno;
+ }
+
+ if (uid >= 0 || gid >= 0) {
+ try {
+ Os.chown(path, uid, gid);
+ } catch (ErrnoException e) {
+ Log.w(TAG, "Failed to chown(" + path + "): " + e);
+ return e.errno;
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * Writes the bytes given in {@code content} to the file whose absolute path
+ * is {@code filename}.
+ */
+ public static void bytesToFile(String filename, byte[] content) throws IOException {
+ try (FileOutputStream fos = new FileOutputStream(filename)) {
+ fos.write(content);
+ }
+ }
+
+ /**
+ * Writes string to file. Basically same as "echo -n $string > $filename"
+ *
+ * @param filename
+ * @param string
+ * @throws IOException
+ */
+ public static void stringToFile(String filename, String string) throws IOException {
+ bytesToFile(filename, string.getBytes(StandardCharsets.UTF_8));
+ }
+
+}
diff --git a/service/java/com/android/server/wifi/util/InformationElementUtil.java b/service/java/com/android/server/wifi/util/InformationElementUtil.java
index 5a55750d69..61b600b97d 100644
--- a/service/java/com/android/server/wifi/util/InformationElementUtil.java
+++ b/service/java/com/android/server/wifi/util/InformationElementUtil.java
@@ -151,73 +151,148 @@ public class InformationElementUtil {
}
public static class HtOperation {
- public int secondChannelOffset = 0;
+ private static final int HT_OPERATION_IE_LEN = 22;
+ private boolean mPresent = false;
+ private int mSecondChannelOffset = 0;
+ /**
+ * returns if HT Operation IE present in the message.
+ */
+ public boolean isPresent() {
+ return mPresent;
+ }
+
+ /**
+ * Returns channel width if it is 20 or 40MHz
+ * Results will be invalid if channel width greater than 40MHz
+ * So caller should only call this method if VHT Operation IE is not present,
+ * or if VhtOperation.getChannelWidth() returns ScanResult.UNSPECIFIED.
+ */
public int getChannelWidth() {
- if (secondChannelOffset != 0) {
- return 1;
+ if (mSecondChannelOffset != 0) {
+ return ScanResult.CHANNEL_WIDTH_40MHZ;
} else {
- return 0;
+ return ScanResult.CHANNEL_WIDTH_20MHZ;
}
}
+ /**
+ * Returns channel Center frequency (for 20/40 MHz channels only)
+ * Results will be invalid for larger channel width,
+ * So, caller should only call this method if VHT Operation IE is not present,
+ * or if VhtOperation.getChannelWidth() returns ScanResult.UNSPECIFIED.
+ */
public int getCenterFreq0(int primaryFrequency) {
- //40 MHz
- if (secondChannelOffset != 0) {
- if (secondChannelOffset == 1) {
+ if (mSecondChannelOffset != 0) {
+ //40 MHz
+ if (mSecondChannelOffset == 1) {
return primaryFrequency + 10;
- } else if (secondChannelOffset == 3) {
+ } else if (mSecondChannelOffset == 3) {
return primaryFrequency - 10;
} else {
- Log.e("HtOperation", "Error on secondChannelOffset: " + secondChannelOffset);
+ Log.e("HtOperation", "Error on secondChannelOffset: " + mSecondChannelOffset);
return 0;
}
} else {
- return 0;
+ //20 MHz
+ return primaryFrequency;
}
}
+ /**
+ * Parse the HT Operation IE to read the fields of interest.
+ */
public void from(InformationElement ie) {
if (ie.id != InformationElement.EID_HT_OPERATION) {
throw new IllegalArgumentException("Element id is not HT_OPERATION, : " + ie.id);
}
- secondChannelOffset = ie.bytes[1] & 0x3;
+ if (ie.bytes.length < HT_OPERATION_IE_LEN) {
+ throw new IllegalArgumentException("Invalid HT_OPERATION len: " + ie.bytes.length);
+ }
+ mPresent = true;
+ mSecondChannelOffset = ie.bytes[1] & 0x3;
}
}
public static class VhtOperation {
- public int channelMode = 0;
- public int centerFreqIndex1 = 0;
- public int centerFreqIndex2 = 0;
+ private static final int VHT_OPERATION_IE_LEN = 5;
+ private boolean mPresent = false;
+ private int mChannelMode = 0;
+ private int mCenterFreqIndex1 = 0;
+ private int mCenterFreqIndex2 = 0;
- public boolean isValid() {
- return channelMode != 0;
+ /**
+ * returns if VHT Operation IE present in the message.
+ */
+ public boolean isPresent() {
+ return mPresent;
}
+ /**
+ * Returns channel width if it is above 40MHz,
+ * otherwise, returns {@link ScanResult.UNSPECIFIED} to indicate that
+ * channel width should be obtained from the HT Operation IE via
+ * HtOperation.getChannelWidth().
+ */
public int getChannelWidth() {
- return channelMode + 1;
+ if (mChannelMode == 0) {
+ // 20 or 40MHz
+ return ScanResult.UNSPECIFIED;
+ } else if (mCenterFreqIndex2 == 0) {
+ // No secondary channel
+ return ScanResult.CHANNEL_WIDTH_80MHZ;
+ } else if (Math.abs(mCenterFreqIndex2 - mCenterFreqIndex1) == 8) {
+ // Primary and secondary channels adjacent
+ return ScanResult.CHANNEL_WIDTH_160MHZ;
+ } else {
+ // Primary and secondary channels not adjacent
+ return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
+ }
}
+ /**
+ * Returns center frequency of primary channel (if channel width greater than 40MHz),
+ * otherwise, it returns zero to indicate that center frequency should be obtained from
+ * the HT Operation IE via HtOperation.getCenterFreq0().
+ */
public int getCenterFreq0() {
- //convert channel index to frequency in MHz, channel 36 is 5180MHz
- return (centerFreqIndex1 - 36) * 5 + 5180;
+ if (mCenterFreqIndex1 == 0 || mChannelMode == 0) {
+ return 0;
+ } else {
+ //convert channel index to frequency in MHz, channel 36 is 5180MHz
+ return (mCenterFreqIndex1 - 36) * 5 + 5180;
+ }
}
+ /**
+ * Returns center frequency of secondary channel if exists (channel width greater than
+ * 40MHz), otherwise, it returns zero.
+ * Note that the secondary channel center frequency only applies to 80+80 or 160 MHz
+ * channels.
+ */
public int getCenterFreq1() {
- if (channelMode > 1) { //160MHz
- return (centerFreqIndex2 - 36) * 5 + 5180;
- } else {
+ if (mCenterFreqIndex2 == 0 || mChannelMode == 0) {
return 0;
+ } else {
+ //convert channel index to frequency in MHz, channel 36 is 5180MHz
+ return (mCenterFreqIndex2 - 36) * 5 + 5180;
}
}
+ /**
+ * Parse the VHT Operation IE to read the fields of interest.
+ */
public void from(InformationElement ie) {
if (ie.id != InformationElement.EID_VHT_OPERATION) {
throw new IllegalArgumentException("Element id is not VHT_OPERATION, : " + ie.id);
}
- channelMode = ie.bytes[0] & Constants.BYTE_MASK;
- centerFreqIndex1 = ie.bytes[1] & Constants.BYTE_MASK;
- centerFreqIndex2 = ie.bytes[2] & Constants.BYTE_MASK;
+ if (ie.bytes.length < VHT_OPERATION_IE_LEN) {
+ throw new IllegalArgumentException("Invalid VHT_OPERATION len: " + ie.bytes.length);
+ }
+ mPresent = true;
+ mChannelMode = ie.bytes[0] & Constants.BYTE_MASK;
+ mCenterFreqIndex1 = ie.bytes[1] & Constants.BYTE_MASK;
+ mCenterFreqIndex2 = ie.bytes[2] & Constants.BYTE_MASK;
}
}
@@ -395,6 +470,7 @@ public class InformationElementUtil {
*/
public static class Capabilities {
private static final int CAP_ESS_BIT_OFFSET = 0;
+ private static final int CAP_IBSS_BIT_OFFSET = 1;
private static final int CAP_PRIVACY_BIT_OFFSET = 4;
private static final int WPA_VENDOR_OUI_TYPE_ONE = 0x01f25000;
@@ -416,6 +492,7 @@ public class InformationElementUtil {
private static final int RSN_AKM_FT_SAE = 0x09ac0f00;
private static final int RSN_AKM_OWE = 0x12ac0f00;
private static final int RSN_AKM_EAP_SUITE_B_192 = 0x0cac0f00;
+ private static final int RSN_OSEN = 0x019a6f50;
private static final int WPA_CIPHER_NONE = 0x00f25000;
private static final int WPA_CIPHER_TKIP = 0x02f25000;
@@ -432,6 +509,7 @@ public class InformationElementUtil {
public ArrayList<ArrayList<Integer>> pairwiseCipher;
public ArrayList<Integer> groupCipher;
public boolean isESS;
+ public boolean isIBSS;
public boolean isPrivacy;
public boolean isWPS;
@@ -514,6 +592,9 @@ public class InformationElementUtil {
case RSN_AKM_EAP_SUITE_B_192:
rsnKeyManagement.add(ScanResult.KEY_MGMT_EAP_SUITE_B_192);
break;
+ case RSN_OSEN:
+ rsnKeyManagement.add(ScanResult.KEY_MGMT_OSEN);
+ break;
default:
// do nothing
break;
@@ -678,6 +759,7 @@ public class InformationElementUtil {
return;
}
isESS = beaconCap.get(CAP_ESS_BIT_OFFSET);
+ isIBSS = beaconCap.get(CAP_IBSS_BIT_OFFSET);
isPrivacy = beaconCap.get(CAP_PRIVACY_BIT_OFFSET);
for (InformationElement ie : ies) {
if (ie.id == InformationElement.EID_RSN) {
@@ -739,6 +821,8 @@ public class InformationElementUtil {
return "WPA";
case ScanResult.PROTOCOL_RSN:
return "RSN";
+ case ScanResult.PROTOCOL_OSEN:
+ return "OSEN";
default:
return "?";
}
@@ -770,6 +854,8 @@ public class InformationElementUtil {
return "FT/SAE";
case ScanResult.KEY_MGMT_EAP_SUITE_B_192:
return "EAP_SUITE_B_192";
+ case ScanResult.KEY_MGMT_OSEN:
+ return "OSEN";
default:
return "?";
}
@@ -814,6 +900,9 @@ public class InformationElementUtil {
if (isESS) {
capabilities.append("[ESS]");
}
+ if (isIBSS) {
+ capabilities.append("[IBSS]");
+ }
if (isWPS) {
capabilities.append("[WPS]");
}
diff --git a/service/java/com/android/server/wifi/util/TelephonyUtil.java b/service/java/com/android/server/wifi/util/TelephonyUtil.java
index 4af40ddf20..a80c18cf66 100644
--- a/service/java/com/android/server/wifi/util/TelephonyUtil.java
+++ b/service/java/com/android/server/wifi/util/TelephonyUtil.java
@@ -22,6 +22,7 @@ import android.net.wifi.WifiEnterpriseConfig;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.util.Pair;
@@ -728,6 +729,45 @@ public class TelephonyUtil {
* Returns true if at least one SIM is present on the device, false otherwise.
*/
public static boolean isSimPresent(@Nonnull SubscriptionManager sm) {
- return sm.getActiveSubscriptionIdList().length > 0;
+ return !sm.getActiveSubscriptionInfoList().isEmpty();
+ }
+
+ /**
+ * Decorates a pseudonym with the NAI realm, in case it wasn't provided by the server
+ *
+ * @param tm TelephonyManager instance
+ * @param pseudonym The pseudonym (temporary identity) provided by the server
+ * @return pseudonym@realm which is based on current MCC/MNC, {@code null} if SIM is
+ * not ready or absent.
+ */
+ public static String decoratePseudonymWith3GppRealm(@NonNull TelephonyManager tm,
+ String pseudonym) {
+ if (tm == null || TextUtils.isEmpty(pseudonym)) {
+ return null;
+ }
+ if (pseudonym.contains("@")) {
+ // Pseudonym is already decorated
+ return pseudonym;
+ }
+ TelephonyManager defaultDataTm = tm.createForSubscriptionId(
+ SubscriptionManager.getDefaultDataSubscriptionId());
+ if (defaultDataTm.getSimState() != TelephonyManager.SIM_STATE_READY) {
+ return null;
+ }
+ String mccMnc = defaultDataTm.getSimOperator();
+ if (mccMnc == null || mccMnc.isEmpty()) {
+ return null;
+ }
+
+ // Extract mcc & mnc from mccMnc
+ String mcc = mccMnc.substring(0, 3);
+ String mnc = mccMnc.substring(3);
+
+ if (mnc.length() == 2) {
+ mnc = "0" + mnc;
+ }
+
+ String realm = String.format(THREE_GPP_NAI_REALM_FORMAT, mnc, mcc);
+ return String.format("%s@%s", pseudonym, realm);
}
}
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
index b1ceaf37af..6e50743581 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
@@ -17,25 +17,24 @@
package com.android.server.wifi.util;
import android.Manifest;
+import android.annotation.Nullable;
import android.app.AppOpsManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.location.LocationManager;
import android.net.NetworkStack;
import android.os.Binder;
import android.os.Build;
-import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
-import android.util.Slog;
+import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiLog;
-import java.util.List;
-
/**
* A wifi permissions utility assessing permissions
* for getting scan results by a package.
@@ -67,45 +66,8 @@ public class WifiPermissionsUtil {
* @return true if the app does have the permission, false otherwise.
*/
public boolean checkConfigOverridePermission(int uid) {
- try {
- int permission = mWifiPermissionsWrapper.getOverrideWifiConfigPermission(uid);
- return (permission == PackageManager.PERMISSION_GRANTED);
- } catch (RemoteException e) {
- mLog.err("Error checking for permission: %").r(e.getMessage()).flush();
- return false;
- }
- }
-
- /**
- * Checks if the app has the permission to change Wi-Fi network configuration or not.
- *
- * @param uid uid of the app.
- * @return true if the app does have the permission, false otherwise.
- */
- public boolean checkChangePermission(int uid) {
- try {
- int permission = mWifiPermissionsWrapper.getChangeWifiConfigPermission(uid);
- return (permission == PackageManager.PERMISSION_GRANTED);
- } catch (RemoteException e) {
- mLog.err("Error checking for permission: %").r(e.getMessage()).flush();
- return false;
- }
- }
-
- /**
- * Checks if the app has the permission to access Wi-Fi state or not.
- *
- * @param uid uid of the app.
- * @return true if the app does have the permission, false otherwise.
- */
- public boolean checkWifiAccessPermission(int uid) {
- try {
- int permission = mWifiPermissionsWrapper.getAccessWifiStatePermission(uid);
- return (permission == PackageManager.PERMISSION_GRANTED);
- } catch (RemoteException e) {
- mLog.err("Error checking for permission: %").r(e.getMessage()).flush();
- return false;
- }
+ int permission = mWifiPermissionsWrapper.getOverrideWifiConfigPermission(uid);
+ return permission == PackageManager.PERMISSION_GRANTED;
}
/**
@@ -128,7 +90,8 @@ public class WifiPermissionsUtil {
long ident = Binder.clearCallingIdentity();
try {
if (mContext.getPackageManager().getApplicationInfoAsUser(
- packageName, 0, UserHandle.getUserId(callingUid)).targetSdkVersion
+ packageName, 0,
+ UserHandle.getUserHandleForUid(callingUid)).targetSdkVersion
< versionCode) {
return true;
}
@@ -168,11 +131,15 @@ public class WifiPermissionsUtil {
// Always checking FINE - even if will not enforce. This will record the request for FINE
// so that a location request by the app is surfaced to the user.
- boolean isAppOpAllowed = noteAppOpAllowed(AppOpsManager.OP_FINE_LOCATION, pkgName, uid);
- if (!isAppOpAllowed && coarseForTargetSdkLessThanQ && isTargetSdkLessThanQ) {
- isAppOpAllowed = noteAppOpAllowed(AppOpsManager.OP_COARSE_LOCATION, pkgName, uid);
+ boolean isFineLocationAllowed = noteAppOpAllowed(
+ AppOpsManager.OPSTR_FINE_LOCATION, pkgName, uid);
+ if (isFineLocationAllowed) {
+ return true;
+ }
+ if (coarseForTargetSdkLessThanQ && isTargetSdkLessThanQ) {
+ return noteAppOpAllowed(AppOpsManager.OPSTR_COARSE_LOCATION, pkgName, uid);
}
- return isAppOpAllowed;
+ return false;
}
/**
@@ -187,7 +154,6 @@ public class WifiPermissionsUtil {
}
}
-
/**
* Checks that calling process has android.Manifest.permission.ACCESS_FINE_LOCATION
* and a corresponding app op is allowed for this package and uid.
@@ -195,7 +161,7 @@ public class WifiPermissionsUtil {
* @param pkgName PackageName of the application requesting access
* @param uid The uid of the package
* @param hideFromAppOps True to invoke {@link AppOpsManager#checkOp(int, int, String)}, false
- * to invoke {@link AppOpsManager#noteOp(int, int, String)}.
+ * to invoke {@link AppOpsManager#noteOp(String, int, String, String)}.
*/
private boolean checkCallersFineLocationPermission(String pkgName, int uid,
boolean hideFromAppOps) {
@@ -207,15 +173,10 @@ public class WifiPermissionsUtil {
}
if (hideFromAppOps) {
// Don't note the operation, just check if the app is allowed to perform the operation.
- if (!checkAppOpAllowed(AppOpsManager.OP_FINE_LOCATION, pkgName, uid)) {
- return false;
- }
+ return checkAppOpAllowed(AppOpsManager.OPSTR_FINE_LOCATION, pkgName, uid);
} else {
- if (!noteAppOpAllowed(AppOpsManager.OP_FINE_LOCATION, pkgName, uid)) {
- return false;
- }
+ return noteAppOpAllowed(AppOpsManager.OPSTR_FINE_LOCATION, pkgName, uid);
}
- return true;
}
/**
@@ -327,7 +288,7 @@ public class WifiPermissionsUtil {
try {
checkPackage(uid, pkgName);
} catch (SecurityException se) {
- Slog.e(TAG, "Package check exception - " + se);
+ Log.e(TAG, "Package check exception - " + se);
return false;
}
@@ -338,7 +299,7 @@ public class WifiPermissionsUtil {
// Location mode must be enabled if needed.
if (needLocationModeEnabled && !isLocationModeEnabled()) {
- Slog.e(TAG, "Location mode is disabled for the device");
+ Log.e(TAG, "Location mode is disabled for the device");
return false;
}
@@ -346,7 +307,7 @@ public class WifiPermissionsUtil {
// location information.
if (!checkCallersLocationPermission(pkgName, uid,
/* coarseForTargetSdkLessThanQ */ false)) {
- Slog.e(TAG, "UID " + uid + " has no location permission");
+ Log.e(TAG, "UID " + uid + " has no location permission");
return false;
}
return true;
@@ -381,7 +342,7 @@ public class WifiPermissionsUtil {
* and package.
*/
private boolean isScanAllowedbyApps(String pkgName, int uid) {
- return noteAppOpAllowed(AppOpsManager.OP_WIFI_SCAN, pkgName, uid);
+ return noteAppOpAllowed(AppOpsManager.OPSTR_WIFI_SCAN, pkgName, uid);
}
/**
@@ -398,27 +359,19 @@ public class WifiPermissionsUtil {
* current user.
*/
private boolean isCurrentProfile(int uid) {
- int currentUser = mWifiPermissionsWrapper.getCurrentUser();
- int callingUserId = mWifiPermissionsWrapper.getCallingUserId(uid);
- if (callingUserId == currentUser) {
- return true;
- } else {
- List<UserInfo> userProfiles = mUserManager.getProfiles(currentUser);
- for (UserInfo user : userProfiles) {
- if (user.id == callingUserId) {
- return true;
- }
- }
- }
- return false;
+ UserHandle currentUser = UserHandle.of(mWifiPermissionsWrapper.getCurrentUser());
+ UserHandle callingUser = UserHandle.getUserHandleForUid(uid);
+ return currentUser.equals(callingUser)
+ || mUserManager.isSameProfileGroup(currentUser, callingUser);
}
- private boolean noteAppOpAllowed(int op, String pkgName, int uid) {
- return mAppOps.noteOp(op, uid, pkgName) == AppOpsManager.MODE_ALLOWED;
+ private boolean noteAppOpAllowed(String op, String pkgName, int uid) {
+ // TODO moltmann: Set correct featureId
+ return mAppOps.noteOp(op, uid, pkgName, null, null) == AppOpsManager.MODE_ALLOWED;
}
- private boolean checkAppOpAllowed(int op, String pkgName, int uid) {
- return mAppOps.checkOp(op, uid, pkgName) == AppOpsManager.MODE_ALLOWED;
+ private boolean checkAppOpAllowed(String op, String pkgName, int uid) {
+ return mAppOps.unsafeCheckOp(op, uid, pkgName) == AppOpsManager.MODE_ALLOWED;
}
private boolean retrieveLocationManagerIfNecessary() {
@@ -508,8 +461,8 @@ public class WifiPermissionsUtil {
* Returns true if the |callingUid|/\callingPackage| holds SYSTEM_ALERT_WINDOW permission.
*/
public boolean checkSystemAlertWindowPermission(int callingUid, String callingPackage) {
- final int mode = mAppOps.noteOp(
- AppOpsManager.OP_SYSTEM_ALERT_WINDOW, callingUid, callingPackage);
+ final int mode = mAppOps.noteOp(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, callingUid,
+ callingPackage, null, null);
if (mode == AppOpsManager.MODE_DEFAULT) {
return mWifiPermissionsWrapper.getUidPermission(
Manifest.permission.SYSTEM_ALERT_WINDOW, callingUid)
@@ -517,4 +470,75 @@ public class WifiPermissionsUtil {
}
return mode == AppOpsManager.MODE_ALLOWED;
}
+
+ private static DevicePolicyManager retrieveDevicePolicyManagerFromContext(Context context) {
+ DevicePolicyManager devicePolicyManager =
+ context.getSystemService(DevicePolicyManager.class);
+ if (devicePolicyManager == null
+ && context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_DEVICE_ADMIN)) {
+ Log.w(TAG, "Error retrieving DPM service");
+ }
+ return devicePolicyManager;
+ }
+
+ private DevicePolicyManager retrieveDevicePolicyManagerFromUserContext(int uid) {
+ Context userContext = null;
+ try {
+ userContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0,
+ UserHandle.getUserHandleForUid(uid));
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Unknown package name");
+ return null;
+ }
+ if (userContext == null) {
+ Log.e(TAG, "Unable to retrieve user context for " + uid);
+ return null;
+ }
+ return retrieveDevicePolicyManagerFromContext(userContext);
+ }
+
+ /**
+ * Returns true if the |callingUid|/\callingPackage| is the device owner.
+ */
+ public boolean isDeviceOwner(int uid, @Nullable String packageName) {
+ // Cannot determine if the app is DO/PO if packageName is null. So, will return false to be
+ // safe.
+ if (packageName == null) {
+ Log.e(TAG, "isDeviceOwner: packageName is null, returning false");
+ return false;
+ }
+ DevicePolicyManager devicePolicyManager =
+ retrieveDevicePolicyManagerFromContext(mContext);
+ if (devicePolicyManager == null) return false;
+ long ident = Binder.clearCallingIdentity();
+ UserHandle deviceOwnerUser = null;
+ ComponentName deviceOwnerComponent = null;
+ try {
+ deviceOwnerUser = devicePolicyManager.getDeviceOwnerUser();
+ deviceOwnerComponent = devicePolicyManager.getDeviceOwnerComponentOnAnyUser();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ // no device owner
+ if (deviceOwnerUser == null || deviceOwnerComponent == null) return false;
+ return deviceOwnerUser.equals(UserHandle.getUserHandleForUid(uid))
+ && deviceOwnerComponent.getPackageName().equals(packageName);
+ }
+
+ /**
+ * Returns true if the |callingUid|/\callingPackage| is the profile owner.
+ */
+ public boolean isProfileOwner(int uid, @Nullable String packageName) {
+ // Cannot determine if the app is DO/PO if packageName is null. So, will return false to be
+ // safe.
+ if (packageName == null) {
+ Log.e(TAG, "isProfileOwner: packageName is null, returning false");
+ return false;
+ }
+ DevicePolicyManager devicePolicyManager =
+ retrieveDevicePolicyManagerFromUserContext(uid);
+ if (devicePolicyManager == null) return false;
+ return devicePolicyManager.isProfileOwnerApp(packageName);
+ }
}
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java b/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java
index 18e08d260b..52ea1c0f13 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java
@@ -18,15 +18,7 @@ package com.android.server.wifi.util;
import android.Manifest;
import android.app.ActivityManager;
-import android.app.AppGlobals;
-import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context;
-import android.os.RemoteException;
-import android.os.UserHandle;
-
-import com.android.server.LocalServices;
-
-import java.util.List;
/**
* A wifi permissions dependency class to wrap around external
@@ -45,44 +37,14 @@ public class WifiPermissionsWrapper {
}
/**
- * Returns the user ID corresponding to the UID
- * @param uid Calling Uid
- * @return userid Corresponding user id
- */
- public int getCallingUserId(int uid) {
- return UserHandle.getUserId(uid);
- }
-
- /**
- * Get the PackageName of the top running task
- * @return String corresponding to the package
- */
- public String getTopPkgName() {
- ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
- String topTaskPkg = " ";
- List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
- if (!tasks.isEmpty()) {
- return tasks.get(0).topActivity.getPackageName();
- }
- return topTaskPkg;
- }
-
- /**
- * API is wrap around ActivityManager class to
- * get location permissions for a certain UID
- * @param: Manifest permission string
- * @param: Uid to get permission for
- * @return: Permissions setting
+ * Determine if a UID has a permission.
+ * @param permissionType permission string
+ * @param uid to get permission for
+ * @return Permissions setting
*/
public int getUidPermission(String permissionType, int uid) {
- return ActivityManager.checkUidPermission(permissionType, uid);
- }
-
- /**
- * Gets the local service {link@ DevicePolicyManagerInternal}, can be null
- */
- public DevicePolicyManagerInternal getDevicePolicyManagerInternal() {
- return LocalServices.getService(DevicePolicyManagerInternal.class);
+ // We don't care about pid, pass in -1
+ return mContext.checkPermission(permissionType, -1, uid);
}
/**
@@ -90,35 +52,9 @@ public class WifiPermissionsWrapper {
*
* @param uid to check the permission for
* @return int representation of success or denied
- * @throws RemoteException
- */
- public int getOverrideWifiConfigPermission(int uid) throws RemoteException {
- return AppGlobals.getPackageManager().checkUidPermission(
- android.Manifest.permission.OVERRIDE_WIFI_CONFIG, uid);
- }
-
- /**
- * Determines if the caller has the change wifi config permission.
- *
- * @param uid to check the permission for
- * @return int representation of success or denied
- * @throws RemoteException
- */
- public int getChangeWifiConfigPermission(int uid) throws RemoteException {
- return AppGlobals.getPackageManager().checkUidPermission(
- Manifest.permission.CHANGE_WIFI_STATE, uid);
- }
-
- /**
- * Determines if the caller has the access wifi state permission.
- *
- * @param uid to check the permission for
- * @return int representation of success or denied
- * @throws RemoteException
*/
- public int getAccessWifiStatePermission(int uid) throws RemoteException {
- return AppGlobals.getPackageManager().checkUidPermission(
- Manifest.permission.ACCESS_WIFI_STATE, uid);
+ public int getOverrideWifiConfigPermission(int uid) {
+ return getUidPermission(android.Manifest.permission.OVERRIDE_WIFI_CONFIG, uid);
}
/**
@@ -126,10 +62,8 @@ public class WifiPermissionsWrapper {
*
* @param uid to check the permission for
* @return int representation of success or denied
- * @throws RemoteException
*/
- public int getLocalMacAddressPermission(int uid) throws RemoteException {
- return AppGlobals.getPackageManager().checkUidPermission(
- Manifest.permission.LOCAL_MAC_ADDRESS, uid);
+ public int getLocalMacAddressPermission(int uid) {
+ return getUidPermission(Manifest.permission.LOCAL_MAC_ADDRESS, uid);
}
}
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
index 188d3b5c72..e1c48785aa 100644
--- a/service/java/com/android/server/wifi/util/XmlUtil.java
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -348,6 +348,7 @@ public class XmlUtil {
public static final String XML_TAG_ROAMING_CONSORTIUM_OIS = "RoamingConsortiumOIs";
public static final String XML_TAG_RANDOMIZED_MAC_ADDRESS = "RandomizedMacAddress";
public static final String XML_TAG_MAC_RANDOMIZATION_SETTING = "MacRandomizationSetting";
+ public static final String XML_TAG_SAE_PASSWORD_ID_KEY = "SaePasswordId";
/**
* Write WepKeys to the XML stream.
@@ -390,6 +391,7 @@ public class XmlUtil {
XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID);
XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey);
+ XmlUtil.writeNextValue(out, XML_TAG_SAE_PASSWORD_ID_KEY, configuration.saePasswordId);
writeWepKeysToXml(out, configuration.wepKeys);
XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID);
@@ -541,6 +543,9 @@ public class XmlUtil {
case XML_TAG_PRE_SHARED_KEY:
configuration.preSharedKey = (String) value;
break;
+ case XML_TAG_SAE_PASSWORD_ID_KEY:
+ configuration.saePasswordId = (String) value;
+ break;
case XML_TAG_WEP_KEYS:
populateWepKeysFromXmlValue(value, configuration.wepKeys);
break;
@@ -808,10 +813,9 @@ public class XmlUtil {
String gatewayAddressString =
(String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS);
if (gatewayAddressString != null) {
- LinkAddress dest = null;
InetAddress gateway =
NetworkUtils.numericToInetAddress(gatewayAddressString);
- RouteInfo route = new RouteInfo(dest, gateway);
+ RouteInfo route = new RouteInfo(null, gateway, null, RouteInfo.RTN_UNICAST);
if (route.isIPv4Default()) {
staticIpConfiguration.gateway = gateway;
} else {
@@ -1017,6 +1021,7 @@ public class XmlUtil {
public static final String XML_TAG_PHASE2_METHOD = "Phase2Method";
public static final String XML_TAG_PLMN = "PLMN";
public static final String XML_TAG_REALM = "Realm";
+ public static final String XML_TAG_OCSP = "Ocsp";
/**
* Write the WifiEnterpriseConfig data elements from the provided config to the XML
@@ -1055,6 +1060,7 @@ public class XmlUtil {
XmlUtil.writeNextValue(out, XML_TAG_PHASE2_METHOD, enterpriseConfig.getPhase2Method());
XmlUtil.writeNextValue(out, XML_TAG_PLMN, enterpriseConfig.getPlmn());
XmlUtil.writeNextValue(out, XML_TAG_REALM, enterpriseConfig.getRealm());
+ XmlUtil.writeNextValue(out, XML_TAG_OCSP, enterpriseConfig.getOcsp());
}
/**
@@ -1124,6 +1130,9 @@ public class XmlUtil {
enterpriseConfig.setFieldValue(
WifiEnterpriseConfig.CA_PATH_KEY, (String) value);
break;
+ case XML_TAG_OCSP:
+ enterpriseConfig.setOcsp((int) value);
+ break;
case XML_TAG_EAP_METHOD:
enterpriseConfig.setEapMethod((int) value);
break;
diff --git a/service/java/com/android/server/wifi/wificond/ChannelSettings.java b/service/java/com/android/server/wifi/wificond/ChannelSettings.java
deleted file mode 100644
index 7b20983b6a..0000000000
--- a/service/java/com/android/server/wifi/wificond/ChannelSettings.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.wificond;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.util.Objects;
-
-/**
- * ChannelSettings for wificond
- *
- * @hide
- */
-public class ChannelSettings implements Parcelable {
- private static final String TAG = "ChannelSettings";
-
- public int frequency;
-
- /** public constructor */
- public ChannelSettings() { }
-
- /** override comparator */
- @Override
- public boolean equals(Object rhs) {
- if (this == rhs) return true;
- if (!(rhs instanceof ChannelSettings)) {
- return false;
- }
- ChannelSettings channel = (ChannelSettings) rhs;
- if (channel == null) {
- return false;
- }
- return frequency == channel.frequency;
- }
-
- /** override hash code */
- @Override
- public int hashCode() {
- return Objects.hash(frequency);
- }
-
- /** implement Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /**
- * implement Parcelable interface
- * |flags| is ignored.
- * */
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(frequency);
- }
-
- /** implement Parcelable interface */
- public static final Parcelable.Creator<ChannelSettings> CREATOR =
- new Parcelable.Creator<ChannelSettings>() {
- /**
- * Caller is responsible for providing a valid parcel.
- */
- @Override
- public ChannelSettings createFromParcel(Parcel in) {
- ChannelSettings result = new ChannelSettings();
- result.frequency = in.readInt();
- if (in.dataAvail() != 0) {
- Log.e(TAG, "Found trailing data after parcel parsing.");
- }
-
- return result;
- }
-
- @Override
- public ChannelSettings[] newArray(int size) {
- return new ChannelSettings[size];
- }
- };
-}
diff --git a/service/java/com/android/server/wifi/wificond/HiddenNetwork.java b/service/java/com/android/server/wifi/wificond/HiddenNetwork.java
deleted file mode 100644
index 1a96f2557a..0000000000
--- a/service/java/com/android/server/wifi/wificond/HiddenNetwork.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.wificond;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-
-/**
- * HiddenNetwork for wificond
- *
- * @hide
- */
-public class HiddenNetwork implements Parcelable {
- private static final String TAG = "HiddenNetwork";
-
- public byte[] ssid;
-
- /** public constructor */
- public HiddenNetwork() { }
-
- /** override comparator */
- @Override
- public boolean equals(Object rhs) {
- if (this == rhs) return true;
- if (!(rhs instanceof HiddenNetwork)) {
- return false;
- }
- HiddenNetwork network = (HiddenNetwork) rhs;
- return Arrays.equals(ssid, network.ssid);
- }
-
- /** override hash code */
- @Override
- public int hashCode() {
- return Arrays.hashCode(ssid);
- }
-
- /** implement Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /**
- * implement Parcelable interface
- * |flags| is ignored.
- */
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeByteArray(ssid);
- }
-
- /** implement Parcelable interface */
- public static final Parcelable.Creator<HiddenNetwork> CREATOR =
- new Parcelable.Creator<HiddenNetwork>() {
- /**
- * Caller is responsible for providing a valid parcel.
- */
- @Override
- public HiddenNetwork createFromParcel(Parcel in) {
- HiddenNetwork result = new HiddenNetwork();
- result.ssid = in.createByteArray();
- return result;
- }
-
- @Override
- public HiddenNetwork[] newArray(int size) {
- return new HiddenNetwork[size];
- }
- };
-}
diff --git a/service/java/com/android/server/wifi/wificond/NativeScanResult.java b/service/java/com/android/server/wifi/wificond/NativeScanResult.java
deleted file mode 100644
index d7bfed8f0e..0000000000
--- a/service/java/com/android/server/wifi/wificond/NativeScanResult.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.wificond;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-
-/**
- * ScanResult from wificond
- *
- * @hide
- */
-public class NativeScanResult implements Parcelable {
- private static final int CAPABILITY_SIZE = 16;
-
- public byte[] ssid;
- public byte[] bssid;
- public byte[] infoElement;
- public int frequency;
- public int signalMbm;
- public long tsf;
- public BitSet capability;
- public boolean associated;
- public ArrayList<RadioChainInfo> radioChainInfos;
-
- /** public constructor */
- public NativeScanResult() { }
-
- /** copy constructor */
- public NativeScanResult(NativeScanResult source) {
- ssid = source.ssid.clone();
- bssid = source.bssid.clone();
- infoElement = source.infoElement.clone();
- frequency = source.frequency;
- signalMbm = source.signalMbm;
- tsf = source.tsf;
- capability = (BitSet) source.capability.clone();
- associated = source.associated;
- }
-
- /** implement Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** implement Parcelable interface */
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeByteArray(ssid);
- out.writeByteArray(bssid);
- out.writeByteArray(infoElement);
- out.writeInt(frequency);
- out.writeInt(signalMbm);
- out.writeLong(tsf);
- int capabilityInt = 0;
- for (int i = 0; i < CAPABILITY_SIZE; i++) {
- if (capability.get(i)) {
- capabilityInt |= 1 << i;
- }
- }
- out.writeInt(capabilityInt);
- out.writeInt(associated ? 1 : 0);
- out.writeTypedList(radioChainInfos);
- }
-
- /** implement Parcelable interface */
- public static final Parcelable.Creator<NativeScanResult> CREATOR =
- new Parcelable.Creator<NativeScanResult>() {
- @Override
- public NativeScanResult createFromParcel(Parcel in) {
- NativeScanResult result = new NativeScanResult();
- result.ssid = in.createByteArray();
- result.bssid = in.createByteArray();
- result.infoElement = in.createByteArray();
- result.frequency = in.readInt();
- result.signalMbm = in.readInt();
- result.tsf = in.readLong();
- int capabilityInt = in.readInt();
- result.capability = new BitSet(CAPABILITY_SIZE);
- for (int i = 0; i < CAPABILITY_SIZE; i++) {
- if ((capabilityInt & (1 << i)) != 0) {
- result.capability.set(i);
- }
- }
- result.associated = (in.readInt() != 0);
- result.radioChainInfos = new ArrayList<>();
- in.readTypedList(result.radioChainInfos, RadioChainInfo.CREATOR);
- return result;
- }
-
- @Override
- public NativeScanResult[] newArray(int size) {
- return new NativeScanResult[size];
- }
- };
-}
diff --git a/service/java/com/android/server/wifi/wificond/PnoNetwork.java b/service/java/com/android/server/wifi/wificond/PnoNetwork.java
deleted file mode 100644
index 6bcad06ce0..0000000000
--- a/service/java/com/android/server/wifi/wificond/PnoNetwork.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.wificond;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * PnoNetwork for wificond
- *
- * @hide
- */
-public class PnoNetwork implements Parcelable {
-
- public boolean isHidden;
- public byte[] ssid;
- public int[] frequencies;
-
- /** public constructor */
- public PnoNetwork() { }
-
- /** override comparator */
- @Override
- public boolean equals(Object rhs) {
- if (this == rhs) return true;
- if (!(rhs instanceof PnoNetwork)) {
- return false;
- }
- PnoNetwork network = (PnoNetwork) rhs;
- return Arrays.equals(ssid, network.ssid)
- && Arrays.equals(frequencies, network.frequencies)
- && isHidden == network.isHidden;
- }
-
- /** override hash code */
- @Override
- public int hashCode() {
- return Objects.hash(
- isHidden,
- Arrays.hashCode(ssid),
- Arrays.hashCode(frequencies));
- }
-
- /** implement Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /**
- * implement Parcelable interface
- * |flag| is ignored.
- */
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(isHidden ? 1 : 0);
- out.writeByteArray(ssid);
- out.writeIntArray(frequencies);
- }
-
- /** implement Parcelable interface */
- public static final Parcelable.Creator<PnoNetwork> CREATOR =
- new Parcelable.Creator<PnoNetwork>() {
- @Override
- public PnoNetwork createFromParcel(Parcel in) {
- PnoNetwork result = new PnoNetwork();
- result.isHidden = in.readInt() != 0 ? true : false;
- result.ssid = in.createByteArray();
- result.frequencies = in.createIntArray();
- return result;
- }
-
- @Override
- public PnoNetwork[] newArray(int size) {
- return new PnoNetwork[size];
- }
- };
-}
diff --git a/service/java/com/android/server/wifi/wificond/PnoSettings.java b/service/java/com/android/server/wifi/wificond/PnoSettings.java
deleted file mode 100644
index 51a7cc19b3..0000000000
--- a/service/java/com/android/server/wifi/wificond/PnoSettings.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.wificond;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-/**
- * PnoSettings for wificond
- *
- * @hide
- */
-public class PnoSettings implements Parcelable {
- public int intervalMs;
- public int min2gRssi;
- public int min5gRssi;
- public ArrayList<PnoNetwork> pnoNetworks;
-
- /** public constructor */
- public PnoSettings() { }
-
- /** override comparator */
- @Override
- public boolean equals(Object rhs) {
- if (this == rhs) return true;
- if (!(rhs instanceof PnoSettings)) {
- return false;
- }
- PnoSettings settings = (PnoSettings) rhs;
- if (settings == null) {
- return false;
- }
- return intervalMs == settings.intervalMs
- && min2gRssi == settings.min2gRssi
- && min5gRssi == settings.min5gRssi
- && pnoNetworks.equals(settings.pnoNetworks);
- }
-
- /** override hash code */
- @Override
- public int hashCode() {
- return Objects.hash(intervalMs, min2gRssi, min5gRssi, pnoNetworks);
- }
-
- /** implement Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /**
- * implement Parcelable interface
- * |flag| is ignored.
- * */
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(intervalMs);
- out.writeInt(min2gRssi);
- out.writeInt(min5gRssi);
- out.writeTypedList(pnoNetworks);
- }
-
- /** implement Parcelable interface */
- public static final Parcelable.Creator<PnoSettings> CREATOR =
- new Parcelable.Creator<PnoSettings>() {
- @Override
- public PnoSettings createFromParcel(Parcel in) {
- PnoSettings result = new PnoSettings();
- result.intervalMs = in.readInt();
- result.min2gRssi = in.readInt();
- result.min5gRssi = in.readInt();
-
- result.pnoNetworks = new ArrayList<PnoNetwork>();
- in.readTypedList(result.pnoNetworks, PnoNetwork.CREATOR);
-
- return result;
- }
-
- @Override
- public PnoSettings[] newArray(int size) {
- return new PnoSettings[size];
- }
- };
-}
diff --git a/service/java/com/android/server/wifi/wificond/RadioChainInfo.java b/service/java/com/android/server/wifi/wificond/RadioChainInfo.java
deleted file mode 100644
index eeb9487e45..0000000000
--- a/service/java/com/android/server/wifi/wificond/RadioChainInfo.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.wificond;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * RadioChainInfo for wificond
- *
- * @hide
- */
-public class RadioChainInfo implements Parcelable {
- private static final String TAG = "RadioChainInfo";
-
- public int chainId;
- public int level;
-
-
- /** public constructor */
- public RadioChainInfo() { }
-
- public RadioChainInfo(int chainId, int level) {
- this.chainId = chainId;
- this.level = level;
- }
-
- /** override comparator */
- @Override
- public boolean equals(Object rhs) {
- if (this == rhs) return true;
- if (!(rhs instanceof RadioChainInfo)) {
- return false;
- }
- RadioChainInfo chainInfo = (RadioChainInfo) rhs;
- if (chainInfo == null) {
- return false;
- }
- return chainId == chainInfo.chainId && level == chainInfo.level;
- }
-
- /** override hash code */
- @Override
- public int hashCode() {
- return Objects.hash(chainId, level);
- }
-
-
- /** implement Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /**
- * implement Parcelable interface
- * |flags| is ignored.
- */
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(chainId);
- out.writeInt(level);
- }
-
- /** implement Parcelable interface */
- public static final Parcelable.Creator<RadioChainInfo> CREATOR =
- new Parcelable.Creator<RadioChainInfo>() {
- /**
- * Caller is responsible for providing a valid parcel.
- */
- @Override
- public RadioChainInfo createFromParcel(Parcel in) {
- RadioChainInfo result = new RadioChainInfo();
- result.chainId = in.readInt();
- result.level = in.readInt();
- return result;
- }
-
- @Override
- public RadioChainInfo[] newArray(int size) {
- return new RadioChainInfo[size];
- }
- };
-}
diff --git a/service/java/com/android/server/wifi/wificond/SingleScanSettings.java b/service/java/com/android/server/wifi/wificond/SingleScanSettings.java
deleted file mode 100644
index ed1e41cdcf..0000000000
--- a/service/java/com/android/server/wifi/wificond/SingleScanSettings.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.wificond;
-
-import android.net.wifi.IWifiScannerImpl;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-/**
- * SingleScanSettings for wificond
- *
- * @hide
- */
-public class SingleScanSettings implements Parcelable {
- private static final String TAG = "SingleScanSettings";
-
- public int scanType;
- public ArrayList<ChannelSettings> channelSettings;
- public ArrayList<HiddenNetwork> hiddenNetworks;
-
- /** public constructor */
- public SingleScanSettings() { }
-
- /** override comparator */
- @Override
- public boolean equals(Object rhs) {
- if (this == rhs) return true;
- if (!(rhs instanceof SingleScanSettings)) {
- return false;
- }
- SingleScanSettings settings = (SingleScanSettings) rhs;
- if (settings == null) {
- return false;
- }
- return scanType == settings.scanType
- && channelSettings.equals(settings.channelSettings)
- && hiddenNetworks.equals(settings.hiddenNetworks);
- }
-
- /** override hash code */
- @Override
- public int hashCode() {
- return Objects.hash(scanType, channelSettings, hiddenNetworks);
- }
-
-
- /** implement Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- private static boolean isValidScanType(int scanType) {
- return scanType == IWifiScannerImpl.SCAN_TYPE_LOW_SPAN
- || scanType == IWifiScannerImpl.SCAN_TYPE_LOW_POWER
- || scanType == IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY;
- }
-
- /**
- * implement Parcelable interface
- * |flags| is ignored.
- */
- @Override
- public void writeToParcel(Parcel out, int flags) {
- if (!isValidScanType(scanType)) {
- Log.wtf(TAG, "Invalid scan type " + scanType);
- }
- out.writeInt(scanType);
- out.writeTypedList(channelSettings);
- out.writeTypedList(hiddenNetworks);
- }
-
- /** implement Parcelable interface */
- public static final Parcelable.Creator<SingleScanSettings> CREATOR =
- new Parcelable.Creator<SingleScanSettings>() {
- /**
- * Caller is responsible for providing a valid parcel.
- */
- @Override
- public SingleScanSettings createFromParcel(Parcel in) {
- SingleScanSettings result = new SingleScanSettings();
- result.scanType = in.readInt();
- if (!isValidScanType(result.scanType)) {
- Log.wtf(TAG, "Invalid scan type " + result.scanType);
- }
- result.channelSettings = new ArrayList<ChannelSettings>();
- in.readTypedList(result.channelSettings, ChannelSettings.CREATOR);
- result.hiddenNetworks = new ArrayList<HiddenNetwork>();
- in.readTypedList(result.hiddenNetworks, HiddenNetwork.CREATOR);
- if (in.dataAvail() != 0) {
- Log.e(TAG, "Found trailing data after parcel parsing.");
- }
- return result;
- }
-
- @Override
- public SingleScanSettings[] newArray(int size) {
- return new SingleScanSettings[size];
- }
- };
-}
diff --git a/service/proguard.flags b/service/proguard.flags
new file mode 100644
index 0000000000..706449103a
--- /dev/null
+++ b/service/proguard.flags
@@ -0,0 +1 @@
+# TBD
diff --git a/service/res/values/strings.xml b/service/res/values/strings.xml
new file mode 100644
index 0000000000..83d6e5412b
--- /dev/null
+++ b/service/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Official label of the wifi stack -->
+ <string name="wifiAppLabel" product="default">System Wi-Fi</string>
+</resources>
diff --git a/service/tests/Android.bp b/service/tests/Android.bp
new file mode 100644
index 0000000000..087691d89e
--- /dev/null
+++ b/service/tests/Android.bp
@@ -0,0 +1,19 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Include subdirectory makefiles
+// ============================================================
+subdirs = [
+ "wifitests",
+]
diff --git a/service/tests/Android.mk b/service/tests/Android.mk
deleted file mode 100644
index 2027fefeb5..0000000000
--- a/service/tests/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2015 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Include subdirectory makefiles
-# ============================================================
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/service/tests/wifitests/Android.bp b/service/tests/wifitests/Android.bp
new file mode 100644
index 0000000000..fbad530e14
--- /dev/null
+++ b/service/tests/wifitests/Android.bp
@@ -0,0 +1,81 @@
+// Copyright (C) 2015 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.
+
+// Make test APK
+// ============================================================
+android_test {
+ // TODO(rpius): Rename once all google3 config files are changed
+ // name: "WifiStackTests",
+ name: "FrameworksWifiTests",
+
+ srcs: ["**/*.java"],
+
+ // For coverage
+ jacoco: {
+ include_filter: [
+ "com.android.server.wifi.**",
+ ],
+ exclude_filter: [
+ ],
+ },
+
+ dxflags: ["--multi-dex"],
+
+ // wifi-service and services must be included here so that the latest changes
+ // will be used when tests. Otherwise the tests would run against the installed
+ // system.
+ // TODO figure out if this is the correct thing to do, this seems to not be right
+ // since neither is declared a static java library.
+ static_libs: [
+ "androidx.test.rules",
+ "hamcrest-library",
+ "mockito-target-extended-minus-junit4",
+ "frameworks-base-testutils",
+ "services",
+ "wifi-service",
+ "truth-prebuilt",
+ ],
+
+ libs: [
+ "android.test.runner",
+ "android.hidl.manager-V1.2-java",
+ "android.test.base",
+ "android.test.mock",
+ ],
+
+ // These must be explicitly included because they are not normally accessible
+ // from apps.
+ jni_libs: [
+ "libwifi-jni",
+ "libbase",
+ "libc++",
+ "ld-android",
+ "libdl_android",
+ "libcgrouprc",
+ "libcutils",
+ "libnativehelper",
+ "libprocessgroup",
+ "libutils",
+ "libvndksupport",
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
+
+ jarjar_rules: ":wifi-jarjar-rules",
+
+ min_sdk_version: "29",
+ platform_apis: true,
+ privileged: true,
+ test_suites: ["device-tests"],
+}
diff --git a/service/tests/wifitests/Android.mk b/service/tests/wifitests/Android.mk
deleted file mode 100644
index 8e48f0c7f5..0000000000
--- a/service/tests/wifitests/Android.mk
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright (C) 2015 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Make test APK
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-# Provide jack a list of classes to exclude form code coverage
-# This list is generated from the java source files in this module
-# The list is a comma separated list of class names with * matching zero or more characters.
-# Example:
-# Input files: src/com/android/server/wifi/Test.java src/com/android/server/wifi/AnotherTest.java
-# Generated exclude list: com.android.server.wifi.Test*,com.android.server.wifi.AnotherTest*
-
-# Filter all src files to just java files
-local_java_files := $(filter %.java,$(LOCAL_SRC_FILES))
-# Transform java file names into full class names.
-# This only works if the class name matches the file name and the directory structure
-# matches the package.
-local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files)))
-# Convert class name list to jacoco exclude list
-# This appends a * to all classes and replace the space separators with commas.
-# These patterns will match all classes in this module and their inner classes.
-jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes)))
-
-jacoco_include := com.android.server.wifi.*
-
-LOCAL_JACK_COVERAGE_INCLUDE_FILTER := $(jacoco_include)
-LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude)
-
-LOCAL_DX_FLAGS := --multi-dex
-LOCAL_JACK_FLAGS := --multi-dex native
-
-# wifi-service and services must be included here so that the latest changes
-# will be used when tests. Otherwise the tests would run against the installed
-# system.
-# TODO figure out if this is the correct thing to do, this seems to not be right
-# since neither is declared a static java library.
-LOCAL_STATIC_JAVA_LIBRARIES := \
- androidx.test.rules hamcrest-library \
- mockito-target-extended-minus-junit4 \
- frameworks-base-testutils \
- services \
- wifi-service \
- truth-prebuilt \
-
-LOCAL_JAVA_LIBRARIES := \
- android.test.runner \
- android.hidl.manager-V1.2-java \
- android.test.base \
- android.test.mock
-
-# These must be explicitly included because they are not normally accessible
-# from apps.
-LOCAL_JNI_SHARED_LIBRARIES := \
- libcrypto \
- libwifi-service \
- libEGL \
- libGLESv2 \
- libaudioutils \
- libbacktrace \
- libbase \
- libbinder \
- libbinderthreadstate \
- libc++ \
- ld-android \
- libdl_android \
- libcamera_client \
- libcamera_metadata \
- libcgrouprc \
- libcutils \
- libexpat \
- libgui \
- libhardware \
- libandroidicu \
- libjsoncpp \
- liblzma \
- libmedia \
- libnativehelper \
- libnbaio \
- libnetutils \
- libnl \
- libpowermanager \
- libprocessgroup \
- libsonivox \
- libstagefright_foundation \
- libstdc++ \
- libsync \
- libwifi-system \
- libui \
- libunwindstack \
- libutils \
- libvndksupport \
- libdexmakerjvmtiagent \
- libstaticjvmtiagent
-
-ifdef WPA_SUPPLICANT_VERSION
-LOCAL_JNI_SHARED_LIBRARIES += libwpa_client
-endif
-
-LOCAL_PACKAGE_NAME := FrameworksWifiTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/service/tests/wifitests/coverage.sh b/service/tests/wifitests/coverage.sh
index f9ea1fbb17..22c681439d 100755
--- a/service/tests/wifitests/coverage.sh
+++ b/service/tests/wifitests/coverage.sh
@@ -1,4 +1,6 @@
-#!/usr/bin/env bash
+#!/bin/sh
+
+# A shell script to generate a coverage report for opt/net/wifi
if [[ ! ($# == 1) ]]; then
echo "$0: usage: coverage.sh OUTPUT_DIR"
@@ -10,10 +12,22 @@ if [ -z $ANDROID_BUILD_TOP ]; then
exit 1
fi
-cd "$(dirname $0)" #cd to directory containing this script
+# Make the output directory and get its full name
+OUTPUT_DIR="$1"
+mkdir -p $OUTPUT_DIR || exit 1
+OUTPUT_DIR="`(cd $OUTPUT_DIR && pwd)`"
+BUILD_OUT_DIR=$OUTPUT_DIR/out
+cd "$(dirname $0)" #cd to directory containing this script
REPORTER_JAR=$ANDROID_HOST_OUT/framework/jacoco-cli.jar
+if [ -f $REPORTER_JAR ]; then
+ echo "jacoco-cli.jar found, skipping uninstrumented build"
+else
+ echo "Building jacoco cli and adb"
+ $ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode \
+ MODULES-IN-system-core MODULES-IN-external-jacoco || exit 1
+fi
OUTPUT_DIR=$1
@@ -26,21 +40,21 @@ COVERAGE_OUTPUT_FILE=$OUTPUT_DIR/wifi_coverage.ec
set -e # fail early
set -x # print commands
-# build this module so we can run its tests, and
-# build system/core so we can invoke `adb`, and
-# build jacoco-cli.jar so we can generate the report
-$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode \
- EMMA_INSTRUMENT=true \
- EMMA_INSTRUMENT_FRAMEWORK=false \
- EMMA_INSTRUMENT_STATIC=true \
- ANDROID_COMPILE_WITH_JACK=false \
- SKIP_BOOT_JARS_CHECK=true \
- MODULES-IN-frameworks-opt-net-wifi-tests \
- MODULES-IN-system-core \
- MODULES-IN-external-jacoco \
- FrameworksWifiTests
-
-APK_NAME="$(ls -t $(find $OUT -name FrameworksWifiTests.apk) | head -n 1)"
+bash <<END_OF_BUILD_SCRIPT || { exit 1; }
+ cd $ANDROID_BUILD_TOP
+ source build/make/envsetup.sh
+ tapas FrameworksWifiTests
+ export OUT_DIR=$BUILD_OUT_DIR
+ export TARGET_PRODUCT=$TARGET_PRODUCT
+ export EMMA_INSTRUMENT=true
+ export EMMA_INSTRUMENT_FRAMEWORK=false
+ export EMMA_INSTRUMENT_STATIC=true
+ export ANDROID_COMPILE_WITH_JACK=false
+ export SKIP_BOOT_JARS_CHECK=true
+ m
+END_OF_BUILD_SCRIPT
+
+APK_NAME="$(ls -t $(find $BUILD_OUT_DIR -name FrameworksWifiTests.apk) | head -n 1)"
adb root
adb wait-for-device
@@ -51,13 +65,12 @@ adb install -r -g "$APK_NAME"
adb shell am instrument -e coverage true --no-hidden-api-checks -w 'com.android.server.wifi.test/com.android.server.wifi.CustomTestRunner'
-mkdir -p $OUTPUT_DIR
adb pull $REMOTE_COVERAGE_OUTPUT_FILE $COVERAGE_OUTPUT_FILE
java -jar $REPORTER_JAR \
report \
- --classfiles $ANDROID_PRODUCT_OUT/../../common/obj/APPS/FrameworksWifiTests_intermediates/jacoco/report-resources/jacoco-report-classes.jar \
+ --classfiles $BUILD_OUT_DIR/soong/.intermediates/frameworks/opt/net/wifi/service/wifi-service/android_common/javac/classes/ \
--html $OUTPUT_DIR \
--sourcefiles $ANDROID_BUILD_TOP/frameworks/opt/net/wifi/tests/wifitests/src \
--sourcefiles $ANDROID_BUILD_TOP/frameworks/opt/net/wifi/service/java \
diff --git a/service/tests/wifitests/runtests.sh b/service/tests/wifitests/runtests.sh
index 6e831994a5..085098a94b 100755
--- a/service/tests/wifitests/runtests.sh
+++ b/service/tests/wifitests/runtests.sh
@@ -31,7 +31,7 @@ set -e # fail early
echo "+ mmma -j32 $ANDROID_BUILD_TOP/frameworks/opt/net/wifi/tests"
# NOTE Don't actually run the command above since this shell doesn't inherit functions from the
# caller.
-$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode MODULES-IN-frameworks-opt-net-wifi-tests
+$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode MODULES-IN-frameworks-opt-net-wifi-tests-wifitests
APK_NAME="$(ls -t $(find $OUT -name FrameworksWifiTests.apk) | head -n 1)"
set -x # print commands
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 f52229c1dc..a8e4a8acca 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
@@ -20,11 +20,30 @@ import static com.android.server.wifi.ActiveModeManager.SCAN_NONE;
import static com.android.server.wifi.ActiveModeManager.SCAN_WITHOUT_HIDDEN_NETWORKS;
import static com.android.server.wifi.ActiveModeManager.SCAN_WITH_HIDDEN_NETWORKS;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
-
+import static com.google.common.truth.Truth.assertThat;
+
+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.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockingDetails;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.Resources;
+import android.location.LocationManager;
+import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.BatteryStats;
@@ -33,7 +52,10 @@ import android.util.Log;
import androidx.test.filters.SmallTest;
+import com.android.internal.R;
import com.android.internal.app.IBatteryStats;
+import com.android.server.wifi.util.GeneralUtil;
+import com.android.server.wifi.util.WifiPermissionsUtil;
import org.junit.After;
import org.junit.Before;
@@ -46,39 +68,48 @@ import org.mockito.stubbing.Answer;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
/**
* Unit tests for {@link com.android.server.wifi.ActiveModeWarden}.
*/
@SmallTest
-public class ActiveModeWardenTest {
+public class ActiveModeWardenTest extends WifiBaseTest {
public static final String TAG = "WifiActiveModeWardenTest";
- private static final String CLIENT_MODE_STATE_STRING = "ClientModeActiveState";
- private static final String SCAN_ONLY_MODE_STATE_STRING = "ScanOnlyModeActiveState";
- private static final String WIFI_DISABLED_STATE_STRING = "WifiDisabledState";
+ private static final String ENABLED_STATE_STRING = "EnabledState";
+ private static final String DISABLED_STATE_STRING = "DisabledState";
+
private static final String WIFI_IFACE_NAME = "mockWlan";
+ private static final int TEST_WIFI_RECOVERY_DELAY_MS = 2000;
+ TestLooper mLooper;
@Mock WifiInjector mWifiInjector;
@Mock Context mContext;
@Mock Resources mResources;
@Mock WifiNative mWifiNative;
@Mock WifiApConfigStore mWifiApConfigStore;
- TestLooper mLooper;
@Mock ClientModeManager mClientModeManager;
- @Mock ScanOnlyModeManager mScanOnlyModeManager;
@Mock SoftApManager mSoftApManager;
@Mock DefaultModeManager mDefaultModeManager;
@Mock IBatteryStats mBatteryStats;
@Mock SelfRecovery mSelfRecovery;
@Mock BaseWifiDiagnostics mWifiDiagnostics;
@Mock ScanRequestProxy mScanRequestProxy;
- ClientModeManager.Listener mClientListener;
- ScanOnlyModeManager.Listener mScanOnlyListener;
- ScanOnlyModeCallback mScanOnlyCallback = new ScanOnlyModeCallback();
- ClientModeCallback mClientModeCallback = new ClientModeCallback();
+ @Mock ClientModeImpl mClientModeImpl;
+ @Mock FrameworkFacade mFacade;
+ @Mock WifiSettingsStore mSettingsStore;
+ @Mock WifiPermissionsUtil mWifiPermissionsUtil;
+
+ ActiveModeManager.Listener mClientListener;
+ ActiveModeManager.Listener mSoftApListener;
WifiManager.SoftApCallback mSoftApManagerCallback;
+ SoftApModeConfiguration mSoftApConfig;
@Mock WifiManager.SoftApCallback mSoftApStateMachineCallback;
+ @Mock WifiManager.SoftApCallback mLohsStateMachineCallback;
WifiNative.StatusListener mWifiNativeStatusListener;
ActiveModeWarden mActiveModeWarden;
@@ -95,36 +126,67 @@ public class ActiveModeWardenTest {
MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
- when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery);
- when(mWifiInjector.getWifiDiagnostics()).thenReturn(mWifiDiagnostics);
when(mWifiInjector.getScanRequestProxy()).thenReturn(mScanRequestProxy);
when(mClientModeManager.getScanMode()).thenReturn(SCAN_WITH_HIDDEN_NETWORKS);
when(mContext.getResources()).thenReturn(mResources);
- when(mScanOnlyModeManager.getScanMode()).thenReturn(SCAN_WITHOUT_HIDDEN_NETWORKS);
when(mSoftApManager.getScanMode()).thenReturn(SCAN_NONE);
- when(mResources.getString(
- eq(com.android.internal.R.string.wifi_localhotspot_configure_ssid_default)))
+ when(mResources.getString(R.string.wifi_localhotspot_configure_ssid_default))
.thenReturn("AndroidShare");
+ when(mResources.getInteger(R.integer.config_wifi_framework_recovery_timeout_delay))
+ .thenReturn(TEST_WIFI_RECOVERY_DELAY_MS);
+
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
+ when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+
+ doAnswer(new Answer<ClientModeManager>() {
+ public ClientModeManager answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ mClientListener = (ClientModeManager.Listener) args[0];
+ return mClientModeManager;
+ }
+ }).when(mWifiInjector).makeClientModeManager(any(ActiveModeManager.Listener.class));
+ doAnswer(new Answer<SoftApManager>() {
+ public SoftApManager answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ mSoftApListener = (ActiveModeManager.Listener) args[0];
+ mSoftApManagerCallback = (WifiManager.SoftApCallback) args[1];
+ mSoftApConfig = (SoftApModeConfiguration) args[2];
+ return mSoftApManager;
+ }
+ }).when(mWifiInjector).makeSoftApManager(any(ActiveModeManager.Listener.class),
+ any(WifiManager.SoftApCallback.class), any());
mActiveModeWarden = createActiveModeWarden();
+ mActiveModeWarden.start();
mLooper.dispatchAll();
verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture());
mWifiNativeStatusListener = mStatusListenerCaptor.getValue();
mActiveModeWarden.registerSoftApCallback(mSoftApStateMachineCallback);
- mActiveModeWarden.registerScanOnlyCallback(mScanOnlyCallback);
- mActiveModeWarden.registerClientModeCallback(mClientModeCallback);
+ mActiveModeWarden.registerLohsCallback(mLohsStateMachineCallback);
}
private ActiveModeWarden createActiveModeWarden() {
- return new ActiveModeWarden(mWifiInjector,
- mContext,
- mLooper.getLooper(),
- mWifiNative,
- mDefaultModeManager,
- mBatteryStats);
+ ActiveModeWarden warden = new ActiveModeWarden(
+ mWifiInjector,
+ mLooper.getLooper(),
+ mWifiNative,
+ mDefaultModeManager,
+ mBatteryStats,
+ mWifiDiagnostics,
+ mContext,
+ mClientModeImpl,
+ mSettingsStore,
+ mFacade,
+ mWifiPermissionsUtil);
+ // SelfRecovery is created in WifiInjector after ActiveModeWarden, so getSelfRecovery()
+ // returns null when constructing ActiveModeWarden.
+ when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery);
+ return warden;
}
/**
@@ -133,24 +195,55 @@ public class ActiveModeWardenTest {
@After
public void cleanUp() throws Exception {
mActiveModeWarden = null;
+ mLooper.dispatchAll();
}
- private class ClientModeCallback implements ClientModeManager.Listener {
- public int currentState = WifiManager.WIFI_STATE_UNKNOWN;
+ /**
+ * Helper method to enter the EnabledState and set ClientModeManager in ConnectMode.
+ */
+ private void enterClientModeActiveState() throws Exception {
+ String fromState = mActiveModeWarden.getCurrentMode();
+ when(mClientModeManager.getScanMode()).thenReturn(SCAN_WITH_HIDDEN_NETWORKS);
+ when(mClientModeManager.isInConnectMode()).thenReturn(true);
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
+ mActiveModeWarden.wifiToggled();
+ mLooper.dispatchAll();
+ mClientListener.onStarted();
+ mLooper.dispatchAll();
- @Override
- public void onStateChanged(int state) {
- currentState = state;
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+ verify(mClientModeManager).switchToConnectMode();
+ verify(mScanRequestProxy).enableScanning(true, true);
+ if (fromState.equals(DISABLED_STATE_STRING)) {
+ verify(mBatteryStats).noteWifiOn();
}
}
- private class ScanOnlyModeCallback implements ScanOnlyModeManager.Listener {
- public int currentState = WifiManager.WIFI_STATE_UNKNOWN;
+ /**
+ * Helper method to enter the EnabledState and set ClientModeManager in ScanOnlyMode.
+ */
+ private void enterScanOnlyModeActiveState() throws Exception {
+ String fromState = mActiveModeWarden.getCurrentMode();
+ when(mClientModeManager.getScanMode()).thenReturn(SCAN_WITHOUT_HIDDEN_NETWORKS);
+ when(mClientModeManager.isInScanOnlyMode()).thenReturn(true);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
+ mActiveModeWarden.wifiToggled();
+ mLooper.dispatchAll();
+ mClientListener.onStarted();
+ mLooper.dispatchAll();
- @Override
- public void onStateChanged(int state) {
- currentState = state;
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+ verify(mClientModeManager).switchToScanOnlyMode();
+ verify(mScanRequestProxy).enableScanning(true, false);
+ if (fromState.equals(DISABLED_STATE_STRING)) {
+ verify(mBatteryStats).noteWifiOn();
}
+ verify(mBatteryStats).noteWifiState(BatteryStats.WIFI_STATE_OFF_SCANNING, null);
}
private void enterSoftApActiveMode() throws Exception {
@@ -159,101 +252,185 @@ public class ActiveModeWardenTest {
}
/**
- * Helper method to enter the ClientModeActiveState for ActiveModeWarden.
+ * Helper method to activate SoftApManager.
+ *
+ * This method puts the test object into the correct state and verifies steps along the way.
*/
- private void enterClientModeActiveState() throws Exception {
+ private void enterSoftApActiveMode(SoftApModeConfiguration softApConfig) throws Exception {
String fromState = mActiveModeWarden.getCurrentMode();
- doAnswer(
- new Answer<Object>() {
- public ClientModeManager answer(InvocationOnMock invocation) {
- Object[] args = invocation.getArguments();
- mClientListener = (ClientModeManager.Listener) args[0];
- return mClientModeManager;
- }
- }).when(mWifiInjector).makeClientModeManager(
- any(ClientModeManager.Listener.class));
- mActiveModeWarden.enterClientMode();
+ mActiveModeWarden.startSoftAp(softApConfig);
mLooper.dispatchAll();
- mClientListener.onStateChanged(WifiManager.WIFI_STATE_ENABLED);
+ mSoftApListener.onStarted();
mLooper.dispatchAll();
- assertEquals(CLIENT_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode());
- verify(mClientModeManager).start();
- if (fromState.equals(SCAN_ONLY_MODE_STATE_STRING)) {
- verify(mScanRequestProxy).enableScanning(false, false);
+ assertInEnabledState();
+ assertThat(softApConfig).isEqualTo(mSoftApConfig);
+ verify(mSoftApManager).start();
+ if (fromState.equals(DISABLED_STATE_STRING)) {
+ verify(mBatteryStats).noteWifiOn();
}
- verify(mScanRequestProxy).enableScanning(true, true);
- verify(mBatteryStats).noteWifiOn();
}
- /**
- * Helper method to enter the ScanOnlyModeActiveState for ActiveModeWarden.
- */
- private void enterScanOnlyModeActiveState() throws Exception {
+ private void enterStaDisabledMode(boolean isSoftApModeManagerActive) {
String fromState = mActiveModeWarden.getCurrentMode();
- doAnswer(
- new Answer<Object>() {
- public ScanOnlyModeManager answer(InvocationOnMock invocation) {
- Object[] args = invocation.getArguments();
- mScanOnlyListener = (ScanOnlyModeManager.Listener) args[0];
- return mScanOnlyModeManager;
- }
- }).when(mWifiInjector).makeScanOnlyModeManager(
- any(ScanOnlyModeManager.Listener.class));
- mActiveModeWarden.enterScanOnlyMode();
- mLooper.dispatchAll();
- mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_ENABLED);
- mLooper.dispatchAll();
-
- assertEquals(SCAN_ONLY_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode());
- verify(mScanOnlyModeManager).start();
- if (fromState.equals(CLIENT_MODE_STATE_STRING)) {
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
+ mActiveModeWarden.wifiToggled();
+ mLooper.dispatchAll();
+ if (mClientListener != null) {
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ }
+
+ if (isSoftApModeManagerActive) {
+ assertInEnabledState();
+ } else {
+ assertInDisabledState();
+ }
+ if (fromState.equals(ENABLED_STATE_STRING)) {
verify(mScanRequestProxy).enableScanning(false, false);
}
- verify(mScanRequestProxy).enableScanning(true, false);
- verify(mBatteryStats).noteWifiOn();
- verify(mBatteryStats).noteWifiState(eq(BatteryStats.WIFI_STATE_OFF_SCANNING), eq(null));
+ }
+
+ private void shutdownWifi() {
+ mActiveModeWarden.recoveryDisableWifi();
+ mLooper.dispatchAll();
+ }
+
+ private void assertInEnabledState() {
+ assertThat(mActiveModeWarden.getCurrentMode()).isEqualTo(ENABLED_STATE_STRING);
+ }
+
+ private void assertInDisabledState() {
+ assertThat(mActiveModeWarden.getCurrentMode()).isEqualTo(DISABLED_STATE_STRING);
}
/**
- * Helper method to enter the SoftApActiveMode for ActiveModeWarden.
+ * Emergency mode is a sub-mode within each main state (ScanOnly, Client, DisabledState).
+ */
+ private void assertInEmergencyMode() {
+ assertThat(mActiveModeWarden.isInEmergencyMode()).isTrue();
+ }
+
+ /**
+ * Counts the number of times a void method was called on a mock.
*
- * This method puts the test object into the correct state and verifies steps along the way.
+ * Void methods cannot be passed to Mockito.mockingDetails(). Thus we have to use method name
+ * matching instead.
*/
- private void enterSoftApActiveMode(SoftApModeConfiguration softApConfig) throws Exception {
- String fromState = mActiveModeWarden.getCurrentMode();
- doAnswer(
- new Answer<Object>() {
- public SoftApManager answer(InvocationOnMock invocation) {
- Object[] args = invocation.getArguments();
- mSoftApManagerCallback = (WifiManager.SoftApCallback) args[0];
- assertEquals(softApConfig, (SoftApModeConfiguration) args[1]);
- return mSoftApManager;
- }
- }).when(mWifiInjector).makeSoftApManager(any(WifiManager.SoftApCallback.class),
- any());
- mActiveModeWarden.enterSoftAPMode(softApConfig);
- mLooper.dispatchAll();
- verify(mSoftApManager).start();
- if (fromState.equals(WIFI_DISABLED_STATE_STRING)) {
- verify(mBatteryStats).noteWifiOn();
- } else if (!fromState.equals(SCAN_ONLY_MODE_STATE_STRING)
- && !fromState.equals(CLIENT_MODE_STATE_STRING)) {
- verify(mScanRequestProxy, atLeastOnce()).enableScanning(false, false);
- }
+ private static int getMethodInvocationCount(Object mock, String methodName) {
+ long count = mockingDetails(mock).getInvocations()
+ .stream()
+ .filter(invocation -> methodName.equals(invocation.getMethod().getName()))
+ .count();
+ return (int) count;
+ }
+
+ /**
+ * Counts the number of times a non-void method was called on a mock.
+ *
+ * For non-void methods, can pass the method call literal directly:
+ * e.g. getMethodInvocationCount(mock.method());
+ */
+ private static int getMethodInvocationCount(Object mockMethod) {
+ return mockingDetails(mockMethod).getInvocations().size();
+ }
+
+ private void assertWifiShutDown(Runnable r) {
+ assertWifiShutDown(r, 1);
}
/**
- * Test that after starting up, ActiveModeWarden is in the Disabled State.
+ * Asserts that the runnable r has shut down wifi properly.
+ *
+ * @param r runnable that will shut down wifi
+ * @param times expected number of times that <code>r</code> shut down wifi
+ */
+ private void assertWifiShutDown(Runnable r, int times) {
+ // take snapshot of ActiveModeManagers
+ Collection<ActiveModeManager> activeModeManagers =
+ mActiveModeWarden.getActiveModeManagers();
+
+ List<Integer> expectedStopInvocationCounts = activeModeManagers
+ .stream()
+ .map(manager -> getMethodInvocationCount(manager, "stop") + times)
+ .collect(Collectors.toList());
+
+ r.run();
+
+ List<Integer> actualStopInvocationCounts = activeModeManagers
+ .stream()
+ .map(manager -> getMethodInvocationCount(manager, "stop"))
+ .collect(Collectors.toList());
+
+ String managerNames = activeModeManagers.stream()
+ .map(manager -> manager.getClass().getCanonicalName())
+ .collect(Collectors.joining(", ", "[", "]"));
+
+ assertThat(actualStopInvocationCounts)
+ .named(managerNames)
+ .isEqualTo(expectedStopInvocationCounts);
+ }
+
+ private void assertEnteredEcmMode(Runnable r) {
+ assertEnteredEcmMode(r, 1);
+ }
+
+ /**
+ * Asserts that the runnable r has entered ECM state properly.
+ *
+ * @param r runnable that will enter ECM
+ * @param times expected number of times that <code>r</code> shut down wifi
*/
+ private void assertEnteredEcmMode(Runnable r, int times) {
+ // take snapshot of ActiveModeManagers
+ Collection<ActiveModeManager> activeModeManagers =
+ mActiveModeWarden.getActiveModeManagers();
+
+ boolean disableWifiInEcm = mFacade.getConfigWiFiDisableInECBM(mContext);
+
+ List<Integer> expectedStopInvocationCounts = activeModeManagers.stream()
+ .map(manager -> {
+ int initialCount = getMethodInvocationCount(manager, "stop");
+ // carrier config enabled, all mode managers should have been shut down once
+ int count = disableWifiInEcm ? initialCount + times : initialCount;
+ if (manager instanceof SoftApManager) {
+ // expect SoftApManager.close() to be called
+ return count + times;
+ } else {
+ // don't expect other Managers close() to be called
+ return count;
+ }
+ })
+ .collect(Collectors.toList());
+
+ r.run();
+
+ assertInEmergencyMode();
+
+ List<Integer> actualStopInvocationCounts = activeModeManagers.stream()
+ .map(manager -> getMethodInvocationCount(manager, "stop"))
+ .collect(Collectors.toList());
+
+ String managerNames = activeModeManagers.stream()
+ .map(manager -> manager.getClass().getCanonicalName())
+ .collect(Collectors.joining(", ", "[", "]"));
+
+ assertThat(actualStopInvocationCounts)
+ .named(managerNames)
+ .isEqualTo(expectedStopInvocationCounts);
+ }
+
+ /** Test that after starting up, ActiveModeWarden is in the DisabledState State. */
@Test
- public void testWifiDisabledAtStartup() throws Exception {
- assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode());
+ public void testDisabledStateAtStartup() {
+ assertInDisabledState();
}
/**
- * Test that ActiveModeWarden properly enters the ScanOnlyModeActiveState from the
- * WifiDisabled state.
+ * Test that ActiveModeWarden properly enters the EnabledState (in ScanOnlyMode) from the
+ * DisabledState state.
*/
@Test
public void testEnterScanOnlyModeFromDisabled() throws Exception {
@@ -261,8 +438,8 @@ public class ActiveModeWardenTest {
}
/**
- * Test that ActiveModeWarden properly enters the SoftApModeActiveState from the
- * WifiDisabled state.
+ * Test that ActiveModeWarden properly starts the SoftApManager from the
+ * DisabledState state.
*/
@Test
public void testEnterSoftApModeFromDisabled() throws Exception {
@@ -270,49 +447,50 @@ public class ActiveModeWardenTest {
}
/**
- * Test that ActiveModeWarden properly enters the SoftApModeActiveState from another state.
+ * Test that ActiveModeWarden properly starts the SoftApManager from another state.
*/
@Test
public void testEnterSoftApModeFromDifferentState() throws Exception {
enterClientModeActiveState();
- mLooper.dispatchAll();
- assertEquals(CLIENT_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode());
+ assertInEnabledState();
reset(mBatteryStats, mScanRequestProxy);
enterSoftApActiveMode();
}
/**
- * Test that we can disable wifi fully from the ScanOnlyModeActiveState.
+ * Test that we can disable wifi fully from the EnabledState (in ScanOnlyMode).
*/
@Test
public void testDisableWifiFromScanOnlyModeActiveState() throws Exception {
enterScanOnlyModeActiveState();
- mActiveModeWarden.disableWifi();
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
+ mActiveModeWarden.scanAlwaysModeChanged();
mLooper.dispatchAll();
- verify(mScanOnlyModeManager).stop();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+
+ verify(mClientModeManager).stop();
verify(mBatteryStats).noteWifiOff();
- assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode());
+ assertInDisabledState();
}
/**
- * Test that we can disable wifi from the SoftApModeActiveState and not impact softap.
+ * Test that we can disable wifi when SoftApManager is active and not impact softap.
*/
@Test
public void testDisableWifiFromSoftApModeActiveStateDoesNotStopSoftAp() throws Exception {
enterSoftApActiveMode();
+ enterScanOnlyModeActiveState();
reset(mDefaultModeManager);
- mActiveModeWarden.disableWifi();
- mLooper.dispatchAll();
+ enterStaDisabledMode(true);
verify(mSoftApManager, never()).stop();
verify(mBatteryStats, never()).noteWifiOff();
- assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode());
}
/**
- * Thest that we can switch from ScanOnlyActiveMode to another mode.
- * Expectation: When switching out of ScanOlyModeActivState we stop the ScanOnlyModeManager.
+ * Test that we can switch from the EnabledState (in ScanOnlyMode) to another mode.
*/
@Test
public void testSwitchModeWhenScanOnlyModeActiveState() throws Exception {
@@ -321,13 +499,25 @@ public class ActiveModeWardenTest {
reset(mBatteryStats, mScanRequestProxy);
enterClientModeActiveState();
mLooper.dispatchAll();
- verify(mScanOnlyModeManager).stop();
- assertEquals(CLIENT_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode());
+ verify(mClientModeManager).switchToConnectMode();
+ assertInEnabledState();
+ }
+
+ /**
+ * Reentering EnabledState should be a NOP.
+ */
+ @Test
+ public void testReenterClientModeActiveStateIsNop() throws Exception {
+ enterClientModeActiveState();
+ reset(mClientModeManager);
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
+ mActiveModeWarden.wifiToggled();
+ mLooper.dispatchAll();
+ verify(mClientModeManager, never()).start();
}
/**
- * Test that we can switch from SoftApActiveMode to another mode.
- * Expectation: When switching out of SoftApModeActiveState we do not impact softap operation
+ * Test that we can switch mode when SoftApManager is active to another mode.
*/
@Test
public void testSwitchModeWhenSoftApActiveMode() throws Exception {
@@ -338,23 +528,21 @@ public class ActiveModeWardenTest {
enterClientModeActiveState();
mLooper.dispatchAll();
verify(mSoftApManager, never()).stop();
- assertEquals(CLIENT_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode());
+ assertInEnabledState();
verify(mWifiNative, never()).teardownAllInterfaces();
}
/**
- * Test that we do enter the SoftApModeActiveState if we are already in WifiDisabledState due to
+ * Test that we activate SoftApModeManager if we are already in DisabledState due to
* a failure.
- * Expectations: We should exit the current WifiDisabledState and re-enter before successfully
- * entering the SoftApModeActiveState.
*/
@Test
public void testEnterSoftApModeActiveWhenAlreadyInSoftApMode() throws Exception {
enterSoftApActiveMode();
// now inject failure through the SoftApManager.Listener
- mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED, 0);
+ mSoftApListener.onStartFailure();
mLooper.dispatchAll();
- assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode());
+ assertInDisabledState();
// clear the first call to start SoftApManager
reset(mSoftApManager, mBatteryStats);
@@ -362,63 +550,57 @@ public class ActiveModeWardenTest {
}
/**
- * Test that we return to the WifiDisabledState after a failure is reported when in the
- * ScanOnlyModeActiveState.
- * Expectations: we should exit the ScanOnlyModeActiveState and stop the ScanOnlyModeManager.
+ * Test that we return to the DisabledState after a failure is reported when in the
+ * EnabledState.
*/
@Test
public void testScanOnlyModeFailureWhenActive() throws Exception {
enterScanOnlyModeActiveState();
// now inject a failure through the ScanOnlyModeManager.Listener
- mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN);
+ mClientListener.onStartFailure();
mLooper.dispatchAll();
- assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode());
- verify(mScanOnlyModeManager).stop();
+ assertInDisabledState();
verify(mBatteryStats).noteWifiOff();
- assertEquals(WifiManager.WIFI_STATE_UNKNOWN, mScanOnlyCallback.currentState);
}
/**
- * Test that we return to the WifiDisabledState after a failure is reported when in the
- * SoftApModeActiveState.
- * Expectations: We should exit the SoftApModeActiveState and stop the SoftApManager.
+ * Test that we return to the DisabledState after a failure is reported when
+ * SoftApManager is active.
*/
@Test
public void testSoftApFailureWhenActive() throws Exception {
enterSoftApActiveMode();
// now inject failure through the SoftApManager.Listener
- mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED, 0);
+ mSoftApListener.onStartFailure();
mLooper.dispatchAll();
verify(mBatteryStats).noteWifiOff();
}
/**
- * Test that we return to the WifiDisabledState after the ScanOnlyModeManager is stopping in the
- * ScanOnlyModeActiveState.
- * Expectations: We should exit the ScanOnlyModeActiveState and stop the ScanOnlyModeManager.
+ * Test that we return to the DisabledState after the ClientModeManager running in ScanOnlyMode
+ * is stopped.
*/
@Test
public void testScanOnlyModeDisabledWhenActive() throws Exception {
enterScanOnlyModeActiveState();
+
// now inject the stop message through the ScanOnlyModeManager.Listener
- mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
+ mClientListener.onStopped();
mLooper.dispatchAll();
- assertEquals(WIFI_DISABLED_STATE_STRING, mActiveModeWarden.getCurrentMode());
- verify(mScanOnlyModeManager).stop();
+
+ assertInDisabledState();
verify(mBatteryStats).noteWifiOff();
}
/**
- * Test that we return to the WifiDisabledState after the SoftApManager is stopped in the
- * SoftApModeActiveState.
- * Expectations: We should exit the SoftApModeActiveState and stop the SoftApManager.
+ * Test that we return to the DisabledState after the SoftApManager is stopped.
*/
@Test
public void testSoftApDisabledWhenActive() throws Exception {
enterSoftApActiveMode();
reset(mWifiNative);
// now inject failure through the SoftApManager.Listener
- mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED, 0);
+ mSoftApListener.onStartFailure();
mLooper.dispatchAll();
verify(mBatteryStats).noteWifiOff();
verifyNoMoreInteractions(mWifiNative);
@@ -431,6 +613,7 @@ public class ActiveModeWardenTest {
public void callsWifiServiceCallbackOnSoftApStateChanged() throws Exception {
enterSoftApActiveMode();
+ mSoftApListener.onStarted();
mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
mLooper.dispatchAll();
@@ -446,11 +629,12 @@ public class ActiveModeWardenTest {
enterSoftApActiveMode(new SoftApModeConfiguration(
WifiManager.IFACE_IP_MODE_LOCAL_ONLY, null));
+ mSoftApListener.onStarted();
mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
mLooper.dispatchAll();
verify(mSoftApStateMachineCallback, never()).onStateChanged(anyInt(), anyInt());
- verify(mSoftApStateMachineCallback, never()).onNumClientsChanged(anyInt());
+ verify(mSoftApStateMachineCallback, never()).onConnectedClientsChanged(any());
}
/**
@@ -474,13 +658,13 @@ public class ActiveModeWardenTest {
* Verifies that NumClientsChanged event is being passed from SoftApManager to WifiServiceImpl
*/
@Test
- public void callsWifiServiceCallbackOnSoftApNumClientsChanged() throws Exception {
- final int testNumClients = 3;
+ public void callsWifiServiceCallbackOnSoftApConnectedClientsChanged() throws Exception {
+ final List<WifiClient> testClients = new ArrayList();
enterSoftApActiveMode();
- mSoftApManagerCallback.onNumClientsChanged(testNumClients);
+ mSoftApManagerCallback.onConnectedClientsChanged(testClients);
mLooper.dispatchAll();
- verify(mSoftApStateMachineCallback).onNumClientsChanged(testNumClients);
+ verify(mSoftApStateMachineCallback).onConnectedClientsChanged(testClients);
}
/**
@@ -488,53 +672,35 @@ public class ActiveModeWardenTest {
* WifiServiceImpl is null.
*/
@Test
- public void testNullCallbackToWifiServiceImplForNumClientsChanged() throws Exception {
-
- final int testNumClients = 3;
+ public void testNullCallbackToWifiServiceImplForConnectedClientsChanged() throws Exception {
+ final List<WifiClient> testClients = new ArrayList();
//set the callback to null
mActiveModeWarden.registerSoftApCallback(null);
enterSoftApActiveMode();
- mSoftApManagerCallback.onNumClientsChanged(testNumClients);
+ mSoftApManagerCallback.onConnectedClientsChanged(testClients);
- verify(mSoftApStateMachineCallback, never()).onNumClientsChanged(anyInt());
+ verify(mSoftApStateMachineCallback, never()).onConnectedClientsChanged(any());
}
/**
* Test that we remain in the active state when we get a state change update that scan mode is
* active.
- * Expectations: We should remain in the ScanOnlyModeActive state.
*/
@Test
public void testScanOnlyModeStaysActiveOnEnabledUpdate() throws Exception {
enterScanOnlyModeActiveState();
- // now inject failure through the SoftApManager.Listener
- mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_ENABLED);
+ // now inject success through the Listener
+ mClientListener.onStarted();
mLooper.dispatchAll();
- assertEquals(SCAN_ONLY_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode());
- verify(mScanOnlyModeManager, never()).stop();
- }
-
- /**
- * Test that we do not act on unepected state string messages and remain in the active state.
- * Expectations: We should remain in the ScanOnlyModeActive state.
- */
- @Test
- public void testScanOnlyModeStaysActiveOnUnexpectedStateUpdate() throws Exception {
- enterScanOnlyModeActiveState();
- // now inject failure through the SoftApManager.Listener
- mScanOnlyListener.onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING);
- mLooper.dispatchAll();
- assertEquals(SCAN_ONLY_MODE_STATE_STRING, mActiveModeWarden.getCurrentMode());
- verify(mScanOnlyModeManager, never()).stop();
+ assertInEnabledState();
+ verify(mClientModeManager, never()).stop();
}
/**
* Test that a config passed in to the call to enterSoftApMode is used to create the new
* SoftApManager.
- * Expectations: We should create a SoftApManager in WifiInjector with the config passed in to
- * ActiveModeWarden to switch to SoftApMode.
*/
@Test
public void testConfigIsPassedToWifiInjector() throws Exception {
@@ -550,8 +716,6 @@ public class ActiveModeWardenTest {
* WifiInjector.makeSoftApManager.
*
* Passing a null config to SoftApManager indicates that the default config should be used.
- *
- * Expectations: WifiInjector should be called with a null config.
*/
@Test
public void testNullConfigIsPassedToWifiInjector() throws Exception {
@@ -575,18 +739,34 @@ public class ActiveModeWardenTest {
SoftApModeConfiguration softApConfig2 =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, config2);
- when(mWifiInjector.makeSoftApManager(any(WifiManager.SoftApCallback.class),
- eq(softApConfig1)))
- .thenReturn(mSoftApManager);
+ doAnswer(new Answer<SoftApManager>() {
+ public SoftApManager answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ mSoftApListener = (ActiveModeManager.Listener) args[0];
+ return mSoftApManager;
+ }
+ }).when(mWifiInjector).makeSoftApManager(any(ActiveModeManager.Listener.class),
+ any(WifiManager.SoftApCallback.class), eq(softApConfig1));
// make a second softap manager
SoftApManager softapManager = mock(SoftApManager.class);
- when(mWifiInjector.makeSoftApManager(any(WifiManager.SoftApCallback.class),
- eq(softApConfig2)))
- .thenReturn(softapManager);
-
- mActiveModeWarden.enterSoftAPMode(softApConfig1);
- mActiveModeWarden.enterSoftAPMode(softApConfig2);
+ GeneralUtil.Mutable<ActiveModeManager.Listener> softApListener =
+ new GeneralUtil.Mutable<>();
+ doAnswer(new Answer<SoftApManager>() {
+ public SoftApManager answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ softApListener.value = (ActiveModeManager.Listener) args[0];
+ return softapManager;
+ }
+ }).when(mWifiInjector).makeSoftApManager(any(ActiveModeManager.Listener.class),
+ any(WifiManager.SoftApCallback.class), eq(softApConfig2));
+
+ mActiveModeWarden.startSoftAp(softApConfig1);
mLooper.dispatchAll();
+ mSoftApListener.onStarted();
+ mActiveModeWarden.startSoftAp(softApConfig2);
+ mLooper.dispatchAll();
+ softApListener.value.onStarted();
+
verify(mSoftApManager).start();
verify(softapManager).start();
verify(mBatteryStats).noteWifiOn();
@@ -594,12 +774,11 @@ public class ActiveModeWardenTest {
/**
* Test that we safely disable wifi if it is already disabled.
- * Expectations: We should not interact with WifiNative since we should have already cleaned up
- * everything.
*/
@Test
public void disableWifiWhenAlreadyOff() throws Exception {
- mActiveModeWarden.disableWifi();
+ enterStaDisabledMode(false);
+ verifyZeroInteractions(mWifiNative);
}
/**
@@ -633,12 +812,12 @@ public class ActiveModeWardenTest {
public void shutdownWifiDoesNotCrashWhenClientModeExitsOnDestroyed() throws Exception {
enterClientModeActiveState();
- mClientListener.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
+ mClientListener.onStopped();
mLooper.dispatchAll();
- mActiveModeWarden.shutdownWifi();
+ shutdownWifi();
- assertEquals(WifiManager.WIFI_STATE_DISABLED, mClientModeCallback.currentState);
+ assertInDisabledState();
}
/**
@@ -648,12 +827,12 @@ public class ActiveModeWardenTest {
public void onDestroyedCallbackDoesNotCrashWhenClientModeAlreadyStopped() throws Exception {
enterClientModeActiveState();
- mActiveModeWarden.shutdownWifi();
+ shutdownWifi();
- mClientListener.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
+ mClientListener.onStopped();
mLooper.dispatchAll();
- assertEquals(WifiManager.WIFI_STATE_DISABLED, mClientModeCallback.currentState);
+ assertInDisabledState();
}
/**
@@ -663,10 +842,12 @@ public class ActiveModeWardenTest {
public void shutdownWifiDoesNotCrashWhenSoftApExitsOnDestroyed() throws Exception {
enterSoftApActiveMode();
+ mSoftApListener.onStopped();
+ mLooper.dispatchAll();
mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
mLooper.dispatchAll();
- mActiveModeWarden.shutdownWifi();
+ shutdownWifi();
verify(mSoftApStateMachineCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
}
@@ -678,8 +859,9 @@ public class ActiveModeWardenTest {
public void onDestroyedCallbackDoesNotCrashWhenSoftApModeAlreadyStopped() throws Exception {
enterSoftApActiveMode();
- mActiveModeWarden.shutdownWifi();
+ shutdownWifi();
+ mSoftApListener.onStopped();
mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
mLooper.dispatchAll();
@@ -703,17 +885,13 @@ public class ActiveModeWardenTest {
public void dumpCallsActiveModeManagers() throws Exception {
enterSoftApActiveMode();
enterClientModeActiveState();
- reset(mScanRequestProxy);
- enterScanOnlyModeActiveState();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(stream);
mActiveModeWarden.dump(null, writer, null);
- verify(mSoftApManager).dump(eq(null), eq(writer), eq(null));
- // can only be in scan or client, so we should not have a client mode active
- verify(mClientModeManager, never()).dump(eq(null), eq(writer), eq(null));
- verify(mScanOnlyModeManager).dump(eq(null), eq(writer), eq(null));
+ verify(mSoftApManager).dump(null, writer, null);
+ verify(mClientModeManager).dump(null, writer, null);
}
/**
@@ -732,27 +910,1134 @@ public class ActiveModeWardenTest {
// mock SoftAPManagers
when(mSoftApManager.getIpMode()).thenReturn(WifiManager.IFACE_IP_MODE_TETHERED);
- when(mWifiInjector.makeSoftApManager(any(WifiManager.SoftApCallback.class),
- eq(tetherConfig)))
- .thenReturn(mSoftApManager);
+ doAnswer(new Answer<SoftApManager>() {
+ public SoftApManager answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ mSoftApListener = (ActiveModeManager.Listener) args[0];
+ return mSoftApManager;
+ }
+ }).when(mWifiInjector).makeSoftApManager(any(ActiveModeManager.Listener.class),
+ any(WifiManager.SoftApCallback.class), eq(tetherConfig));
+ // make a second softap manager
SoftApManager lohsSoftapManager = mock(SoftApManager.class);
- when(lohsSoftapManager.getIpMode()).thenReturn(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
- when(mWifiInjector.makeSoftApManager(any(WifiManager.SoftApCallback.class),
- eq(lohsConfig)))
- .thenReturn(lohsSoftapManager);
+ GeneralUtil.Mutable<ActiveModeManager.Listener> lohsSoftApListener =
+ new GeneralUtil.Mutable<>();
+ doAnswer(new Answer<SoftApManager>() {
+ public SoftApManager answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ lohsSoftApListener.value = (ActiveModeManager.Listener) args[0];
+ return lohsSoftapManager;
+ }
+ }).when(mWifiInjector).makeSoftApManager(any(ActiveModeManager.Listener.class),
+ any(WifiManager.SoftApCallback.class), eq(lohsConfig));
// enable tethering and LOHS
- mActiveModeWarden.enterSoftAPMode(tetherConfig);
- mActiveModeWarden.enterSoftAPMode(lohsConfig);
+ mActiveModeWarden.startSoftAp(tetherConfig);
mLooper.dispatchAll();
+ mSoftApListener.onStarted();
+ mActiveModeWarden.startSoftAp(lohsConfig);
+ mLooper.dispatchAll();
+ lohsSoftApListener.value.onStarted();
verify(mSoftApManager).start();
verify(lohsSoftapManager).start();
verify(mBatteryStats).noteWifiOn();
// disable tethering
- mActiveModeWarden.stopSoftAPMode(WifiManager.IFACE_IP_MODE_TETHERED);
+ mActiveModeWarden.stopSoftAp(WifiManager.IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
verify(mSoftApManager).stop();
verify(lohsSoftapManager, never()).stop();
}
+
+ /**
+ * Verify that toggling wifi from disabled starts client mode.
+ */
+ @Test
+ public void enableWifi() throws Exception {
+ assertInDisabledState();
+
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
+ mActiveModeWarden.wifiToggled();
+ mLooper.dispatchAll();
+
+ mClientListener.onStarted();
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+ }
+
+ /**
+ * Test verifying that we can enter scan mode when the scan mode changes
+ */
+ @Test
+ public void enableScanMode() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ mActiveModeWarden.scanAlwaysModeChanged();
+ mLooper.dispatchAll();
+ verify(mClientModeManager).start();
+ verify(mClientModeManager).switchToScanOnlyMode();
+ assertInEnabledState();
+ verify(mClientModeManager, never()).stop();
+ }
+
+ /**
+ * Verify that if scanning is enabled at startup, we enter scan mode
+ */
+ @Test
+ public void testEnterScanModeAtStartWhenSet() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+
+ mActiveModeWarden = createActiveModeWarden();
+ mActiveModeWarden.start();
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+ }
+
+ /**
+ * Verify that if Wifi is enabled at startup, we enter client mode
+ */
+ @Test
+ public void testEnterClientModeAtStartWhenSet() throws Exception {
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
+
+ mActiveModeWarden = createActiveModeWarden();
+ mActiveModeWarden.start();
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+
+ verify(mClientModeManager).start();
+ verify(mClientModeManager).switchToConnectMode();
+ }
+
+ /**
+ * Do not enter scan mode if location mode disabled.
+ */
+ @Test
+ public void testDoesNotEnterScanModeWhenLocationModeDisabled() throws Exception {
+ // Start a new WifiController with wifi disabled
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
+
+ mActiveModeWarden = createActiveModeWarden();
+ mActiveModeWarden.start();
+ mLooper.dispatchAll();
+
+ assertInDisabledState();
+
+ // toggling scan always available is not sufficient for scan mode
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ mActiveModeWarden.scanAlwaysModeChanged();
+ mLooper.dispatchAll();
+
+ assertInDisabledState();
+ }
+
+ /**
+ * Only enter scan mode if location mode enabled
+ */
+ @Test
+ public void testEnterScanModeWhenLocationModeEnabled() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
+
+ reset(mContext);
+ when(mContext.getResources()).thenReturn(mResources);
+ mActiveModeWarden = createActiveModeWarden();
+ mActiveModeWarden.start();
+ mLooper.dispatchAll();
+
+ ArgumentCaptor<BroadcastReceiver> bcastRxCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class));
+ BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue();
+
+ assertInDisabledState();
+
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION);
+ broadcastReceiver.onReceive(mContext, intent);
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+ }
+
+
+ /**
+ * Disabling location mode when in scan mode will disable wifi
+ */
+ @Test
+ public void testExitScanModeWhenLocationModeDisabled() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+
+ reset(mContext);
+ when(mContext.getResources()).thenReturn(mResources);
+ mActiveModeWarden = createActiveModeWarden();
+ mActiveModeWarden.start();
+ mLooper.dispatchAll();
+ mClientListener.onStarted();
+ mLooper.dispatchAll();
+
+ ArgumentCaptor<BroadcastReceiver> bcastRxCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class));
+ BroadcastReceiver broadcastReceiver = bcastRxCaptor.getValue();
+
+ assertInEnabledState();
+
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
+ Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION);
+ broadcastReceiver.onReceive(mContext, intent);
+ mLooper.dispatchAll();
+
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+
+ assertInDisabledState();
+ }
+
+ /**
+ * When in Client mode, make sure ECM triggers wifi shutdown.
+ */
+ @Test
+ public void testEcmOnFromClientMode() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
+ enableWifi();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertWifiShutDown(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+ }
+
+ /**
+ * ECM disabling messages, when in client mode (not expected) do not trigger state changes.
+ */
+ @Test
+ public void testEcmOffInClientMode() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
+ enableWifi();
+
+ // Test with WifiDisableInECBM turned off
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false);
+
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+ }
+
+ /**
+ * When ECM activates and we are in client mode, disabling ECM should return us to client mode.
+ */
+ @Test
+ public void testEcmDisabledReturnsToClientMode() throws Exception {
+ enableWifi();
+ assertInEnabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertWifiShutDown(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+ }
+
+ /**
+ * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed
+ * update.
+ */
+ @Test
+ public void testEcmOnFromScanMode() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ mActiveModeWarden.scanAlwaysModeChanged();
+ mLooper.dispatchAll();
+
+ mClientListener.onStarted();
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertWifiShutDown(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+ }
+
+ /**
+ * When Ecm mode is disabled, we should not shut down scan mode if we get an emergency mode
+ * changed update, but we should turn off soft AP
+ */
+ @Test
+ public void testEcmOffInScanMode() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ mActiveModeWarden.scanAlwaysModeChanged();
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+
+ // Test with WifiDisableInECBM turned off:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false);
+
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+ }
+
+ /**
+ * When ECM is disabled, we should return to scan mode
+ */
+ @Test
+ public void testEcmDisabledReturnsToScanMode() throws Exception {
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ mActiveModeWarden.scanAlwaysModeChanged();
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertWifiShutDown(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+ }
+
+ /**
+ * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed
+ * update.
+ */
+ @Test
+ public void testEcmOnFromSoftApMode() throws Exception {
+ enterSoftApActiveMode();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+ }
+
+ /**
+ * When Ecm mode is disabled, we should shut down softap mode if we get an emergency mode
+ * changed update
+ */
+ @Test
+ public void testEcmOffInSoftApMode() throws Exception {
+ enterSoftApActiveMode();
+
+ // Test with WifiDisableInECBM turned off:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false);
+
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+
+ verify(mSoftApManager).stop();
+ }
+
+ /**
+ * When ECM is activated and we were in softap mode, we should just return to wifi off when ECM
+ * ends
+ */
+ @Test
+ public void testEcmDisabledRemainsDisabledWhenSoftApHadBeenOn() throws Exception {
+ assertInDisabledState();
+
+ enterSoftApActiveMode();
+
+ // verify Soft AP Manager started
+ verify(mSoftApManager).start();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ mSoftApListener.onStopped();
+ mLooper.dispatchAll();
+ });
+
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+
+ assertInDisabledState();
+
+ // verify no additional calls to enable softap
+ verify(mSoftApManager).start();
+ }
+
+ /**
+ * Wifi should remain off when already disabled and we enter ECM.
+ */
+ @Test
+ public void testEcmOnFromDisabledMode() throws Exception {
+ assertInDisabledState();
+ verify(mSoftApManager, never()).start();
+ verify(mClientModeManager, never()).start();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+ }
+
+
+ /**
+ * Updates about call state change also trigger entry of ECM mode.
+ */
+ @Test
+ public void testEnterEcmOnEmergencyCallStateChange() throws Exception {
+ assertInDisabledState();
+
+ enableWifi();
+ assertInEnabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertEnteredEcmMode(() -> {
+ // test call state changed
+ mActiveModeWarden.emergencyCallStateChanged(true);
+ mLooper.dispatchAll();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ });
+
+ mActiveModeWarden.emergencyCallStateChanged(false);
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+ }
+
+ /**
+ * Verify when both ECM and call state changes arrive, we enter ECM mode
+ */
+ @Test
+ public void testEnterEcmWithBothSignals() throws Exception {
+ assertInDisabledState();
+
+ enableWifi();
+ assertInEnabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertWifiShutDown(() -> {
+ mActiveModeWarden.emergencyCallStateChanged(true);
+ mLooper.dispatchAll();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ });
+
+ assertWifiShutDown(() -> {
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ }, 0); // does not cause another shutdown
+
+ // client mode only started once so far
+ verify(mClientModeManager).start();
+
+ mActiveModeWarden.emergencyCallStateChanged(false);
+ mLooper.dispatchAll();
+
+ // stay in ecm, do not send an additional client mode trigger
+ assertInEmergencyMode();
+ // assert that the underlying state is in disabled state
+ assertInDisabledState();
+
+ // client mode still only started once
+ verify(mClientModeManager).start();
+
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+
+ // now we can re-enable wifi
+ verify(mClientModeManager, times(2)).start();
+ assertInEnabledState();
+ }
+
+ /**
+ * Verify when both ECM and call state changes arrive but out of order, we enter ECM mode
+ */
+ @Test
+ public void testEnterEcmWithBothSignalsOutOfOrder() throws Exception {
+ assertInDisabledState();
+
+ enableWifi();
+
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertEnteredEcmMode(() -> {
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ });
+ assertInDisabledState();
+
+ assertEnteredEcmMode(() -> {
+ mActiveModeWarden.emergencyCallStateChanged(true);
+ mLooper.dispatchAll();
+ }, 0); // does not enter ECM state again
+
+ mActiveModeWarden.emergencyCallStateChanged(false);
+ mLooper.dispatchAll();
+
+ // stay in ecm, do not send an additional client mode trigger
+ assertInEmergencyMode();
+ // assert that the underlying state is in disabled state
+ assertInDisabledState();
+
+ // client mode still only started once
+ verify(mClientModeManager).start();
+
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+
+ // now we can re-enable wifi
+ verify(mClientModeManager, times(2)).start();
+ assertInEnabledState();
+ }
+
+ /**
+ * Verify when both ECM and call state changes arrive but completely out of order,
+ * we still enter and properly exit ECM mode
+ */
+ @Test
+ public void testEnterEcmWithBothSignalsOppositeOrder() throws Exception {
+ assertInDisabledState();
+
+ enableWifi();
+
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertEnteredEcmMode(() -> {
+ mActiveModeWarden.emergencyCallStateChanged(true);
+ mLooper.dispatchAll();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ });
+ assertInDisabledState();
+
+ assertEnteredEcmMode(() -> {
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ }, 0); // still only 1 shutdown
+
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+
+ // stay in ecm, do not send an additional client mode trigger
+ assertInEmergencyMode();
+ // assert that the underlying state is in disabled state
+ assertInDisabledState();
+
+ // client mode still only started once
+ verify(mClientModeManager).start();
+
+ mActiveModeWarden.emergencyCallStateChanged(false);
+ mLooper.dispatchAll();
+
+ // now we can re-enable wifi
+ verify(mClientModeManager, times(2)).start();
+ assertInEnabledState();
+ }
+
+ /**
+ * When ECM is active, we might get addition signals of ECM mode, drop those additional signals,
+ * we must exit when one of each signal is received.
+ *
+ * In any case, duplicate signals indicate a bug from Telephony. Each signal should be turned
+ * off before it is turned on again.
+ */
+ @Test
+ public void testProperExitFromEcmModeWithMultipleMessages() throws Exception {
+ assertInDisabledState();
+
+ enableWifi();
+
+ verify(mClientModeManager).start();
+ assertInEnabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+
+ assertEnteredEcmMode(() -> {
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mActiveModeWarden.emergencyCallStateChanged(true);
+ mActiveModeWarden.emergencyCallStateChanged(true);
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ });
+ assertInDisabledState();
+
+ assertEnteredEcmMode(() -> {
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+ }, 0);
+
+ // didn't enter client mode again
+ verify(mClientModeManager).start();
+ assertInDisabledState();
+
+ // now we will exit ECM
+ mActiveModeWarden.emergencyCallStateChanged(false);
+ mLooper.dispatchAll();
+
+ // now we can re-enable wifi
+ verify(mClientModeManager, times(2)).start();
+ assertInEnabledState();
+ }
+
+ /**
+ * Toggling wifi when in ECM does not exit ecm mode and enable wifi
+ */
+ @Test
+ public void testWifiDoesNotToggleOnWhenInEcm() throws Exception {
+ assertInDisabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+ // test ecm changed
+ assertEnteredEcmMode(() -> {
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+
+ // now toggle wifi and verify we do not start wifi
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
+ mActiveModeWarden.wifiToggled();
+ mLooper.dispatchAll();
+
+ verify(mClientModeManager, never()).start();
+ assertInDisabledState();
+ }
+
+ @Test
+ public void testAirplaneModeDoesNotToggleOnWhenInEcm() throws Exception {
+ // TODO(b/139829963): investigate the expected behavior is when toggling airplane mode in
+ // ECM
+ }
+
+ /**
+ * Toggling scan mode when in ECM does not exit ecm mode and enable scan mode
+ */
+ @Test
+ public void testScanModeDoesNotToggleOnWhenInEcm() throws Exception {
+ assertInDisabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+
+ // now enable scanning and verify we do not start wifi
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ mActiveModeWarden.scanAlwaysModeChanged();
+ mLooper.dispatchAll();
+
+ verify(mClientModeManager, never()).start();
+ assertInDisabledState();
+ }
+
+
+ /**
+ * Toggling softap mode when in ECM does not exit ecm mode and enable softap
+ */
+ @Test
+ public void testSoftApModeDoesNotToggleOnWhenInEcm() throws Exception {
+ assertInDisabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+
+ mActiveModeWarden.startSoftAp(
+ new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
+ mLooper.dispatchAll();
+
+ verify(mSoftApManager, never()).start();
+ assertInDisabledState();
+ }
+
+ /**
+ * Toggling off softap mode when in ECM does not induce a mode change
+ */
+ @Test
+ public void testSoftApStoppedDoesNotSwitchModesWhenInEcm() throws Exception {
+ assertInDisabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+
+ mActiveModeWarden.stopSoftAp(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
+ mLooper.dispatchAll();
+
+ assertInDisabledState();
+ verifyNoMoreInteractions(mSoftApManager, mClientModeManager);
+ }
+
+ /**
+ * Toggling softap mode when in airplane mode needs to enable softap
+ */
+ @Test
+ public void testSoftApModeToggleWhenInAirplaneMode() throws Exception {
+ // Test with airplane mode turned on:
+ when(mSettingsStore.isAirplaneModeOn()).thenReturn(true);
+
+ // Turn on SoftAp.
+ mActiveModeWarden.startSoftAp(
+ new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
+ mLooper.dispatchAll();
+ verify(mSoftApManager).start();
+
+ // Turn off SoftAp.
+ mActiveModeWarden.stopSoftAp(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
+ mLooper.dispatchAll();
+
+ verify(mSoftApManager).stop();
+ }
+
+ /**
+ * Toggling off scan mode when in ECM does not induce a mode change
+ */
+ @Test
+ public void testScanModeStoppedSwitchModeToDisabledStateWhenInEcm() throws Exception {
+ enterScanOnlyModeActiveState();
+ assertInEnabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ });
+
+ // Spurious onStopped
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+
+ assertInDisabledState();
+ }
+
+ /**
+ * Toggling off client mode when in ECM does not induce a mode change
+ */
+ @Test
+ public void testClientModeStoppedSwitchModeToDisabledStateWhenInEcm() throws Exception {
+ enterClientModeActiveState();
+ assertInEnabledState();
+
+ // Test with WifiDisableInECBM turned on:
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+ assertEnteredEcmMode(() -> {
+ // test ecm changed
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ });
+
+ // Spurious onStopped
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+
+ assertInDisabledState();
+ }
+
+ /**
+ * When AP mode is enabled and wifi was previously in AP mode, we should return to
+ * EnabledState after the AP is disabled.
+ * Enter EnabledState, activate AP mode, disable AP mode.
+ * <p>
+ * Expected: AP should successfully start and exit, then return to EnabledState.
+ */
+ @Test
+ public void testReturnToEnabledStateAfterAPModeShutdown() throws Exception {
+ enableWifi();
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+
+ mActiveModeWarden.startSoftAp(
+ new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
+ // add an "unexpected" sta mode stop to simulate a single interface device
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+
+ // Now stop the AP
+ mSoftApListener.onStopped();
+ mLooper.dispatchAll();
+
+ // We should re-enable client mode
+ verify(mClientModeManager, times(2)).start();
+ assertInEnabledState();
+ }
+
+ /**
+ * When in STA mode and SoftAP is enabled and the device supports STA+AP (i.e. the STA wasn't
+ * shut down when the AP started), both modes will be running concurrently.
+ *
+ * Then when the AP is disabled, we should remain in STA mode.
+ *
+ * Enter EnabledState, activate AP mode, toggle WiFi off.
+ * <p>
+ * Expected: AP should successfully start and exit, then return to EnabledState.
+ */
+ @Test
+ public void testReturnToEnabledStateAfterWifiEnabledShutdown() throws Exception {
+ enableWifi();
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+
+ mActiveModeWarden.startSoftAp(
+ new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
+ mLooper.dispatchAll();
+
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
+ mActiveModeWarden.wifiToggled();
+ mSoftApListener.onStopped();
+ mLooper.dispatchAll();
+
+ // wasn't called again
+ verify(mClientModeManager).start();
+ assertInEnabledState();
+ }
+
+ @Test
+ public void testRestartWifiStackInEnabledStateTriggersBugReport() throws Exception {
+ enableWifi();
+ mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ mLooper.dispatchAll();
+ verify(mClientModeImpl).takeBugReport(anyString(), anyString());
+ }
+
+ @Test
+ public void testRestartWifiWatchdogDoesNotTriggerBugReport() throws Exception {
+ enableWifi();
+ mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
+ mLooper.dispatchAll();
+ verify(mClientModeImpl, never()).takeBugReport(anyString(), anyString());
+ }
+
+ /**
+ * When in sta mode, CMD_RECOVERY_DISABLE_WIFI messages should trigger wifi to disable.
+ */
+ @Test
+ public void testRecoveryDisabledTurnsWifiOff() throws Exception {
+ enableWifi();
+ assertInEnabledState();
+ mActiveModeWarden.recoveryDisableWifi();
+ mLooper.dispatchAll();
+ verify(mClientModeManager).stop();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ assertInDisabledState();
+ }
+
+ /**
+ * When wifi is disabled, CMD_RECOVERY_DISABLE_WIFI should not trigger a state change.
+ */
+ @Test
+ public void testRecoveryDisabledWhenWifiAlreadyOff() throws Exception {
+ assertInDisabledState();
+ assertWifiShutDown(() -> {
+ mActiveModeWarden.recoveryDisableWifi();
+ mLooper.dispatchAll();
+ });
+ }
+
+ /**
+ * The command to trigger a WiFi reset should not trigger any action by WifiController if we
+ * are not in STA mode.
+ * WiFi is not in connect mode, so any calls to reset the wifi stack due to connection failures
+ * should be ignored.
+ * Create and start WifiController in DisabledState, send command to restart WiFi
+ * <p>
+ * Expected: WiFiController should not call ActiveModeWarden.disableWifi()
+ */
+ @Test
+ public void testRestartWifiStackInDisabledState() throws Exception {
+ assertInDisabledState();
+
+ mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ mLooper.dispatchAll();
+
+ assertInDisabledState();
+ verifyNoMoreInteractions(mClientModeManager, mSoftApManager);
+ }
+
+ /**
+ * The command to trigger a WiFi reset should trigger a wifi reset in ClientModeImpl through
+ * the ActiveModeWarden.shutdownWifi() call when in STA mode.
+ * When WiFi is in scan mode, calls to reset the wifi stack due to native failure
+ * should trigger a supplicant stop, and subsequently, a driver reload.
+ * Create and start WifiController in EnabledState, send command to restart WiFi
+ * <p>
+ * Expected: WiFiController should call ActiveModeWarden.shutdownWifi() and
+ * ActiveModeWarden should enter SCAN_ONLY mode and the wifi driver should be started.
+ */
+ @Test
+ public void testRestartWifiStackInDisabledStateWithScanState() throws Exception {
+ assertInDisabledState();
+
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ mActiveModeWarden.scanAlwaysModeChanged();
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+ verify(mClientModeManager).switchToScanOnlyMode();
+
+ mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ mLooper.dispatchAll();
+
+ verify(mClientModeManager).stop();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ assertInDisabledState();
+
+ mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS);
+ mLooper.dispatchAll();
+
+ verify(mClientModeManager, times(2)).start();
+ verify(mClientModeManager, times(2)).switchToScanOnlyMode();
+ assertInEnabledState();
+ }
+
+ /**
+ * The command to trigger a WiFi reset should trigger a wifi reset in ClientModeImpl through
+ * the ActiveModeWarden.shutdownWifi() call when in STA mode.
+ * WiFi is in connect mode, calls to reset the wifi stack due to connection failures
+ * should trigger a supplicant stop, and subsequently, a driver reload.
+ * Create and start WifiController in EnabledState, send command to restart WiFi
+ * <p>
+ * Expected: WiFiController should call ActiveModeWarden.shutdownWifi() and
+ * ActiveModeWarden should enter CONNECT_MODE and the wifi driver should be started.
+ */
+ @Test
+ public void testRestartWifiStackInEnabledState() throws Exception {
+ enableWifi();
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+
+ assertWifiShutDown(() -> {
+ mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ mLooper.dispatchAll();
+ // Complete the stop
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ });
+
+ // still only started once
+ verify(mClientModeManager).start();
+
+ mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS);
+ mLooper.dispatchAll();
+
+ // started again
+ verify(mClientModeManager, times(2)).start();
+ assertInEnabledState();
+ }
+
+ /**
+ * The command to trigger a WiFi reset should not trigger a reset when in ECM mode.
+ * Enable wifi and enter ECM state, send command to restart wifi.
+ * <p>
+ * Expected: The command to trigger a wifi reset should be ignored and we should remain in ECM
+ * mode.
+ */
+ @Test
+ public void testRestartWifiStackDoesNotExitECMMode() throws Exception {
+ enableWifi();
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+ verify(mClientModeManager).getScanMode();
+ verify(mClientModeManager).isInScanOnlyMode();
+ verify(mClientModeManager).switchToConnectMode();
+
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+ assertEnteredEcmMode(() -> {
+ mActiveModeWarden.emergencyCallStateChanged(true);
+ mLooper.dispatchAll();
+ mClientListener.onStopped();
+ mLooper.dispatchAll();
+ });
+ assertInEmergencyMode();
+ assertInDisabledState();
+ verify(mClientModeManager).stop();
+
+ mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
+ mLooper.dispatchAll();
+
+ verify(mClientModeManager).start(); // wasn't called again
+ assertInEmergencyMode();
+ assertInDisabledState();
+ verifyNoMoreInteractions(mClientModeManager, mSoftApManager);
+ }
+
+ /**
+ * The command to trigger a WiFi reset should trigger a reset when in AP mode.
+ * Enter AP mode, send command to restart wifi.
+ * <p>
+ * Expected: The command to trigger a wifi reset should trigger wifi shutdown.
+ */
+ @Test
+ public void testRestartWifiStackFullyStopsWifi() throws Exception {
+ mActiveModeWarden.startSoftAp(new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_LOCAL_ONLY, null));
+ mLooper.dispatchAll();
+ verify(mSoftApManager).start();
+
+ assertWifiShutDown(() -> {
+ mActiveModeWarden.recoveryRestartWifi(SelfRecovery.REASON_STA_IFACE_DOWN);
+ mLooper.dispatchAll();
+ });
+ }
+
+ /**
+ * Tests that when Wifi is already disabled and another Wifi toggle command arrives,
+ * don't enter scan mode if {@link WifiSettingsStore#isScanAlwaysAvailable()} is false.
+ * Note: {@link WifiSettingsStore#isScanAlwaysAvailable()} returns false if either the wifi
+ * scanning is disabled and airplane mode is on.
+ */
+ @Test
+ public void staDisabled_toggleWifiOff_scanNotAvailable_dontGoToScanMode() {
+ assertInDisabledState();
+
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
+ when(mSettingsStore.isAirplaneModeOn()).thenReturn(true);
+
+ mActiveModeWarden.wifiToggled();
+ mLooper.dispatchAll();
+
+ assertInDisabledState();
+ verify(mClientModeManager, never()).start();
+ }
+
+ /**
+ * Tests that when Wifi is already disabled and another Wifi toggle command arrives,
+ * enter scan mode if {@link WifiSettingsStore#isScanAlwaysAvailable()} is true.
+ * Note: {@link WifiSettingsStore#isScanAlwaysAvailable()} returns true if both the wifi
+ * scanning is enabled and airplane mode is off.
+ */
+ @Test
+ public void staDisabled_toggleWifiOff_scanAvailable_goToScanMode() {
+ assertInDisabledState();
+
+ when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
+ when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
+
+ mActiveModeWarden.wifiToggled();
+ mLooper.dispatchAll();
+
+ assertInEnabledState();
+ verify(mClientModeManager).start();
+ verify(mClientModeManager).switchToScanOnlyMode();
+ }
+
+ /**
+ * Tests that if the carrier config to disable Wifi is enabled during ECM, Wifi is shut down
+ * when entering ECM and turned back on when exiting ECM.
+ */
+ @Test
+ public void ecmDisablesWifi_exitEcm_restartWifi() throws Exception {
+ enterClientModeActiveState();
+
+ verify(mClientModeManager).start();
+
+ when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
+ assertEnteredEcmMode(() -> {
+ mActiveModeWarden.emergencyCallbackModeChanged(true);
+ mLooper.dispatchAll();
+ });
+ assertInEnabledState();
+ verify(mClientModeManager).stop();
+
+ mActiveModeWarden.emergencyCallbackModeChanged(false);
+ mLooper.dispatchAll();
+
+ assertThat(mActiveModeWarden.isInEmergencyMode()).isFalse();
+ // client mode restarted
+ verify(mClientModeManager, times(2)).start();
+ assertInEnabledState();
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/BinderUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/BinderUtilTest.java
index 74ad17f538..af570a1e6c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/BinderUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/BinderUtilTest.java
@@ -31,7 +31,7 @@ import org.junit.Test;
* Unit tests for {@link com.android.server.wifi.BinderUtil}.
*/
@SmallTest
-public class BinderUtilTest {
+public class BinderUtilTest extends WifiBaseTest {
static final int FAKE_UID = 30000000;
private long mToken;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ByteBufferReaderTest.java b/service/tests/wifitests/src/com/android/server/wifi/ByteBufferReaderTest.java
index add8f14e03..c2a4021dd5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ByteBufferReaderTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ByteBufferReaderTest.java
@@ -32,7 +32,7 @@ import java.nio.charset.StandardCharsets;
* Unit tests for {@link com.android.server.wifi.ByteBufferReader}.
*/
@SmallTest
-public class ByteBufferReaderTest {
+public class ByteBufferReaderTest extends WifiBaseTest {
/**
* Verify that BufferUnderflowException will be thrown when reading an integer from a buffer
* that contained less data than needed.
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 3db50c5f28..037fd14ab4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java
@@ -45,7 +45,7 @@ import java.util.List;
*/
@SmallTest
@RunWith(Parameterized.class)
-public class CandidateScorerTest {
+public class CandidateScorerTest extends WifiBaseTest {
@Parameters(name = "{index}: {0}")
public static List<Object[]> listOfObjectArraysBecauseJUnitMadeUs() {
@@ -166,8 +166,8 @@ public class CandidateScorerTest {
*/
@Test
public void testPreferTheCurrentNetworkEvenIfRssiDifferenceIsSignificant() throws Exception {
- assertThat(evaluate(mCandidate1.setScanRssi(-77).setCurrentNetwork(true)),
- greaterThan(evaluate(mCandidate2.setScanRssi(-68))));
+ assertThat(evaluate(mCandidate1.setScanRssi(-74).setCurrentNetwork(true)),
+ greaterThan(evaluate(mCandidate2.setScanRssi(-65))));
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkConfigTest.java b/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkConfigTest.java
index d89358df03..45b340f363 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkConfigTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkConfigTest.java
@@ -27,6 +27,7 @@ import android.database.ContentObserver;
import android.net.Uri;
import android.net.wifi.EAPConstants;
import android.net.wifi.WifiEnterpriseConfig;
+import android.os.Handler;
import android.os.PersistableBundle;
import android.os.test.TestLooper;
import android.telephony.CarrierConfigManager;
@@ -52,7 +53,7 @@ import java.util.Collections;
* Unit tests for {@link com.android.server.wifi.CarrierNetworkConfig}.
*/
@SmallTest
-public class CarrierNetworkConfigTest {
+public class CarrierNetworkConfigTest extends WifiBaseTest {
private static final String TEST_SSID = "Test SSID";
private static final int TEST_STANDARD_EAP_TYPE = EAPConstants.EAP_SIM;
private static final int TEST_INTERNAL_EAP_TYPE = WifiEnterpriseConfig.Eap.SIM;
@@ -108,11 +109,11 @@ public class CarrierNetworkConfigTest {
when(mCarrierConfigManager.getConfigForSubId(TEST_SUBSCRIPTION_ID))
.thenReturn(generateTestConfig(TEST_SSID, TEST_STANDARD_EAP_TYPE));
when(mSubscriptionManager.getActiveSubscriptionInfoList())
- .thenReturn(Arrays.asList(new SubscriptionInfo[] {TEST_SUBSCRIPTION_INFO}));
+ .thenReturn(Arrays.asList(TEST_SUBSCRIPTION_INFO));
when(mDataTelephonyManager.getCarrierInfoForImsiEncryption(TelephonyManager.KEY_TYPE_WLAN))
.thenReturn(mImsiEncryptionInfo);
mLooper = new TestLooper();
- mCarrierNetworkConfig = new CarrierNetworkConfig(mContext, mLooper.getLooper(),
+ mCarrierNetworkConfig = new CarrierNetworkConfig(mContext, new Handler(mLooper.getLooper()),
mFrameworkFacade);
ArgumentCaptor<BroadcastReceiver> receiver =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@@ -153,7 +154,7 @@ public class CarrierNetworkConfigTest {
null, 0, null, "0", "0", null, false, null, null);
when(mSubscriptionManager.getActiveSubscriptionInfoList())
.thenReturn(Collections.singletonList(testSubscriptionInfoNullDisplayName));
- mCarrierNetworkConfig = new CarrierNetworkConfig(mContext, mLooper.getLooper(),
+ mCarrierNetworkConfig = new CarrierNetworkConfig(mContext, new Handler(mLooper.getLooper()),
mFrameworkFacade);
reset(mCarrierConfigManager);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkEvaluatorTest.java b/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkEvaluatorTest.java
index c4d5864bf3..01b14a6128 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkEvaluatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkEvaluatorTest.java
@@ -58,7 +58,7 @@ import java.util.Map;
* Unit tests for CarrierNeteworkEvaluator
*/
@SmallTest
-public class CarrierNetworkEvaluatorTest {
+public class CarrierNetworkEvaluatorTest extends WifiBaseTest {
private static final String CARRIER1_SSID = "\"carrier1\"";
private static final String CARRIER2_SSID = "\"carrier2\"";
private static final String CARRIER_SAVED_SSID = "\"carrier3-saved\"";
@@ -142,7 +142,8 @@ public class CarrierNetworkEvaluatorTest {
mGetConfiguredNetworkForScanDetailsAnswer.addConfig(scanDetail, newConfig);
}
- when(mWifiConfigManager.enableNetwork(networkId, false, Process.WIFI_UID)).thenReturn(true);
+ when(mWifiConfigManager.enableNetwork(
+ networkId, false, Process.WIFI_UID, null)).thenReturn(true);
when(mWifiConfigManager.setNetworkCandidateScanResult(eq(networkId), any(),
anyInt())).thenReturn(true);
when(mWifiConfigManager.getConfiguredNetwork(networkId)).thenReturn(newConfig);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkNotifierTest.java b/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkNotifierTest.java
deleted file mode 100644
index 91a9a5de71..0000000000
--- a/service/tests/wifitests/src/com/android/server/wifi/CarrierNetworkNotifierTest.java
+++ /dev/null
@@ -1,819 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import static com.android.server.wifi.CarrierNetworkNotifier.DEFAULT_REPEAT_DELAY_SEC;
-import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.ACTION_CONNECT_TO_NETWORK;
-import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.ACTION_PICK_WIFI_NETWORK;
-import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE;
-import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.ACTION_USER_DISMISSED_NOTIFICATION;
-import static com.android.server.wifi.ConnectToNetworkNotificationBuilder.AVAILABLE_NETWORK_NOTIFIER_TAG;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiManager;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.test.TestLooper;
-import android.provider.Settings;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.server.wifi.nano.WifiMetricsProto;
-import com.android.server.wifi.nano.WifiMetricsProto.ConnectToNetworkNotificationAndActionCount;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit tests for {@link CarrierNetworkNotifier}.
- */
-@SmallTest
-public class CarrierNetworkNotifierTest {
-
- private static final String TEST_SSID_1 = "Test SSID 1";
- private static final String TEST_SSID_2 = "Test SSID 2";
- private static final int MIN_RSSI_LEVEL = -127;
- private static final String CARRIER_NET_NOTIFIER_TAG = CarrierNetworkNotifier.TAG;
- private static final int TEST_NETWORK_ID = 42;
-
- @Mock private Context mContext;
- @Mock private Resources mResources;
- @Mock private FrameworkFacade mFrameworkFacade;
- @Mock private WifiMetrics mWifiMetrics;
- @Mock private Clock mClock;
- @Mock private WifiConfigStore mWifiConfigStore;
- @Mock private WifiConfigManager mWifiConfigManager;
- @Mock private NotificationManager mNotificationManager;
- @Mock private ClientModeImpl mClientModeImpl;
- @Mock private ConnectToNetworkNotificationBuilder mNotificationBuilder;
- @Mock private UserManager mUserManager;
- private CarrierNetworkNotifier mNotificationController;
- private TestLooper mLooper;
- private BroadcastReceiver mBroadcastReceiver;
- private ContentObserver mContentObserver;
- private ScanResult mDummyNetwork;
- private List<ScanDetail> mCarrierNetworks;
-
-
- /** Initialize objects before each test run. */
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- when(mContext.getSystemService(Context.NOTIFICATION_SERVICE))
- .thenReturn(mNotificationManager);
- when(mFrameworkFacade.getIntegerSetting(mContext,
- Settings.Global.WIFI_CARRIER_NETWORKS_AVAILABLE_NOTIFICATION_ON, 1)).thenReturn(1);
- when(mFrameworkFacade.getIntegerSetting(mContext,
- Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, DEFAULT_REPEAT_DELAY_SEC))
- .thenReturn(DEFAULT_REPEAT_DELAY_SEC);
- when(mContext.getSystemService(Context.USER_SERVICE))
- .thenReturn(mUserManager);
- when(mContext.getResources()).thenReturn(mResources);
- mDummyNetwork = new ScanResult();
- mDummyNetwork.SSID = TEST_SSID_1;
- mDummyNetwork.capabilities = "[ESS]";
- mDummyNetwork.level = MIN_RSSI_LEVEL;
- mCarrierNetworks = new ArrayList<>();
- mCarrierNetworks.add(new ScanDetail(mDummyNetwork, null /* networkDetail */));
-
- mLooper = new TestLooper();
- mNotificationController = new CarrierNetworkNotifier(
- mContext, mLooper.getLooper(), mFrameworkFacade, mClock, mWifiMetrics,
- mWifiConfigManager, mWifiConfigStore, mClientModeImpl, mNotificationBuilder);
- ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
- ArgumentCaptor.forClass(BroadcastReceiver.class);
- verify(mContext).registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
- mBroadcastReceiver = broadcastReceiverCaptor.getValue();
- ArgumentCaptor<ContentObserver> observerCaptor =
- ArgumentCaptor.forClass(ContentObserver.class);
- verify(mFrameworkFacade).registerContentObserver(eq(mContext), any(Uri.class), eq(true),
- observerCaptor.capture());
- mContentObserver = observerCaptor.getValue();
- mNotificationController.handleScreenStateChanged(true);
- when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt()))
- .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
- }
-
- /**
- * On {@link CarrierNetworkNotifier} construction, WifiMetrics should track setting state.
- */
- @Test
- public void onCreate_setWifiNetworksAvailableNotificationSettingState() {
- verify(mWifiMetrics).setIsWifiNetworksAvailableNotificationEnabled(CARRIER_NET_NOTIFIER_TAG,
- true);
- }
-
- /**
- * When feature setting is toggled, WifiMetrics should track the disabled setting state.
- */
- @Test
- public void onFeatureDisable_setWifiNetworksAvailableNotificationSettingDisabled() {
- when(mFrameworkFacade.getIntegerSetting(mContext,
- Settings.Global.WIFI_CARRIER_NETWORKS_AVAILABLE_NOTIFICATION_ON, 1)).thenReturn(0);
- mContentObserver.onChange(false);
-
- verify(mWifiMetrics).setIsWifiNetworksAvailableNotificationEnabled(CARRIER_NET_NOTIFIER_TAG,
- false);
- }
-
- /**
- * When scan results with carrier networks are handled, a notification is posted.
- */
- @Test
- public void handleScanResults_hasCarrierNetworks_notificationDisplayed() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
- }
-
- /**
- * When scan results with no carrier networks are handled, a notification is not posted.
- */
- @Test
- public void handleScanResults_emptyList_notificationNotDisplayed() {
- mNotificationController.handleScanResults(new ArrayList<>());
-
- verify(mNotificationManager, never()).notify(anyInt(), any());
- }
-
- /**
- * When the feature is disabled, no notifications are posted.
- */
- @Test
- public void handleScanResults_featureDisabled_notificationNotDisplayed() {
- when(mFrameworkFacade.getIntegerSetting(mContext,
- Settings.Global.WIFI_CARRIER_NETWORKS_AVAILABLE_NOTIFICATION_ON, 1)).thenReturn(0);
- mContentObserver.onChange(false);
- mNotificationController.handleScanResults(new ArrayList<>());
-
- verify(mNotificationManager, never()).notify(anyInt(), any());
- }
-
- /**
- * When a notification is showing and scan results with no carrier networks are handled, the
- * notification is cleared.
- */
- @Test
- public void handleScanResults_notificationShown_emptyList_notificationCleared() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mNotificationController.handleScanResults(new ArrayList<>());
-
- verify(mNotificationManager).cancel(anyInt());
- }
-
- /**
- * When a notification is showing and no recommendation is made for the new scan results, the
- * notification is cleared.
- */
- @Test
- public void handleScanResults_notificationShown_noRecommendation_notificationCleared() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mCarrierNetworks.clear();
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationManager).cancel(anyInt());
- }
-
- /**
- * When a notification is showing, screen is off, and scan results with no carrier networks are
- * handled, the notification is cleared.
- */
- @Test
- public void handleScanResults_notificationShown_screenOff_emptyList_notificationCleared() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mNotificationController.handleScreenStateChanged(false);
- mNotificationController.handleScanResults(new ArrayList<>());
-
- verify(mNotificationManager).cancel(anyInt());
- }
-
- /**
- * When {@link CarrierNetworkNotifier#clearPendingNotification(boolean)} is called and a
- * notification is shown, clear the notification.
- */
- @Test
- public void clearPendingNotification_clearsNotificationIfOneIsShowing() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mNotificationController.clearPendingNotification(true);
-
- verify(mNotificationManager).cancel(anyInt());
- }
-
- /**
- * When {@link CarrierNetworkNotifier#clearPendingNotification(boolean)} is called and a
- * notification was not previously shown, do not clear the notification.
- */
- @Test
- public void clearPendingNotification_doesNotClearNotificationIfNoneShowing() {
- mNotificationController.clearPendingNotification(true);
-
- verify(mNotificationManager, never()).cancel(anyInt());
- }
-
- /**
- * When screen is off and notification is not displayed, notification is not posted on handling
- * new scan results with carrier networks.
- */
- @Test
- public void screenOff_notificationNotShowing_handleScanResults_notificationNotDisplayed() {
- mNotificationController.handleScreenStateChanged(false);
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationManager, never()).notify(anyInt(), any());
- }
-
- /**
- * When screen is off and notification is displayed, the notification can be updated with a new
- * recommendation.
- */
- @Test
- public void screenOff_notificationShowing_handleScanResults_recommendationCanBeUpdated() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- ScanResult newNetwork = new ScanResult();
- newNetwork.SSID = TEST_SSID_2;
- mDummyNetwork.capabilities = "[ESS]";
- mDummyNetwork.level = MIN_RSSI_LEVEL + 1;
- mCarrierNetworks.add(new ScanDetail(newNetwork, null /* networkDetail */));
-
- mNotificationController.handleScreenStateChanged(false);
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- // Recommendation changed
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, newNetwork);
- verify(mWifiMetrics).incrementNumNetworkRecommendationUpdates(CARRIER_NET_NOTIFIER_TAG);
- verify(mNotificationManager, times(2)).notify(anyInt(), any());
- }
-
- /**
- * When a notification is posted and cleared without resetting delay, the next scan with carrier
- * networks should not post another notification.
- */
- @Test
- public void postNotification_clearNotificationWithoutDelayReset_shouldNotPostNotification() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mNotificationController.clearPendingNotification(false);
-
- verify(mNotificationManager).cancel(anyInt());
-
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- // no new notification posted
- verify(mNotificationManager).notify(anyInt(), any());
- }
-
- /**
- * When a notification is posted and cleared without resetting delay, the next scan with carrier
- * networks should post a notification.
- */
- @Test
- public void postNotification_clearNotificationWithDelayReset_shouldPostNotification() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mNotificationController.clearPendingNotification(true);
-
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder, times(2)).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics, times(2)).incrementConnectToNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager, times(2)).notify(anyInt(), any());
- }
-
- private Intent createIntent(String action) {
- return new Intent(action).putExtra(AVAILABLE_NETWORK_NOTIFIER_TAG,
- CARRIER_NET_NOTIFIER_TAG);
- }
-
- /**
- * When user dismissed notification and there is a recommended network, network ssid should be
- * blacklisted.
- */
- @Test
- public void userDismissedNotification_shouldBlacklistNetwork() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_USER_DISMISSED_NOTIFICATION));
-
- verify(mWifiConfigManager).saveToStore(false /* forceWrite */);
-
- mNotificationController.clearPendingNotification(true);
- List<ScanDetail> scanResults = mCarrierNetworks;
- mNotificationController.handleScanResults(scanResults);
-
- verify(mWifiMetrics).setNetworkRecommenderBlacklistSize(CARRIER_NET_NOTIFIER_TAG, 1);
- }
-
- /**
- * When the user chooses to connect to recommended network, network ssid should be
- * blacklisted so that if the user removes the network in the future the same notification
- * won't show up again.
- */
- @Test
- public void userConnectedNotification_shouldBlacklistNetwork() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
-
- verify(mWifiConfigManager).saveToStore(false /* forceWrite */);
- verify(mWifiMetrics).setNetworkRecommenderBlacklistSize(CARRIER_NET_NOTIFIER_TAG, 1);
-
- List<ScanDetail> scanResults = mCarrierNetworks;
- mNotificationController.handleScanResults(scanResults);
- }
-
- /**
- * When a notification is posted and cleared without resetting delay, after the delay has passed
- * the next scan with carrier networks should post a notification.
- */
- @Test
- public void delaySet_delayPassed_shouldPostNotification() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mNotificationController.clearPendingNotification(false);
-
- // twice the delay time passed
- when(mClock.getWallClockMillis()).thenReturn(DEFAULT_REPEAT_DELAY_SEC * 1000L * 2);
-
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder, times(2)).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics, times(2)).incrementConnectToNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager, times(2)).notify(anyInt(), any());
- }
-
- /** Verifies that {@link UserManager#DISALLOW_CONFIG_WIFI} disables the feature. */
- @Test
- public void userHasDisallowConfigWifiRestriction_notificationNotDisplayed() {
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT))
- .thenReturn(true);
-
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationManager, never()).notify(anyInt(), any());
- }
-
- /** Verifies that {@link UserManager#DISALLOW_CONFIG_WIFI} clears the showing notification. */
- @Test
- public void userHasDisallowConfigWifiRestriction_showingNotificationIsCleared() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT))
- .thenReturn(true);
-
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- verify(mNotificationManager).cancel(anyInt());
- }
-
- /**
- * {@link ConnectToNetworkNotificationBuilder#ACTION_CONNECT_TO_NETWORK} does not connect to
- * any network if the initial notification is not showing.
- */
- @Test
- public void actionConnectToNetwork_notificationNotShowing_doesNothing() {
- mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
-
- verify(mClientModeImpl, never()).sendMessage(any(Message.class));
- }
-
- /**
- * {@link ConnectToNetworkNotificationBuilder#ACTION_CONNECT_TO_NETWORK} connects to the
- * currently recommended network if it exists.
- */
- @Test
- public void actionConnectToNetwork_currentRecommendationExists_connectsAndPostsNotification() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- // Initial Notification
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
-
- verify(mClientModeImpl).sendMessage(any(Message.class));
- // Connecting Notification
- verify(mNotificationBuilder).createNetworkConnectingNotification(CARRIER_NET_NOTIFIER_TAG,
- mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_CONNECTING_TO_NETWORK);
- verify(mWifiMetrics).incrementConnectToNetworkNotificationAction(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK,
- ConnectToNetworkNotificationAndActionCount.ACTION_CONNECT_TO_NETWORK);
- verify(mNotificationManager, times(2)).notify(anyInt(), any());
- }
-
- /**
- * {@link ConnectToNetworkNotificationBuilder#ACTION_PICK_WIFI_NETWORK} opens Wi-Fi settings
- * if the recommendation notification is showing.
- */
- @Test
- public void actionPickWifiNetwork_currentRecommendationExists_opensWifiSettings() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- // Initial Notification
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_PICK_WIFI_NETWORK));
-
- ArgumentCaptor<Intent> pickerIntentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext).startActivity(pickerIntentCaptor.capture());
- assertEquals(pickerIntentCaptor.getValue().getAction(), Settings.ACTION_WIFI_SETTINGS);
- verify(mWifiMetrics).incrementConnectToNetworkNotificationAction(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK,
- ConnectToNetworkNotificationAndActionCount.ACTION_PICK_WIFI_NETWORK);
- }
-
- /**
- * {@link CarrierNetworkNotifier#handleWifiConnected(String ssid)} does not post connected
- * notification if the connecting notification is not showing
- */
- @Test
- public void networkConnectionSuccess_wasNotInConnectingFlow_doesNothing() {
- mNotificationController.handleWifiConnected(TEST_SSID_1);
-
- verify(mNotificationManager, never()).notify(anyInt(), any());
- verify(mWifiMetrics, never()).incrementConnectToNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_CONNECTED_TO_NETWORK);
- }
-
- /**
- * {@link CarrierNetworkNotifier#handleWifiConnected(String ssid)} clears notification
- * that is not connecting.
- */
- @Test
- public void networkConnectionSuccess_wasShowingNotification_clearsNotification() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- // Initial Notification
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mNotificationController.handleWifiConnected(TEST_SSID_1);
-
- verify(mNotificationManager).cancel(anyInt());
- }
-
- /**
- * {@link CarrierNetworkNotifier#handleWifiConnected(String ssid)} posts the connected
- * notification if the connecting notification is showing.
- */
- @Test
- public void networkConnectionSuccess_wasInConnectingFlow_postsConnectedNotification() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- // Initial Notification
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
-
- // Connecting Notification
- verify(mNotificationBuilder).createNetworkConnectingNotification(CARRIER_NET_NOTIFIER_TAG,
- mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_CONNECTING_TO_NETWORK);
- verify(mWifiMetrics).incrementConnectToNetworkNotificationAction(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK,
- ConnectToNetworkNotificationAndActionCount.ACTION_CONNECT_TO_NETWORK);
- verify(mNotificationManager, times(2)).notify(anyInt(), any());
-
- mNotificationController.handleWifiConnected(TEST_SSID_1);
-
- // Connected Notification
- verify(mNotificationBuilder).createNetworkConnectedNotification(CARRIER_NET_NOTIFIER_TAG,
- mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_CONNECTED_TO_NETWORK);
- verify(mNotificationManager, times(3)).notify(anyInt(), any());
- }
-
- /**
- * {@link CarrierNetworkNotifier#handleConnectionFailure()} posts the Failed to Connect
- * notification if the connecting notification is showing.
- */
- @Test
- public void networkConnectionFailure_wasNotInConnectingFlow_doesNothing() {
- mNotificationController.handleConnectionFailure();
-
- verify(mNotificationManager, never()).notify(anyInt(), any());
- verify(mWifiMetrics, never()).incrementConnectToNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_FAILED_TO_CONNECT);
- }
-
- /**
- * {@link CarrierNetworkNotifier#handleConnectionFailure()} posts the Failed to Connect
- * notification if the connecting notification is showing.
- */
- @Test
- public void networkConnectionFailure_wasInConnectingFlow_postsFailedToConnectNotification() {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- // Initial Notification
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
-
- // Connecting Notification
- verify(mNotificationBuilder).createNetworkConnectingNotification(CARRIER_NET_NOTIFIER_TAG,
- mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_CONNECTING_TO_NETWORK);
- verify(mWifiMetrics).incrementConnectToNetworkNotificationAction(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK,
- ConnectToNetworkNotificationAndActionCount.ACTION_CONNECT_TO_NETWORK);
- verify(mNotificationManager, times(2)).notify(anyInt(), any());
-
- mNotificationController.handleConnectionFailure();
-
- // Failed to Connect Notification
- verify(mNotificationBuilder).createNetworkFailedNotification(CARRIER_NET_NOTIFIER_TAG);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_FAILED_TO_CONNECT);
- verify(mNotificationManager, times(3)).notify(anyInt(), any());
- }
-
- /**
- * When a {@link WifiManager#CONNECT_NETWORK_FAILED} is received from the connection callback
- * of {@link ClientModeImpl#sendMessage(Message)}, a Failed to Connect notification should
- * be posted. On tapping this notification, Wi-Fi Settings should be launched.
- */
- @Test
- public void connectionFailedCallback_postsFailedToConnectNotification() throws RemoteException {
- mNotificationController.handleScanResults(mCarrierNetworks);
-
- // Initial Notification
- verify(mNotificationBuilder).createConnectToAvailableNetworkNotification(
- CARRIER_NET_NOTIFIER_TAG, mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
- verify(mNotificationManager).notify(anyInt(), any());
-
- mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
-
- verify(mWifiMetrics).setNominatorForNetwork(TEST_NETWORK_ID,
- WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER);
-
- ArgumentCaptor<Message> connectMessageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mClientModeImpl).sendMessage(connectMessageCaptor.capture());
- Message connectMessage = connectMessageCaptor.getValue();
-
- // Connecting Notification
- verify(mNotificationBuilder).createNetworkConnectingNotification(CARRIER_NET_NOTIFIER_TAG,
- mDummyNetwork);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_CONNECTING_TO_NETWORK);
- verify(mWifiMetrics).incrementConnectToNetworkNotificationAction(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK,
- ConnectToNetworkNotificationAndActionCount.ACTION_CONNECT_TO_NETWORK);
- verify(mNotificationManager, times(2)).notify(anyInt(), any());
-
- Message connectFailedMsg = Message.obtain();
- connectFailedMsg.what = WifiManager.CONNECT_NETWORK_FAILED;
- connectMessage.replyTo.send(connectFailedMsg);
- mLooper.dispatchAll();
-
- // Failed to Connect Notification
- verify(mNotificationBuilder).createNetworkFailedNotification(CARRIER_NET_NOTIFIER_TAG);
- verify(mWifiMetrics).incrementConnectToNetworkNotification(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_FAILED_TO_CONNECT);
- verify(mWifiMetrics).incrementNumNetworkConnectMessageFailedToSend(
- CARRIER_NET_NOTIFIER_TAG);
- verify(mNotificationManager, times(3)).notify(anyInt(), any());
-
- mBroadcastReceiver.onReceive(mContext,
- createIntent(ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE));
-
- ArgumentCaptor<Intent> pickerIntentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext).startActivity(pickerIntentCaptor.capture());
- assertEquals(pickerIntentCaptor.getValue().getAction(), Settings.ACTION_WIFI_SETTINGS);
- verify(mWifiMetrics).incrementConnectToNetworkNotificationAction(CARRIER_NET_NOTIFIER_TAG,
- ConnectToNetworkNotificationAndActionCount.NOTIFICATION_FAILED_TO_CONNECT,
- ConnectToNetworkNotificationAndActionCount
- .ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE);
- }
-
- private List<ScanDetail> createCarrierScanResults(String... ssids) {
- List<ScanDetail> scanResults = new ArrayList<>();
- for (String ssid : ssids) {
- ScanResult scanResult = new ScanResult();
- scanResult.SSID = ssid;
- scanResult.capabilities = "[ESS]";
- scanResults.add(new ScanDetail(scanResult, null /* networkDetail */));
- }
- return scanResults;
- }
-
- /** If list of carrier networks contain only one network, that network should be returned. */
- @Test
- public void onlyNetworkIsRecommended() {
- List<ScanDetail> scanResults = createCarrierScanResults(TEST_SSID_1);
- scanResults.get(0).getScanResult().level = MIN_RSSI_LEVEL;
-
- ScanResult actual = mNotificationController.recommendNetwork(scanResults);
- ScanResult expected = scanResults.get(0).getScanResult();
- assertEquals(expected, actual);
- }
-
- /** Verifies that the network with the highest rssi is recommended. */
- @Test
- public void networkWithHighestRssiIsRecommended() {
- List<ScanDetail> scanResults = createCarrierScanResults(TEST_SSID_1, TEST_SSID_2);
- scanResults.get(0).getScanResult().level = MIN_RSSI_LEVEL;
- scanResults.get(1).getScanResult().level = MIN_RSSI_LEVEL + 1;
-
- ScanResult actual = mNotificationController.recommendNetwork(scanResults);
- ScanResult expected = scanResults.get(1).getScanResult();
- assertEquals(expected, actual);
- }
-
- /**
- * If the best available carrier network is blacklisted, no network should be recommended.
- */
- @Test
- public void blacklistBestNetworkSsid_shouldNeverRecommendNetwork() {
- // Add TEST_SSID_1 to blacklist
- userDismissedNotification_shouldBlacklistNetwork();
-
- List<ScanDetail> scanResults = createCarrierScanResults(mDummyNetwork.SSID, TEST_SSID_2);
- scanResults.get(0).getScanResult().level = MIN_RSSI_LEVEL + 1;
- scanResults.get(1).getScanResult().level = MIN_RSSI_LEVEL;
-
- ScanResult actual = mNotificationController.recommendNetwork(scanResults);
- assertNull(actual);
- }
-
- /**
- * Test null input is handled
- */
- @Test
- public void removeNetworkFromBlacklist_handlesNull() {
- mNotificationController.handleWifiConnected(null);
- verify(mWifiConfigManager, never()).saveToStore(false /* forceWrite */);
- }
-
- /**
- * If the blacklist didn't change then there is no need to continue further.
- */
- @Test
- public void removeNetworkFromBlacklist_returnsEarlyIfNothingIsRemoved() {
- mNotificationController.handleWifiConnected(TEST_SSID_1);
- verify(mWifiConfigManager, never()).saveToStore(false /* forceWrite */);
- }
-
- /**
- * If we connected to a blacklisted network, then remove it from the blacklist.
- */
- @Test
- public void connectToNetwork_shouldRemoveSsidFromBlacklist() {
- // Add TEST_SSID_1 to blacklist
- userDismissedNotification_shouldBlacklistNetwork();
-
- // Simulate the user connecting to TEST_SSID_1 and verify it is removed from the blacklist
- mNotificationController.handleWifiConnected(mDummyNetwork.SSID);
- verify(mWifiConfigManager, times(2)).saveToStore(false /* forceWrite */);
- verify(mWifiMetrics).setNetworkRecommenderBlacklistSize(CARRIER_NET_NOTIFIER_TAG, 0);
- ScanResult actual = mNotificationController.recommendNetwork(mCarrierNetworks);
- ScanResult expected = mCarrierNetworks.get(0).getScanResult();
- assertEquals(expected, actual);
- }
-}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/CellularLinkLayerStatsCollectorTest.java b/service/tests/wifitests/src/com/android/server/wifi/CellularLinkLayerStatsCollectorTest.java
deleted file mode 100644
index 8b1647fcb5..0000000000
--- a/service/tests/wifitests/src/com/android/server/wifi/CellularLinkLayerStatsCollectorTest.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import static android.telephony.TelephonyManager.NETWORK_TYPE_CDMA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_EVDO_0;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_GSM;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_NR;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_TD_SCDMA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.validateMockitoUsage;
-
-import android.content.Context;
-import android.telephony.CellInfo;
-import android.telephony.CellInfoCdma;
-import android.telephony.CellInfoGsm;
-import android.telephony.CellInfoLte;
-import android.telephony.CellInfoTdscdma;
-import android.telephony.CellInfoWcdma;
-import android.telephony.CellSignalStrengthCdma;
-import android.telephony.CellSignalStrengthGsm;
-import android.telephony.CellSignalStrengthLte;
-import android.telephony.CellSignalStrengthNr;
-import android.telephony.CellSignalStrengthTdscdma;
-import android.telephony.CellSignalStrengthWcdma;
-import android.telephony.SignalStrength;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.TelephonyManager.NetworkType;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit tests for {@link com.android.server.wifi.CellularLinkLayerStatsCollector}.
- */
-@SmallTest
-public class CellularLinkLayerStatsCollectorTest {
- private CellularLinkLayerStatsCollector mCollector;
- private static final String TAG = "CellCollectorTest";
- private static final int DBM_VAL = -110;
- private static final int DB_VAL = -20;
- private static final int DB_VAL_EVDO = 4;
- private static final int SUBID = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
- MockitoSession mMockingSession = null;
- @Mock Context mContext;
- @Mock TelephonyManager mTelephonyManager;
- @Mock SubscriptionManager mSubscriptionManager;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- when(mContext.getSystemService(Context.TELEPHONY_SERVICE))
- .thenReturn(mTelephonyManager);
- when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE))
- .thenReturn(mSubscriptionManager);
- when(mTelephonyManager.createForSubscriptionId(anyInt()))
- .thenReturn(mTelephonyManager);
- mCollector = new CellularLinkLayerStatsCollector(mContext);
- mMockingSession = mockitoSession().mockStatic(SubscriptionManager.class).startMocking();
- when(SubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(SUBID);
- when(SubscriptionManager.getDefaultSubscriptionId()).thenReturn(SUBID);
- }
-
- @After
- public void cleanUp() throws Exception {
- validateMockitoUsage();
- if (mMockingSession != null) {
- mMockingSession.finishMocking();
- }
- }
-
- private List<CellInfo> generateCellInfoList(@NetworkType int networkType) {
- List<CellInfo> cil = new ArrayList<>();
- int numCellInfo = 2;
- for (int i = 0; i < numCellInfo; ++i) {
- CellInfo ci;
- if (networkType == NETWORK_TYPE_LTE) {
- ci = new CellInfoLte();
- } else if (networkType == NETWORK_TYPE_CDMA || networkType == NETWORK_TYPE_EVDO_0) {
- ci = new CellInfoCdma();
- } else if (networkType == NETWORK_TYPE_GSM) {
- ci = new CellInfoGsm();
- } else if (networkType == NETWORK_TYPE_TD_SCDMA) {
- ci = new CellInfoTdscdma();
- } else if (networkType == NETWORK_TYPE_UMTS) {
- ci = new CellInfoWcdma();
- } else if (networkType == NETWORK_TYPE_NR) {
- // TODO: CellInfoNr() is not supported yet.
- ci = new CellInfoLte();
- } else {
- ci = new CellInfoLte();
- }
- if (i == 0 && networkType != NETWORK_TYPE_UNKNOWN) {
- ci.setRegistered(true);
- } else {
- ci.setRegistered(false);
- }
- cil.add(ci);
- }
- return cil;
- }
-
- private SignalStrength generateSignalStrength(int dBmVal, int dBVal,
- @NetworkType int networkType) {
- int dummy = 1000;
- CellSignalStrengthLte mLte = new CellSignalStrengthLte();
- CellSignalStrengthNr mNr = new CellSignalStrengthNr();
- CellSignalStrengthGsm mGsm = new CellSignalStrengthGsm();
- CellSignalStrengthCdma mCdma = new CellSignalStrengthCdma();
- CellSignalStrengthTdscdma mTdscdma = new CellSignalStrengthTdscdma();
- CellSignalStrengthWcdma mWcdma = new CellSignalStrengthWcdma();
-
- if (networkType == NETWORK_TYPE_UNKNOWN) {
- return new SignalStrength();
- } else if (networkType == NETWORK_TYPE_LTE) {
- mLte = new CellSignalStrengthLte(dummy, dBmVal, dBVal, dummy, dummy, dummy);
- } else if (networkType == NETWORK_TYPE_CDMA) {
- mCdma = new CellSignalStrengthCdma(dBmVal, dBVal, dBmVal, dummy,
- SignalStrength.INVALID);
- } else if (networkType == NETWORK_TYPE_EVDO_0) {
- mCdma = new CellSignalStrengthCdma(dBmVal, dummy, dBmVal, dummy, dBVal);
- } else if (networkType == NETWORK_TYPE_TD_SCDMA) {
- mTdscdma = new CellSignalStrengthTdscdma(dummy, dummy, dBmVal);
- } else if (networkType == NETWORK_TYPE_UMTS) {
- mWcdma = new CellSignalStrengthWcdma(dummy, dummy, dBmVal, dBVal);
- } else if (networkType == NETWORK_TYPE_GSM) {
- mGsm = new CellSignalStrengthGsm(dBmVal, dummy, dummy);
- } else if (networkType == NETWORK_TYPE_NR) {
- mNr = new CellSignalStrengthNr(dBmVal, dummy, dBVal, dummy, dummy, dummy);
- } else {
- return null;
- }
- return new SignalStrength(mCdma, mGsm, mWcdma, mTdscdma, mLte, mNr);
- }
-
- private void testCollectorUpdate(@NetworkType int networkType, boolean isSignalStrengthEmpty,
- CellularLinkLayerStats trueStats) throws Exception {
- int dBmVal = DBM_VAL;
- int dBVal;
- if (networkType == NETWORK_TYPE_EVDO_0) {
- dBVal = DB_VAL_EVDO;
- } else {
- dBVal = DB_VAL;
- }
-
- SignalStrength ss = null;
- if (!isSignalStrengthEmpty) ss = generateSignalStrength(dBmVal, dBVal, networkType);
- List<CellInfo> allList = generateCellInfoList(networkType);
- when(mTelephonyManager.getSignalStrength()).thenReturn(ss);
- when(mTelephonyManager.getAllCellInfo()).thenReturn(allList);
- when(mTelephonyManager.getDataNetworkType()).thenReturn(networkType);
-
- CellularLinkLayerStats mStats = mCollector.update();
-
- assertEquals(SUBID, SubscriptionManager.getDefaultDataSubscriptionId());
- assertEquals(SUBID, SubscriptionManager.getDefaultSubscriptionId());
-
- assertEquals(trueStats.getSignalStrengthDbm(), mStats.getSignalStrengthDbm());
- assertEquals(trueStats.getSignalStrengthDb(), mStats.getSignalStrengthDb());
- assertEquals(trueStats.getDataNetworkType(), mStats.getDataNetworkType());
- assertEquals(trueStats.getIsSameRegisteredCell(), mStats.getIsSameRegisteredCell());
- }
-
- @Test
- public void testEmptySignalStrengthLte() throws Exception {
- @NetworkType int networkType;
- CellularLinkLayerStats trueStats = new CellularLinkLayerStats();
-
- networkType = NETWORK_TYPE_LTE;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(SignalStrength.INVALID);
- trueStats.setSignalStrengthDbm(SignalStrength.INVALID);
- trueStats.setDataNetworkType(NETWORK_TYPE_UNKNOWN);
- testCollectorUpdate(networkType, true, trueStats);
- }
-
- @Test
- public void testRepeatCellInfoTypeTwice() throws Exception {
- @NetworkType int networkType;
- CellularLinkLayerStats trueStats = new CellularLinkLayerStats();
-
- networkType = NETWORK_TYPE_LTE;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(DB_VAL);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_LTE;
- trueStats.setIsSameRegisteredCell(true);
- trueStats.setSignalStrengthDb(DB_VAL);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_EVDO_0;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(DB_VAL_EVDO);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_EVDO_0;
- trueStats.setIsSameRegisteredCell(true);
- trueStats.setSignalStrengthDb(DB_VAL_EVDO);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_NR;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(DB_VAL);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_NR;
- trueStats.setIsSameRegisteredCell(true);
- trueStats.setSignalStrengthDb(DB_VAL);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
- }
-
- @Test
- public void testLoopOverAllNetworksWithoutRepeat() throws Exception {
- @NetworkType int networkType;
- CellularLinkLayerStats trueStats = new CellularLinkLayerStats();
-
- networkType = NETWORK_TYPE_UNKNOWN;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(SignalStrength.INVALID);
- trueStats.setSignalStrengthDbm(SignalStrength.INVALID);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_LTE;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(DB_VAL);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_CDMA;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(DB_VAL);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_EVDO_0;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(DB_VAL_EVDO);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_TD_SCDMA;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(SignalStrength.INVALID);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_UMTS;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(DB_VAL);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_GSM;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(SignalStrength.INVALID);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- networkType = NETWORK_TYPE_NR;
- trueStats.setIsSameRegisteredCell(false);
- trueStats.setSignalStrengthDb(DB_VAL);
- trueStats.setSignalStrengthDbm(DBM_VAL);
- trueStats.setDataNetworkType(networkType);
- testCollectorUpdate(networkType, false, trueStats);
-
- }
-}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/CellularLinkLayerStatsTest.java b/service/tests/wifitests/src/com/android/server/wifi/CellularLinkLayerStatsTest.java
deleted file mode 100644
index 712d65355c..0000000000
--- a/service/tests/wifitests/src/com/android/server/wifi/CellularLinkLayerStatsTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import static org.junit.Assert.assertEquals;
-
-import android.telephony.TelephonyManager;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link com.android.server.wifi.CellularLinkLayerStats}.
- */
-@SmallTest
-public class CellularLinkLayerStatsTest {
- private static final String TAG = "CellularStatsTest";
-
- CellularLinkLayerStats mStats;
-
- /**
- * Sets up for unit test
- */
- @Before
- public void setUp() throws Exception {
- mStats = new CellularLinkLayerStats();
- }
-
- @After
- public void cleanUp() throws Exception {
- }
-
- /**
- * Test all set and get methods by checking if the inputs of set() match the output of get()
- */
- @Test
- public void testAllSetGetMethods() throws Exception {
- int dataNetworkType = TelephonyManager.NETWORK_TYPE_GSM;
- mStats.setDataNetworkType(dataNetworkType);
- assertEquals(dataNetworkType, mStats.getDataNetworkType());
- int dbmVal = -100;
- mStats.setSignalStrengthDbm(dbmVal);
- assertEquals(dbmVal, mStats.getSignalStrengthDbm());
- int dbVal = -20;
- mStats.setSignalStrengthDb(dbVal);
- assertEquals(dbVal, mStats.getSignalStrengthDb());
- boolean isSameCell = true;
- mStats.setIsSameRegisteredCell(isSameCell);
- assertEquals(isSameCell, mStats.getIsSameRegisteredCell());
- }
-}
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 36d8441c72..efd45b1842 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -35,7 +35,6 @@ import android.app.test.TestAlarmManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
import android.net.ConnectivityManager;
import android.net.DhcpResults;
@@ -48,6 +47,7 @@ import android.net.NetworkMisc;
import android.net.NetworkSpecifier;
import android.net.ip.IIpClient;
import android.net.ip.IpClientCallbacks;
+import android.net.wifi.IActionListener;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
@@ -59,8 +59,6 @@ import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.pps.HomeSp;
import android.net.wifi.p2p.IWifiP2pManager;
import android.os.BatteryStats;
import android.os.Binder;
@@ -76,12 +74,10 @@ import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.Process;
-import android.os.UserHandle;
import android.os.UserManager;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.security.KeyStore;
-import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
@@ -90,6 +86,7 @@ import android.util.Pair;
import androidx.test.filters.SmallTest;
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.internal.R;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.AsyncChannel;
@@ -114,6 +111,8 @@ import org.mockito.ArgumentMatcher;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
@@ -122,7 +121,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
@@ -131,7 +129,7 @@ import java.util.function.Consumer;
* Unit tests for {@link com.android.server.wifi.ClientModeImpl}.
*/
@SmallTest
-public class ClientModeImplTest {
+public class ClientModeImplTest extends WifiBaseTest {
public static final String TAG = "ClientModeImplTest";
private static final int MANAGED_PROFILE_UID = 1100000;
@@ -153,6 +151,8 @@ public class ClientModeImplTest {
MacAddress.fromString("10:22:34:56:78:92");
private static final MacAddress TEST_LOCAL_MAC_ADDRESS =
MacAddress.fromString("2a:53:43:c3:56:21");
+ private static final MacAddress TEST_DEFAULT_MAC_ADDRESS =
+ MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
// NetworkAgent creates threshold ranges with Integers
private static final int RSSI_THRESHOLD_MAX = -30;
@@ -162,6 +162,7 @@ public class ClientModeImplTest {
private static final byte RSSI_THRESHOLD_BREACH_MAX = -20;
private long mBinderToken;
+ private MockitoSession mSession;
private static <T> T mockWithInterfaces(Class<T> class1, Class<?>... interfaces) {
return mock(class1, withSettings().extraInterfaces(interfaces));
@@ -248,6 +249,9 @@ public class ClientModeImplTest {
when(context.getOpPackageName()).thenReturn(OP_PACKAGE_NAME);
+ when(context.getSystemService(ActivityManager.class)).thenReturn(
+ mock(ActivityManager.class));
+
return context;
}
@@ -294,7 +298,8 @@ public class ClientModeImplTest {
ScanDetail detail = new ScanDetail(nd, sWifiSsid, bssid, "", rssi, freq,
Long.MAX_VALUE, /* needed so that scan results aren't rejected because
there older than scan start */
- ie, new ArrayList<String>());
+ ie, new ArrayList<String>(), ScanResults.generateIERawDatafromScanResultIE(ie));
+
return detail;
}
@@ -337,7 +342,6 @@ public class ClientModeImplTest {
MockResources mResources;
FrameworkFacade mFrameworkFacade;
IpClientCallbacks mIpClientCallback;
- PhoneStateListener mPhoneStateListener;
OsuProvider mOsuProvider;
WifiConfiguration mConnectedNetwork;
@@ -371,7 +375,7 @@ public class ClientModeImplTest {
@Mock BaseWifiDiagnostics mWifiDiagnostics;
@Mock ConnectivityManager mConnectivityManager;
@Mock IProvisioningCallback mProvisioningCallback;
- @Mock HandlerThread mWifiServiceHandlerThread;
+ @Mock HandlerThread mWifiHandlerThread;
@Mock WifiPermissionsWrapper mWifiPermissionsWrapper;
@Mock WakeupController mWakeupController;
@Mock WifiDataStall mWifiDataStall;
@@ -385,9 +389,8 @@ public class ClientModeImplTest {
@Mock CarrierNetworkConfig mCarrierNetworkConfig;
@Mock Handler mNetworkAgentHandler;
-
- final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
- ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
+ final ArgumentCaptor<WifiConfigManager.OnNetworkUpdateListener> mConfigUpdateListenerCaptor =
+ ArgumentCaptor.forClass(WifiConfigManager.OnNetworkUpdateListener.class);
public ClientModeImplTest() throws Exception {
}
@@ -403,7 +406,6 @@ public class ClientModeImplTest {
/** uncomment this to enable logs from ClientModeImpls */
// enableDebugLogs();
-
mWifiMonitor = new MockWifiMonitor();
when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
when(mWifiInjector.getClock()).thenReturn(new Clock());
@@ -427,8 +429,8 @@ public class ClientModeImplTest {
when(mWifiInjector.makeTelephonyManager()).thenReturn(mTelephonyManager);
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager);
when(mWifiInjector.getClock()).thenReturn(mClock);
- when(mWifiServiceHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
- when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(mWifiServiceHandlerThread);
+ when(mWifiHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
+ when(mWifiInjector.getWifiHandlerThread()).thenReturn(mWifiHandlerThread);
when(mWifiInjector.getWifiPermissionsWrapper()).thenReturn(mWifiPermissionsWrapper);
when(mWifiInjector.getWakeupController()).thenReturn(mWakeupController);
when(mWifiInjector.getScoringParams()).thenReturn(new ScoringParams());
@@ -441,6 +443,8 @@ public class ClientModeImplTest {
when(mWifiInjector.getWifiScoreCard()).thenReturn(mWifiScoreCard);
when(mWifiInjector.getWifiLockManager()).thenReturn(mWifiLockManager);
when(mWifiInjector.getCarrierNetworkConfig()).thenReturn(mCarrierNetworkConfig);
+ when(mWifiInjector.getWifiThreadRunner())
+ .thenReturn(new WifiThreadRunner(new Handler(mLooper.getLooper())));
when(mWifiNetworkFactory.getSpecificNetworkRequestUidAndPackageName(any()))
.thenReturn(Pair.create(Process.INVALID_UID, ""));
when(mWifiNative.initialize()).thenReturn(true);
@@ -455,6 +459,12 @@ public class ClientModeImplTest {
return true;
}
});
+ doAnswer(new AnswerWithArguments() {
+ public MacAddress answer(
+ WifiConfiguration config) {
+ return config.getRandomizedMacAddress();
+ }
+ }).when(mWifiConfigManager).getRandomizedMacAndUpdateIfNeeded(any());
when(mWifiNative.connectToNetwork(any(), any())).thenReturn(true);
when(mWifiNetworkFactory.hasConnectionRequests()).thenReturn(true);
@@ -476,19 +486,6 @@ public class ClientModeImplTest {
any(Context.class), any(WifiConfigManager.class),
any(Handler.class))).thenReturn(mSupplicantStateTracker);
- when(mUserManager.getProfileParent(11))
- .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "owner", 0));
- when(mUserManager.getProfiles(UserHandle.USER_SYSTEM)).thenReturn(Arrays.asList(
- new UserInfo(UserHandle.USER_SYSTEM, "owner", 0),
- new UserInfo(11, "managed profile", 0)));
-
- doAnswer(new AnswerWithArguments() {
- public void answer(PhoneStateListener phoneStateListener, int events)
- throws Exception {
- mPhoneStateListener = phoneStateListener;
- }
- }).when(mDataTelephonyManager).listen(any(PhoneStateListener.class), anyInt());
-
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
when(mWifiPermissionsWrapper.getLocalMacAddressPermission(anyInt()))
.thenReturn(PackageManager.PERMISSION_DENIED);
@@ -496,6 +493,11 @@ public class ClientModeImplTest {
mIpClientCallback.onQuit();
return null;
}).when(mIpClient).shutdown();
+
+ // static mocking
+ mSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT)
+ .spyStatic(MacAddress.class)
+ .startMocking();
initializeCmi();
mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true);
@@ -561,6 +563,9 @@ public class ClientModeImplTest {
verify(mWifiNetworkFactory, atLeastOnce()).register();
verify(mUntrustedWifiNetworkFactory, atLeastOnce()).register();
+ verify(mWifiConfigManager, atLeastOnce()).addOnNetworkUpdateListener(
+ mConfigUpdateListenerCaptor.capture());
+ assertNotNull(mConfigUpdateListenerCaptor.getValue());
mLooper.startAutoDispatch();
mCmi.syncInitialize(mCmiAsyncChannel);
@@ -582,6 +587,7 @@ public class ClientModeImplTest {
mNetworkAgentAsyncChannel = null;
mNetworkAgentHandler = null;
mCmi = null;
+ mSession.finishMocking();
}
@Test
@@ -671,40 +677,13 @@ public class ClientModeImplTest {
}
}
- private void canRemoveNetwork() {
- boolean result;
- when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true);
- mLooper.startAutoDispatch();
- result = mCmi.syncRemoveNetwork(mCmiAsyncChannel, 0);
- mLooper.stopAutoDispatch();
-
- assertTrue(result);
- verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt());
- }
-
- /**
- * Verifies that configs can be removed when not in client mode.
- */
- @Test
- public void canRemoveNetworkConfigWhenWifiDisabled() {
- canRemoveNetwork();
- }
-
-
- /**
- * Verifies that configs can be removed when in client mode.
- */
- @Test
- public void canRemoveNetworkConfigInClientMode() throws Exception {
- initializeAndAddNetworkAndVerifySuccess();
- canRemoveNetwork();
- }
-
- private void canForgetNetwork() {
- when(mWifiConfigManager.removeNetwork(eq(0), anyInt())).thenReturn(true);
- mCmi.sendMessage(WifiManager.FORGET_NETWORK, 0, MANAGED_PROFILE_UID);
+ private void canForgetNetwork() throws Exception {
+ when(mWifiConfigManager.removeNetwork(eq(0), anyInt(), any())).thenReturn(true);
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.forget(0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
mLooper.dispatchAll();
- verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt());
+ verify(connectActionListener).onSuccess();
+ verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt(), any());
}
/**
@@ -724,22 +703,22 @@ public class ClientModeImplTest {
canForgetNetwork();
}
- private void canSaveNetworkConfig() {
+ private void canSaveNetworkConfig() throws Exception {
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
int networkId = TEST_NETWORK_ID;
when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
.thenReturn(new NetworkUpdateResult(networkId));
- when(mWifiConfigManager.enableNetwork(eq(networkId), eq(false), anyInt()))
+ when(mWifiConfigManager.enableNetwork(eq(networkId), eq(false), anyInt(), any()))
.thenReturn(true);
- mLooper.startAutoDispatch();
- Message reply = mCmiAsyncChannel.sendMessageSynchronously(WifiManager.SAVE_NETWORK, config);
- mLooper.stopAutoDispatch();
- assertEquals(WifiManager.SAVE_NETWORK_SUCCEEDED, reply.what);
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.save(config, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
verify(mWifiConfigManager).addOrUpdateNetwork(any(WifiConfiguration.class), anyInt());
- verify(mWifiConfigManager).enableNetwork(eq(networkId), eq(false), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(networkId), eq(false), anyInt(), any());
}
/**
@@ -764,15 +743,15 @@ public class ClientModeImplTest {
*/
@Test
public void saveNetworkConfigFailsWithNullConfig() throws Exception {
- mLooper.startAutoDispatch();
- Message reply = mCmiAsyncChannel.sendMessageSynchronously(WifiManager.SAVE_NETWORK, null);
- mLooper.stopAutoDispatch();
- assertEquals(WifiManager.SAVE_NETWORK_FAILED, reply.what);
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.save(null, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onFailure(WifiManager.ERROR);
verify(mWifiConfigManager, never())
.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt());
verify(mWifiConfigManager, never())
- .enableNetwork(anyInt(), anyBoolean(), anyInt());
+ .enableNetwork(anyInt(), anyBoolean(), anyInt(), any());
}
/**
@@ -785,14 +764,14 @@ public class ClientModeImplTest {
when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
.thenReturn(new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID));
- mLooper.startAutoDispatch();
- Message reply = mCmiAsyncChannel.sendMessageSynchronously(WifiManager.SAVE_NETWORK, config);
- mLooper.stopAutoDispatch();
- assertEquals(WifiManager.SAVE_NETWORK_FAILED, reply.what);
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.save(config, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onFailure(WifiManager.ERROR);
verify(mWifiConfigManager).addOrUpdateNetwork(any(WifiConfiguration.class), anyInt());
verify(mWifiConfigManager, never())
- .enableNetwork(anyInt(), anyBoolean(), anyInt());
+ .enableNetwork(anyInt(), anyBoolean(), anyInt(), any());
}
/**
@@ -805,16 +784,16 @@ public class ClientModeImplTest {
int networkId = 5;
when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
.thenReturn(new NetworkUpdateResult(networkId));
- when(mWifiConfigManager.enableNetwork(eq(networkId), eq(false), anyInt()))
+ when(mWifiConfigManager.enableNetwork(eq(networkId), eq(false), anyInt(), any()))
.thenReturn(false);
- mLooper.startAutoDispatch();
- Message reply = mCmiAsyncChannel.sendMessageSynchronously(WifiManager.SAVE_NETWORK, config);
- mLooper.stopAutoDispatch();
- assertEquals(WifiManager.SAVE_NETWORK_FAILED, reply.what);
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.save(config, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onFailure(WifiManager.ERROR);
verify(mWifiConfigManager).addOrUpdateNetwork(any(WifiConfiguration.class), anyInt());
- verify(mWifiConfigManager).enableNetwork(eq(networkId), eq(false), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(networkId), eq(false), anyInt(), any());
}
/**
@@ -831,34 +810,16 @@ public class ClientModeImplTest {
assertEquals("DisconnectedState", getCurrentState().getName());
}
- private void addNetworkAndVerifySuccess(boolean isHidden) throws Exception {
+ private void initializeMocksForAddedNetwork(boolean isHidden) throws Exception {
WifiConfiguration config = new WifiConfiguration();
config.networkId = FRAMEWORK_NETWORK_ID;
config.SSID = sSSID;
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.hiddenSSID = isHidden;
- when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
- .thenReturn(new NetworkUpdateResult(0));
when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(Arrays.asList(config));
when(mWifiConfigManager.getConfiguredNetwork(0)).thenReturn(config);
when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config);
-
- mLooper.startAutoDispatch();
- mCmi.syncAddOrUpdateNetwork(mCmiAsyncChannel, config);
- mLooper.stopAutoDispatch();
-
- verify(mWifiConfigManager).addOrUpdateNetwork(eq(config), anyInt());
-
- mLooper.startAutoDispatch();
- List<WifiConfiguration> configs = mCmi.syncGetConfiguredNetworks(-1, mCmiAsyncChannel,
- Process.WIFI_UID);
- mLooper.stopAutoDispatch();
- assertEquals(1, configs.size());
-
- WifiConfiguration config2 = configs.get(0);
- assertEquals("\"GoogleGuest\"", config2.SSID);
- assertTrue(config2.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE));
}
private void initializeAndAddNetworkAndVerifySuccess() throws Exception {
@@ -867,30 +828,12 @@ public class ClientModeImplTest {
private void initializeAndAddNetworkAndVerifySuccess(boolean isHidden) throws Exception {
loadComponentsInStaMode();
- addNetworkAndVerifySuccess(isHidden);
- }
-
- /**
- * Helper method to retrieve WifiConfiguration by SSID.
- *
- * Returns the associated WifiConfiguration if it is found, null otherwise.
- */
- private WifiConfiguration getWifiConfigurationForNetwork(String ssid) {
- mLooper.startAutoDispatch();
- List<WifiConfiguration> configs = mCmi.syncGetConfiguredNetworks(-1, mCmiAsyncChannel,
- Process.WIFI_UID);
- mLooper.stopAutoDispatch();
-
- for (WifiConfiguration checkConfig : configs) {
- if (checkConfig.SSID.equals(ssid)) {
- return checkConfig;
- }
- }
- return null;
+ initializeMocksForAddedNetwork(isHidden);
}
private void setupAndStartConnectSequence(WifiConfiguration config) throws Exception {
- when(mWifiConfigManager.enableNetwork(eq(config.networkId), eq(true), anyInt()))
+ when(mWifiConfigManager.enableNetwork(
+ eq(config.networkId), eq(true), anyInt(), any()))
.thenReturn(true);
when(mWifiConfigManager.updateLastConnectUid(eq(config.networkId), anyInt()))
.thenReturn(true);
@@ -901,13 +844,16 @@ public class ClientModeImplTest {
verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME);
- mLooper.startAutoDispatch();
- assertTrue(mCmi.syncEnableNetwork(mCmiAsyncChannel, config.networkId, true));
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, config.networkId, mock(Binder.class), connectActionListener, 0,
+ Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
}
private void validateSuccessfulConnectSequence(WifiConfiguration config) {
- verify(mWifiConfigManager).enableNetwork(eq(config.networkId), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(
+ eq(config.networkId), eq(true), anyInt(), any());
verify(mWifiConnectivityManager).setUserConnectChoice(eq(config.networkId));
verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId));
verify(mWifiConfigManager).getConfiguredNetworkWithoutMasking(eq(config.networkId));
@@ -915,7 +861,8 @@ public class ClientModeImplTest {
}
private void validateFailureConnectSequence(WifiConfiguration config) {
- verify(mWifiConfigManager).enableNetwork(eq(config.networkId), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(
+ eq(config.networkId), eq(true), anyInt(), any());
verify(mWifiConnectivityManager).setUserConnectChoice(eq(config.networkId));
verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId));
verify(mWifiConfigManager, never())
@@ -935,7 +882,7 @@ public class ClientModeImplTest {
loadComponentsInStaMode();
WifiConfiguration config = mConnectedNetwork;
config.networkId = FRAMEWORK_NETWORK_ID;
- when(config.getOrCreateRandomizedMacAddress()).thenReturn(TEST_LOCAL_MAC_ADDRESS);
+ config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS);
config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
setupAndStartConnectSequence(config);
validateSuccessfulConnectSequence(config);
@@ -956,7 +903,8 @@ public class ClientModeImplTest {
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(Process.myUid()))
.thenReturn(false);
setupAndStartConnectSequence(config);
- verify(mWifiConfigManager).enableNetwork(eq(config.networkId), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(
+ eq(config.networkId), eq(true), anyInt(), any());
verify(mWifiConnectivityManager, never()).setUserConnectChoice(eq(config.networkId));
verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId));
verify(mWifiConfigManager).getConfiguredNetworkWithoutMasking(eq(config.networkId));
@@ -1047,6 +995,9 @@ public class ClientModeImplTest {
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
+ // Initial value should be "not set"
+ assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
+
triggerConnect();
// CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm>
@@ -1066,15 +1017,15 @@ public class ClientModeImplTest {
mLooper.dispatchAll();
verify(mWifiNative).getEapAnonymousIdentity(any());
- // check that the anonymous identity remains anonymous@<realm> for subsequent connections.
- assertEquals(expectedAnonymousIdentity,
- mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
- // verify that WifiConfigManager#addOrUpdateNetwork() was never called if there is no
- // real pseudonym to be stored. i.e. Encrypted IMSI will be always used
+
+ // Post connection value should remain "not set"
+ assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
+ // verify that WifiConfigManager#addOrUpdateNetwork() was called to clear any previously
+ // stored pseudonym. i.e. to enable Encrypted IMSI for subsequent connections.
// Note: This test will fail if future logic will have additional conditions that would
// trigger "add or update network" operation. The test needs to be updated to account for
// this change.
- verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt());
}
/**
@@ -1127,6 +1078,55 @@ public class ClientModeImplTest {
}
/**
+ * Tests anonymous identity is set again whenever a connection is established for the carrier
+ * that supports encrypted IMSI and anonymous identity but real but not decorated pseudonym was
+ * provided for subsequent connections.
+ */
+ @Test
+ public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithNonDecoratedPseudonym()
+ throws Exception {
+ mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork(
+ WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE));
+ when(mDataTelephonyManager.getSimOperator()).thenReturn("123456");
+ when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
+ mConnectedNetwork.enterpriseConfig.setAnonymousIdentity("");
+
+ String realm = "wlan.mnc456.mcc123.3gppnetwork.org";
+ String expectedAnonymousIdentity = "anonymous";
+ String pseudonym = "83bcca9384fca";
+
+ when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
+
+ triggerConnect();
+
+ // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm>
+ assertEquals(expectedAnonymousIdentity + "@" + realm,
+ mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
+
+ when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID))
+ .thenReturn(mScanDetailCache);
+ when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn(
+ getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq));
+ when(mScanDetailCache.getScanResult(sBSSID)).thenReturn(
+ getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult());
+ when(mWifiNative.getEapAnonymousIdentity(anyString()))
+ .thenReturn(pseudonym);
+
+ mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ verify(mWifiNative).getEapAnonymousIdentity(any());
+ assertEquals(pseudonym + "@" + realm,
+ mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
+ // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a
+ // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by
+ // pseudonym usage in all subsequent connections.
+ // Note: This test will fail if future logic will have additional conditions that would
+ // trigger "add or update network" operation. The test needs to be updated to account for
+ // this change.
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt());
+ }
+ /**
* Tests the Passpoint information is set in WifiInfo for Passpoint AP connection.
*/
@Test
@@ -1136,7 +1136,6 @@ public class ClientModeImplTest {
config.SSID = sWifiSsid.toString();
config.BSSID = sBSSID;
config.networkId = FRAMEWORK_NETWORK_ID;
- when(config.getOrCreateRandomizedMacAddress()).thenReturn(TEST_LOCAL_MAC_ADDRESS);
config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
setupAndStartConnectSequence(config);
validateSuccessfulConnectSequence(config);
@@ -1165,7 +1164,6 @@ public class ClientModeImplTest {
config.SSID = sWifiSsid.toString();
config.BSSID = sBSSID;
config.networkId = PASSPOINT_NETWORK_ID;
- when(config.getOrCreateRandomizedMacAddress()).thenReturn(TEST_LOCAL_MAC_ADDRESS);
config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
setupAndStartConnectSequence(config);
validateSuccessfulConnectSequence(config);
@@ -1198,7 +1196,6 @@ public class ClientModeImplTest {
osuConfig.osu = true;
osuConfig.networkId = FRAMEWORK_NETWORK_ID;
osuConfig.providerFriendlyName = WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME;
- when(osuConfig.getOrCreateRandomizedMacAddress()).thenReturn(TEST_LOCAL_MAC_ADDRESS);
osuConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
setupAndStartConnectSequence(osuConfig);
validateSuccessfulConnectSequence(osuConfig);
@@ -1229,7 +1226,6 @@ public class ClientModeImplTest {
osuConfig.osu = true;
osuConfig.networkId = PASSPOINT_NETWORK_ID;
osuConfig.providerFriendlyName = WifiConfigurationTestUtil.TEST_PROVIDER_FRIENDLY_NAME;
- when(osuConfig.getOrCreateRandomizedMacAddress()).thenReturn(TEST_LOCAL_MAC_ADDRESS);
osuConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
setupAndStartConnectSequence(osuConfig);
validateSuccessfulConnectSequence(osuConfig);
@@ -1307,7 +1303,8 @@ public class ClientModeImplTest {
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
config.networkId = FRAMEWORK_NETWORK_ID + 1;
setupAndStartConnectSequence(config);
- verify(mWifiConfigManager).enableNetwork(eq(config.networkId), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(
+ eq(config.networkId), eq(true), anyInt(), any());
verify(mWifiConnectivityManager, never()).setUserConnectChoice(eq(config.networkId));
verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId));
verify(mWifiConfigManager, never())
@@ -1323,11 +1320,12 @@ public class ClientModeImplTest {
verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME);
- mLooper.startAutoDispatch();
- assertFalse(mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true));
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onFailure(anyInt());
- verify(mWifiConfigManager, never()).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager, never()).enableNetwork(eq(0), eq(true), anyInt(), any());
verify(mWifiConfigManager, never()).updateLastConnectUid(eq(0), anyInt());
}
@@ -1339,16 +1337,62 @@ public class ClientModeImplTest {
* that connection request returns with CONNECT_NETWORK_SUCCEEDED.
*/
@Test
- public void reconnectToConnectedNetwork() throws Exception {
+ public void reconnectToConnectedNetworkWithNetworkId() throws Exception {
+ connect();
+
+ // try to reconnect
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, FRAMEWORK_NETWORK_ID, mock(Binder.class), connectActionListener, 0,
+ Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
+
+ // Verify that we didn't trigger a second connection.
+ verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any());
+ }
+
+ /**
+ * If caller tries to connect to a network that is already connected, the connection request
+ * should succeed.
+ *
+ * Test: Create and connect to a network, then try to reconnect to the same network. Verify
+ * that connection request returns with CONNECT_NETWORK_SUCCEEDED.
+ */
+ @Test
+ public void reconnectToConnectedNetworkWithConfig() throws Exception {
+ connect();
+
+ // try to reconnect
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = FRAMEWORK_NETWORK_ID;
+ when(mWifiConfigManager.addOrUpdateNetwork(eq(config), anyInt()))
+ .thenReturn(new NetworkUpdateResult(FRAMEWORK_NETWORK_ID));
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(config, WifiConfiguration.INVALID_NETWORK_ID, mock(Binder.class),
+ connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
+
+ // Verify that we didn't trigger a second connection.
+ verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), any());
+ }
+
+ /**
+ * If caller tries to connect to a new network while still provisioning the current one,
+ * the connection attempt should succeed.
+ */
+ @Test
+ public void connectWhileObtainingIp() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME);
- mLooper.startAutoDispatch();
- mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true);
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID);
mLooper.dispatchAll();
@@ -1358,13 +1402,22 @@ public class ClientModeImplTest {
mLooper.dispatchAll();
assertEquals("ObtainingIpState", getCurrentState().getName());
+ reset(mWifiNative);
- // try to reconnect
- mLooper.startAutoDispatch();
- Message reply = mCmiAsyncChannel.sendMessageSynchronously(WifiManager.CONNECT_NETWORK, 0);
- mLooper.stopAutoDispatch();
+ // Connect to a different network
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = TEST_NETWORK_ID;
+ when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
+
+ mCmi.connect(null, TEST_NETWORK_ID, mock(Binder.class), null, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED));
+ mLooper.dispatchAll();
+
+ verify(mWifiConnectivityManager).prepareForForcedConnection(eq(config.networkId));
- assertEquals(WifiManager.CONNECT_NETWORK_SUCCEEDED, reply.what);
}
/**
@@ -1373,19 +1426,16 @@ public class ClientModeImplTest {
@Test
public void testManualConnectNominator() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- Message msg = Message.obtain();
- msg.what = WifiManager.CONNECT_NETWORK;
- msg.arg1 = TEST_NETWORK_ID;
- msg.obj = null;
- msg.sendingUid = Process.SYSTEM_UID;
WifiConfiguration config = new WifiConfiguration();
config.networkId = TEST_NETWORK_ID;
-
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
- mCmi.sendMessage(msg);
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, TEST_NETWORK_ID, mock(Binder.class), connectActionListener, 0,
+ Process.SYSTEM_UID);
mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
verify(mWifiMetrics).setNominatorForNetwork(TEST_NETWORK_ID,
WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL);
@@ -1395,11 +1445,12 @@ public class ClientModeImplTest {
public void testDhcpFailure() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- mLooper.startAutoDispatch();
- mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true);
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID);
mLooper.dispatchAll();
@@ -1429,11 +1480,12 @@ public class ClientModeImplTest {
public void testWrongPasswordWithPreviouslyConnected() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- mLooper.startAutoDispatch();
- mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true);
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
WifiConfiguration config = new WifiConfiguration();
config.getNetworkSelectionStatus().setHasEverConnected(true);
@@ -1459,11 +1511,12 @@ public class ClientModeImplTest {
public void testWrongPasswordWithNeverConnected() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- mLooper.startAutoDispatch();
- mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true);
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
WifiConfiguration config = new WifiConfiguration();
config.SSID = sSSID;
@@ -1489,11 +1542,12 @@ public class ClientModeImplTest {
public void testWrongPasswordWithNullNetwork() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- mLooper.startAutoDispatch();
- mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true);
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(null);
@@ -1517,11 +1571,12 @@ public class ClientModeImplTest {
public void testEapSimErrorVendorSpecific() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- mLooper.startAutoDispatch();
- mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true);
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
WifiConfiguration config = new WifiConfiguration();
config.getNetworkSelectionStatus().setHasEverConnected(true);
@@ -1545,11 +1600,12 @@ public class ClientModeImplTest {
public void testEapTlsErrorVendorSpecific() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- mLooper.startAutoDispatch();
- mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true);
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
WifiConfiguration config = new WifiConfiguration();
config.getNetworkSelectionStatus().setHasEverConnected(true);
@@ -1572,11 +1628,12 @@ public class ClientModeImplTest {
public void testEapSimNoSubscribedError() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- mLooper.startAutoDispatch();
- mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true);
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(null);
@@ -1594,11 +1651,12 @@ public class ClientModeImplTest {
public void testBadNetworkEvent() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- mLooper.startAutoDispatch();
- mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true);
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID);
mLooper.dispatchAll();
@@ -1823,108 +1881,11 @@ public class ClientModeImplTest {
}
/**
- * Verify that syncAddOrUpdatePasspointConfig will redirect calls to {@link PasspointManager}
- * and returning the result that's returned from {@link PasspointManager}.
- */
- @Test
- public void syncAddOrUpdatePasspointConfig() throws Exception {
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn("test.com");
- config.setHomeSp(homeSp);
-
- when(mPasspointManager.addOrUpdateProvider(config, MANAGED_PROFILE_UID,
- OP_PACKAGE_NAME)).thenReturn(true);
- mLooper.startAutoDispatch();
- assertTrue(mCmi.syncAddOrUpdatePasspointConfig(
- mCmiAsyncChannel, config, MANAGED_PROFILE_UID, OP_PACKAGE_NAME));
- mLooper.stopAutoDispatch();
- reset(mPasspointManager);
-
- when(mPasspointManager.addOrUpdateProvider(config, MANAGED_PROFILE_UID,
- OP_PACKAGE_NAME)).thenReturn(false);
- mLooper.startAutoDispatch();
- assertFalse(mCmi.syncAddOrUpdatePasspointConfig(
- mCmiAsyncChannel, config, MANAGED_PROFILE_UID, OP_PACKAGE_NAME));
- mLooper.stopAutoDispatch();
- }
-
- /**
- * Verify that syncAddOrUpdatePasspointConfig will redirect calls to {@link PasspointManager}
- * and returning the result that's returned from {@link PasspointManager} when in client mode.
- */
- @Test
- public void syncAddOrUpdatePasspointConfigInClientMode() throws Exception {
- loadComponentsInStaMode();
- syncAddOrUpdatePasspointConfig();
- }
-
- /**
- * Verify that syncRemovePasspointConfig will redirect calls to {@link PasspointManager}
- * and returning the result that's returned from {@link PasspointManager}.
- */
- @Test
- public void syncRemovePasspointConfig() throws Exception {
- String fqdn = "test.com";
- when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), eq(fqdn))).thenReturn(true);
- mLooper.startAutoDispatch();
- assertTrue(mCmi.syncRemovePasspointConfig(mCmiAsyncChannel, true, fqdn));
- mLooper.stopAutoDispatch();
- reset(mPasspointManager);
-
- when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), eq(fqdn))).thenReturn(false);
- mLooper.startAutoDispatch();
- assertFalse(mCmi.syncRemovePasspointConfig(mCmiAsyncChannel, true, fqdn));
- mLooper.stopAutoDispatch();
- }
-
- /**
- * Verify that syncRemovePasspointConfig will redirect calls to {@link PasspointManager}
- * and returning the result that's returned from {@link PasspointManager} when in client mode.
- */
- @Test
- public void syncRemovePasspointConfigInClientMode() throws Exception {
- loadComponentsInStaMode();
- syncRemovePasspointConfig();
- }
-
- /**
- * Verify that syncGetPasspointConfigs will redirect calls to {@link PasspointManager}
- * and returning the result that's returned from {@link PasspointManager}.
- */
- @Test
- public void syncGetPasspointConfigs() throws Exception {
- // Setup expected configs.
- List<PasspointConfiguration> expectedConfigs = new ArrayList<>();
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn("test.com");
- config.setHomeSp(homeSp);
- expectedConfigs.add(config);
-
- when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
- .thenReturn(expectedConfigs);
- mLooper.startAutoDispatch();
- assertEquals(expectedConfigs, mCmi.syncGetPasspointConfigs(mCmiAsyncChannel, true));
- mLooper.stopAutoDispatch();
- reset(mPasspointManager);
-
- when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
- .thenReturn(new ArrayList<>());
- mLooper.startAutoDispatch();
- assertTrue(mCmi.syncGetPasspointConfigs(mCmiAsyncChannel, true).isEmpty());
- mLooper.stopAutoDispatch();
- }
-
- /**
* Verify that syncStartSubscriptionProvisioning will redirect calls with right parameters
* to {@link PasspointManager} with expected true being returned when in client mode.
*/
@Test
public void syncStartSubscriptionProvisioningInClientMode() throws Exception {
- // syncInitialize is invoke in Setup.
- verify(mPasspointManager).initializeProvisioner(any(Looper.class));
-
loadComponentsInStaMode();
when(mPasspointManager.startSubscriptionProvisioning(anyInt(),
any(OsuProvider.class), any(IProvisioningCallback.class))).thenReturn(true);
@@ -1972,16 +1933,18 @@ public class ClientModeImplTest {
public void disconnectFromNetworkWhenRemovedWhileObtainingIpAddr() throws Exception {
initializeAndAddNetworkAndVerifySuccess();
- when(mWifiConfigManager.enableNetwork(eq(0), eq(true), anyInt())).thenReturn(true);
+ when(mWifiConfigManager.enableNetwork(eq(0), eq(true), anyInt(), any()))
+ .thenReturn(true);
when(mWifiConfigManager.updateLastConnectUid(eq(0), anyInt())).thenReturn(true);
verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME);
- mLooper.startAutoDispatch();
- assertTrue(mCmi.syncEnableNetwork(mCmiAsyncChannel, 0, true));
- mLooper.stopAutoDispatch();
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
- verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt());
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
verify(mWifiConnectivityManager).setUserConnectChoice(eq(0));
when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID))
.thenReturn(mScanDetailCache);
@@ -2001,11 +1964,18 @@ public class ClientModeImplTest {
assertEquals("ObtainingIpState", getCurrentState().getName());
// now remove the config
- when(mWifiConfigManager.removeNetwork(eq(FRAMEWORK_NETWORK_ID), anyInt()))
+ reset(connectActionListener);
+ when(mWifiConfigManager.removeNetwork(eq(FRAMEWORK_NETWORK_ID), anyInt(), any()))
.thenReturn(true);
- mCmi.sendMessage(WifiManager.FORGET_NETWORK, FRAMEWORK_NETWORK_ID, MANAGED_PROFILE_UID);
+ mCmi.forget(FRAMEWORK_NETWORK_ID, mock(Binder.class), connectActionListener, 0,
+ Binder.getCallingUid());
mLooper.dispatchAll();
- verify(mWifiConfigManager).removeNetwork(eq(FRAMEWORK_NETWORK_ID), anyInt());
+ verify(connectActionListener).onSuccess();
+ verify(mWifiConfigManager).removeNetwork(eq(FRAMEWORK_NETWORK_ID), anyInt(), any());
+ // trigger removal callback to trigger disconnect.
+ WifiConfiguration removedConfig = new WifiConfiguration();
+ removedConfig.networkId = FRAMEWORK_NETWORK_ID;
+ mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedConfig);
reset(mWifiConfigManager);
@@ -2101,7 +2071,7 @@ public class ClientModeImplTest {
// This simulates the behavior of roaming to network with |sBSSID1|, |sFreq1|.
// Send a CMD_ASSOCIATED_BSSID, verify WifiInfo is updated.
- mCmi.sendMessage(ClientModeImpl.CMD_ASSOCIATED_BSSID, 0, 0, sBSSID1);
+ mCmi.sendMessage(WifiMonitor.ASSOCIATED_BSSID_EVENT, 0, 0, sBSSID1);
mLooper.dispatchAll();
WifiInfo wifiInfo = mCmi.getWifiInfo();
@@ -2133,7 +2103,6 @@ public class ClientModeImplTest {
assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState());
inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true));
inOrder.verify(mWifiNetworkFactory).setWifiState(eq(true));
- inOrderSarMgr.verify(mSarManager).setClientWifiState(WifiManager.WIFI_STATE_ENABLED);
inOrderMetrics.verify(mWifiMetrics)
.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED);
inOrderMetrics.verify(mWifiMetrics).logStaEvent(StaEvent.TYPE_WIFI_ENABLED);
@@ -2157,7 +2126,6 @@ public class ClientModeImplTest {
assertEquals(WifiManager.WIFI_STATE_DISABLED, mCmi.syncGetWifiState());
inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(false));
inOrder.verify(mWifiNetworkFactory).setWifiState(eq(false));
- inOrderSarMgr.verify(mSarManager).setClientWifiState(WifiManager.WIFI_STATE_DISABLED);
inOrderMetrics.verify(mWifiMetrics).setWifiState(WifiMetricsProto.WifiLog.WIFI_DISABLED);
inOrderMetrics.verify(mWifiMetrics).logStaEvent(StaEvent.TYPE_WIFI_DISABLED);
assertNull(wifiInfo.getBSSID());
@@ -2181,7 +2149,6 @@ public class ClientModeImplTest {
assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState());
inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(true));
inOrder.verify(mWifiNetworkFactory).setWifiState(eq(true));
- inOrderSarMgr.verify(mSarManager).setClientWifiState(WifiManager.WIFI_STATE_ENABLED);
inOrderMetrics.verify(mWifiMetrics)
.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED);
inOrderMetrics.verify(mWifiMetrics).logStaEvent(StaEvent.TYPE_WIFI_ENABLED);
@@ -2247,38 +2214,11 @@ public class ClientModeImplTest {
public void addNetworkInDefaultState() throws Exception {
// We should not be in initial state now.
assertTrue("DefaultState".equals(getCurrentState().getName()));
- addNetworkAndVerifySuccess(false);
+ initializeMocksForAddedNetwork(false);
verify(mWifiConnectivityManager, never()).setUserConnectChoice(eq(0));
}
/**
- * Test that DISABLE_NETWORK returns failure to public API when WifiConfigManager returns
- * failure.
- */
- @Test
- public void testSyncDisableNetwork_failure() throws Exception {
- loadComponentsInStaMode();
- when(mWifiConfigManager.disableNetwork(anyInt(), anyInt())).thenReturn(false);
-
- mLooper.startAutoDispatch();
- boolean succeeded = mCmi.syncDisableNetwork(mCmiAsyncChannel, 0);
- mLooper.stopAutoDispatch();
- assertFalse(succeeded);
- }
-
- /**
- * Test that we don't register the telephony call state listener on devices which do not support
- * setting/resetting Tx power limit.
- */
- @Test
- public void testVoiceCallSar_disabledTxPowerScenario_WifiOn() throws Exception {
- loadComponentsInStaMode();
- assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest());
- assertEquals("DisconnectedState", getCurrentState().getName());
- assertNull(mPhoneStateListener);
- }
-
- /**
* Verifies that ClientModeImpl sets and unsets appropriate 'RecentFailureReason' values
* on a WifiConfiguration when it fails association, authentication, or successfully connects
*/
@@ -2577,8 +2517,6 @@ public class ClientModeImplTest {
assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState());
connect();
- verify(mWifiConfigManager, never()).setNetworkRandomizedMacAddress(0,
- TEST_LOCAL_MAC_ADDRESS);
verify(mWifiNative, never()).setMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS);
verify(mWifiMetrics, never())
.logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class));
@@ -2602,7 +2540,6 @@ public class ClientModeImplTest {
assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState());
connect();
- verify(mWifiConfigManager).setNetworkRandomizedMacAddress(0, TEST_LOCAL_MAC_ADDRESS);
verify(mWifiNative).setMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS);
verify(mWifiMetrics)
.logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class));
@@ -2627,7 +2564,6 @@ public class ClientModeImplTest {
.thenReturn(TEST_LOCAL_MAC_ADDRESS.toString());
connect();
- verify(mWifiConfigManager).setNetworkRandomizedMacAddress(0, TEST_LOCAL_MAC_ADDRESS);
verify(mWifiNative, never()).setMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS);
verify(mWifiMetrics, never())
.logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class));
@@ -2661,12 +2597,10 @@ public class ClientModeImplTest {
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
mLooper.dispatchAll();
- verify(mWifiConfigManager, never()).setNetworkRandomizedMacAddress(anyInt(), any());
verify(mWifiNative).setMacAddress(WIFI_IFACE_NAME, TEST_GLOBAL_MAC_ADDRESS);
verify(mWifiMetrics)
.logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class));
assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress());
- verify(config, never()).getOrCreateRandomizedMacAddress();
}
/**
@@ -2693,12 +2627,10 @@ public class ClientModeImplTest {
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
mLooper.dispatchAll();
- verify(mWifiConfigManager, never()).setNetworkRandomizedMacAddress(anyInt(), any());
verify(mWifiNative, never()).setMacAddress(WIFI_IFACE_NAME, TEST_GLOBAL_MAC_ADDRESS);
verify(mWifiMetrics, never())
.logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class));
assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress());
- verify(config, never()).getOrCreateRandomizedMacAddress();
}
/**
@@ -2735,8 +2667,7 @@ public class ClientModeImplTest {
WifiConfiguration config = mock(WifiConfiguration.class);
config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
- when(config.getOrCreateRandomizedMacAddress())
- .thenReturn(MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS));
+ config.setRandomizedMacAddress(MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS));
when(config.getNetworkSelectionStatus())
.thenReturn(new WifiConfiguration.NetworkSelectionStatus());
when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config);
@@ -2744,7 +2675,6 @@ public class ClientModeImplTest {
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
mLooper.dispatchAll();
- verify(config).getOrCreateRandomizedMacAddress();
verify(mWifiNative, never()).setMacAddress(eq(WIFI_IFACE_NAME), any(MacAddress.class));
}
@@ -3555,23 +3485,6 @@ public class ClientModeImplTest {
}
/**
- * Verify removing Passpoint configuration will also remove the WifiConfiguration for it.
- */
- @Test
- public void testRemovePasspointConfig() throws Exception {
- String fqdn = "test.com";
- when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), anyString()))
- .thenReturn(true);
-
- // switch to connect mode and verify wifi is reported as enabled
- startSupplicantAndDispatchMessages();
- mCmi.sendMessage(ClientModeImpl.CMD_REMOVE_PASSPOINT_CONFIG, TEST_UID, 0, fqdn);
- mLooper.dispatchAll();
-
- verify(mWifiConfigManager).removePasspointConfiguredNetwork(fqdn);
- }
-
- /**
* Verify removing sim will also remove an ephemeral Passpoint Provider.
*/
@Test
@@ -3667,64 +3580,131 @@ public class ClientModeImplTest {
}
/**
- * Verify that syncGetAllMatchingFqdnsForScanResults does not return null from a null message.
+ * Tests that when {@link ClientModeImpl} receives a SUP_REQUEST_IDENTITY message, it responds
+ * to the supplicant with the SIM identity.
*/
@Test
- public void testSyncGetAllMatchingFqdnsForScanResult_doesNotReturnNull() {
- assertNotNull(
- mCmi.syncGetAllMatchingFqdnsForScanResults(null, mNullAsyncChannel));
+ public void testSupRequestIdentity_setsIdentityResponse() throws Exception {
+ mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork(
+ WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE));
+ mConnectedNetwork.SSID = DEFAULT_TEST_SSID;
+
+ when(mDataTelephonyManager.getSubscriberId()).thenReturn("3214561234567890");
+ when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
+ when(mDataTelephonyManager.getSimOperator()).thenReturn("321456");
+ when(mDataTelephonyManager.getCarrierInfoForImsiEncryption(anyInt())).thenReturn(null);
+
+ triggerConnect();
+
+ mCmi.sendMessage(WifiMonitor.SUP_REQUEST_IDENTITY,
+ 0, FRAMEWORK_NETWORK_ID, DEFAULT_TEST_SSID);
+ mLooper.dispatchAll();
+
+ verify(mWifiNative).simIdentityResponse(WIFI_IFACE_NAME,
+ "13214561234567890@wlan.mnc456.mcc321.3gppnetwork.org", "");
}
/**
- * Verify that syncGetMatchingOsuProviders does not return null from a null message.
+ * Verifies that WifiLastResortWatchdog is notified of DHCP failures when recevied
+ * NETWORK_DISCONNECTION_EVENT while in ObtainingIpState.
*/
@Test
- public void testSyncGetMatchingOsuProviders_doesNotReturnNull() {
- assertNotNull(
- mCmi.syncGetMatchingOsuProviders(null, mNullAsyncChannel));
+ public void testDhcpFailureUpdatesWatchdog_WhenDisconnectedWhileObtainingIpAddr()
+ throws Exception {
+ initializeAndAddNetworkAndVerifySuccess();
+
+ verify(mWifiNative).removeAllNetworks(WIFI_IFACE_NAME);
+
+ IActionListener connectActionListener = mock(IActionListener.class);
+ mCmi.connect(null, 0, mock(Binder.class), connectActionListener, 0, Binder.getCallingUid());
+ mLooper.dispatchAll();
+ verify(connectActionListener).onSuccess();
+
+ verify(mWifiConfigManager).enableNetwork(eq(0), eq(true), anyInt(), any());
+
+ mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED));
+ mLooper.dispatchAll();
+
+ assertEquals("ObtainingIpState", getCurrentState().getName());
+
+ // Verifies that WifiLastResortWatchdog be notified.
+ mCmi.sendMessage(WifiMonitor.NETWORK_DISCONNECTION_EVENT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ assertEquals("DisconnectedState", getCurrentState().getName());
+ verify(mWifiLastResortWatchdog).noteConnectionFailureAndTriggerIfNeeded(
+ sSSID, sBSSID, WifiLastResortWatchdog.FAILURE_CODE_DHCP);
}
/**
- * Verify that syncGetMatchingPasspointConfigsForOsuProviders does not return null from a null
- * message.
+ * Verifies that we trigger a disconnect when the {@link WifiConfigManager.
+ * OnNetworkUpdateListener#onNetworkRemoved(WifiConfiguration)} is invoked.
*/
@Test
- public void testSyncGetMatchingPasspointConfigsForOsuProviders_doesNotReturnNull() {
- assertNotNull(
- mCmi.syncGetMatchingPasspointConfigsForOsuProviders(null, mNullAsyncChannel));
+ public void testOnNetworkRemoved() throws Exception {
+ connect();
+
+ WifiConfiguration removedNetwork = new WifiConfiguration();
+ removedNetwork.networkId = FRAMEWORK_NETWORK_ID;
+ mConfigUpdateListenerCaptor.getValue().onNetworkRemoved(removedNetwork);
+ mLooper.dispatchAll();
+
+ verify(mWifiNative).removeNetworkCachedData(FRAMEWORK_NETWORK_ID);
+ assertEquals("DisconnectingState", getCurrentState().getName());
}
/**
- * Verify that syncGetWifiConfigsForPasspointProfiles does not return null from a null message.
+ * Verifies that we trigger a disconnect when the {@link WifiConfigManager
+ * .OnNetworkUpdateListener#onNetworkPermanentlyDisabled(WifiConfiguration, int)} is invoked.
*/
@Test
- public void testSyncGetWifiConfigsForPasspointProfiles_doesNotReturnNull() {
- assertNotNull(
- mCmi.syncGetWifiConfigsForPasspointProfiles(null, mNullAsyncChannel));
+ public void testOnNetworkPermanentlyDisabled() throws Exception {
+ connect();
+
+ WifiConfiguration disabledNetwork = new WifiConfiguration();
+ disabledNetwork.networkId = FRAMEWORK_NETWORK_ID;
+ mConfigUpdateListenerCaptor.getValue().onNetworkPermanentlyDisabled(disabledNetwork,
+ WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD);
+ mLooper.dispatchAll();
+
+ assertEquals("DisconnectingState", getCurrentState().getName());
}
/**
- * Tests that when {@link ClientModeImpl} receives a SUP_REQUEST_IDENTITY message, it responds
- * to the supplicant with the SIM identity.
+ * Verifies that we don't trigger a disconnect when the {@link WifiConfigManager
+ * .OnNetworkUpdateListener#onNetworkPermanentlyDisabled(WifiConfiguration, int)} is invoked.
*/
@Test
- public void testSupRequestIdentity_setsIdentityResponse() throws Exception {
- mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork(
- WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE));
- mConnectedNetwork.SSID = DEFAULT_TEST_SSID;
+ public void testOnNetworkPermanentlyDisabledWithNoInternet() throws Exception {
+ connect();
- when(mDataTelephonyManager.getSubscriberId()).thenReturn("3214561234567890");
- when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
- when(mDataTelephonyManager.getSimOperator()).thenReturn("321456");
- when(mDataTelephonyManager.getCarrierInfoForImsiEncryption(anyInt())).thenReturn(null);
+ WifiConfiguration disabledNetwork = new WifiConfiguration();
+ disabledNetwork.networkId = FRAMEWORK_NETWORK_ID;
+ mConfigUpdateListenerCaptor.getValue().onNetworkPermanentlyDisabled(disabledNetwork,
+ WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_PERMANENT);
+ mLooper.dispatchAll();
- triggerConnect();
+ assertEquals("ConnectedState", getCurrentState().getName());
+ }
- mCmi.sendMessage(WifiMonitor.SUP_REQUEST_IDENTITY,
- 0, FRAMEWORK_NETWORK_ID, DEFAULT_TEST_SSID);
+ /**
+ * Verifies that we don't trigger a disconnect when the {@link WifiConfigManager
+ * .OnNetworkUpdateListener#onNetworkTemporarilyDisabled(WifiConfiguration, int)} is invoked.
+ */
+ @Test
+ public void testOnNetworkTemporarilyDisabledWithNoInternet() throws Exception {
+ connect();
+
+ WifiConfiguration disabledNetwork = new WifiConfiguration();
+ disabledNetwork.networkId = FRAMEWORK_NETWORK_ID;
+ mConfigUpdateListenerCaptor.getValue().onNetworkTemporarilyDisabled(disabledNetwork,
+ WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY);
mLooper.dispatchAll();
- verify(mWifiNative).simIdentityResponse(WIFI_IFACE_NAME, FRAMEWORK_NETWORK_ID,
- "13214561234567890@wlan.mnc456.mcc321.3gppnetwork.org", "");
+ assertEquals("ConnectedState", getCurrentState().getName());
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java
index 867b8ab09e..e94d307b93 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java
@@ -17,9 +17,7 @@
package com.android.server.wifi;
import static android.net.wifi.WifiManager.EXTRA_PREVIOUS_WIFI_STATE;
-import static android.net.wifi.WifiManager.EXTRA_SCAN_AVAILABLE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_STATE;
-import static android.net.wifi.WifiManager.WIFI_SCAN_AVAILABLE;
import static android.net.wifi.WifiManager.WIFI_STATE_CHANGED_ACTION;
import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
@@ -28,6 +26,7 @@ import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*;
import android.content.Context;
@@ -40,6 +39,7 @@ import android.util.Log;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -49,7 +49,7 @@ import java.util.List;
* Unit tests for {@link ClientModeManager}.
*/
@SmallTest
-public class ClientModeManagerTest {
+public class ClientModeManagerTest extends WifiBaseTest {
private static final String TAG = "ClientModeManagerTest";
private static final String TEST_INTERFACE_NAME = "testif0";
private static final String OTHER_INTERFACE_NAME = "notTestIf";
@@ -62,7 +62,8 @@ public class ClientModeManagerTest {
@Mock WifiMetrics mWifiMetrics;
@Mock WifiNative mWifiNative;
@Mock ClientModeManager.Listener mListener;
- @Mock WifiMonitor mWifiMonitor;
+ @Mock SarManager mSarManager;
+ @Mock WakeupController mWakeupController;
@Mock ClientModeImpl mClientModeImpl;
final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
@@ -79,44 +80,72 @@ public class ClientModeManagerTest {
private ClientModeManager createClientModeManager() {
return new ClientModeManager(mContext, mLooper.getLooper(), mWifiNative, mListener,
- mWifiMetrics, mClientModeImpl);
+ mWifiMetrics, mSarManager, mWakeupController, mClientModeImpl);
}
- private void startClientModeAndVerifyEnabled() throws Exception {
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ private void startClientInScanOnlyModeAndVerifyEnabled() throws Exception {
+ when(mWifiNative.setupInterfaceForClientInScanMode(any()))
+ .thenReturn(TEST_INTERFACE_NAME);
+ mClientModeManager.start();
+ mLooper.dispatchAll();
+
+ verify(mWifiNative).setupInterfaceForClientInScanMode(
+ mInterfaceCallbackCaptor.capture());
+ verify(mClientModeImpl).setOperationalMode(
+ ClientModeImpl.SCAN_ONLY_MODE, TEST_INTERFACE_NAME);
+ verify(mSarManager).setScanOnlyWifiState(WIFI_STATE_ENABLED);
+
+ // now mark the interface as up
+ mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME);
+ mLooper.dispatchAll();
+
+ // Ensure that no public broadcasts were sent.
+ verifyNoMoreInteractions(mContext);
+ verify(mListener).onStarted();
+ }
- when(mWifiNative.setupInterfaceForClientInConnectivityMode(any()))
+ private void startClientInConnectModeAndVerifyEnabled() throws Exception {
+ when(mWifiNative.setupInterfaceForClientInScanMode(any()))
.thenReturn(TEST_INTERFACE_NAME);
+ when(mWifiNative.switchClientInterfaceToConnectivityMode(any()))
+ .thenReturn(true);
mClientModeManager.start();
mLooper.dispatchAll();
- verify(mWifiNative).setupInterfaceForClientInConnectivityMode(
+ verify(mWifiNative).setupInterfaceForClientInScanMode(
mInterfaceCallbackCaptor.capture());
+ verify(mClientModeImpl).setOperationalMode(
+ ClientModeImpl.SCAN_ONLY_MODE, TEST_INTERFACE_NAME);
+ mLooper.dispatchAll();
+
+ mClientModeManager.switchToConnectMode();
+ mLooper.dispatchAll();
+
+ verify(mWifiNative).switchClientInterfaceToConnectivityMode(TEST_INTERFACE_NAME);
+ verify(mClientModeImpl).setOperationalMode(
+ ClientModeImpl.CONNECT_MODE, TEST_INTERFACE_NAME);
+ verify(mSarManager).setClientWifiState(WIFI_STATE_ENABLED);
// now mark the interface as up
mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
List<Intent> intents = intentCaptor.getAllValues();
assertEquals(2, intents.size());
Log.d(TAG, "captured intents: " + intents);
- checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, WIFI_STATE_DISABLED);
- checkWifiStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED, WIFI_STATE_ENABLING);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING,
+ WIFI_STATE_DISABLED);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED,
+ WIFI_STATE_ENABLING);
- checkWifiStateChangeListenerUpdate(WIFI_STATE_ENABLED);
+ verify(mListener, times(2)).onStarted();
}
- private void checkWifiScanStateChangedBroadcast(Intent intent, int expectedCurrentState) {
- String action = intent.getAction();
- assertEquals(WIFI_SCAN_AVAILABLE, action);
- int currentState = intent.getIntExtra(EXTRA_SCAN_AVAILABLE, WIFI_STATE_UNKNOWN);
- assertEquals(expectedCurrentState, currentState);
- }
-
- private void checkWifiStateChangedBroadcast(
+ private void checkWifiConnectModeStateChangedBroadcast(
Intent intent, int expectedCurrentState, int expectedPrevState) {
String action = intent.getAction();
assertEquals(WIFI_STATE_CHANGED_ACTION, action);
@@ -128,80 +157,135 @@ public class ClientModeManagerTest {
verify(mClientModeImpl, atLeastOnce()).setWifiStateForApiCalls(expectedCurrentState);
}
-
- private void checkWifiStateChangeListenerUpdate(int expectedCurrentState) {
- verify(mListener).onStateChanged(eq(expectedCurrentState));
- }
-
- private void verifyNotificationsForCleanShutdown(int fromState) {
+ private void verifyConnectModeNotificationsForCleanShutdown(int fromState) {
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeastOnce())
.sendStickyBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL));
List<Intent> intents = intentCaptor.getAllValues();
- assertEquals(2, intents.size());
- checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLING, fromState);
- checkWifiStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED, WIFI_STATE_DISABLING);
+ assertTrue(intents.size() >= 2);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(intents.size() - 2),
+ WIFI_STATE_DISABLING, fromState);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(intents.size() - 1),
+ WIFI_STATE_DISABLED, WIFI_STATE_DISABLING);
}
- private void verifyNotificationsForFailure() {
+ private void verifyConnectModeNotificationsForFailure() {
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeastOnce())
.sendStickyBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL));
List<Intent> intents = intentCaptor.getAllValues();
assertEquals(2, intents.size());
- checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLING, WIFI_STATE_UNKNOWN);
- checkWifiStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED, WIFI_STATE_DISABLING);
- checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLING,
+ WIFI_STATE_UNKNOWN);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED,
+ WIFI_STATE_DISABLING);
}
/**
* ClientMode start sets up an interface in ClientMode.
*/
@Test
- public void clientModeStartCreatesClientInterface() throws Exception {
- startClientModeAndVerifyEnabled();
+ public void clientInConnectModeStartCreatesClientInterface() throws Exception {
+ startClientInConnectModeAndVerifyEnabled();
}
/**
- * ClientMode increments failure metrics when failing to setup client mode.
+ * ClientMode start sets up an interface in ClientMode.
*/
@Test
- public void detectAndReportErrorWhenSetupForClientWifiNativeFailure() throws Exception {
- when(mWifiNative.setupInterfaceForClientInConnectivityMode(any())).thenReturn(null);
- mClientModeManager.start();
+ public void clientInScanOnlyModeStartCreatesClientInterface() throws Exception {
+ startClientInScanOnlyModeAndVerifyEnabled();
+ }
+
+ /**
+ * Switch ClientModeManager from ScanOnly mode To Connect mode.
+ */
+ @Test
+ public void switchFromScanOnlyModeToConnectMode() throws Exception {
+ startClientInScanOnlyModeAndVerifyEnabled();
+
+ when(mWifiNative.switchClientInterfaceToConnectivityMode(any()))
+ .thenReturn(true);
+ mClientModeManager.switchToConnectMode();
mLooper.dispatchAll();
+ verify(mSarManager).setScanOnlyWifiState(WIFI_STATE_DISABLED);
+ verify(mClientModeImpl).setOperationalMode(
+ ClientModeImpl.SCAN_ONLY_MODE, TEST_INTERFACE_NAME);
+ verify(mClientModeImpl).setOperationalMode(
+ ClientModeImpl.CONNECT_MODE, TEST_INTERFACE_NAME);
+ verify(mSarManager).setClientWifiState(WIFI_STATE_ENABLED);
+
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
+
List<Intent> intents = intentCaptor.getAllValues();
assertEquals(2, intents.size());
- checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, WIFI_STATE_DISABLED);
- checkWifiStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED, WIFI_STATE_UNKNOWN);
- checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
+ Log.d(TAG, "captured intents: " + intents);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING,
+ WIFI_STATE_DISABLED);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED,
+ WIFI_STATE_ENABLING);
+
+ verify(mListener, times(2)).onStarted();
}
/**
- * ClientMode start does not indicate scanning is available when the interface name is empty.
+ * Switch ClientModeManager from Connect mode to ScanOnly mode.
*/
@Test
- public void clientModeStartDoesNotSendScanningActiveWhenClientInterfaceNameIsEmpty()
+ public void switchFromConnectModeToScanOnlyMode() throws Exception {
+ startClientInConnectModeAndVerifyEnabled();
+
+ when(mWifiNative.switchClientInterfaceToScanMode(any()))
+ .thenReturn(true);
+ mClientModeManager.switchToScanOnlyMode();
+ mLooper.dispatchAll();
+
+ verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
+
+ verify(mSarManager).setClientWifiState(WIFI_STATE_DISABLED);
+ verify(mWifiNative).setupInterfaceForClientInScanMode(
+ mInterfaceCallbackCaptor.capture());
+ verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME);
+ verify(mClientModeImpl, times(2)).setOperationalMode(
+ ClientModeImpl.SCAN_ONLY_MODE, TEST_INTERFACE_NAME);
+ verify(mSarManager, times(2)).setScanOnlyWifiState(WIFI_STATE_ENABLED);
+
+ // Ensure that no public broadcasts were sent.
+ verifyNoMoreInteractions(mContext);
+ verify(mListener, times(3)).onStarted();
+ }
+
+ /**
+ * ClientMode increments failure metrics when failing to setup client mode in connectivity mode.
+ */
+ @Test
+ public void detectAndReportErrorWhenSetupForClientInConnectivityModeWifiNativeFailure()
throws Exception {
- when(mWifiNative.setupInterfaceForClientInConnectivityMode(any())).thenReturn("");
+ when(mWifiNative.setupInterfaceForClientInScanMode(any()))
+ .thenReturn(TEST_INTERFACE_NAME);
+ when(mWifiNative.switchClientInterfaceToConnectivityMode(any())).thenReturn(false);
+
mClientModeManager.start();
mLooper.dispatchAll();
+ mClientModeManager.switchToConnectMode();
+ mLooper.dispatchAll();
+
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
-
List<Intent> intents = intentCaptor.getAllValues();
assertEquals(2, intents.size());
- checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, WIFI_STATE_DISABLED);
- checkWifiStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED, WIFI_STATE_UNKNOWN);
- checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING,
+ WIFI_STATE_DISABLED);
+ checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED,
+ WIFI_STATE_UNKNOWN);
+ verify(mListener).onStartFailure();
}
/**
@@ -209,7 +293,7 @@ public class ClientModeManagerTest {
*/
@Test
public void clientModeStartCalledTwice() throws Exception {
- startClientModeAndVerifyEnabled();
+ startClientInConnectModeAndVerifyEnabled();
reset(mWifiNative, mContext);
mClientModeManager.start();
mLooper.dispatchAll();
@@ -221,12 +305,13 @@ public class ClientModeManagerTest {
*/
@Test
public void clientModeStopCleansUpState() throws Exception {
- startClientModeAndVerifyEnabled();
+ startClientInConnectModeAndVerifyEnabled();
reset(mContext, mListener);
mClientModeManager.stop();
mLooper.dispatchAll();
+ verify(mListener).onStopped();
- verifyNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
+ verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
// on an explicit stop, we should not trigger the callback
verifyNoMoreInteractions(mListener);
@@ -237,18 +322,18 @@ public class ClientModeManagerTest {
*/
@Test
public void clientModeStopWhenNotStartedDoesNotUpdateScanStateUpdates() throws Exception {
- startClientModeAndVerifyEnabled();
+ startClientInConnectModeAndVerifyEnabled();
reset(mContext);
mClientModeManager.stop();
mLooper.dispatchAll();
- verifyNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
+ verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
reset(mContext, mListener);
// now call stop again
mClientModeManager.stop();
mLooper.dispatchAll();
verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
- verify(mListener, never()).onStateChanged(anyInt());
+ verifyNoMoreInteractions(mListener);
}
/**
@@ -256,13 +341,14 @@ public class ClientModeManagerTest {
*/
@Test
public void clientModeStartedStopsWhenInterfaceDown() throws Exception {
- startClientModeAndVerifyEnabled();
+ startClientInConnectModeAndVerifyEnabled();
reset(mContext);
when(mClientModeImpl.isConnectedMacRandomizationEnabled()).thenReturn(false);
mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
verify(mClientModeImpl).failureDetected(eq(SelfRecovery.REASON_STA_IFACE_DOWN));
- verifyNotificationsForFailure();
+ verifyConnectModeNotificationsForFailure();
+ verify(mListener).onStopped();
}
/**
@@ -272,7 +358,7 @@ public class ClientModeManagerTest {
@Test
public void clientModeStartedWithConnectedMacRandDoesNotStopWhenInterfaceDown()
throws Exception {
- startClientModeAndVerifyEnabled();
+ startClientInConnectModeAndVerifyEnabled();
reset(mContext);
when(mClientModeImpl.isConnectedMacRandomizationEnabled()).thenReturn(true);
mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
@@ -286,12 +372,13 @@ public class ClientModeManagerTest {
*/
@Test
public void clientModeStartedStopsOnInterfaceDestroyed() throws Exception {
- startClientModeAndVerifyEnabled();
+ startClientInConnectModeAndVerifyEnabled();
reset(mContext);
mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
- verifyNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
+ verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
verify(mClientModeImpl).handleIfaceDestroyed();
+ verify(mListener).onStopped();
}
/**
@@ -299,7 +386,7 @@ public class ClientModeManagerTest {
*/
@Test
public void noCallbackOnInterfaceDestroyedWhenAlreadyStopped() throws Exception {
- startClientModeAndVerifyEnabled();
+ startClientInConnectModeAndVerifyEnabled();
reset(mListener);
@@ -309,8 +396,37 @@ public class ClientModeManagerTest {
// now trigger interface destroyed and make sure callback doesn't get called
mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
+ verify(mListener).onStopped();
verifyNoMoreInteractions(mListener);
verify(mClientModeImpl, never()).handleIfaceDestroyed();
}
+
+ /**
+ * Entering ScanOnly state starts the WakeupController.
+ */
+ @Test
+ public void scanModeEnterStartsWakeupController() throws Exception {
+ startClientInScanOnlyModeAndVerifyEnabled();
+
+ verify(mWakeupController).start();
+ }
+
+ /**
+ * Exiting ScanOnly state stops the WakeupController.
+ */
+ @Test
+ public void scanModeExitStopsWakeupController() throws Exception {
+ startClientInScanOnlyModeAndVerifyEnabled();
+
+ mClientModeManager.stop();
+ mLooper.dispatchAll();
+
+ InOrder inOrder = inOrder(mWakeupController, mWifiNative, mListener);
+
+ inOrder.verify(mListener).onStarted();
+ inOrder.verify(mWakeupController).start();
+ inOrder.verify(mWakeupController).stop();
+ inOrder.verify(mWifiNative).teardownInterface(eq(TEST_INTERFACE_NAME));
+ }
}
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 3f3bbe6e72..871218f1f1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java
@@ -30,6 +30,7 @@ public final class ConcreteCandidate implements WifiCandidates.Candidate {
private boolean mIsPasspoint;
private boolean mIsEphemeral;
private boolean mIsTrusted;
+ private boolean mIsMetered;
private int mEvaluatorId = -1;
private int mEvaluatorScore = Integer.MIN_VALUE;
private double mLastSelectionWeight;
@@ -51,6 +52,7 @@ public final class ConcreteCandidate implements WifiCandidates.Candidate {
mIsPasspoint = candidate.isPasspoint();
mIsEphemeral = candidate.isEphemeral();
mIsTrusted = candidate.isTrusted();
+ mIsMetered = candidate.isMetered();
mEvaluatorId = candidate.getEvaluatorId();
mEvaluatorScore = candidate.getEvaluatorScore();
mLastSelectionWeight = candidate.getLastSelectionWeight();
@@ -134,6 +136,16 @@ public final class ConcreteCandidate implements WifiCandidates.Candidate {
return mIsTrusted;
}
+ public ConcreteCandidate setMetered(boolean isMetered) {
+ mIsMetered = isMetered;
+ return this;
+ }
+
+ @Override
+ public boolean isMetered() {
+ return mIsMetered;
+ }
+
public ConcreteCandidate setEvaluatorId(int evaluatorId) {
mEvaluatorId = evaluatorId;
return this;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java b/service/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
index 97141c4963..0b3cc45e88 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
@@ -19,10 +19,9 @@ package com.android.server.wifi;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.when;
-import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.pm.UserInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
@@ -48,7 +47,8 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.ConfigurationMapTest}.
*/
@SmallTest
-public class ConfigurationMapTest {
+public class ConfigurationMapTest extends WifiBaseTest {
+ private static final int SYSTEM_MANAGE_PROFILE_USER_ID = 12;
private static final List<WifiConfiguration> CONFIGS = Arrays.asList(
WifiConfigurationTestUtil.generateWifiConfig(
0, 1000000, "\"red\"", true, true, null, null),
@@ -67,7 +67,7 @@ public class ConfigurationMapTest {
static {
USER_PROFILES.put(UserHandle.USER_SYSTEM, Arrays.asList(
new UserInfo(UserHandle.USER_SYSTEM, "Owner", 0),
- new UserInfo(12, "Managed Profile", 0)));
+ new UserInfo(SYSTEM_MANAGE_PROFILE_USER_ID, "Managed Profile", 0)));
USER_PROFILES.put(10, Arrays.asList(new UserInfo(10, "Alice", 0)));
USER_PROFILES.put(11, Arrays.asList(new UserInfo(11, "Bob", 0)));
}
@@ -84,12 +84,15 @@ public class ConfigurationMapTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mUserManager.getProfiles(anyInt()))
- .then(new AnswerWithArguments() {
- public List<UserInfo> answer(int userId) {
- return USER_PROFILES.get(userId);
- }
- });
+ // by default, return false
+ when(mUserManager.isSameProfileGroup(any(), any())).thenReturn(false);
+ // return true for these 2 userids
+ when(mUserManager.isSameProfileGroup(UserHandle.SYSTEM,
+ UserHandle.of(SYSTEM_MANAGE_PROFILE_USER_ID)))
+ .thenReturn(true);
+ when(mUserManager.isSameProfileGroup(UserHandle.of(SYSTEM_MANAGE_PROFILE_USER_ID),
+ UserHandle.SYSTEM))
+ .thenReturn(true);
mConfigs = new ConfigurationMap(mUserManager);
}
@@ -133,8 +136,10 @@ public class ConfigurationMapTest {
// user. Also, check that *ForAllUsers() methods can be used to access all network
// configurations, irrespective of their visibility to the current user.
for (WifiConfiguration config : configs) {
- if (WifiConfigurationUtil.isVisibleToAnyProfile(config,
- USER_PROFILES.get(mCurrentUserId))) {
+ final UserHandle currentUser = UserHandle.of(mCurrentUserId);
+ final UserHandle creatorUser = UserHandle.getUserHandleForUid(config.creatorUid);
+ if (config.shared || currentUser.equals(creatorUser)
+ || mUserManager.isSameProfileGroup(currentUser, creatorUser)) {
configsForCurrentUser.add(config);
if (config.status != WifiConfiguration.Status.DISABLED) {
enabledConfigsForCurrentUser.add(config);
@@ -228,7 +233,7 @@ public class ConfigurationMapTest {
final WifiConfiguration config1 = CONFIGS.get(0);
// Verify that there are no network configurations to start with.
- switchUser(UserHandle.getUserId(config1.creatorUid));
+ switchUser(UserHandle.getUserHandleForUid(config1.creatorUid).getIdentifier());
verifyGetters(configs);
// Add |config1|.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java
index 702aa99dff..9829427e36 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java
@@ -42,7 +42,7 @@ import java.util.Map;
* Unit tests for {@link com.android.server.wifi.DeletedEphemeralSsidsStoreData}.
*/
@SmallTest
-public class DeletedEphemeralSsidsStoreDataTest {
+public class DeletedEphemeralSsidsStoreDataTest extends WifiBaseTest {
private static final String TEST_SSID1 = "SSID 1";
private static final String TEST_SSID2 = "SSID 2";
private static final long TEST_SSID1_TSTAMP = 6837367L;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java b/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
new file mode 100644
index 0000000000..1c04b7439f
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.*;
+import static org.mockito.MockitoAnnotations.*;
+
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
+import android.content.Context;
+import android.os.Handler;
+import android.os.test.TestLooper;
+import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.OnPropertiesChangedListener;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+
+
+/**
+ * Unit tests for {@link com.android.server.wifi.DeviceConfigFacade}.
+ */
+@SmallTest
+public class DeviceConfigFacadeTest extends WifiBaseTest {
+ @Mock Context mContext;
+ @Mock WifiMetrics mWifiMetrics;
+
+ final ArgumentCaptor<OnPropertiesChangedListener> mOnPropertiesChangedListenerCaptor =
+ ArgumentCaptor.forClass(OnPropertiesChangedListener.class);
+
+ private DeviceConfigFacade mDeviceConfigFacade;
+ private TestLooper mLooper = new TestLooper();
+ private MockResources mResources;
+ private MockitoSession mSession;
+
+ /**
+ * Setup the mocks and an instance of WifiConfigManager before each test.
+ */
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mResources = new MockResources();
+ mResources.setBoolean(
+ R.bool.config_wifi_aggressive_randomization_ssid_whitelist_enabled, false);
+ when(mContext.getResources()).thenReturn(mResources);
+
+ // static mocking
+ mSession = ExtendedMockito.mockitoSession()
+ .mockStatic(DeviceConfig.class, withSettings().lenient())
+ .startMocking();
+ // Have DeviceConfig return the default value passed in.
+ when(DeviceConfig.getBoolean(anyString(), anyString(), anyBoolean()))
+ .then(new AnswerWithArguments() {
+ public boolean answer(String namespace, String field, boolean def) {
+ return def;
+ }
+ });
+ when(DeviceConfig.getInt(anyString(), anyString(), anyInt()))
+ .then(new AnswerWithArguments() {
+ public int answer(String namespace, String field, int def) {
+ return def;
+ }
+ });
+
+ mDeviceConfigFacade = new DeviceConfigFacade(mContext, new Handler(mLooper.getLooper()),
+ mWifiMetrics);
+ verify(() -> DeviceConfig.addOnPropertiesChangedListener(anyString(), any(),
+ mOnPropertiesChangedListenerCaptor.capture()));
+ }
+
+ /**
+ * Called after each test
+ */
+ @After
+ public void cleanup() {
+ validateMockitoUsage();
+ mSession.finishMocking();
+ }
+
+ /**
+ * Verifies that all fields are updated properly.
+ */
+ @Test
+ public void testFieldUpdates() throws Exception {
+ // First verify fields are set to their default values.
+ assertEquals(false, mDeviceConfigFacade.isAbnormalConnectionBugreportEnabled());
+ assertEquals(DeviceConfigFacade.DEFAULT_ABNORMAL_CONNECTION_DURATION_MS,
+ mDeviceConfigFacade.getAbnormalConnectionDurationMs());
+ assertEquals(false,
+ mDeviceConfigFacade.isAggressiveMacRandomizationSsidWhitelistEnabled());
+ assertEquals(DeviceConfigFacade.DEFAULT_DATA_STALL_DURATION_MS,
+ mDeviceConfigFacade.getDataStallDurationMs());
+ assertEquals(DeviceConfigFacade.DEFAULT_DATA_STALL_TX_TPUT_THR_KBPS,
+ mDeviceConfigFacade.getDataStallTxTputThrKbps());
+ assertEquals(DeviceConfigFacade.DEFAULT_DATA_STALL_RX_TPUT_THR_KBPS,
+ mDeviceConfigFacade.getDataStallRxTputThrKbps());
+ assertEquals(DeviceConfigFacade.DEFAULT_DATA_STALL_TX_PER_THR,
+ mDeviceConfigFacade.getDataStallTxPerThr());
+ assertEquals(DeviceConfigFacade.DEFAULT_DATA_STALL_CCA_LEVEL_THR,
+ mDeviceConfigFacade.getDataStallCcaLevelThr());
+
+ // Simulate updating the fields
+ when(DeviceConfig.getBoolean(anyString(), eq("abnormal_connection_bugreport_enabled"),
+ anyBoolean())).thenReturn(true);
+ when(DeviceConfig.getInt(anyString(), eq("abnormal_connection_duration_ms"),
+ anyInt())).thenReturn(100);
+ when(DeviceConfig.getBoolean(anyString(),
+ eq("aggressive_randomization_ssid_whitelist_enabled"),
+ anyBoolean())).thenReturn(true);
+ when(DeviceConfig.getInt(anyString(), eq("data_stall_duration_ms"),
+ anyInt())).thenReturn(0);
+ when(DeviceConfig.getInt(anyString(), eq("data_stall_tx_tput_thr_kbps"),
+ anyInt())).thenReturn(1000);
+ when(DeviceConfig.getInt(anyString(), eq("data_stall_rx_tput_thr_kbps"),
+ anyInt())).thenReturn(1500);
+ when(DeviceConfig.getInt(anyString(), eq("data_stall_tx_per_thr"),
+ anyInt())).thenReturn(95);
+ when(DeviceConfig.getInt(anyString(), eq("data_stall_cca_level_thr"),
+ anyInt())).thenReturn(80);
+ mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
+
+ // Verifying fields are updated to the new values
+ assertEquals(true, mDeviceConfigFacade.isAbnormalConnectionBugreportEnabled());
+ assertEquals(100, mDeviceConfigFacade.getAbnormalConnectionDurationMs());
+ assertEquals(true, mDeviceConfigFacade.isAggressiveMacRandomizationSsidWhitelistEnabled());
+ assertEquals(0, mDeviceConfigFacade.getDataStallDurationMs());
+ assertEquals(1000, mDeviceConfigFacade.getDataStallTxTputThrKbps());
+ assertEquals(1500, mDeviceConfigFacade.getDataStallRxTputThrKbps());
+ assertEquals(95, mDeviceConfigFacade.getDataStallTxPerThr());
+ assertEquals(80, mDeviceConfigFacade.getDataStallCcaLevelThr());
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java
index ee1264a9e4..9aaaca28a2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java
@@ -54,6 +54,7 @@ import android.content.Context;
import android.net.wifi.EasyConnectStatusCallback;
import android.net.wifi.IDppCallback;
import android.net.wifi.WifiConfiguration;
+import android.os.Handler;
import android.os.IBinder;
import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
@@ -70,7 +71,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link DppManager}.
*/
@SmallTest
-public class DppManagerTest {
+public class DppManagerTest extends WifiBaseTest {
private static final String TAG = "DppManagerTest";
private static final String TEST_INTERFACE_NAME = "testif0";
private static final int TEST_PEER_ID = 1;
@@ -133,8 +134,8 @@ public class DppManagerTest {
}
private DppManager createDppManager() {
- DppManager dppManger = new DppManager(mLooper.getLooper(), mWifiNative, mWifiConfigManager,
- mContext, mDppMetrics);
+ DppManager dppManger = new DppManager(new Handler(mLooper.getLooper()), mWifiNative,
+ mWifiConfigManager, mContext, mDppMetrics);
dppManger.mDppTimeoutMessage = mWakeupMessage;
dppManger.enableVerboseLogging(1);
return dppManger;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java b/service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java
index e3b980256e..303c6e7d7b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java
@@ -47,7 +47,7 @@ import java.util.Random;
* Unit tests for {@link com.android.server.wifi.DppMetrics}.
*/
@SmallTest
-public class DppMetricsTest {
+public class DppMetricsTest extends WifiBaseTest {
private static final int MAX_ITERATIONS = 30;
private DppMetrics mDppMetrics = new DppMetrics();
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 36da41bd3a..2e68864936 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
@@ -85,7 +85,7 @@ import java.util.Set;
* Unit test harness for HalDeviceManagerTest.
*/
@SmallTest
-public class HalDeviceManagerTest {
+public class HalDeviceManagerTest extends WifiBaseTest {
private HalDeviceManager mDut;
@Mock IServiceManager mServiceManagerMock;
@Mock IWifi mWifiMock;
@@ -107,7 +107,7 @@ public class HalDeviceManagerTest {
private class HalDeviceManagerSpy extends HalDeviceManager {
HalDeviceManagerSpy() {
- super(mClock, mTestLooper.getLooper());
+ super(mClock, mHandler);
}
@Override
diff --git a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
index 2cf8f222fd..e2a32272f7 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
@@ -31,6 +31,7 @@ import android.hardware.wifi.hostapd.V1_1.IHostapdCallback;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
import android.net.wifi.WifiConfiguration;
+import android.os.Handler;
import android.os.IHwBinder;
import android.os.RemoteException;
import android.os.test.TestLooper;
@@ -53,7 +54,7 @@ import java.util.ArrayList;
* Unit tests for HostapdHal
*/
@SmallTest
-public class HostapdHalTest {
+public class HostapdHalTest extends WifiBaseTest {
private static final String IFACE_NAME = "mock-wlan0";
private static final String NETWORK_SSID = "test-ssid";
private static final String NETWORK_PSK = "test-psk";
@@ -88,7 +89,7 @@ public class HostapdHalTest {
private class HostapdHalSpy extends HostapdHal {
HostapdHalSpy() {
- super(mContext, mLooper.getLooper());
+ super(mContext, new Handler(mLooper.getLooper()));
}
@Override
diff --git a/service/tests/wifitests/src/com/android/server/wifi/IMSIParameterTest.java b/service/tests/wifitests/src/com/android/server/wifi/IMSIParameterTest.java
index c87f2b3f98..522dba32e6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/IMSIParameterTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/IMSIParameterTest.java
@@ -31,7 +31,7 @@ import java.util.Map;
* Unit tests for {@link com.android.server.wifi.IMSIParameter}.
*/
@SmallTest
-public class IMSIParameterTest {
+public class IMSIParameterTest extends WifiBaseTest {
/**
* Data points for testing function {@link IMSIParameter#build}.
*/
diff --git a/service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java b/service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java
index 0180d6a04d..6d76f4a858 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java
@@ -24,10 +24,10 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
-import android.os.FileUtils;
-
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.util.FileUtils;
+
import libcore.io.IoUtils;
import org.junit.Before;
@@ -44,7 +44,7 @@ import java.io.StringWriter;
* Unit tests for {@link LastMileLogger}.
*/
@SmallTest
-public class LastMileLoggerTest {
+public class LastMileLoggerTest extends WifiBaseTest {
@Mock WifiInjector mWifiInjector;
@Spy FakeWifiLog mLog;
@@ -58,7 +58,7 @@ public class LastMileLoggerTest {
mTraceDataFile.deleteOnExit();
mTraceEnableFile.deleteOnExit();
mTraceReleaseFile.deleteOnExit();
- FileUtils.stringToFile(mTraceEnableFile, "0");
+ FileUtils.stringToFile(mTraceEnableFile.getPath(), "0");
mLastMileLogger = new LastMileLogger(mWifiInjector, mTraceDataFile.getPath(),
mTraceEnableFile.getPath(), mTraceReleaseFile.getPath());
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java
index 32eb78d8cd..91692be323 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.database.ContentObserver;
import android.net.wifi.WifiInfo;
+import android.os.Handler;
import android.os.test.TestLooper;
import android.provider.Settings;
@@ -50,7 +51,7 @@ import java.util.HashSet;
* Unit tests for LinkProbeManager
*/
@SmallTest
-public class LinkProbeManagerTest {
+public class LinkProbeManagerTest extends WifiBaseTest {
private static final String TEST_IFACE_NAME = "testIfaceName";
private static final String TEST_BSSID = "6c:f3:7f:ae:8c:f3";
@@ -98,7 +99,7 @@ public class LinkProbeManagerTest {
private void initLinkProbeManager() {
mLinkProbeManager = new LinkProbeManager(mClock, mWifiNative, mWifiMetrics,
- mFrameworkFacade, mLooper.getLooper(), mContext);
+ mFrameworkFacade, new Handler(mLooper.getLooper()), mContext);
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/LocalOnlyHotspotRequestInfoTest.java b/service/tests/wifitests/src/com/android/server/wifi/LocalOnlyHotspotRequestInfoTest.java
index e0d2b5fdd8..b90332ad26 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/LocalOnlyHotspotRequestInfoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/LocalOnlyHotspotRequestInfoTest.java
@@ -19,15 +19,12 @@ package com.android.server.wifi;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
+import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
-import android.os.Handler;
import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
import android.os.Process;
import android.os.RemoteException;
-import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
@@ -40,14 +37,12 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.LocalOnlyHotspotRequestInfo}.
*/
@SmallTest
-public class LocalOnlyHotspotRequestInfoTest {
+public class LocalOnlyHotspotRequestInfoTest extends WifiBaseTest {
private static final String TAG = "LocalOnlyHotspotRequestInfoTest";
@Mock IBinder mAppBinder;
- @Mock LocalOnlyHotspotRequestInfo.RequestingApplicationDeathCallback mCallback;
- private Handler mHandler;
- private Messenger mMessenger;
- private TestLooper mTestLooper;
+ @Mock ILocalOnlyHotspotCallback mCallback;
+ @Mock LocalOnlyHotspotRequestInfo.RequestingApplicationDeathCallback mDeathCallback;
RemoteException mRemoteException;
private LocalOnlyHotspotRequestInfo mLOHSRequestInfo;
@@ -57,9 +52,7 @@ public class LocalOnlyHotspotRequestInfoTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mTestLooper = new TestLooper();
- mHandler = new Handler(mTestLooper.getLooper());
- mMessenger = new Messenger(mHandler);
+ when(mCallback.asBinder()).thenReturn(mAppBinder);
mRemoteException = new RemoteException("Test Remote Exception");
}
@@ -69,32 +62,24 @@ public class LocalOnlyHotspotRequestInfoTest {
*/
@Test
public void verifyBinderLinkToDeathIsCalled() throws Exception {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, mMessenger, mCallback);
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mCallback, mDeathCallback);
verify(mAppBinder).linkToDeath(eq(mLOHSRequestInfo), eq(0));
}
/**
- * Calls to create the requestor to binder death should not pass null callback.
+ * Calls to link the requestor to binder death should not pass null binder
*/
@Test(expected = NullPointerException.class)
public void verifyNullCallbackChecked() throws Exception {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, mMessenger, null);
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(null, mDeathCallback);
}
/**
- * Calls to create the request info object should not pass a null messenger.
- */
- @Test(expected = NullPointerException.class)
- public void verifyNullMessengerChecked() throws Exception {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, null, mCallback);
- }
-
- /**
- * Calls to link the requestor to binder death should not pass null binder
+ * Calls to create the requestor to binder death should not pass null death callback.
*/
@Test(expected = NullPointerException.class)
- public void verifyNullBinderChecked() throws Exception {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(null, mMessenger, mCallback);
+ public void verifyNullDeathCallbackChecked() throws Exception {
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mCallback, null);
}
/**
@@ -102,7 +87,7 @@ public class LocalOnlyHotspotRequestInfoTest {
*/
@Test
public void verifyUnlinkDeathRecipientUnlinksFromBinder() throws Exception {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, mMessenger, mCallback);
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mCallback, mDeathCallback);
mLOHSRequestInfo.unlinkDeathRecipient();
verify(mAppBinder).unlinkToDeath(eq(mLOHSRequestInfo), eq(0));
}
@@ -112,9 +97,9 @@ public class LocalOnlyHotspotRequestInfoTest {
*/
@Test
public void verifyBinderDeathTriggersCallback() {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, mMessenger, mCallback);
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mCallback, mDeathCallback);
mLOHSRequestInfo.binderDied();
- verify(mCallback).onLocalOnlyHotspotRequestorDeath(eq(mLOHSRequestInfo));
+ verify(mDeathCallback).onLocalOnlyHotspotRequestorDeath(eq(mLOHSRequestInfo));
}
/**
@@ -124,8 +109,8 @@ public class LocalOnlyHotspotRequestInfoTest {
public void verifyRemoteExceptionTriggersCallback() throws Exception {
doThrow(mRemoteException).when(mAppBinder)
.linkToDeath(any(IBinder.DeathRecipient.class), eq(0));
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, mMessenger, mCallback);
- verify(mCallback).onLocalOnlyHotspotRequestorDeath(eq(mLOHSRequestInfo));
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mCallback, mDeathCallback);
+ verify(mDeathCallback).onLocalOnlyHotspotRequestorDeath(eq(mLOHSRequestInfo));
}
/**
@@ -133,7 +118,7 @@ public class LocalOnlyHotspotRequestInfoTest {
*/
@Test
public void verifyPid() {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, mMessenger, mCallback);
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mCallback, mDeathCallback);
assertEquals(Process.myPid(), mLOHSRequestInfo.getPid());
}
@@ -142,12 +127,10 @@ public class LocalOnlyHotspotRequestInfoTest {
*/
@Test
public void verifySendFailedMessage() throws Exception {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, mMessenger, mCallback);
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mCallback, mDeathCallback);
mLOHSRequestInfo.sendHotspotFailedMessage(
WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC);
- Message message = mTestLooper.nextMessage();
- assertEquals(WifiManager.HOTSPOT_FAILED, message.what);
- assertEquals(WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC, message.arg1);
+ verify(mCallback).onHotspotFailed(WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC);
}
/**
@@ -155,12 +138,10 @@ public class LocalOnlyHotspotRequestInfoTest {
*/
@Test
public void verifySendStartedMessage() throws Exception {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, mMessenger, mCallback);
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mCallback, mDeathCallback);
WifiConfiguration config = mock(WifiConfiguration.class);
mLOHSRequestInfo.sendHotspotStartedMessage(config);
- Message message = mTestLooper.nextMessage();
- assertEquals(WifiManager.HOTSPOT_STARTED, message.what);
- assertEquals(config, (WifiConfiguration) message.obj);
+ verify(mCallback).onHotspotStarted(config);
}
/**
@@ -168,9 +149,8 @@ public class LocalOnlyHotspotRequestInfoTest {
*/
@Test
public void verifySendStoppedMessage() throws Exception {
- mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mAppBinder, mMessenger, mCallback);
+ mLOHSRequestInfo = new LocalOnlyHotspotRequestInfo(mCallback, mDeathCallback);
mLOHSRequestInfo.sendHotspotStoppedMessage();
- Message message = mTestLooper.nextMessage();
- assertEquals(WifiManager.HOTSPOT_STOPPED, message.what);
+ verify(mCallback).onHotspotStopped();
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/LogcatLogTest.java b/service/tests/wifitests/src/com/android/server/wifi/LogcatLogTest.java
index e75404e768..a29c863d8e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/LogcatLogTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/LogcatLogTest.java
@@ -29,7 +29,7 @@ import org.junit.Test;
* Unit tests for {@link LogcatLog}.
*/
@SmallTest
-public class LogcatLogTest {
+public class LogcatLogTest extends WifiBaseTest {
private static final String TAG = "LogcatLogTest";
private LogcatLog mLogger;
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 a4ac1e8c3f..0288dd50a5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/MemoryStoreImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/MemoryStoreImplTest.java
@@ -37,7 +37,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.MemoryStoreImpl}.
*/
@SmallTest
-public class MemoryStoreImplTest {
+public class MemoryStoreImplTest extends WifiBaseTest {
@Mock Context mContext;
@Mock WifiScoreCard mWifiScoreCard;
@Mock WifiScoreCard.BlobListener mBlobListener;
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 7336c41197..6032680b63 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
@@ -52,7 +52,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.NetworkListStoreData}.
*/
@SmallTest
-public class NetworkListStoreDataTest {
+public class NetworkListStoreDataTest extends WifiBaseTest {
private static final String TEST_SSID = "WifiConfigStoreDataSSID_";
private static final String TEST_CONNECT_CHOICE = "XmlUtilConnectChoice";
@@ -68,6 +68,7 @@ public class NetworkListStoreDataTest {
+ "<string name=\"SSID\">%s</string>\n"
+ "<null name=\"BSSID\" />\n"
+ "<null name=\"PreSharedKey\" />\n"
+ + "<null name=\"SaePasswordId\" />\n"
+ "<null name=\"WEPKeys\" />\n"
+ "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+ "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
@@ -123,6 +124,7 @@ public class NetworkListStoreDataTest {
+ "<string name=\"SSID\">%s</string>\n"
+ "<null name=\"BSSID\" />\n"
+ "<null name=\"PreSharedKey\" />\n"
+ + "<null name=\"SaePasswordId\" />\n"
+ "<null name=\"WEPKeys\" />\n"
+ "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+ "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
@@ -186,6 +188,7 @@ public class NetworkListStoreDataTest {
+ "<int name=\"Phase2Method\" value=\"0\" />\n"
+ "<string name=\"PLMN\"></string>\n"
+ "<string name=\"Realm\"></string>\n"
+ + "<int name=\"Ocsp\" value=\"0\" />\n"
+ "</WifiEnterpriseConfiguration>\n"
+ "</Network>\n";
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 f40f71bcfc..16f975bc2e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
@@ -49,7 +49,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.NetworkRequestStoreData}.
*/
@SmallTest
-public class NetworkRequestStoreDataTest {
+public class NetworkRequestStoreDataTest extends WifiBaseTest {
private static final String TEST_PACKAGE_NAME_1 = "com.android.test.1";
private static final String TEST_PACKAGE_NAME_2 = "com.android.test.2";
private static final String TEST_CORRUPT_DATA_INVALID_SSID =
diff --git a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionEvaluatorTest.java b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionEvaluatorTest.java
index fadfc6bc53..d301d6b959 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionEvaluatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionEvaluatorTest.java
@@ -50,7 +50,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.NetworkSuggestionEvaluator}.
*/
@SmallTest
-public class NetworkSuggestionEvaluatorTest {
+public class NetworkSuggestionEvaluatorTest extends WifiBaseTest {
private static final int TEST_UID = 3555;
private static final int TEST_UID_OTHER = 3545;
private static final int TEST_NETWORK_ID = 55;
@@ -435,6 +435,10 @@ public class NetworkSuggestionEvaluatorTest {
appInteractions, meteredness, priorities, uids, packageNames);
// Link the scan result with suggestions.
linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
+ // setup config manager interactions.
+ suggestions[0].wifiConfiguration.fromWifiNetworkSuggestion = true;
+ suggestions[0].wifiConfiguration.ephemeral = true;
+ setupAddToWifiConfigManager(suggestions[0].wifiConfiguration);
// Existing saved network matching the credentials.
when(mWifiConfigManager.getConfiguredNetwork(suggestions[0].wifiConfiguration.configKey()))
.thenReturn(suggestions[0].wifiConfiguration);
@@ -455,6 +459,9 @@ public class NetworkSuggestionEvaluatorTest {
verify(mWifiConfigManager, times(scanSsids.length))
.wasEphemeralNetworkDeleted(anyString());
verify(mWifiConfigManager).getConfiguredNetwork(candidate.configKey());
+ verify(mWifiConfigManager).addOrUpdateNetwork(eq(suggestions[0].wifiConfiguration),
+ eq(suggestions[0].suggestorUid), eq(suggestions[0].suggestorPackageName));
+ verify(mWifiConfigManager).getConfiguredNetwork(suggestions[0].wifiConfiguration.networkId);
// Verify we did not try to add any new networks or other interactions with
// WifiConfigManager.
verifyNoMoreInteractions(mWifiConfigManager);
@@ -538,6 +545,8 @@ public class NetworkSuggestionEvaluatorTest {
// Link the scan result with suggestions.
linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
// setup config manager interactions.
+ suggestions[0].wifiConfiguration.fromWifiNetworkSuggestion = true;
+ suggestions[0].wifiConfiguration.ephemeral = true;
setupAddToWifiConfigManager(suggestions[0].wifiConfiguration);
// Mark the network disabled.
suggestions[0].wifiConfiguration.getNetworkSelectionStatus().setNetworkSelectionStatus(
@@ -560,6 +569,9 @@ public class NetworkSuggestionEvaluatorTest {
.wasEphemeralNetworkDeleted(anyString());
verify(mWifiConfigManager).getConfiguredNetwork(eq(
suggestions[0].wifiConfiguration.configKey()));
+ verify(mWifiConfigManager).addOrUpdateNetwork(eq(suggestions[0].wifiConfiguration),
+ eq(suggestions[0].suggestorUid), eq(suggestions[0].suggestorPackageName));
+ verify(mWifiConfigManager).getConfiguredNetwork(suggestions[0].wifiConfiguration.networkId);
verify(mWifiConfigManager).tryEnableNetwork(eq(
suggestions[0].wifiConfiguration.networkId));
// Verify we did not try to add any new networks or other interactions with
@@ -596,6 +608,8 @@ public class NetworkSuggestionEvaluatorTest {
// Link the scan result with suggestions.
linkScanDetailsWithNetworkSuggestions(scanDetails, suggestions);
// setup config manager interactions.
+ suggestions[0].wifiConfiguration.fromWifiNetworkSuggestion = true;
+ suggestions[0].wifiConfiguration.ephemeral = true;
setupAddToWifiConfigManager(suggestions[0].wifiConfiguration);
// Mark the network disabled.
suggestions[0].wifiConfiguration.getNetworkSelectionStatus().setNetworkSelectionStatus(
@@ -622,6 +636,9 @@ public class NetworkSuggestionEvaluatorTest {
.wasEphemeralNetworkDeleted(anyString());
verify(mWifiConfigManager).getConfiguredNetwork(eq(
suggestions[0].wifiConfiguration.configKey()));
+ verify(mWifiConfigManager).addOrUpdateNetwork(eq(suggestions[0].wifiConfiguration),
+ eq(suggestions[0].suggestorUid), eq(suggestions[0].suggestorPackageName));
+ verify(mWifiConfigManager).getConfiguredNetwork(suggestions[0].wifiConfiguration.networkId);
verify(mWifiConfigManager).tryEnableNetwork(eq(
suggestions[0].wifiConfiguration.networkId));
// Verify we did not try to add any new networks or other interactions with
@@ -727,7 +744,7 @@ public class NetworkSuggestionEvaluatorTest {
configs[i].meteredOverride = meteredness[i]
? WifiConfiguration.METERED_OVERRIDE_METERED
: WifiConfiguration.METERED_OVERRIDE_NONE;
- suggestions[i] = new WifiNetworkSuggestion(configs[i], appInteractions[i],
+ suggestions[i] = new WifiNetworkSuggestion(configs[i], null, appInteractions[i],
false, uids[i], packageNames[i]);
}
return suggestions;
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 5c1dcb459b..97e20fc953 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
@@ -48,7 +48,7 @@ import java.util.Map;
* Unit tests for {@link com.android.server.wifi.NetworkSuggestionStoreData}.
*/
@SmallTest
-public class NetworkSuggestionStoreDataTest {
+public class NetworkSuggestionStoreDataTest extends WifiBaseTest {
private static final int TEST_UID_1 = 14556;
private static final int TEST_UID_2 = 14536;
private static final String TEST_PACKAGE_NAME_1 = "com.android.test.1";
@@ -156,7 +156,7 @@ public class NetworkSuggestionStoreDataTest {
configuration.enterpriseConfig =
WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
WifiNetworkSuggestion networkSuggestion =
- new WifiNetworkSuggestion(configuration, false, false, TEST_UID_1,
+ new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID_1,
TEST_PACKAGE_NAME_1);
appInfo.hasUserApproved = false;
appInfo.extNetworkSuggestions.add(
@@ -186,7 +186,7 @@ public class NetworkSuggestionStoreDataTest {
PerAppInfo appInfo1 = new PerAppInfo(TEST_PACKAGE_NAME_1);
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_NAME_1);
appInfo1.hasUserApproved = false;
appInfo1.extNetworkSuggestions.add(
@@ -195,7 +195,7 @@ public class NetworkSuggestionStoreDataTest {
PerAppInfo appInfo2 = new PerAppInfo(TEST_PACKAGE_NAME_2);
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_2,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_2,
TEST_PACKAGE_NAME_2);
appInfo2.hasUserApproved = true;
appInfo2.extNetworkSuggestions.add(
@@ -214,10 +214,10 @@ public class NetworkSuggestionStoreDataTest {
PerAppInfo appInfo1 = new PerAppInfo(TEST_PACKAGE_NAME_1);
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, true, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, true, TEST_UID_1,
TEST_PACKAGE_NAME_1);
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_NAME_1);
appInfo1.hasUserApproved = true;
appInfo1.extNetworkSuggestions.add(
@@ -228,10 +228,10 @@ public class NetworkSuggestionStoreDataTest {
PerAppInfo appInfo2 = new PerAppInfo(TEST_PACKAGE_NAME_2);
WifiNetworkSuggestion networkSuggestion3 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_2,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_2,
TEST_PACKAGE_NAME_2);
WifiNetworkSuggestion networkSuggestion4 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, true, TEST_UID_2,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, true, TEST_UID_2,
TEST_PACKAGE_NAME_2);
appInfo2.hasUserApproved = true;
appInfo2.extNetworkSuggestions.add(
diff --git a/service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java b/service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
index 5e1e7283cd..e47a182691 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java
@@ -40,9 +40,12 @@ import android.content.Intent;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
+import android.net.wifi.IActionListener;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
+import android.os.Binder;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -67,7 +70,7 @@ import java.util.List;
* Unit tests for {@link OpenNetworkNotifier}.
*/
@SmallTest
-public class OpenNetworkNotifierTest {
+public class OpenNetworkNotifierTest extends WifiBaseTest {
private static final String TEST_SSID_1 = "Test SSID 1";
private static final String TEST_SSID_2 = "Test SSID 2";
@@ -104,7 +107,7 @@ public class OpenNetworkNotifierTest {
when(mFrameworkFacade.getIntegerSetting(mContext,
Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, DEFAULT_REPEAT_DELAY_SEC))
.thenReturn(DEFAULT_REPEAT_DELAY_SEC);
- when(mContext.getSystemService(Context.USER_SERVICE))
+ when(mContext.getSystemService(UserManager.class))
.thenReturn(mUserManager);
when(mContext.getResources()).thenReturn(mResources);
mDummyNetwork = new ScanResult();
@@ -455,7 +458,9 @@ public class OpenNetworkNotifierTest {
/** Verifies that {@link UserManager#DISALLOW_CONFIG_WIFI} disables the feature. */
@Test
public void userHasDisallowConfigWifiRestriction_notificationNotDisplayed() {
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT))
+ // TODO (b/142234604): This will not work on multi-user device scenarios.
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI,
+ UserHandle.CURRENT_OR_SELF))
.thenReturn(true);
mNotificationController.handleScanResults(mOpenNetworks);
@@ -474,7 +479,9 @@ public class OpenNetworkNotifierTest {
ConnectToNetworkNotificationAndActionCount.NOTIFICATION_RECOMMEND_NETWORK);
verify(mNotificationManager).notify(anyInt(), any());
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT))
+ // TODO (b/142234604): This will not work on multi-user device scenarios.
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI,
+ UserHandle.CURRENT_OR_SELF))
.thenReturn(true);
mNotificationController.handleScanResults(mOpenNetworks);
@@ -489,8 +496,8 @@ public class OpenNetworkNotifierTest {
@Test
public void actionConnectToNetwork_notificationNotShowing_doesNothing() {
mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
-
- verify(mClientModeImpl, never()).sendMessage(any(Message.class));
+ verify(mClientModeImpl, never()).connect(any(), anyInt(), any(Binder.class),
+ any(IActionListener.class), anyInt(), eq(Process.WIFI_UID));
}
/**
@@ -510,7 +517,8 @@ public class OpenNetworkNotifierTest {
mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK));
- verify(mClientModeImpl).sendMessage(any(Message.class));
+ verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class),
+ any(IActionListener.class), anyInt(), eq(Process.WIFI_UID));
// Connecting Notification
verify(mNotificationBuilder).createNetworkConnectingNotification(OPEN_NET_NOTIFIER_TAG,
mDummyNetwork);
@@ -688,9 +696,11 @@ public class OpenNetworkNotifierTest {
verify(mWifiMetrics).setNominatorForNetwork(TEST_NETWORK_ID,
WifiMetricsProto.ConnectionEvent.NOMINATOR_OPEN_NETWORK_AVAILABLE);
- ArgumentCaptor<Message> connectMessageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mClientModeImpl).sendMessage(connectMessageCaptor.capture());
- Message connectMessage = connectMessageCaptor.getValue();
+ ArgumentCaptor<IActionListener> connectListenerCaptor =
+ ArgumentCaptor.forClass(IActionListener.class);
+ verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class),
+ connectListenerCaptor.capture(), anyInt(), eq(Process.WIFI_UID));
+ IActionListener connectListener = connectListenerCaptor.getValue();
// Connecting Notification
verify(mNotificationBuilder).createNetworkConnectingNotification(OPEN_NET_NOTIFIER_TAG,
@@ -702,9 +712,7 @@ public class OpenNetworkNotifierTest {
ConnectToNetworkNotificationAndActionCount.ACTION_CONNECT_TO_NETWORK);
verify(mNotificationManager, times(2)).notify(anyInt(), any());
- Message connectFailedMsg = Message.obtain();
- connectFailedMsg.what = WifiManager.CONNECT_NETWORK_FAILED;
- connectMessage.replyTo.send(connectFailedMsg);
+ connectListener.onFailure(WifiManager.ERROR);
mLooper.dispatchAll();
// Failed to Connect Notification
diff --git a/service/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java
index 4df560fd2a..b91dc186b9 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java
@@ -40,7 +40,7 @@ import java.util.Map;
* Unit tests for {@link com.android.server.wifi.RandomizedMacStoreData}.
*/
@SmallTest
-public class RandomizedMacStoreDataTest {
+public class RandomizedMacStoreDataTest extends WifiBaseTest {
private static final String TEST_MAC_ADDRESS_1 = "da:a1:19:0:0:0";
private static final String TEST_MAC_ADDRESS_2 = "ff:ff:ff:0:0:0";
private static final String TEST_CONFIG_KEY_1 = "TP-LINK_B6C1_5GWPA_PSK";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/RttManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/RttManagerTest.java
index e179142fc6..1cb8eac735 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/RttManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/RttManagerTest.java
@@ -31,7 +31,7 @@ import org.junit.Test;
* Unit test for {@link RttManager}
*/
@SmallTest
-public class RttManagerTest {
+public class RttManagerTest extends WifiBaseTest {
// Verify ParcelableRttParams are the same after writing and reading from parcel.
private void verifyReadWriteParcelForRttParams(ParcelableRttParams params) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SarInfoTest.java b/service/tests/wifitests/src/com/android/server/wifi/SarInfoTest.java
index 23edbd7f18..72f48ffa46 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SarInfoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SarInfoTest.java
@@ -29,7 +29,7 @@ import org.junit.Test;
* unit tests for {@link com.android.server.wifi.SarInfo}.
*/
@SmallTest
-public class SarInfoTest {
+public class SarInfoTest extends WifiBaseTest {
private static final String TAG = "WifiSarInfoTest";
private SarInfo mSarInfo;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java
index e8d0820018..39f4d6a0ee 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java
@@ -59,7 +59,7 @@ import java.util.List;
* unit tests for {@link com.android.server.wifi.SarManager}.
*/
@SmallTest
-public class SarManagerTest {
+public class SarManagerTest extends WifiBaseTest {
private static final String TAG = "WifiSarManagerTest";
private static final String OP_PACKAGE_NAME = "com.xxx";
private static final String SAR_SENSOR_NAME = "com.google.sensor.sar";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java b/service/tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java
index ff8c8250a0..19f7422ec7 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SavedNetworkEvaluatorTest.java
@@ -28,9 +28,9 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.os.SystemClock;
import android.telephony.SubscriptionManager;
+import android.test.suitebuilder.annotation.SmallTest;
import android.util.LocalLog;
-import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.server.wifi.WifiNetworkSelector.NetworkEvaluator.OnConnectableListener;
@@ -42,13 +42,14 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Collections;
import java.util.List;
/**
* Unit tests for {@link com.android.server.wifi.SavedNetworkEvaluator}.
*/
@SmallTest
-public class SavedNetworkEvaluatorTest {
+public class SavedNetworkEvaluatorTest extends WifiBaseTest {
/** Sets up test. */
@Before
@@ -79,7 +80,8 @@ public class SavedNetworkEvaluatorTest {
new ScoringParams(mContext), mWifiConfigManager,
mClock, mLocalLog, mWifiConnectivityHelper, mSubscriptionManager);
// SIM is absent
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[0]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Collections.emptyList());
}
/** Cleans up test. */
@@ -207,6 +209,70 @@ public class SavedNetworkEvaluatorTest {
}
/**
+ * Pick a worse candidate that allows auto-join over a better candidate that
+ * disallows auto-join.
+ */
+ @Test
+ public void ignoreNetworksIfAutojoinNotAllowed() {
+ String[] ssids = {"\"test1\"", "\"test2\""};
+ String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
+ int[] freqs = {2470, 2437};
+ String[] caps = {"[ESS]", "[ESS]"};
+ int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 10};
+ int[] securities = {SECURITY_NONE, SECURITY_NONE};
+
+ ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
+ WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
+ freqs, caps, levels, securities, mWifiConfigManager, mClock);
+ List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+ WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
+
+ WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
+ null, null, true, false, mOnConnectableListener);
+
+ ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
+ WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[1], candidate);
+ WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
+ chosenScanResult, candidate);
+
+ savedConfigs[1].allowAutojoin = false;
+ candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
+ null, null, true, false, mOnConnectableListener);
+
+ chosenScanResult = scanDetails.get(0).getScanResult();
+ WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
+ WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
+ chosenScanResult, candidate);
+ }
+
+ /**
+ * Do not return a candidate if all networks do not {@link WifiConfiguration#allowAutojoin}
+ */
+ @Test
+ public void returnNoCandidateIfNoNetworksAllowAutojoin() {
+ String[] ssids = {"\"test1\"", "\"test2\""};
+ String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
+ int[] freqs = {2470, 2437};
+ String[] caps = {"[ESS]", "[ESS]"};
+ int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 10};
+ int[] securities = {SECURITY_NONE, SECURITY_NONE};
+
+ ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
+ WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
+ freqs, caps, levels, securities, mWifiConfigManager, mClock);
+ List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
+ WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
+ for (WifiConfiguration wifiConfiguration : savedConfigs) {
+ wifiConfiguration.allowAutojoin = false;
+ }
+
+ WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
+ null, null, true, false, mOnConnectableListener);
+
+ assertNull(candidate);
+ }
+
+ /**
* Set the candidate {@link ScanResult} for all {@link WifiConfiguration}s regardless of
* whether they are secure saved, open saved, or {@link WifiConfiguration#useExternalScores}.
*/
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ScanOnlyModeManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/ScanOnlyModeManagerTest.java
deleted file mode 100644
index c20be33e08..0000000000
--- a/service/tests/wifitests/src/com/android/server/wifi/ScanOnlyModeManagerTest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import static android.net.wifi.WifiManager.EXTRA_SCAN_AVAILABLE;
-import static android.net.wifi.WifiManager.WIFI_SCAN_AVAILABLE;
-import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
-import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
-import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.UserHandle;
-import android.os.test.TestLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Unit tests for {@link ScanOnlyModeManager}.
- */
-@SmallTest
-public class ScanOnlyModeManagerTest {
- private static final String TAG = "ScanOnlyModeManagerTest";
- private static final String TEST_INTERFACE_NAME = "testif0";
- private static final String OTHER_INTERFACE_NAME = "notTestIf";
-
- TestLooper mLooper;
-
- ScanOnlyModeManager mScanOnlyModeManager;
-
- @Mock Context mContext;
- @Mock WifiMetrics mWifiMetrics;
- @Mock WifiNative mWifiNative;
- @Mock ScanOnlyModeManager.Listener mListener;
- @Mock WifiMonitor mWifiMonitor;
- @Mock WakeupController mWakeupController;
- @Mock SarManager mSarManager;
-
- final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
- ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mLooper = new TestLooper();
-
- mScanOnlyModeManager = createScanOnlyModeManager();
- mLooper.dispatchAll();
- }
-
- private ScanOnlyModeManager createScanOnlyModeManager() {
- return new ScanOnlyModeManager(mContext, mLooper.getLooper(), mWifiNative, mListener,
- mWifiMetrics, mWakeupController, mSarManager);
- }
-
- private void startScanOnlyModeAndVerifyEnabled() throws Exception {
- when(mWifiNative.setupInterfaceForClientInScanMode(any())).thenReturn(
- TEST_INTERFACE_NAME);
- mScanOnlyModeManager.start();
- mLooper.dispatchAll();
-
- verify(mWifiNative).setupInterfaceForClientInScanMode(
- mInterfaceCallbackCaptor.capture());
-
- // now mark the interface as up
- mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME);
- mLooper.dispatchAll();
-
- checkWifiStateChangeListenerUpdate(WIFI_STATE_ENABLED);
- verify(mSarManager).setScanOnlyWifiState(eq(WIFI_STATE_ENABLED));
- }
-
- private void checkWifiScanStateChangedBroadcast(Intent intent, int expectedCurrentState) {
- String action = intent.getAction();
- assertEquals(WIFI_SCAN_AVAILABLE, action);
- int currentState = intent.getIntExtra(EXTRA_SCAN_AVAILABLE, WIFI_STATE_UNKNOWN);
- assertEquals(expectedCurrentState, currentState);
- }
-
- private void checkWifiStateChangeListenerUpdate(int expectedCurrentState) {
- verify(mListener).onStateChanged(eq(expectedCurrentState));
- }
-
- /**
- * ScanMode start sets up an interface in ClientMode for scanning.
- */
- @Test
- public void scanModeStartAndVerifyEnabled() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
- }
-
- /**
- * ScanMode start does not indicate scanning is available when the interface name is empty.
- */
- @Test
- public void scanModeStartDoesNotSendScanningActiveWhenClientInterfaceNameIsEmpty()
- throws Exception {
- when(mWifiNative.setupInterfaceForClientInScanMode(any())).thenReturn("");
- mScanOnlyModeManager.start();
- mLooper.dispatchAll();
-
- verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
- checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
- }
-
- /**
- * Calling ScanOnlyModeManager.start twice does not crash or restart scan mode.
- */
- @Test
- public void scanOnlyModeStartCalledTwice() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
- reset(mWifiNative, mContext);
- mScanOnlyModeManager.start();
- mLooper.dispatchAll();
- verifyNoMoreInteractions(mWifiNative, mContext);
- }
-
- /**
- * ScanMode stop properly cleans up state
- */
- @Test
- public void scanModeStopCleansUpState() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
- reset(mContext, mListener);
- mScanOnlyModeManager.stop();
- mLooper.dispatchAll();
- verify(mWifiNative).teardownInterface(TEST_INTERFACE_NAME);
- verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
- verify(mSarManager).setScanOnlyWifiState(eq(WIFI_STATE_DISABLED));
- verifyNoMoreInteractions(mListener);
- }
-
- /**
- * ScanMode properly stops when underlying interface is destroyed.
- */
- @Test
- public void scanModeStopsOnInterfaceDestroyed() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
- reset(mContext);
- mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
- mLooper.dispatchAll();
- verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
- }
-
- /**
- * Calling stop when ScanMode is not started should not send scan state updates
- */
- @Test
- public void scanModeStopWhenNotStartedDoesNotUpdateScanStateUpdates() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
- mScanOnlyModeManager.stop();
- mLooper.dispatchAll();
- reset(mContext, mListener);
-
- // now call stop again
- mScanOnlyModeManager.stop();
- mLooper.dispatchAll();
- verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
- verify(mListener, never()).onStateChanged(anyInt());
- }
-
- /**
- * Triggering interface down when ScanOnlyMode is active properly exits the active state and
- * reports an error.
- */
- @Test
- public void scanModeStartedStopsWhenInterfaceDown() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
- reset(mContext);
- mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
- mLooper.dispatchAll();
- verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
- checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
- }
-
- /**
- * Triggering an interface down for a different interface will not exit scan mode.
- */
- @Test
- public void scanModeStartedDoesNotStopOnDownForDifferentIface() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
- reset(mContext, mListener);
- mInterfaceCallbackCaptor.getValue().onDown(OTHER_INTERFACE_NAME);
-
- mLooper.dispatchAll();
-
- verifyNoMoreInteractions(mContext, mListener);
- }
-
- /**
- * Verify that onDestroyed after scan mode is stopped doesn't trigger a callback.
- */
- @Test
- public void noCallbackOnInterfaceDestroyedWhenAlreadyStopped() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
-
- reset(mListener);
-
- mScanOnlyModeManager.stop();
- mLooper.dispatchAll();
-
- // now trigger interface destroyed and make sure callback doesn't get called
- mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
- mLooper.dispatchAll();
-
- verifyNoMoreInteractions(mListener);
- }
-
- /**
- * Entering StartedState starts the WakeupController.
- */
- @Test
- public void scanModeEnterStartsWakeupController() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
-
- verify(mWakeupController).start();
- }
-
- /**
- * Exiting StartedState stops the WakeupController.
- */
- @Test
- public void scanModeExitStopsWakeupController() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
-
- mScanOnlyModeManager.stop();
- mLooper.dispatchAll();
-
- InOrder inOrder = inOrder(mWakeupController, mWifiNative, mListener);
-
- inOrder.verify(mWakeupController).start();
- inOrder.verify(mWakeupController).stop();
- inOrder.verify(mWifiNative).teardownInterface(eq(TEST_INTERFACE_NAME));
- }
-}
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 38e2eaf869..d5286d27a2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java
@@ -29,12 +29,16 @@ import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
+import android.net.wifi.IScanResultsListener;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
+import android.os.Binder;
import android.os.Handler;
+import android.os.IBinder;
import android.os.UserHandle;
import android.os.WorkSource;
+import android.os.test.TestLooper;
import android.provider.Settings;
import androidx.test.filters.SmallTest;
@@ -56,7 +60,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.ScanRequestProxy}.
*/
@SmallTest
-public class ScanRequestProxyTest {
+public class ScanRequestProxyTest extends WifiBaseTest {
private static final int TEST_UID = 5;
private static final String TEST_PACKAGE_NAME_1 = "com.test.1";
private static final String TEST_PACKAGE_NAME_2 = "com.test.2";
@@ -83,6 +87,10 @@ public class ScanRequestProxyTest {
@Mock private Clock mClock;
@Mock private FrameworkFacade mFrameworkFacade;
@Mock private WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
+ @Mock private IScanResultsListener mScanResultsListener;
+ @Mock private IScanResultsListener mAnotherScanResultsListener;
+ @Mock private TestLooper mLooper;
+ @Mock private IBinder mBinder;
private ArgumentCaptor<WorkSource> mWorkSourceArgumentCaptor =
ArgumentCaptor.forClass(WorkSource.class);
@@ -132,10 +140,11 @@ public class ScanRequestProxyTest {
when(mFrameworkFacade.getIntegerSetting(
eq(mContext), eq(Settings.Global.WIFI_SCAN_THROTTLE_ENABLED), anyInt()))
.thenReturn(1);
+ mLooper = new TestLooper();
mScanRequestProxy =
new ScanRequestProxy(mContext, mAppOps, mActivityManager, mWifiInjector,
mWifiConfigManager, mWifiPermissionsUtil, mWifiMetrics, mClock,
- mFrameworkFacade, mock(Handler.class));
+ mFrameworkFacade, new Handler(mLooper.getLooper()));
}
@After
@@ -144,6 +153,16 @@ public class ScanRequestProxyTest {
validateMockitoUsage();
}
+ private void enableScanning() {
+ // Enable scanning
+ mScanRequestProxy.enableScanning(true, false);
+ mInOrder.verify(mWifiScanner).registerScanListener(any());
+ mInOrder.verify(mWifiScanner).setScanningEnabled(true);
+ validateScanAvailableBroadcastSent(true);
+
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(782L);
+ }
+
/**
* Verify scan enable sequence.
*/
@@ -181,8 +200,8 @@ public class ScanRequestProxyTest {
*/
@Test
public void testStartScanSuccess() {
+ enableScanning();
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
assertTrue(mWorkSourceArgumentCaptor.getValue().equals(
@@ -197,9 +216,9 @@ public class ScanRequestProxyTest {
*/
@Test
public void testStartScanSuccessFromAppWithNetworkSettings() {
+ enableScanning();
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID)).thenReturn(true);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
assertTrue(mWorkSourceArgumentCaptor.getValue().equals(
@@ -212,9 +231,9 @@ public class ScanRequestProxyTest {
*/
@Test
public void testStartScanSuccessFromAppWithNetworkSetupWizard() {
+ enableScanning();
when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(TEST_UID)).thenReturn(true);
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
assertEquals(mWorkSourceArgumentCaptor.getValue(),
@@ -310,9 +329,9 @@ public class ScanRequestProxyTest {
*/
@Test
public void testScanSuccessOverwritesPreviousResults() {
+ enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
@@ -341,9 +360,9 @@ public class ScanRequestProxyTest {
*/
@Test
public void testScanFailureDoesNotOverwritePreviousResults() {
+ enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
@@ -373,9 +392,9 @@ public class ScanRequestProxyTest {
*/
@Test
public void testNewScanRequestAfterPreviousScanSucceeds() {
+ enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Now send the scan results for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
@@ -407,9 +426,9 @@ public class ScanRequestProxyTest {
*/
@Test
public void testNewScanRequestAfterPreviousScanSucceedsWithInvalidScanDatas() {
+ enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Now send scan success for request 1, but with invalid scan datas.
@@ -441,9 +460,9 @@ public class ScanRequestProxyTest {
*/
@Test
public void testNewScanRequestAfterPreviousScanFailure() {
+ enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Now send scan failure for request 1.
@@ -504,11 +523,11 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestsDontUseSameListener() {
+ enableScanning();
WifiScanner.ScanListener listener1;
WifiScanner.ScanListener listener2;
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
listener1 = mScanRequestListenerArgumentCaptor.getValue();
@@ -530,14 +549,12 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestFromSameFgAppThrottled() {
+ enableScanning();
long firstRequestMs = 782;
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
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));
- if (i == 0) {
- mInOrder.verify(mWifiScanner).registerScanListener(any());
- }
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Make next scan request from the same package name & ensure that it is throttled.
@@ -556,14 +573,12 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestFromSameFgAppNotThrottled() {
+ enableScanning();
long firstRequestMs = 782;
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
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));
- if (i == 0) {
- mInOrder.verify(mWifiScanner).registerScanListener(any());
- }
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
long lastRequestMs = firstRequestMs + SCAN_REQUEST_THROTTLE_TIME_WINDOW_FG_APPS_MS + 1;
@@ -582,6 +597,7 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestFromSameAppWithNetworkSettingsPermissionNotThrottled() {
+ enableScanning();
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(TEST_UID)).thenReturn(true);
long firstRequestMs = 782;
@@ -589,9 +605,6 @@ public class ScanRequestProxyTest {
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));
- if (i == 0) {
- mInOrder.verify(mWifiScanner).registerScanListener(any());
- }
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Make next scan request from the same package name & ensure that it is not throttled.
@@ -605,6 +618,7 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestFromSameAppWithNetworkSetupWizardPermissionNotThrottled() {
+ enableScanning();
when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(TEST_UID)).thenReturn(true);
long firstRequestMs = 782;
@@ -612,9 +626,6 @@ public class ScanRequestProxyTest {
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));
- if (i == 0) {
- mInOrder.verify(mWifiScanner).registerScanListener(any());
- }
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Make next scan request from the same package name & ensure that it is not throttled.
@@ -657,14 +668,12 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestFromDifferentFgAppsNotThrottled() {
+ enableScanning();
long firstRequestMs = 782;
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
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));
- if (i == 0) {
- mInOrder.verify(mWifiScanner).registerScanListener(any());
- }
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
for (int i = 0; i < SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS / 2; i++) {
@@ -689,14 +698,12 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestFromSameAppAfterRemovalAndReinstallNotThrottled() {
+ enableScanning();
long firstRequestMs = 782;
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
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));
- if (i == 0) {
- mInOrder.verify(mWifiScanner).registerScanListener(any());
- }
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Now simulate removing the app.
@@ -718,14 +725,12 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestFromSameAppAfterRemovalOnAnotherUserThrottled() {
+ enableScanning();
long firstRequestMs = 782;
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
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));
- if (i == 0) {
- mInOrder.verify(mWifiScanner).registerScanListener(any());
- }
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
}
// Now simulate removing the app for another user (User 1).
@@ -748,6 +753,7 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestFromBgAppsThrottled() {
+ enableScanning();
when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
.thenReturn(IMPORTANCE_FOREGROUND_SERVICE + 1);
when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2))
@@ -757,7 +763,6 @@ public class ScanRequestProxyTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Make scan request 2 from the different package name & ensure that it is throttled.
@@ -774,6 +779,7 @@ public class ScanRequestProxyTest {
*/
@Test
public void testSuccessiveScanRequestFromBgAppsNotThrottled() {
+ enableScanning();
when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
.thenReturn(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND + 1);
when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_2))
@@ -783,7 +789,6 @@ public class ScanRequestProxyTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(firstRequestMs);
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
long secondRequestMs =
@@ -802,9 +807,9 @@ public class ScanRequestProxyTest {
*/
@Test
public void testFullInternalScanResultsOverwritesPreviousResults() {
+ enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
@@ -832,9 +837,9 @@ public class ScanRequestProxyTest {
*/
@Test
public void testPartialInternalScanResultsDoesNotOverwritePreviousResults() {
+ enableScanning();
// Make scan request 1.
assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1));
- mInOrder.verify(mWifiScanner).registerScanListener(any());
mInOrder.verify(mWifiScanner).startScan(any(), any(), any());
// Verify the scan results processing for request 1.
mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
@@ -949,4 +954,85 @@ public class ScanRequestProxyTest {
boolean scanAvailable = scanState == WifiManager.WIFI_STATE_ENABLED;
assertEquals(expectedScanAvailable, scanAvailable);
}
+
+ /**
+ * Test register scan result listener from different apps, all of them will receive the event.
+ */
+ @Test
+ public void testScanSuccessWithMultipleListenerFromDifferentApps() throws Exception {
+ final int listenerIdentifier1 = 1;
+ final int listenerIdentifier2 = 2;
+ Binder binder1 = new Binder();
+ Binder binder2 = new Binder();
+ mScanRequestProxy.registerScanResultsListener(binder1, mScanResultsListener,
+ listenerIdentifier1);
+ mScanRequestProxy.registerScanResultsListener(binder2, mAnotherScanResultsListener,
+ listenerIdentifier2);
+ mLooper.dispatchAll();
+ testStartScanSuccess();
+ // Verify the scan results processing.
+ mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
+ verify(mScanResultsListener).onScanResultsAvailable();
+ verify(mAnotherScanResultsListener).onScanResultsAvailable();
+ validateScanResultsAvailableBroadcastSent(true);
+
+ reset(mScanResultsListener);
+ reset(mAnotherScanResultsListener);
+ mScanRequestProxy.unregisterScanResultsListener(listenerIdentifier1);
+ mLooper.dispatchAll();
+ mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
+ verify(mScanResultsListener, never()).onScanResultsAvailable();
+ verify(mAnotherScanResultsListener).onScanResultsAvailable();
+ validateScanResultsAvailableBroadcastSent(true);
+ }
+
+ /**
+ * Test same app register scan result listener second time will replace the first one.
+ */
+ @Test
+ public void testScanSuccessWithMultipleListenerFromSameApps() throws Exception {
+ final int listenerIdentifier = 1;
+ Binder binder = new Binder();
+ mScanRequestProxy.registerScanResultsListener(binder, mScanResultsListener,
+ listenerIdentifier);
+ mScanRequestProxy.registerScanResultsListener(binder, mAnotherScanResultsListener,
+ listenerIdentifier);
+ testStartScanSuccess();
+ // Verify the scan results processing.
+ mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
+ verify(mScanResultsListener, never()).onScanResultsAvailable();
+ verify(mAnotherScanResultsListener).onScanResultsAvailable();
+ validateScanResultsAvailableBroadcastSent(true);
+ }
+
+ /**
+ * Test registered scan result listener will be unregistered when calling binder is died.
+ */
+ @Test
+ public void testUnregisterScanResultListenerOnBinderDied() throws Exception {
+ final int callbackIdentifier = 1;
+ ArgumentCaptor<IBinder.DeathRecipient> drCaptor =
+ ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
+ mScanRequestProxy.registerScanResultsListener(mBinder, mScanResultsListener,
+ callbackIdentifier);
+ verify(mBinder).linkToDeath(drCaptor.capture(), anyInt());
+ testStartScanSuccess();
+ // Verify the scan results processing.
+ mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
+ verify(mScanResultsListener).onScanResultsAvailable();
+ validateScanResultsAvailableBroadcastSent(true);
+ reset(mScanResultsListener);
+ drCaptor.getValue().binderDied();
+ mLooper.dispatchAll();
+ verify(mBinder).unlinkToDeath(drCaptor.capture(), eq(0));
+ // Verify the scan results processing.
+ mGlobalScanListenerArgumentCaptor.getValue().onResults(mTestScanDatas1);
+ mLooper.dispatchAll();
+ verify(mScanResultsListener, never()).onScanResultsAvailable();
+ validateScanResultsAvailableBroadcastSent(true);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ScanResultMatchInfoTest.java b/service/tests/wifitests/src/com/android/server/wifi/ScanResultMatchInfoTest.java
index 2712ce0771..1cc7fa83fc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ScanResultMatchInfoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ScanResultMatchInfoTest.java
@@ -30,7 +30,7 @@ import org.junit.Test;
* Unit tests for {@link com.android.server.wifi.ScanResultMatchInfoTest}.
*/
@SmallTest
-public class ScanResultMatchInfoTest {
+public class ScanResultMatchInfoTest extends WifiBaseTest {
/**
* Tests that equivalent ScanResultMatchInfo objects are created for WifiConfigurations and
* their associated ScanResult
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ScanResults.java b/service/tests/wifitests/src/com/android/server/wifi/ScanResults.java
index 5800979275..052b4dd2b5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ScanResults.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ScanResults.java
@@ -21,6 +21,7 @@ import android.net.wifi.WifiScanner.ScanData;
import android.net.wifi.WifiSsid;
import com.android.server.wifi.hotspot2.NetworkDetail;
+import com.android.server.wifi.util.NativeUtil;
import java.math.BigInteger;
import java.nio.charset.Charset;
@@ -87,6 +88,21 @@ public class ScanResults {
return ie;
}
+ public static byte[] generateIERawDatafromScanResultIE(ScanResult.InformationElement[] ies) {
+ ArrayList<Byte> ieRawData = new ArrayList<>();
+ for (int i = 0; i < ies.length; i++) {
+ if (ies[i].id > 255 || ies[i].bytes.length > 255) {
+ break;
+ }
+ ieRawData.add(BigInteger.valueOf(ies[i].id).toByteArray()[0]);
+ ieRawData.add(BigInteger.valueOf(ies[i].bytes.length).toByteArray()[0]);
+ for (int j = 0; j < ies[i].bytes.length; j++) {
+ ieRawData.add(ies[i].bytes[j]);
+ }
+ }
+ return NativeUtil.byteArrayFromArrayList(ieRawData);
+ }
+
/**
* Generates an array of random ScanDetails with the given frequencies, seeded by the provided
* seed value and test method name and class (annotated with @Test). This method will be
@@ -120,7 +136,7 @@ public class ScanResults {
bssid, "", rssi, freq,
Long.MAX_VALUE, /* needed so that scan results aren't rejected because
they are older than scan start */
- ie, anqpLines);
+ ie, anqpLines, generateIERawDatafromScanResultIE(ie));
results[i] = detail;
}
return results;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ScoredNetworkEvaluatorTest.java b/service/tests/wifitests/src/com/android/server/wifi/ScoredNetworkEvaluatorTest.java
index d1de03cbc9..7c60fead09 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ScoredNetworkEvaluatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ScoredNetworkEvaluatorTest.java
@@ -32,6 +32,7 @@ import android.net.Uri;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiNetworkScoreCache;
+import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.provider.Settings;
@@ -58,7 +59,7 @@ import java.util.List;
* Unit tests for {@link ScoredNetworkEvaluator}.
*/
@SmallTest
-public class ScoredNetworkEvaluatorTest {
+public class ScoredNetworkEvaluatorTest extends WifiBaseTest {
private static final String TEST_PACKAGE_NAME = "name.package.test";
private static final int TEST_UID = 12345;
private static final NetworkScorerAppData TEST_APP_DATA = new NetworkScorerAppData(
@@ -95,7 +96,7 @@ public class ScoredNetworkEvaluatorTest {
ArgumentCaptor.forClass(ContentObserver.class);
mScoreCache = new WifiNetworkScoreCache(mContext);
mScoredNetworkEvaluator = new ScoredNetworkEvaluator(mContext,
- Looper.getMainLooper(), mFrameworkFacade, mNetworkScoreManager,
+ new Handler(Looper.getMainLooper()), mFrameworkFacade, mNetworkScoreManager,
mWifiConfigManager, new LocalLog(0), mScoreCache, mWifiPermissionsUtil);
verify(mFrameworkFacade).registerContentObserver(eq(mContext), any(Uri.class), eq(false),
observerCaptor.capture());
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ScoringParamsTest.java b/service/tests/wifitests/src/com/android/server/wifi/ScoringParamsTest.java
index e73294589f..a6a3b0f766 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ScoringParamsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ScoringParamsTest.java
@@ -48,7 +48,7 @@ import org.mockito.Spy;
* Unit tests for {@link com.android.server.wifi.ScoringParams}.
*/
@SmallTest
-public class ScoringParamsTest {
+public class ScoringParamsTest extends WifiBaseTest {
private static final String EXPECTED_DEFAULTS =
"rssi2=-83:-80:-73:-60,rssi5=-80:-77:-70:-57,pps=0:1:100,horizon=15,nud=8,expid=0";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java b/service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java
index bcef92ca92..fe8bfd575f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SelfRecoveryTest.java
@@ -29,45 +29,45 @@ import org.mockito.Mock;
* Unit tests for {@link com.android.server.wifi.SelfRecovery}.
*/
@SmallTest
-public class SelfRecoveryTest {
+public class SelfRecoveryTest extends WifiBaseTest {
SelfRecovery mSelfRecovery;
- @Mock WifiController mWifiController;
+ @Mock ActiveModeWarden mActiveModeWarden;
@Mock Clock mClock;
@Before
public void setUp() throws Exception {
initMocks(this);
- mSelfRecovery = new SelfRecovery(mWifiController, mClock);
+ mSelfRecovery = new SelfRecovery(mActiveModeWarden, mClock);
}
/**
* Verifies that invocations of {@link SelfRecovery#trigger(int)} with valid reasons will send
- * the restart message to {@link WifiController}.
+ * the restart message to {@link ActiveModeWarden}.
*/
@Test
public void testValidTriggerReasonsSendMessageToWifiController() {
mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
+ reset(mActiveModeWarden);
when(mClock.getElapsedSinceBootMillis())
.thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1);
mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ reset(mActiveModeWarden);
}
/**
* Verifies that invocations of {@link SelfRecovery#trigger(int)} with invalid reasons will not
- * send the restart message to {@link WifiController}.
+ * send the restart message to {@link ActiveModeWarden}.
*/
@Test
public void testInvalidTriggerReasonsDoesNotSendMessageToWifiController() {
mSelfRecovery.trigger(-1);
- verify(mWifiController, never()).sendMessage(anyInt(), anyString());
+ verifyNoMoreInteractions(mActiveModeWarden);
mSelfRecovery.trigger(8);
- verify(mWifiController, never()).sendMessage(anyInt(), anyString());
+ verifyNoMoreInteractions(mActiveModeWarden);
}
/**
@@ -76,7 +76,7 @@ public class SelfRecoveryTest {
@Test
public void testStaIfaceDownDisablesWifi() {
mSelfRecovery.trigger(SelfRecovery.REASON_STA_IFACE_DOWN);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI));
+ verify(mActiveModeWarden).recoveryDisableWifi();
}
/**
@@ -91,58 +91,53 @@ public class SelfRecoveryTest {
// aren't ignored
for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW / 2; i++) {
mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI),
- anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ reset(mActiveModeWarden);
mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI),
- anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ reset(mActiveModeWarden);
}
if ((SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW % 2) == 1) {
mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI),
- anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ reset(mActiveModeWarden);
}
// Verify that further attempts to trigger restarts disable wifi
mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
- verify(mWifiController, never()).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI),
- anyString());
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI));
- reset(mWifiController);
+ verify(mActiveModeWarden, never())
+ .recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ verify(mActiveModeWarden).recoveryDisableWifi();
+ reset(mActiveModeWarden);
mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
- verify(mWifiController, never()).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI),
- anyString());
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI));
- reset(mWifiController);
+ verify(mActiveModeWarden, never()).recoveryRestartWifi(anyInt());
+ verify(mActiveModeWarden).recoveryDisableWifi();
+ reset(mActiveModeWarden);
// Verify L.R.Watchdog can still restart things (It has its own complex limiter)
mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI),
- anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
+ reset(mActiveModeWarden);
// Verify Sta Interface Down will still disable wifi
mSelfRecovery.trigger(SelfRecovery.REASON_STA_IFACE_DOWN);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI));
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryDisableWifi();
+ reset(mActiveModeWarden);
// now TRAVEL FORWARDS IN TIME and ensure that more restarts can occur
when(mClock.getElapsedSinceBootMillis())
.thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1);
mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
+ reset(mActiveModeWarden);
when(mClock.getElapsedSinceBootMillis())
.thenReturn(SelfRecovery.MAX_RESTARTS_TIME_WINDOW_MILLIS + 1);
mSelfRecovery.trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ reset(mActiveModeWarden);
}
/**
@@ -156,9 +151,8 @@ public class SelfRecoveryTest {
for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW * 2; i++) {
// Verify L.R.Watchdog can still restart things (It has it's own complex limiter)
mSelfRecovery.trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI),
- anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryRestartWifi(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
+ reset(mActiveModeWarden);
}
}
@@ -172,10 +166,9 @@ public class SelfRecoveryTest {
public void testTimeWindowLimiting_staIfaceDown_noEffect() {
for (int i = 0; i < SelfRecovery.MAX_RESTARTS_IN_TIME_WINDOW * 2; i++) {
mSelfRecovery.trigger(SelfRecovery.REASON_STA_IFACE_DOWN);
- verify(mWifiController).sendMessage(eq(WifiController.CMD_RECOVERY_DISABLE_WIFI));
- verify(mWifiController, never())
- .sendMessage(eq(WifiController.CMD_RECOVERY_RESTART_WIFI), anyInt());
- reset(mWifiController);
+ verify(mActiveModeWarden).recoveryDisableWifi();
+ verify(mActiveModeWarden, never()).recoveryRestartWifi(anyInt());
+ reset(mActiveModeWarden);
}
}
}
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 c08adc1d1c..1f5166abbe 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -30,16 +30,31 @@ import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
import android.app.test.TestAlarmManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.net.MacAddress;
import android.net.Uri;
-import android.net.wifi.IApInterfaceEventCallback;
+import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.UserHandle;
@@ -50,20 +65,25 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.internal.util.WakeupMessage;
+import com.android.server.wifi.wificond.IApInterfaceEventCallback;
+import com.android.server.wifi.wificond.NativeWifiClient;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Locale;
/** Unit tests for {@link SoftApManager}. */
@SmallTest
-public class SoftApManagerTest {
+public class SoftApManagerTest extends WifiBaseTest {
private static final String TAG = "SoftApManagerTest";
@@ -74,6 +94,16 @@ public class SoftApManagerTest {
private static final String TEST_INTERFACE_NAME = "testif0";
private static final String OTHER_INTERFACE_NAME = "otherif";
private static final int TEST_NUM_CONNECTED_CLIENTS = 4;
+ private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("22:33:44:55:66:77");
+ private static final WifiClient TEST_CONNECTED_CLIENT = new WifiClient(TEST_MAC_ADDRESS);
+ private static final List<WifiClient> TEST_CONNECTED_CLIENTS =
+ new ArrayList(Arrays.asList(TEST_CONNECTED_CLIENT));
+ private static final NativeWifiClient TEST_NATIVE_CLIENT = new NativeWifiClient() {{
+ macAddress = TEST_MAC_ADDRESS.toByteArray();
+ }
+ };
+ private static final List<NativeWifiClient> TEST_CONNECTED_NATIVECLIENTS =
+ new ArrayList(Arrays.asList(TEST_NATIVE_CLIENT));
private final WifiConfiguration mDefaultApConfig = createDefaultApConfig();
@@ -85,6 +115,7 @@ public class SoftApManagerTest {
@Mock Resources mResources;
@Mock WifiNative mWifiNative;
@Mock WifiManager.SoftApCallback mCallback;
+ @Mock ActiveModeManager.Listener mListener;
@Mock FrameworkFacade mFrameworkFacade;
@Mock WifiApConfigStore mWifiApConfigStore;
@Mock WifiMetrics mWifiMetrics;
@@ -116,6 +147,7 @@ public class SoftApManagerTest {
when(mWifiNative.setCountryCodeHal(
TEST_INTERFACE_NAME, TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT)))
.thenReturn(true);
+ when(mWifiNative.getFactoryMacAddress(any())).thenReturn(TEST_MAC_ADDRESS);
}
private WifiConfiguration createDefaultApConfig() {
@@ -133,6 +165,7 @@ public class SoftApManagerTest {
mFrameworkFacade,
mWifiNative,
countryCode,
+ mListener,
mCallback,
mWifiApConfigStore,
config,
@@ -207,6 +240,7 @@ public class SoftApManagerTest {
mFrameworkFacade,
mWifiNative,
TEST_COUNTRY_CODE,
+ mListener,
mCallback,
mWifiApConfigStore,
nullApConfig,
@@ -218,6 +252,7 @@ public class SoftApManagerTest {
mLooper.dispatchAll();
verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mListener).onStartFailure();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, times(2)).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
@@ -251,6 +286,7 @@ public class SoftApManagerTest {
mFrameworkFacade,
mWifiNative,
TEST_COUNTRY_CODE,
+ mListener,
mCallback,
mWifiApConfigStore,
nullApConfig,
@@ -262,6 +298,7 @@ public class SoftApManagerTest {
mLooper.dispatchAll();
verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mListener).onStartFailure();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
@@ -294,6 +331,7 @@ public class SoftApManagerTest {
mFrameworkFacade,
mWifiNative,
TEST_COUNTRY_CODE,
+ mListener,
mCallback,
mWifiApConfigStore,
nullApConfig,
@@ -305,6 +343,7 @@ public class SoftApManagerTest {
mLooper.dispatchAll();
verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mListener).onStartFailure();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
@@ -336,6 +375,7 @@ public class SoftApManagerTest {
mFrameworkFacade,
mWifiNative,
null,
+ mListener,
mCallback,
mWifiApConfigStore,
softApConfig,
@@ -383,6 +423,7 @@ public class SoftApManagerTest {
mFrameworkFacade,
mWifiNative,
TEST_COUNTRY_CODE,
+ mListener,
mCallback,
mWifiApConfigStore,
softApConfig,
@@ -500,6 +541,7 @@ public class SoftApManagerTest {
mFrameworkFacade,
mWifiNative,
TEST_COUNTRY_CODE,
+ mListener,
mCallback,
mWifiApConfigStore,
softApConfig,
@@ -539,6 +581,7 @@ public class SoftApManagerTest {
mFrameworkFacade,
mWifiNative,
TEST_COUNTRY_CODE,
+ mListener,
mCallback,
mWifiApConfigStore,
softApModeConfig,
@@ -551,6 +594,7 @@ public class SoftApManagerTest {
mLooper.dispatchAll();
verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mListener).onStartFailure();
verify(mWifiNative).teardownInterface(TEST_INTERFACE_NAME);
}
@@ -566,6 +610,7 @@ public class SoftApManagerTest {
mLooper.dispatchAll();
/* Verify no state changes. */
verify(mCallback, never()).onStateChanged(anyInt(), anyInt());
+ verifyNoMoreInteractions(mListener);
verify(mSarManager, never()).setSapWifiState(anyInt());
verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
verify(mWifiNative, never()).teardownInterface(anyString());
@@ -583,7 +628,7 @@ public class SoftApManagerTest {
// reset to clear verified Intents for ap state change updates
reset(mContext);
- InOrder order = inOrder(mCallback, mContext);
+ InOrder order = inOrder(mCallback, mListener, mContext);
mSoftApManager.stop();
mLooper.dispatchAll();
@@ -618,7 +663,7 @@ public class SoftApManagerTest {
// reset to clear verified Intents for ap state change updates
reset(mContext);
- InOrder order = inOrder(mCallback, mContext);
+ InOrder order = inOrder(mCallback, mListener, mContext);
mWifiNativeInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
@@ -637,6 +682,7 @@ public class SoftApManagerTest {
checkApStateChangedBroadcast(intentCaptor.getValue(), WIFI_AP_STATE_DISABLED,
WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME,
softApModeConfig.getTargetMode());
+ order.verify(mListener).onStopped();
}
/**
@@ -650,6 +696,7 @@ public class SoftApManagerTest {
mSoftApManager.stop();
mLooper.dispatchAll();
+ verify(mListener).onStopped();
verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
@@ -660,7 +707,7 @@ public class SoftApManagerTest {
mWifiNativeInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
- verifyNoMoreInteractions(mCallback);
+ verifyNoMoreInteractions(mCallback, mListener);
}
/**
@@ -675,7 +722,7 @@ public class SoftApManagerTest {
// reset to clear verified Intents for ap state change updates
reset(mContext, mCallback, mWifiNative);
- InOrder order = inOrder(mCallback, mContext);
+ InOrder order = inOrder(mCallback, mListener, mContext);
mWifiNativeInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
@@ -683,6 +730,7 @@ public class SoftApManagerTest {
order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
WifiManager.SAP_START_FAILURE_GENERAL);
+ order.verify(mListener).onStopped();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, times(3)).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
@@ -717,7 +765,7 @@ public class SoftApManagerTest {
mLooper.dispatchAll();
- verifyNoMoreInteractions(mContext, mCallback, mWifiNative);
+ verifyNoMoreInteractions(mContext, mCallback, mListener, mWifiNative);
}
/**
@@ -732,13 +780,14 @@ public class SoftApManagerTest {
// reset to clear verified Intents for ap state change updates
reset(mContext, mCallback, mWifiNative);
- InOrder order = inOrder(mCallback, mContext);
+ InOrder order = inOrder(mCallback, mListener, mContext);
mSoftApListenerCaptor.getValue().onFailure();
mLooper.dispatchAll();
order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
WifiManager.SAP_START_FAILURE_GENERAL);
+ order.verify(mListener).onStopped();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, times(3)).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
@@ -835,17 +884,21 @@ public class SoftApManagerTest {
}
@Test
- public void updatesNumAssociatedStations() throws Exception {
+ public void updatesConnectedClients() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
startSoftApAndVerifyEnabled(apConfig);
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(
- TEST_NUM_CONNECTED_CLIENTS);
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(
+ TEST_CONNECTED_NATIVECLIENTS);
mLooper.dispatchAll();
- verify(mCallback).onNumClientsChanged(TEST_NUM_CONNECTED_CLIENTS);
- verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(TEST_NUM_CONNECTED_CLIENTS,
+ verify(mCallback).onConnectedClientsChanged(
+ Mockito.argThat((List<WifiClient> clients) ->
+ clients.contains(TEST_CONNECTED_CLIENT))
+ );
+ verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(
+ TEST_CONNECTED_CLIENTS.size(),
apConfig.getTargetMode());
}
@@ -854,36 +907,41 @@ public class SoftApManagerTest {
* trigger callbacks a second time.
*/
@Test
- public void testDoesNotTriggerCallbackForSameNumberClientUpdate() throws Exception {
+ public void testDoesNotTriggerCallbackForSameClients() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
startSoftApAndVerifyEnabled(apConfig);
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(
- TEST_NUM_CONNECTED_CLIENTS);
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(
+ TEST_CONNECTED_NATIVECLIENTS);
mLooper.dispatchAll();
// now trigger callback again, but we should have each method only called once
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(
- TEST_NUM_CONNECTED_CLIENTS);
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(
+ TEST_CONNECTED_NATIVECLIENTS);
mLooper.dispatchAll();
- verify(mCallback).onNumClientsChanged(TEST_NUM_CONNECTED_CLIENTS);
- verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(TEST_NUM_CONNECTED_CLIENTS,
+ verify(mCallback).onConnectedClientsChanged(
+ Mockito.argThat((List<WifiClient> clients) ->
+ clients.contains(TEST_CONNECTED_CLIENT))
+ );
+ verify(mWifiMetrics)
+ .addSoftApNumAssociatedStationsChangedEvent(
+ TEST_CONNECTED_CLIENTS.size(),
apConfig.getTargetMode());
}
@Test
- public void handlesInvalidNumAssociatedStations() throws Exception {
+ public void handlesInvalidConnectedClients() throws Exception {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
startSoftApAndVerifyEnabled(apConfig);
/* Invalid values should be ignored */
- final int mInvalidNumClients = -1;
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(mInvalidNumClients);
+ final List<NativeWifiClient> mInvalidClients = null;
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(mInvalidClients);
mLooper.dispatchAll();
- verify(mCallback, never()).onNumClientsChanged(mInvalidNumClients);
+ verify(mCallback, never()).onConnectedClientsChanged(null);
verify(mWifiMetrics, never()).addSoftApNumAssociatedStationsChangedEvent(anyInt(),
anyInt());
}
@@ -895,20 +953,23 @@ public class SoftApManagerTest {
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
startSoftApAndVerifyEnabled(apConfig);
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(
- TEST_NUM_CONNECTED_CLIENTS);
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(
+ TEST_CONNECTED_NATIVECLIENTS);
mLooper.dispatchAll();
- order.verify(mCallback).onNumClientsChanged(TEST_NUM_CONNECTED_CLIENTS);
+ verify(mCallback).onConnectedClientsChanged(
+ Mockito.argThat((List<WifiClient> clients) ->
+ clients.contains(TEST_CONNECTED_CLIENT))
+ );
order.verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(
- TEST_NUM_CONNECTED_CLIENTS, apConfig.getTargetMode());
+ TEST_CONNECTED_CLIENTS.size(), apConfig.getTargetMode());
// Verify timer is canceled at this point
verify(mAlarmManager.getAlarmManager()).cancel(any(WakeupMessage.class));
mSoftApManager.stop();
mLooper.dispatchAll();
- order.verify(mCallback).onNumClientsChanged(0);
+ order.verify(mCallback).onConnectedClientsChanged(new ArrayList<>());
order.verify(mWifiMetrics).addSoftApNumAssociatedStationsChangedEvent(0,
apConfig.getTargetMode());
// Verify timer is canceled after stop softap
@@ -943,8 +1004,8 @@ public class SoftApManagerTest {
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
startSoftApAndVerifyEnabled(apConfig);
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(
- TEST_NUM_CONNECTED_CLIENTS);
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(
+ TEST_CONNECTED_NATIVECLIENTS);
mLooper.dispatchAll();
// Verify timer is canceled
@@ -957,16 +1018,23 @@ public class SoftApManagerTest {
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
startSoftApAndVerifyEnabled(apConfig);
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(
- TEST_NUM_CONNECTED_CLIENTS);
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(
+ TEST_CONNECTED_NATIVECLIENTS);
mLooper.dispatchAll();
- verify(mCallback).onNumClientsChanged(TEST_NUM_CONNECTED_CLIENTS);
+ verify(mCallback).onConnectedClientsChanged(
+ Mockito.argThat((List<WifiClient> clients) ->
+ clients.contains(TEST_CONNECTED_CLIENT))
+ );
// Verify timer is canceled at this point
verify(mAlarmManager.getAlarmManager()).cancel(any(WakeupMessage.class));
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(0);
+ List<NativeWifiClient> testClients = new ArrayList();
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(testClients);
mLooper.dispatchAll();
- verify(mCallback, times(2)).onNumClientsChanged(0);
+ verify(mCallback).onConnectedClientsChanged(
+ Mockito.argThat((List<WifiClient> clients) ->
+ clients.contains(TEST_CONNECTED_CLIENT))
+ );
// Verify timer is scheduled again
verify(mAlarmManager.getAlarmManager(), times(2)).setExact(anyInt(), anyLong(),
eq(mSoftApManager.SOFT_AP_SEND_MESSAGE_TIMEOUT_TAG), any(), any());
@@ -1042,11 +1110,12 @@ public class SoftApManagerTest {
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
startSoftApAndVerifyEnabled(apConfig);
// add some clients
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(
- TEST_NUM_CONNECTED_CLIENTS);
+ mSoftApListenerCaptor.getValue().onConnectedClientsChanged(
+ TEST_CONNECTED_NATIVECLIENTS);
mLooper.dispatchAll();
// remove all clients
- mSoftApListenerCaptor.getValue().onNumAssociatedStationsChanged(0);
+ mSoftApListenerCaptor.getValue()
+ .onConnectedClientsChanged(new ArrayList<NativeWifiClient>());
mLooper.dispatchAll();
// Verify timer is not scheduled
verify(mAlarmManager.getAlarmManager(), never()).setExact(anyInt(), anyLong(),
@@ -1064,6 +1133,57 @@ public class SoftApManagerTest {
verify(mFrameworkFacade).unregisterContentObserver(eq(mContext), eq(mContentObserver));
}
+ @Test
+ public void setsRandomMacWhenEnabled() throws Exception {
+ SoftApModeConfiguration apConfig =
+ new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
+ when(mResources.getBoolean(R.bool.config_wifi_ap_mac_randomization_supported))
+ .thenReturn(true);
+ ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
+ when(mWifiNative.setMacAddress(eq(TEST_INTERFACE_NAME), mac.capture())).thenReturn(true);
+
+ startSoftApAndVerifyEnabled(apConfig);
+ mSoftApManager.stop();
+ mLooper.dispatchAll();
+
+ clearInvocations(mWifiNative, mCallback, mSarManager, mWifiDiagnostics, mWifiMetrics,
+ mListener, mFrameworkFacade, mContext);
+
+ startSoftApAndVerifyEnabled(apConfig);
+ mSoftApManager.stop();
+
+ assertThat(mac.getAllValues()).hasSize(2);
+ assertThat(mac.getAllValues()).containsNoDuplicates();
+ }
+
+ @Test
+ public void resetsFactoryMacWhenRandomizationOff() throws Exception {
+ when(mResources.getBoolean(R.bool.config_wifi_ap_mac_randomization_supported))
+ .thenReturn(false);
+ SoftApModeConfiguration apConfig =
+ new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
+ ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
+ when(mWifiNative.getFactoryMacAddress(TEST_INTERFACE_NAME)).thenReturn(TEST_MAC_ADDRESS);
+ when(mWifiNative.setMacAddress(eq(TEST_INTERFACE_NAME), mac.capture())).thenReturn(true);
+
+ startSoftApAndVerifyEnabled(apConfig);
+
+ assertThat(mac.getValue()).isEqualTo(TEST_MAC_ADDRESS);
+ }
+
+ @Test
+ public void setMacFailureAllowedWhenRandomizationOff() throws Exception {
+ when(mResources.getBoolean(R.bool.config_wifi_ap_mac_randomization_supported))
+ .thenReturn(false);
+ SoftApModeConfiguration apConfig =
+ new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
+ ArgumentCaptor<MacAddress> mac = ArgumentCaptor.forClass(MacAddress.class);
+
+ when(mWifiNative.setMacAddress(any(), any())).thenReturn(false);
+
+ startSoftApAndVerifyEnabled(apConfig);
+ }
+
/** Starts soft AP and verifies that it is enabled successfully. */
protected void startSoftApAndVerifyEnabled(
SoftApModeConfiguration softApConfig) throws Exception {
@@ -1105,11 +1225,11 @@ public class SoftApManagerTest {
mWifiNativeInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
- order.verify(mCallback).onNumClientsChanged(0);
+ order.verify(mCallback).onConnectedClientsChanged(new ArrayList<>());
verify(mSarManager).setSapWifiState(WifiManager.WIFI_AP_STATE_ENABLED);
verify(mWifiDiagnostics).startLogging(TEST_INTERFACE_NAME);
verify(mContext, times(2)).sendStickyBroadcastAsUser(intentCaptor.capture(),
- eq(UserHandle.ALL));
+ eq(UserHandle.ALL));
List<Intent> capturedIntents = intentCaptor.getAllValues();
checkApStateChangedBroadcast(capturedIntents.get(0), WIFI_AP_STATE_ENABLING,
WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME,
@@ -1117,6 +1237,7 @@ public class SoftApManagerTest {
checkApStateChangedBroadcast(capturedIntents.get(1), WIFI_AP_STATE_ENABLED,
WIFI_AP_STATE_ENABLING, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME,
softApConfig.getTargetMode());
+ verify(mListener).onStarted();
verify(mWifiMetrics).addSoftApUpChangedEvent(true, softApConfig.mTargetMode);
verify(mFrameworkFacade).registerContentObserver(eq(mContext), any(Uri.class), eq(true),
observerCaptor.capture());
@@ -1124,8 +1245,8 @@ public class SoftApManagerTest {
}
private void checkApStateChangedBroadcast(Intent intent, int expectedCurrentState,
- int expectedPrevState, int expectedErrorCode,
- String expectedIfaceName, int expectedMode) {
+ int expectedPrevState, int expectedErrorCode,
+ String expectedIfaceName, int expectedMode) {
int currentState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
int errorCode = intent.getIntExtra(EXTRA_WIFI_AP_FAILURE_REASON, HOTSPOT_NO_ERROR);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
index ac6ae21a26..cc6cc689bc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
@@ -49,7 +49,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.SsidSetStoreData}.
*/
@SmallTest
-public class SsidSetStoreDataTest {
+public class SsidSetStoreDataTest extends WifiBaseTest {
private static final String TEST_NOTIFIER_NAME = "TestNetwork";
private static final String TEST_SSID1 = "SSID 1";
private static final String TEST_SSID2 = "SSID 2";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
index cae7e2dac6..254f10d0d2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
@@ -24,6 +24,7 @@ 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.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
@@ -38,6 +39,7 @@ import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -56,21 +58,24 @@ import android.hardware.wifi.supplicant.V1_0.IfaceType;
import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
+import android.hardware.wifi.supplicant.V1_3.ConnectionCapabilities;
+import android.hardware.wifi.supplicant.V1_3.WifiTechnology;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
-import android.net.IpConfiguration;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
+import android.os.Handler;
import android.os.IHwBinder;
import android.os.RemoteException;
import android.os.test.TestLooper;
import android.text.TextUtils;
-import android.util.SparseArray;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.SupplicantStaIfaceHal.PmkCacheStoreData;
import com.android.server.wifi.hotspot2.AnqpEvent;
import com.android.server.wifi.hotspot2.IconEvent;
import com.android.server.wifi.hotspot2.WnmData;
@@ -95,7 +100,7 @@ import java.util.Random;
* Unit tests for SupplicantStaIfaceHal
*/
@SmallTest
-public class SupplicantStaIfaceHalTest {
+public class SupplicantStaIfaceHalTest extends WifiBaseTest {
private static final String TAG = "SupplicantStaIfaceHalTest";
private static final Map<Integer, String> NETWORK_ID_TO_SSID = new HashMap<Integer, String>() {{
put(1, "\"ssid1\"");
@@ -112,22 +117,27 @@ public class SupplicantStaIfaceHalTest {
private static final String ICON_FILE_NAME = "blahblah";
private static final int ICON_FILE_SIZE = 72;
private static final String HS20_URL = "http://blahblah";
+ private static final long PMK_CACHE_EXPIRATION_IN_SEC = 1024;
private @Mock IServiceManager mServiceManagerMock;
private @Mock ISupplicant mISupplicantMock;
private android.hardware.wifi.supplicant.V1_1.ISupplicant mISupplicantMockV1_1;
private android.hardware.wifi.supplicant.V1_2.ISupplicant mISupplicantMockV1_2;
+ private android.hardware.wifi.supplicant.V1_3.ISupplicant mISupplicantMockV13;
private @Mock ISupplicantIface mISupplicantIfaceMock;
private @Mock ISupplicantStaIface mISupplicantStaIfaceMock;
private @Mock android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface
mISupplicantStaIfaceMockV1_1;
private @Mock android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
mISupplicantStaIfaceMockV1_2;
+ private @Mock android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
+ mISupplicantStaIfaceMockV13;
private @Mock Context mContext;
private @Mock WifiMonitor mWifiMonitor;
private @Mock PropertyService mPropertyService;
private @Mock SupplicantStaNetworkHal mSupplicantStaNetworkMock;
private @Mock WifiNative.SupplicantDeathEventHandler mSupplicantHalDeathHandler;
+ private @Mock Clock mClock;
SupplicantStatus mStatusSuccess;
SupplicantStatus mStatusFailure;
@@ -140,7 +150,10 @@ public class SupplicantStaIfaceHalTest {
mISupplicantStaIfaceCallbackV1_1;
android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback
mISupplicantStaIfaceCallbackV1_2;
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback
+ mISupplicantStaIfaceCallbackV13 = null;
private TestLooper mLooper = new TestLooper();
+ private Handler mHandler = null;
private SupplicantStaIfaceHal mDut;
private ArgumentCaptor<IHwBinder.DeathRecipient> mServiceManagerDeathCaptor =
ArgumentCaptor.forClass(IHwBinder.DeathRecipient.class);
@@ -155,7 +168,8 @@ public class SupplicantStaIfaceHalTest {
private class SupplicantStaIfaceHalSpy extends SupplicantStaIfaceHal {
SupplicantStaIfaceHalSpy() {
- super(mContext, mWifiMonitor, mPropertyService, mLooper.getLooper());
+ super(mContext, mWifiMonitor, mPropertyService,
+ mHandler, mClock);
}
@Override
@@ -192,6 +206,14 @@ public class SupplicantStaIfaceHalTest {
}
@Override
+ protected android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
+ getStaIfaceMockableV1_3(ISupplicantIface iface) {
+ return (mISupplicantMockV13 != null)
+ ? mISupplicantStaIfaceMockV13
+ : null;
+ }
+
+ @Override
protected SupplicantStaNetworkHal getStaNetworkMockable(
@NonNull String ifaceName,
ISupplicantStaNetwork iSupplicantStaNetwork) {
@@ -212,7 +234,6 @@ public class SupplicantStaIfaceHalTest {
mIfaceInfoList.add(mStaIface0);
mIfaceInfoList.add(mStaIface1);
mIfaceInfoList.add(mP2pIface);
-
when(mServiceManagerMock.getTransport(anyString(), anyString()))
.thenReturn(IServiceManager.Transport.EMPTY);
when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
@@ -221,6 +242,7 @@ public class SupplicantStaIfaceHalTest {
any(IServiceNotification.Stub.class))).thenReturn(true);
when(mISupplicantMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
anyLong())).thenReturn(true);
+ mHandler = spy(new Handler(mLooper.getLooper()));
mDut = new SupplicantStaIfaceHalSpy();
}
@@ -275,10 +297,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testInitialize_successV1_1() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_1();
executeAndValidateInitializationSequenceV1_1(false, false);
}
@@ -288,27 +307,27 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testInitialize_successV1_2() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_2.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_2 = mock(android.hardware.wifi.supplicant.V1_2.ISupplicant.class);
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_2();
executeAndValidateInitializationSequenceV1_2();
}
/**
+ * Sunny day scenario for SupplicantStaIfaceHal initialization
+ * Asserts successful initialization
+ */
+ @Test
+ public void testInitialize_successV1_3() throws Exception {
+ setupMocksForHalV1_3();
+ executeAndValidateInitializationSequenceV1_3();
+ }
+
+ /**
* Tests the initialization flow, with a RemoteException occurring when 'getInterface' is called
* Ensures initialization fails.
*/
@Test
public void testInitialize_remoteExceptionFailureV1_1() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_1();
executeAndValidateInitializationSequenceV1_1(true, false);
}
@@ -318,10 +337,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testInitialize_nullInterfaceFailureV1_1() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_1();
executeAndValidateInitializationSequenceV1_1(false, true);
}
@@ -348,10 +364,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testDuplicateSetupIfaceV1_1_Fails() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_1();
executeAndValidateInitializationSequenceV1_1(false, false);
// Trying setting up the wlan0 interface again & ensure it fails.
@@ -422,240 +435,6 @@ public class SupplicantStaIfaceHalTest {
verify(mISupplicantStaIfaceMock, never()).cancelWps();
}
-
- /**
- * Tests the loading of networks using {@link SupplicantStaNetworkHal}.
- * Fills up only the SSID field of configs and uses it as a configKey as well.
- */
- @Test
- public void testLoadNetworks() throws Exception {
- executeAndValidateInitializationSequence();
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(ISupplicantStaIface.listNetworksCallback cb) {
- cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet()));
- }
- }).when(mISupplicantStaIfaceMock)
- .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) {
- // Reset the |mSupplicantStaNetwork| mock for each network.
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public boolean answer(
- WifiConfiguration config, Map<String, String> networkExtra) {
- config.SSID = NETWORK_ID_TO_SSID.get(networkId);
- config.networkId = networkId;
- networkExtra.put(
- SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY, config.SSID);
- return true;
- }
- }).when(mSupplicantStaNetworkMock)
- .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class));
- cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class));
- return;
- }
- }).when(mISupplicantStaIfaceMock)
- .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class));
-
- Map<String, WifiConfiguration> configs = new HashMap<>();
- SparseArray<Map<String, String>> extras = new SparseArray<>();
- assertTrue(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras));
-
- assertEquals(3, configs.size());
- assertEquals(3, extras.size());
- for (Map.Entry<Integer, String> network : NETWORK_ID_TO_SSID.entrySet()) {
- WifiConfiguration config = configs.get(network.getValue());
- assertTrue(config != null);
- assertEquals(network.getKey(), Integer.valueOf(config.networkId));
- assertEquals(network.getValue(), config.SSID);
- assertEquals(IpConfiguration.IpAssignment.DHCP, config.getIpAssignment());
- assertEquals(IpConfiguration.ProxySettings.NONE, config.getProxySettings());
- }
- }
-
- /**
- * Tests the loading of networks using {@link SupplicantStaNetworkHal} removes any networks
- * with duplicate config key.
- * Fills up only the SSID field of configs and uses it as a configKey as well.
- */
- @Test
- public void testLoadNetworksRemovesDuplicates() throws Exception {
- // Network ID which will have the same config key as the previous one.
- final int duplicateNetworkId = 2;
- final int toRemoveNetworkId = duplicateNetworkId - 1;
- executeAndValidateInitializationSequence();
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(ISupplicantStaIface.listNetworksCallback cb) {
- cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet()));
- }
- }).when(mISupplicantStaIfaceMock)
- .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public SupplicantStatus answer(int id) {
- return mStatusSuccess;
- }
- }).when(mISupplicantStaIfaceMock).removeNetwork(eq(toRemoveNetworkId));
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) {
- // Reset the |mSupplicantStaNetwork| mock for each network.
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public boolean answer(
- WifiConfiguration config, Map<String, String> networkExtra) {
- config.SSID = NETWORK_ID_TO_SSID.get(networkId);
- config.networkId = networkId;
- // Duplicate network gets the same config key as the to removed one.
- if (networkId == duplicateNetworkId) {
- networkExtra.put(
- SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY,
- NETWORK_ID_TO_SSID.get(toRemoveNetworkId));
- } else {
- networkExtra.put(
- SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY,
- NETWORK_ID_TO_SSID.get(networkId));
- }
- return true;
- }
- }).when(mSupplicantStaNetworkMock)
- .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class));
- cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class));
- return;
- }
- }).when(mISupplicantStaIfaceMock)
- .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class));
-
- Map<String, WifiConfiguration> configs = new HashMap<>();
- SparseArray<Map<String, String>> extras = new SparseArray<>();
- assertTrue(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras));
-
- assertEquals(2, configs.size());
- assertEquals(2, extras.size());
- for (Map.Entry<Integer, String> network : NETWORK_ID_TO_SSID.entrySet()) {
- if (network.getKey() == toRemoveNetworkId) {
- continue;
- }
- WifiConfiguration config;
- // Duplicate network gets the same config key as the to removed one. So, use that to
- // lookup the map.
- if (network.getKey() == duplicateNetworkId) {
- config = configs.get(NETWORK_ID_TO_SSID.get(toRemoveNetworkId));
- } else {
- config = configs.get(network.getValue());
- }
- assertTrue(config != null);
- assertEquals(network.getKey(), Integer.valueOf(config.networkId));
- assertEquals(network.getValue(), config.SSID);
- assertEquals(IpConfiguration.IpAssignment.DHCP, config.getIpAssignment());
- assertEquals(IpConfiguration.ProxySettings.NONE, config.getProxySettings());
- }
- }
-
- /**
- * Tests the failure to load networks because of listNetworks failure.
- */
- @Test
- public void testLoadNetworksFailedDueToListNetworks() throws Exception {
- executeAndValidateInitializationSequence();
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(ISupplicantStaIface.listNetworksCallback cb) {
- cb.onValues(mStatusFailure, null);
- }
- }).when(mISupplicantStaIfaceMock)
- .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
-
- Map<String, WifiConfiguration> configs = new HashMap<>();
- SparseArray<Map<String, String>> extras = new SparseArray<>();
- assertFalse(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras));
- }
-
- /**
- * Tests the failure to load networks because of getNetwork failure.
- */
- @Test
- public void testLoadNetworksFailedDueToGetNetwork() throws Exception {
- executeAndValidateInitializationSequence();
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(ISupplicantStaIface.listNetworksCallback cb) {
- cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet()));
- }
- }).when(mISupplicantStaIfaceMock)
- .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) {
- cb.onValues(mStatusFailure, mock(ISupplicantStaNetwork.class));
- return;
- }
- }).when(mISupplicantStaIfaceMock)
- .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class));
-
- Map<String, WifiConfiguration> configs = new HashMap<>();
- SparseArray<Map<String, String>> extras = new SparseArray<>();
- assertFalse(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras));
- }
-
- /**
- * Tests the failure to load networks because of loadWifiConfiguration failure.
- */
- @Test
- public void testLoadNetworksFailedDueToLoadWifiConfiguration() throws Exception {
- executeAndValidateInitializationSequence();
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(ISupplicantStaIface.listNetworksCallback cb) {
- cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet()));
- }
- }).when(mISupplicantStaIfaceMock)
- .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) {
- cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class));
- return;
- }
- }).when(mISupplicantStaIfaceMock)
- .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class));
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public boolean answer(WifiConfiguration config, Map<String, String> networkExtra) {
- return false;
- }
- }).when(mSupplicantStaNetworkMock)
- .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class));
-
- Map<String, WifiConfiguration> configs = new HashMap<>();
- SparseArray<Map<String, String>> extras = new SparseArray<>();
- assertTrue(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras));
- assertTrue(configs.isEmpty());
- }
-
- /**
- * Tests the failure to load networks because of loadWifiConfiguration exception.
- */
- @Test
- public void testLoadNetworksFailedDueToExceptionInLoadWifiConfiguration() throws Exception {
- executeAndValidateInitializationSequence();
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(ISupplicantStaIface.listNetworksCallback cb) {
- cb.onValues(mStatusSuccess, new ArrayList<>(NETWORK_ID_TO_SSID.keySet()));
- }
- }).when(mISupplicantStaIfaceMock)
- .listNetworks(any(ISupplicantStaIface.listNetworksCallback.class));
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public void answer(final int networkId, ISupplicantStaIface.getNetworkCallback cb) {
- cb.onValues(mStatusSuccess, mock(ISupplicantStaNetwork.class));
- return;
- }
- }).when(mISupplicantStaIfaceMock)
- .getNetwork(anyInt(), any(ISupplicantStaIface.getNetworkCallback.class));
- doAnswer(new MockAnswerUtil.AnswerWithArguments() {
- public boolean answer(WifiConfiguration config, Map<String, String> networkExtra)
- throws Exception {
- throw new IllegalArgumentException();
- }
- }).when(mSupplicantStaNetworkMock)
- .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class));
-
- Map<String, WifiConfiguration> configs = new HashMap<>();
- SparseArray<Map<String, String>> extras = new SparseArray<>();
- assertTrue(mDut.loadNetworks(WLAN0_IFACE_NAME, configs, extras));
- assertTrue(configs.isEmpty());
- }
-
/**
* Tests connection to a specified network with empty existing network.
*/
@@ -1694,10 +1473,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testStartDaemonV1_1() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_1();
executeAndValidateInitializationSequenceV1_1(false, false);
assertTrue(mDut.startDaemon());
@@ -1720,10 +1496,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testTerminateV1_1() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_1();
executeAndValidateInitializationSequenceV1_1(false, false);
mDut.terminate();
@@ -1749,10 +1522,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesOldHal() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_1();
executeAndValidateInitializationSequenceV1_1(false, false);
@@ -1764,14 +1534,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesWpa3Sae() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_2.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_2 = mock(android.hardware.wifi.supplicant.V1_2.ISupplicant.class);
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_2();
executeAndValidateInitializationSequenceV1_2();
@@ -1789,14 +1552,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesWpa3SuiteB() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_2.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_2 = mock(android.hardware.wifi.supplicant.V1_2.ISupplicant.class);
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_2();
executeAndValidateInitializationSequenceV1_2();
@@ -1815,14 +1571,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesOwe() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_2.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_2 = mock(android.hardware.wifi.supplicant.V1_2.ISupplicant.class);
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_2();
executeAndValidateInitializationSequenceV1_2();
@@ -1840,14 +1589,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesOweAndSae() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_2.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_2 = mock(android.hardware.wifi.supplicant.V1_2.ISupplicant.class);
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_2();
executeAndValidateInitializationSequenceV1_2();
@@ -1867,14 +1609,7 @@ public class SupplicantStaIfaceHalTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesDpp() throws Exception {
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_2.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_2 = mock(android.hardware.wifi.supplicant.V1_2.ISupplicant.class);
- when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
- .kInterfaceName), anyString()))
- .thenReturn(IServiceManager.Transport.HWBINDER);
- mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ setupMocksForHalV1_2();
executeAndValidateInitializationSequenceV1_2();
@@ -1901,6 +1636,139 @@ public class SupplicantStaIfaceHalTest {
assertFalse(mDut.startDppEnrolleeInitiator(WLAN0_IFACE_NAME, 3, 14));
}
+ /**
+ * Test adding PMK cache entry to the supplicant.
+ */
+ @Test
+ public void testSetPmkSuccess() throws Exception {
+ int testFrameworkNetworkId = 9;
+ long testStartSeconds = PMK_CACHE_EXPIRATION_IN_SEC / 2;
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = testFrameworkNetworkId;
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ PmkCacheStoreData pmkCacheData =
+ new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>());
+ mDut.mPmkCacheEntries.put(testFrameworkNetworkId, pmkCacheData);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartSeconds * 1000L);
+
+ setupMocksForHalV1_3();
+ setupMocksForPmkCache();
+ setupMocksForConnectSequence(false);
+
+ executeAndValidateInitializationSequenceV1_3();
+ assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
+
+ verify(mSupplicantStaNetworkMock).setPmkCache(eq(pmkCacheData.data));
+ verify(mISupplicantStaIfaceCallbackV13)
+ .onPmkCacheAdded(eq(PMK_CACHE_EXPIRATION_IN_SEC), eq(pmkCacheData.data));
+ // there is only one cache entry, the next expiration alarm should be the same as
+ // its expiration time.
+ verify(mHandler).postDelayed(
+ /* private listener */ any(),
+ eq(SupplicantStaIfaceHal.PMK_CACHE_EXPIRATION_ALARM_TAG),
+ eq((PMK_CACHE_EXPIRATION_IN_SEC - testStartSeconds) * 1000));
+ }
+
+ /**
+ * Test adding PMK cache entry is not called if there is no
+ * valid PMK cache for a corresponding configuratoin.
+ */
+ @Test
+ public void testAddPmkEntryNotCalledIfNoPmkCache() throws Exception {
+ int testFrameworkNetworkId = 9;
+ long testStartSeconds = PMK_CACHE_EXPIRATION_IN_SEC / 2;
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = testFrameworkNetworkId;
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartSeconds * 1000L);
+
+ setupMocksForHalV1_3();
+ setupMocksForPmkCache();
+ setupMocksForConnectSequence(false);
+ executeAndValidateInitializationSequenceV1_3();
+ assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
+
+ verify(mSupplicantStaNetworkMock, never()).setPmkCache(any(ArrayList.class));
+ verify(mISupplicantStaIfaceCallbackV13, never()).onPmkCacheAdded(
+ anyLong(), any(ArrayList.class));
+ verify(mHandler, never()).postDelayed(
+ /* private listener */ any(),
+ eq(SupplicantStaIfaceHal.PMK_CACHE_EXPIRATION_ALARM_TAG),
+ anyLong());
+ }
+
+ /**
+ * Test adding PMK cache entry returns faliure if HAL version is less than 1_3
+ */
+ @Test
+ public void testAddPmkEntryIsOmittedWithOldHal() throws Exception {
+ int testFrameworkNetworkId = 9;
+ long testStartSeconds = PMK_CACHE_EXPIRATION_IN_SEC / 2;
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = testFrameworkNetworkId;
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ PmkCacheStoreData pmkCacheData =
+ new PmkCacheStoreData(PMK_CACHE_EXPIRATION_IN_SEC, new ArrayList<Byte>());
+ mDut.mPmkCacheEntries.put(testFrameworkNetworkId, pmkCacheData);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartSeconds * 1000L);
+
+ setupMocksForConnectSequence(false);
+ executeAndValidateInitializationSequence();
+ assertTrue(mDut.connectToNetwork(WLAN0_IFACE_NAME, config));
+
+ verify(mSupplicantStaNetworkMock).setPmkCache(eq(pmkCacheData.data));
+ assertNull(mISupplicantStaIfaceCallbackV13);
+ verify(mHandler, never()).postDelayed(
+ /* private listener */ any(),
+ eq(SupplicantStaIfaceHal.PMK_CACHE_EXPIRATION_ALARM_TAG),
+ anyLong());
+ }
+
+ /**
+ * Test getWifiTechnology
+ * Should fail if running HAL lower than V1_3
+ */
+ @Test
+ public void testGetWifiTechnologyV1_2() throws Exception {
+ setupMocksForHalV1_2();
+ executeAndValidateInitializationSequenceV1_2();
+
+ assertEquals(WifiInfo.WIFI_TECHNOLOGY_UNKNOWN, mDut.getWifiTechnology(WLAN0_IFACE_NAME));
+ }
+
+ private class GetConnCapabilitiesAnswer extends MockAnswerUtil.AnswerWithArguments {
+ private ConnectionCapabilities mConnCapabilities;
+
+ GetConnCapabilitiesAnswer(int wifiTechnology) {
+ mConnCapabilities = new ConnectionCapabilities();
+ mConnCapabilities.technology = wifiTechnology;
+ }
+
+ public void answer(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
+ .getConnectionCapabilitiesCallback cb) {
+ cb.onValues(mStatusSuccess, mConnCapabilities);
+ }
+ }
+
+ /**
+ * Test getWifiTechnology if running with HAL V1_3
+ */
+ @Test
+ public void testGetWifiTechnologyV1_3() throws Exception {
+ setupMocksForHalV1_3();
+
+ executeAndValidateInitializationSequenceV1_3();
+ int testWifiTechnologyHal = WifiTechnology.VHT;
+ int testWifiTechnologyWifiInfo = WifiInfo.WIFI_TECHNOLOGY_11AC;
+
+ doAnswer(new GetConnCapabilitiesAnswer(testWifiTechnologyHal))
+ .when(mISupplicantStaIfaceMockV13).getConnectionCapabilities(any(
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
+ .getConnectionCapabilitiesCallback.class));
+
+ assertEquals(testWifiTechnologyWifiInfo, mDut.getWifiTechnology(WLAN0_IFACE_NAME));
+ }
+
private WifiConfiguration createTestWifiConfiguration() {
WifiConfiguration config = new WifiConfiguration();
config.networkId = SUPPLICANT_NETWORK_ID;
@@ -2152,6 +2020,60 @@ public class SupplicantStaIfaceHalTest {
// any(ISupplicant.getInterfaceCallback.class));
}
+ /**
+ * Calls.initialize(), mocking various call back answers and verifying flow, asserting for the
+ * expected result. Verifies if ISupplicantStaIface manager is initialized or reset.
+ * Each of the arguments will cause a different failure mode when set true.
+ */
+ private void executeAndValidateInitializationSequenceV1_3()
+ throws Exception {
+ // Setup callback mock answers
+ doAnswer(new GetAddInterfaceAnswerV1_3(false))
+ .when(mISupplicantMockV1_1).addInterface(any(ISupplicant.IfaceInfo.class),
+ any(android.hardware.wifi.supplicant.V1_1.ISupplicant
+ .addInterfaceCallback.class));
+
+ /** Callback registration */
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public SupplicantStatus answer(
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback cb)
+ throws RemoteException {
+ mISupplicantStaIfaceCallbackV13 = spy(cb);
+ return mStatusSuccess;
+ }
+ }).when(mISupplicantStaIfaceMockV13)
+ .registerCallback_1_3(
+ any(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback
+ .class));
+
+ mInOrder = inOrder(mServiceManagerMock, mISupplicantMock, mISupplicantMockV1_1,
+ mISupplicantStaIfaceMockV13, mWifiMonitor);
+ // Initialize SupplicantStaIfaceHal, should call serviceManager.registerForNotifications
+ assertTrue(mDut.initialize());
+ // verify: service manager initialization sequence
+ mInOrder.verify(mServiceManagerMock).linkToDeath(mServiceManagerDeathCaptor.capture(),
+ anyLong());
+ mInOrder.verify(mServiceManagerMock).registerForNotifications(
+ eq(ISupplicant.kInterfaceName), eq(""), mServiceNotificationCaptor.capture());
+ // act: cause the onRegistration(...) callback to execute
+ mServiceNotificationCaptor.getValue().onRegistration(ISupplicant.kInterfaceName, "", true);
+
+ assertTrue(mDut.isInitializationComplete());
+ assertTrue(mDut.setupIface(WLAN0_IFACE_NAME));
+ mInOrder.verify(mISupplicantMock).linkToDeath(mSupplicantDeathCaptor.capture(),
+ anyLong());
+ // verify: addInterface is called
+ mInOrder.verify(mISupplicantMockV1_1)
+ .addInterface(any(ISupplicant.IfaceInfo.class),
+ any(android.hardware.wifi.supplicant.V1_1.ISupplicant
+ .addInterfaceCallback.class));
+
+ mInOrder.verify(mISupplicantStaIfaceMockV13)
+ .registerCallback_1_3(
+ any(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback
+ .class));
+ }
+
private SupplicantStatus createSupplicantStatus(int code) {
SupplicantStatus status = new SupplicantStatus();
status.code = code;
@@ -2232,6 +2154,24 @@ public class SupplicantStaIfaceHalTest {
}
}
+ private class GetAddInterfaceAnswerV1_3 extends MockAnswerUtil.AnswerWithArguments {
+ boolean mGetNullInterface;
+
+ GetAddInterfaceAnswerV1_3(boolean getNullInterface) {
+ mGetNullInterface = getNullInterface;
+ }
+
+ public void answer(ISupplicant.IfaceInfo iface,
+ android.hardware.wifi.supplicant.V1_3.ISupplicant
+ .addInterfaceCallback cb) {
+ if (mGetNullInterface) {
+ cb.onValues(mStatusSuccess, null);
+ } else {
+ cb.onValues(mStatusSuccess, mISupplicantIfaceMock);
+ }
+ }
+ }
+
/**
* Setup mocks for connect sequence.
*/
@@ -2360,4 +2300,65 @@ public class SupplicantStaIfaceHalTest {
verify(mISupplicantStaIfaceMock).reassociate();
}
}
+
+ /**
+ * Helper function to set up Hal cascadingly.
+ */
+ private void setupMocksForHalV1_1() throws Exception {
+ // V1_0 is set up by default, no need to do it.
+ when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_1.ISupplicant
+ .kInterfaceName), anyString()))
+ .thenReturn(IServiceManager.Transport.HWBINDER);
+ mISupplicantMockV1_1 = mock(android.hardware.wifi.supplicant.V1_1.ISupplicant.class);
+ }
+
+ private void setupMocksForHalV1_2() throws Exception {
+ setupMocksForHalV1_1();
+ when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_2.ISupplicant
+ .kInterfaceName), anyString()))
+ .thenReturn(IServiceManager.Transport.HWBINDER);
+ mISupplicantMockV1_2 = mock(android.hardware.wifi.supplicant.V1_2.ISupplicant.class);
+ }
+
+ private void setupMocksForHalV1_3() throws Exception {
+ setupMocksForHalV1_2();
+ when(mServiceManagerMock.getTransport(eq(android.hardware.wifi.supplicant.V1_3.ISupplicant
+ .kInterfaceName), anyString()))
+ .thenReturn(IServiceManager.Transport.HWBINDER);
+ mISupplicantMockV13 = mock(android.hardware.wifi.supplicant.V1_3.ISupplicant.class);
+ }
+
+ private void setupMocksForPmkCache() throws Exception {
+ /** Callback registration */
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public SupplicantStatus answer(
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback cb)
+ throws RemoteException {
+ mISupplicantStaIfaceCallbackV13 = cb;
+ return mStatusSuccess;
+ }
+ }).when(mISupplicantStaIfaceMockV13)
+ .registerCallback_1_3(
+ any(android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback
+ .class));
+
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public boolean answer(WifiConfiguration config, Map<String, String> networkExtra)
+ throws Exception {
+ config.networkId = SUPPLICANT_NETWORK_ID;
+ return true;
+ }
+ }).when(mSupplicantStaNetworkMock)
+ .loadWifiConfiguration(any(WifiConfiguration.class), any(Map.class));
+
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public boolean answer(ArrayList<Byte> serializedData)
+ throws Exception {
+ mISupplicantStaIfaceCallbackV13.onPmkCacheAdded(
+ PMK_CACHE_EXPIRATION_IN_SEC, serializedData);
+ return true;
+ }
+ }).when(mSupplicantStaNetworkMock)
+ .setPmkCache(any(ArrayList.class));
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java
index 796dce1dfa..1013318687 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java
@@ -19,6 +19,7 @@ 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.assertTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.eq;
@@ -62,7 +63,7 @@ import java.util.Random;
* Unit tests for SupplicantStaNetworkHal
*/
@SmallTest
-public class SupplicantStaNetworkHalTest {
+public class SupplicantStaNetworkHalTest extends WifiBaseTest {
private static final String IFACE_NAME = "wlan0";
private static final Map<String, String> NETWORK_EXTRAS_VALUES = new HashMap<>();
static {
@@ -79,6 +80,8 @@ public class SupplicantStaNetworkHalTest {
@Mock private ISupplicantStaNetwork mISupplicantStaNetworkMock;
@Mock
private android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork mISupplicantStaNetworkV12;
+ @Mock
+ private android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork mISupplicantStaNetworkV13;
@Mock private Context mContext;
@Mock private WifiMonitor mWifiMonitor;
@@ -86,6 +89,12 @@ public class SupplicantStaNetworkHalTest {
private MockResources mResources;
private ISupplicantStaNetworkCallback mISupplicantStaNetworkCallback;
+ enum SupplicantStaNetworkVersion {
+ V1_0,
+ V1_2,
+ V1_3,
+ }
+
/**
* Spy used to return the V1_2 ISupplicantStaNetwork mock object to simulate the 1.2 HAL running
* on the device.
@@ -104,6 +113,24 @@ public class SupplicantStaNetworkHalTest {
}
}
+ /**
+ * Spy used to return the V1_3 ISupplicantStaNetwork mock object to simulate the 1.3 HAL running
+ * on the device.
+ */
+ private class SupplicantStaNetworkHalSpyV1_3 extends SupplicantStaNetworkHalSpyV1_2 {
+ SupplicantStaNetworkHalSpyV1_3(ISupplicantStaNetwork iSupplicantStaNetwork,
+ String ifaceName,
+ Context context, WifiMonitor monitor) {
+ super(iSupplicantStaNetwork, ifaceName, context, monitor);
+ }
+
+ @Override
+ protected android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
+ getSupplicantStaNetworkForV1_3Mockable() {
+ return mISupplicantStaNetworkV13;
+ }
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -114,7 +141,7 @@ public class SupplicantStaNetworkHalTest {
mResources = new MockResources();
when(mContext.getResources()).thenReturn(mResources);
- createSupplicantStaNetwork();
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_0);
}
/**
@@ -123,8 +150,7 @@ public class SupplicantStaNetworkHalTest {
@Test
public void testOweNetworkWifiConfigurationSaveLoad() throws Exception {
// Now expose the V1.2 ISupplicantStaNetwork
- mSupplicantNetwork = new SupplicantStaNetworkHalSpyV1_2(mISupplicantStaNetworkMock,
- IFACE_NAME, mContext, mWifiMonitor);
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_2);
WifiConfiguration config = WifiConfigurationTestUtil.createOweNetwork();
config.updateIdentifier = "46";
@@ -147,15 +173,39 @@ public class SupplicantStaNetworkHalTest {
@Test
public void testSaePasswordNetworkWifiConfigurationSaveLoad() throws Exception {
// Now expose the V1.2 ISupplicantStaNetwork
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_2);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createSaeNetwork();
+ testWifiConfigurationSaveLoad(config);
+ verify(mISupplicantStaNetworkV12).setSaePassword(any(String.class));
+ verify(mISupplicantStaNetworkV12, never())
+ .getSaePassword(any(android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
+ .getSaePasswordCallback.class));
+ verify(mISupplicantStaNetworkV12, never()).setSaePasswordId(any(String.class));
+ verify(mISupplicantStaNetworkV12, never())
+ .getPskPassphrase(any(ISupplicantStaNetwork.getPskPassphraseCallback.class));
+ verify(mISupplicantStaNetworkV12, never()).setPsk(any(byte[].class));
+ verify(mISupplicantStaNetworkV12, never())
+ .getPsk(any(ISupplicantStaNetwork.getPskCallback.class));
+ }
+
+ /**
+ * Tests the saving/loading of WifiConfiguration to wpa_supplicant with SAE password identifier.
+ */
+ @Test
+ public void testSaePasswordIdNetworkWifiConfigurationSaveLoad() throws Exception {
+ // Now expose the V1.2 ISupplicantStaNetwork
mSupplicantNetwork = new SupplicantStaNetworkHalSpyV1_2(mISupplicantStaNetworkMock,
IFACE_NAME, mContext, mWifiMonitor);
WifiConfiguration config = WifiConfigurationTestUtil.createSaeNetwork();
+ config.saePasswordId = "TestIdentifier";
testWifiConfigurationSaveLoad(config);
verify(mISupplicantStaNetworkV12).setSaePassword(any(String.class));
verify(mISupplicantStaNetworkV12, never())
.getSaePassword(any(android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
.getSaePasswordCallback.class));
+ verify(mISupplicantStaNetworkV12).setSaePasswordId(any(String.class));
verify(mISupplicantStaNetworkV12, never())
.getPskPassphrase(any(ISupplicantStaNetwork.getPskPassphraseCallback.class));
verify(mISupplicantStaNetworkV12, never()).setPsk(any(byte[].class));
@@ -257,6 +307,23 @@ public class SupplicantStaNetworkHalTest {
* Tests the saving of WifiConfiguration to wpa_supplicant.
*/
@Test
+ public void testEapTlsNoneClientCertNetworkWithOcspWifiConfigurationSaveLoad()
+ throws Exception {
+ // Now expose the V1.3 ISupplicantStaNetwork
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_3);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
+ config.enterpriseConfig =
+ WifiConfigurationTestUtil.createTLSWifiEnterpriseConfigWithNonePhase2();
+ config.enterpriseConfig.setClientCertificateAlias("test_alias");
+ config.enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
+ testWifiConfigurationSaveLoad(config);
+ }
+
+ /**
+ * Tests the saving of WifiConfiguration to wpa_supplicant.
+ */
+ @Test
public void testEapTlsAkaNetworkWifiConfigurationSaveLoad() throws Exception {
WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
config.enterpriseConfig =
@@ -270,8 +337,7 @@ public class SupplicantStaNetworkHalTest {
@Test
public void testEapSuiteBRsaNetworkWifiConfigurationSaveLoad() throws Exception {
// Now expose the V1.2 ISupplicantStaNetwork
- mSupplicantNetwork = new SupplicantStaNetworkHalSpyV1_2(mISupplicantStaNetworkMock,
- IFACE_NAME, mContext, mWifiMonitor);
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_2);
WifiConfiguration config = WifiConfigurationTestUtil.createEapSuiteBNetwork();
config.allowedSuiteBCiphers.set(WifiConfiguration.SuiteBCipher.ECDHE_RSA);
@@ -297,8 +363,7 @@ public class SupplicantStaNetworkHalTest {
@Test
public void testEapSuiteBEcdsaNetworkWifiConfigurationSaveLoad() throws Exception {
// Now expose the V1.2 ISupplicantStaNetwork
- mSupplicantNetwork = new SupplicantStaNetworkHalSpyV1_2(mISupplicantStaNetworkMock,
- IFACE_NAME, mContext, mWifiMonitor);
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_2);
WifiConfiguration config = WifiConfigurationTestUtil.createEapSuiteBNetwork();
config.allowedSuiteBCiphers.set(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA);
@@ -320,42 +385,6 @@ public class SupplicantStaNetworkHalTest {
}
/**
- * Tests the loading of network ID.
- */
- @Test
- public void testNetworkIdLoad() throws Exception {
- WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
- assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
-
- // Modify the supplicant variable directly.
- mSupplicantVariables.networkId = 5;
- WifiConfiguration loadConfig = new WifiConfiguration();
- Map<String, String> networkExtras = new HashMap<>();
- assertTrue(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
- assertEquals(mSupplicantVariables.networkId, loadConfig.networkId);
- }
-
- /**
- * Tests the failure to load ssid aborts the loading of network variables.
- */
- @Test
- public void testSsidLoadFailure() throws Exception {
- WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
- assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
-
- doAnswer(new AnswerWithArguments() {
- public void answer(ISupplicantStaNetwork.getSsidCallback cb) throws RemoteException {
- cb.onValues(mStatusFailure, mSupplicantVariables.ssid);
- }
- }).when(mISupplicantStaNetworkMock)
- .getSsid(any(ISupplicantStaNetwork.getSsidCallback.class));
-
- WifiConfiguration loadConfig = new WifiConfiguration();
- Map<String, String> networkExtras = new HashMap<>();
- assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
- }
-
- /**
* Tests the failure to save ssid.
*/
@Test
@@ -388,27 +417,6 @@ public class SupplicantStaNetworkHalTest {
}
/**
- * Tests the failure to load invalid key mgmt (unknown bit set in the
- * supplicant network key_mgmt variable read).
- */
- @Test
- public void testInvalidKeyMgmtLoadFailure() throws Exception {
- WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
- assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
-
- // Modify the supplicant variable directly.
- mSupplicantVariables.keyMgmtMask = 0xFFFFF;
- WifiConfiguration loadConfig = new WifiConfiguration();
- Map<String, String> networkExtras = new HashMap<>();
- try {
- assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
- } catch (IllegalArgumentException e) {
- return;
- }
- assertTrue(false);
- }
-
- /**
* Tests the failure to save invalid bssid (less than 6 bytes in the
* {@link WifiConfiguration#BSSID} being saved).
*/
@@ -425,81 +433,6 @@ public class SupplicantStaNetworkHalTest {
}
/**
- * Tests the failure to load invalid bssid (less than 6 bytes in the supplicant bssid variable
- * read).
- */
- @Test
- public void testInvalidBssidLoadFailure() throws Exception {
- WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
- assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
-
- // Modify the supplicant variable directly.
- mSupplicantVariables.bssid = new byte[3];
- WifiConfiguration loadConfig = new WifiConfiguration();
- Map<String, String> networkExtras = new HashMap<>();
- try {
- assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
- } catch (IllegalArgumentException e) {
- return;
- }
- assertTrue(false);
- }
-
- /**
- * Tests the loading of invalid ssid from wpa_supplicant.
- */
- @Test
- public void testInvalidSsidLoadFailure() throws Exception {
- WifiConfiguration config = WifiConfigurationTestUtil.createWepHiddenNetwork();
- assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
-
- // Modify the supplicant variable directly.
- mSupplicantVariables.ssid = null;
-
- WifiConfiguration loadConfig = new WifiConfiguration();
- Map<String, String> networkExtras = new HashMap<>();
- assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
- }
-
- /**
- * Tests the loading of invalid eap method from wpa_supplicant.
- * Invalid eap method is assumed to be a non enterprise network. So, the loading should
- * succeed as a non-enterprise network.
- */
- @Test
- public void testInvalidEapMethodLoadFailure() throws Exception {
- WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
- config.enterpriseConfig =
- WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
- assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
-
- // Modify the supplicant variable directly.
- mSupplicantVariables.eapMethod = -1;
-
- WifiConfiguration loadConfig = new WifiConfiguration();
- Map<String, String> networkExtras = new HashMap<>();
- assertTrue(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
- }
-
- /**
- * Tests the loading of invalid eap phase2 method from wpa_supplicant.
- */
- @Test
- public void testInvalidEapPhase2MethodLoadFailure() throws Exception {
- WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
- config.enterpriseConfig =
- WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
- assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
-
- // Modify the supplicant variable directly.
- mSupplicantVariables.eapPhase2Method = -1;
-
- WifiConfiguration loadConfig = new WifiConfiguration();
- Map<String, String> networkExtras = new HashMap<>();
- assertFalse(mSupplicantNetwork.loadWifiConfiguration(loadConfig, networkExtras));
- }
-
- /**
* Tests the parsing of GSM auth response parameters.
*/
@Test
@@ -732,8 +665,7 @@ public class SupplicantStaNetworkHalTest {
any(ArrayList.class), any(ArrayList.class));
// Now expose the V1.2 ISupplicantStaNetwork
- mSupplicantNetwork = new SupplicantStaNetworkHalSpyV1_2(mISupplicantStaNetworkMock,
- IFACE_NAME, mContext, mWifiMonitor);
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_2);
doAnswer(new AnswerWithArguments() {
public SupplicantStatus answer(ArrayList<Byte> identity,
ArrayList<Byte> encryptedIdentity)
@@ -755,7 +687,7 @@ public class SupplicantStaNetworkHalTest {
@Test
public void testAddFtPskFlags() throws Exception {
mResources.setBoolean(R.bool.config_wifi_fast_bss_transition_enabled, true);
- createSupplicantStaNetwork();
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_0);
WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
@@ -777,7 +709,7 @@ public class SupplicantStaNetworkHalTest {
@Test
public void testAddFtEapFlags() throws Exception {
mResources.setBoolean(R.bool.config_wifi_fast_bss_transition_enabled, true);
- createSupplicantStaNetwork();
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_0);
WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
@@ -800,8 +732,7 @@ public class SupplicantStaNetworkHalTest {
public void testAddPskSha256Flags() throws Exception {
WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
// Now expose the V1.2 ISupplicantStaNetwork
- mSupplicantNetwork = new SupplicantStaNetworkHalSpyV1_2(mISupplicantStaNetworkMock,
- IFACE_NAME, mContext, mWifiMonitor);
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_2);
assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
// Check the supplicant variables to ensure that we have added the SHA256 flags.
@@ -824,8 +755,7 @@ public class SupplicantStaNetworkHalTest {
public void testAddEapSha256Flags() throws Exception {
WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
// Now expose the V1.2 ISupplicantStaNetwork
- mSupplicantNetwork = new SupplicantStaNetworkHalSpyV1_2(mISupplicantStaNetworkMock,
- IFACE_NAME, mContext, mWifiMonitor);
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_2);
assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
// Check the supplicant variables to ensure that we have added the SHA256 flags.
@@ -872,6 +802,23 @@ public class SupplicantStaNetworkHalTest {
}
/**
+ * Tests OCSP status is ignored on HAL v1.2 or lower
+ */
+ @Test
+ public void testOcspStatusHal1_2OrLower() throws Exception {
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
+ config.enterpriseConfig =
+ WifiConfigurationTestUtil.createTLSWifiEnterpriseConfigWithNonePhase2();
+ config.enterpriseConfig.setClientCertificateAlias("test_alias");
+ config.enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
+
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ // Check the supplicant variables to ensure that we have NOT change the OCSP status.
+ assertEquals(WifiEnterpriseConfig.OCSP_NONE, mSupplicantVariables.ocsp);
+ }
+
+ /**
* Tests the retrieval of WPS NFC token.
*/
@Test
@@ -1026,6 +973,35 @@ public class SupplicantStaNetworkHalTest {
assertEquals(ANONYMOUS_IDENTITY, mSupplicantNetwork.fetchEapAnonymousIdentity());
}
+ /** Verifies that setPmkCache can set PMK cache
+ *
+ */
+ public void testSetPmkCache() {
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
+ config.enterpriseConfig =
+ WifiConfigurationTestUtil.createTLSWifiEnterpriseConfigWithNonePhase2();
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ ArrayList<Byte> serializedData = new ArrayList<>();
+ assertTrue(mSupplicantNetwork.setPmkCache(serializedData));
+ assertEquals(serializedData, mSupplicantVariables.serializedPmkCache);
+ }
+
+ /**
+ * Tests PMK cache is not set on HAL v1.2 or lower
+ */
+ @Test
+ public void testSetPmkCacheHal1_2OrLower() throws Exception {
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
+ config.enterpriseConfig =
+ WifiConfigurationTestUtil.createTLSWifiEnterpriseConfigWithNonePhase2();
+ assertTrue(mSupplicantNetwork.saveWifiConfiguration(config));
+
+ ArrayList<Byte> serializedData = new ArrayList<>();
+ assertFalse(mSupplicantNetwork.setPmkCache(serializedData));
+ assertNull(mSupplicantVariables.serializedPmkCache);
+ }
+
/**
* Sets up the HIDL interface mock with all the setters/getter values.
* Note: This only sets up the mock to return success on all methods.
@@ -1111,6 +1087,22 @@ public class SupplicantStaNetworkHalTest {
}).when(mISupplicantStaNetworkV12)
.getSaePassword(any(android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
.getSaePasswordCallback.class));
+ /** SAE password identifier*/
+ doAnswer(new AnswerWithArguments() {
+ public SupplicantStatus answer(String saePasswordId) throws RemoteException {
+ mSupplicantVariables.saePasswordId = saePasswordId;
+ return mStatusSuccess;
+ }
+ }).when(mISupplicantStaNetworkV12).setSaePasswordId(any(String.class));
+ doAnswer(new AnswerWithArguments() {
+ public void answer(android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
+ .getSaePasswordIdCallback cb)
+ throws RemoteException {
+ cb.onValues(mStatusSuccess, mSupplicantVariables.saePasswordId);
+ }
+ }).when(mISupplicantStaNetworkV12)
+ .getSaePasswordId(any(android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
+ .getSaePasswordIdCallback.class));
/** PSK passphrase */
doAnswer(new AnswerWithArguments() {
@@ -1565,6 +1557,32 @@ public class SupplicantStaNetworkHalTest {
return mStatusSuccess;
}
}).when(mISupplicantStaNetworkV12).enableSuiteBEapOpenSslCiphers();
+
+ /** OCSP */
+ doAnswer(new AnswerWithArguments() {
+ public SupplicantStatus answer(int ocsp) throws RemoteException {
+ mSupplicantVariables.ocsp = ocsp;
+ return mStatusSuccess;
+ }
+ }).when(mISupplicantStaNetworkV13).setOcsp(any(int.class));
+ doAnswer(new AnswerWithArguments() {
+ public void answer(
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.getOcspCallback cb)
+ throws RemoteException {
+ cb.onValues(mStatusSuccess, mSupplicantVariables.ocsp);
+ }
+ }).when(mISupplicantStaNetworkV13)
+ .getOcsp(any(android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
+ .getOcspCallback.class));
+
+ /** PMK cache */
+ doAnswer(new AnswerWithArguments() {
+ public SupplicantStatus answer(ArrayList<Byte> serializedData) throws RemoteException {
+ mSupplicantVariables.serializedPmkCache = serializedData;
+ return mStatusSuccess;
+ }
+ }).when(mISupplicantStaNetworkV13).setPmkCache(any(ArrayList.class));
+
}
private SupplicantStatus createSupplicantStatus(int code) {
@@ -1576,10 +1594,21 @@ public class SupplicantStaNetworkHalTest {
/**
* Need this for tests which wants to manipulate context before creating the instance.
*/
- private void createSupplicantStaNetwork() {
- mSupplicantNetwork =
- new SupplicantStaNetworkHal(mISupplicantStaNetworkMock, IFACE_NAME, mContext,
- mWifiMonitor);
+ private void createSupplicantStaNetwork(SupplicantStaNetworkVersion version) {
+ switch (version) {
+ case V1_0:
+ mSupplicantNetwork = new SupplicantStaNetworkHal(
+ mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor);
+ break;
+ case V1_2:
+ mSupplicantNetwork = new SupplicantStaNetworkHalSpyV1_2(
+ mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor);
+ break;
+ case V1_3:
+ mSupplicantNetwork = new SupplicantStaNetworkHalSpyV1_3(
+ mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor);
+ break;
+ }
mSupplicantNetwork.enableVerboseLogging(true);
}
@@ -1598,6 +1627,7 @@ public class SupplicantStaNetworkHalTest {
public String idStr;
public int updateIdentifier;
public String pskPassphrase;
+ public String saePasswordId;
public byte[] psk;
public ArrayList<Byte>[] wepKey = new ArrayList[4];
public int wepTxKeyIdx;
@@ -1616,5 +1646,7 @@ public class SupplicantStaNetworkHalTest {
public String eapEngineID;
public String eapDomainSuffixMatch;
public boolean eapProactiveKeyCaching;
+ public int ocsp;
+ public ArrayList<Byte> serializedPmkCache;
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStateTrackerTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStateTrackerTest.java
index d0713cc0f6..023d16d690 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStateTrackerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStateTrackerTest.java
@@ -43,7 +43,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link android.net.wifi.SupplicantStateTracker}.
*/
@SmallTest
-public class SupplicantStateTrackerTest {
+public class SupplicantStateTrackerTest extends WifiBaseTest {
private static final String TAG = "SupplicantStateTrackerTest";
private static final String sSSID = "\"GoogleGuest\"";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java b/service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java
index 5ef629254d..012889d4b8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/UntrustedWifiNetworkFactoryTest.java
@@ -35,7 +35,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.UntrustedWifiNetworkFactory}.
*/
@SmallTest
-public class UntrustedWifiNetworkFactoryTest {
+public class UntrustedWifiNetworkFactoryTest extends WifiBaseTest {
@Mock WifiConnectivityManager mWifiConnectivityManager;
@Mock Context mContext;
NetworkCapabilities mNetworkCapabilities;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/VelocityBasedConnectedScoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/VelocityBasedConnectedScoreTest.java
index 5fa0188bc7..1de1600848 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/VelocityBasedConnectedScoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/VelocityBasedConnectedScoreTest.java
@@ -38,7 +38,7 @@ import org.mockito.Spy;
* Unit tests for {@link com.android.server.wifi.VelocityBasedConnectedScore}.
*/
@SmallTest
-public class VelocityBasedConnectedScoreTest {
+public class VelocityBasedConnectedScoreTest extends WifiBaseTest {
class FakeClock extends Clock {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java
index c814aef1a8..7519de0644 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java
@@ -48,7 +48,7 @@ import java.util.Set;
* Unit tests for {@link WakeupConfigStoreData}.
*/
@SmallTest
-public class WakeupConfigStoreDataTest {
+public class WakeupConfigStoreDataTest extends WifiBaseTest {
@Mock private WakeupConfigStoreData.DataSource<Boolean> mActiveDataSource;
@Mock private WakeupConfigStoreData.DataSource<Boolean> mIsOnboardedDataSource;
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 009429b3f0..112d2fb74a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
@@ -32,6 +32,7 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
+import android.os.Handler;
import android.os.test.TestLooper;
import android.provider.Settings;
@@ -60,7 +61,7 @@ import java.util.Set;
* Unit tests for {@link WakeupController}.
*/
@SmallTest
-public class WakeupControllerTest {
+public class WakeupControllerTest extends WifiBaseTest {
private static final String SAVED_SSID = "test scan ssid";
private static final int DFS_CHANNEL_FREQ = 5540;
@@ -77,7 +78,7 @@ public class WakeupControllerTest {
@Mock private FrameworkFacade mFrameworkFacade;
@Mock private WifiSettingsStore mWifiSettingsStore;
@Mock private WifiWakeMetrics mWifiWakeMetrics;
- @Mock private WifiController mWifiController;
+ @Mock private ActiveModeWarden mActiveModeWarden;
@Mock private WifiNative mWifiNative;
@Mock private Clock mClock;
@@ -94,7 +95,7 @@ public class WakeupControllerTest {
when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
when(mWifiInjector.getWifiSettingsStore()).thenReturn(mWifiSettingsStore);
- when(mWifiInjector.getWifiController()).thenReturn(mWifiController);
+ when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
when(mWifiInjector.getWifiNative()).thenReturn(mWifiNative);
when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY))
.thenReturn(new int[]{DFS_CHANNEL_FREQ});
@@ -126,7 +127,7 @@ public class WakeupControllerTest {
Settings.Global.WIFI_WAKEUP_ENABLED, 0)).thenReturn(settingsValue);
when(mWakeupOnboarding.isOnboarded()).thenReturn(true);
mWakeupController = new WakeupController(mContext,
- mLooper.getLooper(),
+ new Handler(mLooper.getLooper()),
mWakeupLock,
mWakeupEvaluator,
mWakeupOnboarding,
@@ -363,10 +364,10 @@ public class WakeupControllerTest {
// suggestions
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork(quotedSsid);
WifiNetworkSuggestion openNetworkSuggestion =
- new WifiNetworkSuggestion(openNetwork, false, false, -1, "");
+ new WifiNetworkSuggestion(openNetwork, null, false, false, -1, "");
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
WifiNetworkSuggestion wepNetworkSuggestion =
- new WifiNetworkSuggestion(wepNetwork, false, false, -1, "");
+ new WifiNetworkSuggestion(wepNetwork, null, false, false, -1, "");
when(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions())
.thenReturn(new HashSet<>(Arrays.asList(
openNetworkSuggestion, wepNetworkSuggestion)));
@@ -408,7 +409,7 @@ public class WakeupControllerTest {
WifiConfiguration oweNetwork = WifiConfigurationTestUtil.createOweNetwork(quotedSsid2);
WifiNetworkSuggestion oweNetworkSuggestion =
- new WifiNetworkSuggestion(oweNetwork, false, false, -1, "");
+ new WifiNetworkSuggestion(oweNetwork, null, false, false, -1, "");
when(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions())
.thenReturn(new HashSet<>(Arrays.asList(oweNetworkSuggestion)));
@@ -506,7 +507,7 @@ public class WakeupControllerTest {
WifiConfiguration openNetwork = WifiConfigurationTestUtil
.createOpenNetwork(ScanResultUtil.createQuotedSSID(SAVED_SSID));
WifiNetworkSuggestion openNetworkSuggestion =
- new WifiNetworkSuggestion(openNetwork, false, false, -1, "");
+ new WifiNetworkSuggestion(openNetwork, null, false, false, -1, "");
when(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions())
.thenReturn(new HashSet<>(Collections.singletonList(openNetworkSuggestion)));
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WakeupEvaluatorTest.java b/service/tests/wifitests/src/com/android/server/wifi/WakeupEvaluatorTest.java
index 2510c33beb..fcbc7e2fde 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WakeupEvaluatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WakeupEvaluatorTest.java
@@ -40,7 +40,7 @@ import java.util.Set;
* Unit tests for {@link WakeupEvaluator}.
*/
@SmallTest
-public class WakeupEvaluatorTest {
+public class WakeupEvaluatorTest extends WifiBaseTest {
private static final String SAVED_SSID_1 = "saved ssid 1";
private static final String SAVED_SSID_2 = "saved ssid 2";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WakeupLockTest.java b/service/tests/wifitests/src/com/android/server/wifi/WakeupLockTest.java
index b588d6ace9..7c53f49851 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WakeupLockTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WakeupLockTest.java
@@ -39,7 +39,7 @@ import java.util.List;
* Unit tests for {@link WakeupLock}.
*/
@SmallTest
-public class WakeupLockTest {
+public class WakeupLockTest extends WifiBaseTest {
private static final String SSID_1 = "ssid1";
private static final String SSID_2 = "ssid2";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WakeupOnboardingTest.java b/service/tests/wifitests/src/com/android/server/wifi/WakeupOnboardingTest.java
index 605a08ff21..7d9cec22bb 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WakeupOnboardingTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WakeupOnboardingTest.java
@@ -50,7 +50,7 @@ import org.mockito.MockitoAnnotations;
/** Unit tests for {@link com.android.server.wifi.WakeupOnboarding} */
@SmallTest
-public class WakeupOnboardingTest {
+public class WakeupOnboardingTest extends WifiBaseTest {
@Mock private Context mContext;
@Mock private WifiConfigManager mWifiConfigManager;
@@ -78,8 +78,8 @@ public class WakeupOnboardingTest {
.thenReturn(mNotificationManager);
mLooper = new TestLooper();
- mWakeupOnboarding = new WakeupOnboarding(mContext, mWifiConfigManager, mLooper.getLooper(),
- mFrameworkFacade, mWakeupNotificationFactory);
+ mWakeupOnboarding = new WakeupOnboarding(mContext, mWifiConfigManager,
+ new Handler(mLooper.getLooper()), mFrameworkFacade, mWakeupNotificationFactory);
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
index c182788938..8799ba6e2d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -34,6 +34,7 @@ import android.content.pm.ApplicationInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.Build;
+import android.os.Handler;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
@@ -58,7 +59,7 @@ import java.util.Random;
* Unit tests for {@link com.android.server.wifi.WifiApConfigStore}.
*/
@SmallTest
-public class WifiApConfigStoreTest {
+public class WifiApConfigStoreTest extends WifiBaseTest {
private static final String TAG = "WifiApConfigStoreTest";
@@ -81,7 +82,8 @@ public class WifiApConfigStoreTest {
private static final String TEST_STRING_UTF8_WITH_34_BYTES = "Ευπροσηγοροςγινου";
@Mock private Context mContext;
- private TestLooper mLooper;
+ @Mock private WifiInjector mWifiInjector;
+ private Handler mHandler;
@Mock private BackupManagerProxy mBackupManagerProxy;
@Mock private FrameworkFacade mFrameworkFacade;
private File mApConfigFile;
@@ -94,7 +96,7 @@ public class WifiApConfigStoreTest {
@Before
public void setUp() throws Exception {
- mLooper = new TestLooper();
+ mHandler = new Handler(new TestLooper().getLooper());
MockitoAnnotations.initMocks(this);
when(mContext.getSystemService(Context.NOTIFICATION_SERVICE))
.thenReturn(mNotificationManager);
@@ -139,7 +141,7 @@ public class WifiApConfigStoreTest {
*/
private WifiApConfigStore createWifiApConfigStore() {
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
@@ -191,6 +193,7 @@ public class WifiApConfigStoreTest {
int randomPortion = Integer.parseInt(splitSsid[1]);
assertTrue(randomPortion >= RAND_SSID_INT_MIN && randomPortion <= RAND_SSID_INT_MAX);
assertTrue(config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK));
+ assertEquals(15, config.preSharedKey.length());
}
private void verifyDefaultLocalOnlyApConfig(WifiConfiguration config, String expectedSsid,
@@ -202,6 +205,7 @@ public class WifiApConfigStoreTest {
int randomPortion = Integer.parseInt(splitSsid[1]);
assertTrue(randomPortion >= RAND_SSID_INT_MIN && randomPortion <= RAND_SSID_INT_MAX);
assertTrue(config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK));
+ assertEquals(15, config.preSharedKey.length());
}
@@ -212,7 +216,7 @@ public class WifiApConfigStoreTest {
@Test
public void initWithDefaultConfiguration() throws Exception {
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
}
@@ -232,7 +236,7 @@ public class WifiApConfigStoreTest {
true /* Hidden SSID */);
writeApConfigFile(expectedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyApConfig(expectedConfig, store.getApConfiguration());
}
@@ -254,7 +258,7 @@ public class WifiApConfigStoreTest {
true /* Hidden SSID */);
writeApConfigFile(expectedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyApConfig(expectedConfig, store.getApConfiguration());
@@ -270,7 +274,7 @@ public class WifiApConfigStoreTest {
public void updateApConfiguration() throws Exception {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
@@ -296,7 +300,7 @@ public class WifiApConfigStoreTest {
public void convertSingleModeDeviceAnyTo5Ghz() throws Exception {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
@@ -330,7 +334,7 @@ public class WifiApConfigStoreTest {
public void singleModeDevice5GhzNotConverted() throws Exception {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
@@ -357,7 +361,7 @@ public class WifiApConfigStoreTest {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
@@ -393,7 +397,7 @@ public class WifiApConfigStoreTest {
/* Initialize WifiApConfigStore with default configuration. */
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyDefaultApConfig(store.getApConfiguration(), TEST_DEFAULT_AP_SSID);
@@ -434,7 +438,7 @@ public class WifiApConfigStoreTest {
false /* Hidden SSID */);
writeApConfigFile(persistedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyApConfig(expectedConfig, store.getApConfiguration());
verify(mBackupManagerProxy).notifyDataChanged();
@@ -457,7 +461,7 @@ public class WifiApConfigStoreTest {
writeApConfigFile(persistedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyApConfig(persistedConfig, store.getApConfiguration());
verify(mBackupManagerProxy, never()).notifyDataChanged();
@@ -489,7 +493,7 @@ public class WifiApConfigStoreTest {
writeApConfigFile(persistedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyApConfig(expectedConfig, store.getApConfiguration());
verify(mBackupManagerProxy).notifyDataChanged();
@@ -514,7 +518,7 @@ public class WifiApConfigStoreTest {
writeApConfigFile(persistedConfig);
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
verifyApConfig(persistedConfig, store.getApConfiguration());
verify(mBackupManagerProxy, never()).notifyDataChanged();
@@ -526,7 +530,7 @@ public class WifiApConfigStoreTest {
@Test
public void getDefaultApConfigurationIsValid() {
WifiApConfigStore store = new WifiApConfigStore(
- mContext, mLooper.getLooper(), mBackupManagerProxy, mFrameworkFacade,
+ mContext, mWifiInjector, mHandler, mBackupManagerProxy, mFrameworkFacade,
mApConfigFile.getPath());
WifiConfiguration config = store.getApConfiguration();
assertTrue(WifiApConfigStore.validateApWifiConfiguration(config));
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 9501143c89..45060a67e1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
@@ -51,7 +51,7 @@ import java.util.Random;
* Unit tests for {@link com.android.server.wifi.WifiBackupRestore}.
*/
@SmallTest
-public class WifiBackupRestoreTest {
+public class WifiBackupRestoreTest extends WifiBaseTest {
private static final String WIFI_BACKUP_DATA_WITH_UNSUPPORTED_TAG =
"<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiBaseTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiBaseTest.java
new file mode 100644
index 0000000000..a7fb733c77
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiBaseTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import org.junit.After;
+import org.mockito.Mockito;
+
+/**
+ * Base class for Wifi unit tests that cleans up inline mocks.
+ */
+public abstract class WifiBaseTest {
+ /**
+ * Clean up inline mocks to prevent OutOfMemory errors.
+ * See https://github.com/mockito/mockito/issues/1614
+ */
+ @After
+ public final void clearInlineMocks() {
+ Mockito.framework().clearInlineMocks();
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java
index 275d90deb2..5c07edc279 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java
@@ -36,7 +36,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WifiCandidates}.
*/
@SmallTest
-public class WifiCandidatesTest {
+public class WifiCandidatesTest extends WifiBaseTest {
@Mock ScanDetail mScanDetail1;
@Mock ScanDetail mScanDetail2;
@@ -79,10 +79,10 @@ public class WifiCandidatesTest {
*/
@Test
public void testDontDieFromNulls() throws Exception {
- mWifiCandidates.add(null, mConfig1, 1, 42);
- mWifiCandidates.add(mScanDetail1, null, 2, 16);
+ mWifiCandidates.add(null, mConfig1, 1, 42, 0.0, false);
+ mWifiCandidates.add(mScanDetail1, null, 2, 16, 0.0, false);
doReturn(null).when(mScanDetail2).getScanResult();
- mWifiCandidates.add(mScanDetail2, mConfig2, 3, 314, 1.0);
+ mWifiCandidates.add(mScanDetail2, mConfig2, 3, 314, 1.0, true);
assertFalse(mWifiCandidates.remove(null));
assertEquals(0, mWifiCandidates.size());
@@ -93,7 +93,7 @@ public class WifiCandidatesTest {
*/
@Test
public void testAddJustOne() throws Exception {
- assertTrue(mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0));
+ assertTrue(mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0, false));
assertEquals(1, mWifiCandidates.size());
assertEquals(0, mWifiCandidates.getFaultCount());
@@ -108,7 +108,7 @@ public class WifiCandidatesTest {
public void testQuotingBotch() throws Exception {
// Unfortunately ScanResult.SSID is not quoted; make sure we catch that
mScanResult1.SSID = mConfig1.SSID;
- mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0);
+ mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0, true);
// Should not have added this one
assertEquals(0, mWifiCandidates.size());
@@ -136,7 +136,7 @@ public class WifiCandidatesTest {
assertFalse(matchInfo1 == matchInfo1Prime); // Checking assumption
MacAddress mac1 = MacAddress.createRandomUnicastAddress();
MacAddress mac2 = MacAddress.createRandomUnicastAddress();
- assertNotEquals(mac1, mac2); // really tiny probablility of failing here
+ assertNotEquals(mac1, mac2); // really tiny probability of failing here
WifiCandidates.Key key1 = new WifiCandidates.Key(matchInfo1, mac1, 1);
@@ -167,7 +167,7 @@ public class WifiCandidatesTest {
assertTrue(mWifiCandidates == mWifiCandidates.setPicky(true));
try {
mScanResult1.SSID = mConfig1.SSID; // As in testQuotingBotch()
- mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0);
+ mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0, false);
fail("Exception not raised in picky mode");
} catch (IllegalArgumentException e) {
assertEquals(1, mWifiCandidates.getFaultCount());
@@ -181,23 +181,23 @@ public class WifiCandidatesTest {
@Test
public void testNoOverwriteCases() throws Exception {
// Setup is to add the first candidate
- mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0);
+ mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0, false);
assertEquals(1, mWifiCandidates.size());
// Same evaluator, same score. Should not add.
- assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0));
+ assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0, false));
assertEquals(0, mWifiCandidates.getFaultCount()); // But not considered a fault
// Same evaluator, lower score. Should not add.
- assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 2, 13, 0.0));
+ assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 2, 13, 0.0, false));
assertEquals(0, mWifiCandidates.getFaultCount()); // Also not a fault
// Later evaluator. Should not add (regardless of score).
- assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 5, 13));
- assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 5, 15));
+ assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 5, 13, 0.0, false));
+ assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 5, 15, 0.0, false));
assertEquals(0, mWifiCandidates.getFaultCount()); // Still no faults
// Evaluator out of order. Should not add (regardless of score).
- assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 1, 12));
+ assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 1, 12, 0.0, false));
assertNotNull(mWifiCandidates.getLastFault()); // This one is considered a caller error
- assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 1, 15));
+ assertFalse(mWifiCandidates.add(mScanDetail1, mConfig1, 1, 15, 0.0, false));
assertEquals(2, mWifiCandidates.getFaultCount());
// After all that, only one candidate should be there.
assertEquals(1, mWifiCandidates.size());
@@ -210,12 +210,12 @@ public class WifiCandidatesTest {
public void testBssidValidation() throws Exception {
// Null BSSID.
mScanResult1.BSSID = null;
- mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14);
+ mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0, false);
assertTrue("Expecting NPE, got " + mWifiCandidates.getLastFault(),
mWifiCandidates.getLastFault() instanceof NullPointerException);
// Malformed BSSID
mScanResult1.BSSID = "NotaBssid!";
- mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14);
+ mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0, false);
assertTrue("Expecting IAE, got " + mWifiCandidates.getLastFault(),
mWifiCandidates.getLastFault() instanceof IllegalArgumentException);
assertEquals(0, mWifiCandidates.size());
@@ -232,8 +232,8 @@ public class WifiCandidatesTest {
mScanResult2.SSID = mScanResult1.SSID;
mScanResult2.BSSID = mScanResult1.BSSID.replace('1', '2');
// Add both
- mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14);
- mWifiCandidates.add(mScanDetail2, mConfig2, 2, 14);
+ mWifiCandidates.add(mScanDetail1, mConfig1, 2, 14, 0.0, false);
+ mWifiCandidates.add(mScanDetail2, mConfig2, 2, 14, 0.0, false);
// We expect them both to be there
assertEquals(2, mWifiCandidates.size());
// But just one group
@@ -268,8 +268,8 @@ public class WifiCandidatesTest {
mScanResult2.SSID = mScanResult1.SSID;
mScanResult2.BSSID = mScanResult1.BSSID;
// Try adding them both, the higher-scoring one second
- assertTrue(mWifiCandidates.add(mScanDetail2, mConfig2, 2, 14));
- assertTrue(mWifiCandidates.add(mScanDetail1, mConfig1, 2, 15));
+ assertTrue(mWifiCandidates.add(mScanDetail2, mConfig2, 2, 14, 0.0, false));
+ assertTrue(mWifiCandidates.add(mScanDetail1, mConfig1, 2, 15, 0.0, false));
// Only one should survive
assertEquals(1, mWifiCandidates.size());
// And no faults
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 686b2098de..9789e1bec0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -20,14 +20,12 @@ import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import android.annotation.Nullable;
-import android.app.admin.DeviceAdminInfo;
-import android.app.admin.DevicePolicyManagerInternal;
+import android.app.ActivityManager;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.net.IpConfiguration;
import android.net.MacAddress;
@@ -38,6 +36,7 @@ import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
+import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
@@ -63,6 +62,7 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -80,7 +80,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.WifiConfigManager}.
*/
@SmallTest
-public class WifiConfigManagerTest {
+public class WifiConfigManagerTest extends WifiBaseTest {
private static final String TEST_SSID = "\"test_ssid\"";
private static final String TEST_BSSID = "0a:08:5c:67:89:00";
@@ -111,6 +111,8 @@ public class WifiConfigManagerTest {
private static final int TEST_FREQUENCY_1 = 2412;
private static final int TEST_FREQUENCY_2 = 5180;
private static final int TEST_FREQUENCY_3 = 5240;
+ private static final MacAddress TEST_RANDOMIZED_MAC =
+ MacAddress.fromString("d2:11:19:34:a5:20");
@Mock private Context mContext;
@Mock private Clock mClock;
@@ -120,7 +122,6 @@ public class WifiConfigManagerTest {
@Mock private WifiKeyStore mWifiKeyStore;
@Mock private WifiConfigStore mWifiConfigStore;
@Mock private PackageManager mPackageManager;
- @Mock private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
@Mock private WifiPermissionsUtil mWifiPermissionsUtil;
@Mock private WifiPermissionsWrapper mWifiPermissionsWrapper;
@Mock private WifiInjector mWifiInjector;
@@ -129,8 +130,9 @@ public class WifiConfigManagerTest {
@Mock private NetworkListUserStoreData mNetworkListUserStoreData;
@Mock private DeletedEphemeralSsidsStoreData mDeletedEphemeralSsidsStoreData;
@Mock private RandomizedMacStoreData mRandomizedMacStoreData;
- @Mock private WifiConfigManager.OnSavedNetworkUpdateListener mWcmListener;
+ @Mock private WifiConfigManager.OnNetworkUpdateListener mWcmListener;
@Mock private FrameworkFacade mFrameworkFacade;
+ @Mock private DeviceConfigFacade mDeviceConfigFacade;
@Mock private CarrierNetworkConfig mCarrierNetworkConfig;
private MockResources mResources;
@@ -187,15 +189,17 @@ public class WifiConfigManagerTest {
return "";
}
}).when(mPackageManager).getNameForUid(anyInt());
- doAnswer(new AnswerWithArguments() {
- public int answer(String packageName, int flags, int userId) throws Exception {
- if (packageName.equals(WifiConfigManager.SYSUI_PACKAGE_NAME)) {
- return TEST_SYSUI_UID;
- } else {
- return 0;
- }
- }
- }).when(mPackageManager).getPackageUidAsUser(anyString(), anyInt(), anyInt());
+
+ when(mContext.getSystemService(ActivityManager.class))
+ .thenReturn(mock(ActivityManager.class));
+ Context mockContext = mock(Context.class);
+ when(mContext.createPackageContextAsUser(
+ eq(WifiConfigManager.SYSUI_PACKAGE_NAME), anyInt(), any()))
+ .thenReturn(mockContext);
+ PackageManager mockPackageManager = mock(PackageManager.class);
+ when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
+ when(mockPackageManager.getPackageUid(eq(WifiConfigManager.SYSUI_PACKAGE_NAME), anyInt()))
+ .thenReturn(TEST_SYSUI_UID);
when(mWifiKeyStore
.updateNetworkKeys(any(WifiConfiguration.class), any()))
@@ -204,17 +208,15 @@ public class WifiConfigManagerTest {
when(mWifiConfigStore.areStoresPresent()).thenReturn(true);
setupStoreDataForRead(new ArrayList<>(), new ArrayList<>(), new HashMap<>());
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(), anyInt()))
- .thenReturn(false);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
- when(mWifiPermissionsWrapper.getDevicePolicyManagerInternal())
- .thenReturn(mDevicePolicyManagerInternal);
+ when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), any())).thenReturn(false);
+ when(mWifiPermissionsUtil.isProfileOwner(anyInt(), any())).thenReturn(false);
when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog);
when(mWifiInjector.getWifiLastResortWatchdog().shouldIgnoreSsidUpdate())
.thenReturn(false);
when(mWifiInjector.getCarrierNetworkConfig()).thenReturn(mCarrierNetworkConfig);
createWifiConfigManager();
- mWifiConfigManager.setOnSavedNetworkUpdateListener(mWcmListener);
+ mWifiConfigManager.addOnNetworkUpdateListener(mWcmListener);
ArgumentCaptor<ContentObserver> observerCaptor =
ArgumentCaptor.forClass(ContentObserver.class);
verify(mFrameworkFacade).registerContentObserver(eq(mContext), eq(Settings.Global.getUriFor(
@@ -228,9 +230,13 @@ public class WifiConfigManagerTest {
// static mocking
mSession = ExtendedMockito.mockitoSession()
.mockStatic(WifiConfigStore.class, withSettings().lenient())
+ .spyStatic(WifiConfigurationUtil.class)
+ .strictness(Strictness.LENIENT)
.startMocking();
when(WifiConfigStore.createUserFiles(anyInt())).thenReturn(mock(List.class));
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager);
+ when(WifiConfigurationUtil.calculatePersistentMacForConfiguration(any(), any()))
+ .thenReturn(TEST_RANDOMIZED_MAC);
}
/**
@@ -239,7 +245,9 @@ public class WifiConfigManagerTest {
@After
public void cleanup() {
validateMockitoUsage();
- mSession.finishMocking();
+ if (mSession != null) {
+ mSession.finishMocking();
+ }
}
/**
@@ -368,6 +376,7 @@ public class WifiConfigManagerTest {
*/
@Test
public void testAddingNetworkWithMatchingMacAddressOverridesField() {
+ int prevMappingSize = mWifiConfigManager.getRandomizedMacAddressMappingSize();
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
Map<String, String> randomizedMacAddressMapping = new HashMap<>();
final String randMac = "12:23:34:45:56:67";
@@ -382,6 +391,9 @@ public class WifiConfigManagerTest {
List<WifiConfiguration> retrievedNetworks =
mWifiConfigManager.getConfiguredNetworksWithPasswords();
assertEquals(randMac, retrievedNetworks.get(0).getRandomizedMacAddress().toString());
+ // Verify that for networks that we already have randomizedMacAddressMapping saved
+ // we are still correctly writing into the WifiConfigStore.
+ assertEquals(prevMappingSize + 1, mWifiConfigManager.getRandomizedMacAddressMappingSize());
}
/**
@@ -391,6 +403,7 @@ public class WifiConfigManagerTest {
*/
@Test
public void testRandomizedMacAddressIsPersistedOverForgetNetwork() {
+ int prevMappingSize = mWifiConfigManager.getRandomizedMacAddressMappingSize();
// Create and add an open network
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
verifyAddNetworkToWifiConfigManager(openNetwork);
@@ -410,6 +423,8 @@ public class WifiConfigManagerTest {
verifyAddNetworkToWifiConfigManager(openNetwork);
retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
assertEquals(randMac, retrievedNetworks.get(0).getRandomizedMacAddress().toString());
+ // Verify that we are no longer persisting the randomized MAC address with WifiConfigStore.
+ assertEquals(prevMappingSize, mWifiConfigManager.getRandomizedMacAddressMappingSize());
}
/**
@@ -438,7 +453,8 @@ public class WifiConfigManagerTest {
// This MAC should be different from the default, uninitialized randomized MAC.
assertNotEquals(defaultMac, randMac);
- assertTrue(mWifiConfigManager.removeNetwork(openNetwork.networkId, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.removeNetwork(
+ openNetwork.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
// Adds the network back again and verify randomized MAC address stays the same.
@@ -453,12 +469,15 @@ public class WifiConfigManagerTest {
*/
@Test
public void testUpdateSingleOpenNetwork() {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
List<WifiConfiguration> networks = new ArrayList<>();
networks.add(openNetwork);
verifyAddNetworkToWifiConfigManager(openNetwork);
- verify(mWcmListener).onSavedNetworkAdded(openNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
reset(mWcmListener);
// Now change BSSID for the network.
@@ -470,7 +489,8 @@ public class WifiConfigManagerTest {
mWifiConfigManager.getConfiguredNetworksWithPasswords();
WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
networks, retrievedNetworks);
- verify(mWcmListener).onSavedNetworkUpdated(openNetwork.networkId);
+ verify(mWcmListener).onNetworkUpdated(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -479,15 +499,17 @@ public class WifiConfigManagerTest {
*/
@Test
public void testCannotUpdateMacRandomizationSettingWithoutPermission() {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false);
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(), anyInt()))
- .thenReturn(true);
+ when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), any())).thenReturn(true);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
openNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
verifyAddNetworkToWifiConfigManager(openNetwork);
- verify(mWcmListener).onSavedNetworkAdded(openNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
reset(mWcmListener);
// Change BSSID for the network and verify success
@@ -507,6 +529,8 @@ public class WifiConfigManagerTest {
*/
@Test
public void testCanUpdateMacRandomizationSettingWithNetworkSettingPermission() {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
openNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
@@ -514,7 +538,8 @@ public class WifiConfigManagerTest {
networks.add(openNetwork);
verifyAddNetworkToWifiConfigManager(openNetwork);
- verify(mWcmListener).onSavedNetworkAdded(openNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
reset(mWcmListener);
// Now change the macRandomizationSetting and verify success
@@ -534,17 +559,19 @@ public class WifiConfigManagerTest {
*/
@Test
public void testCanUpdateMacRandomizationSettingWithSetupWizardPermission() {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(true);
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(), anyInt()))
- .thenReturn(true);
+ when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), any())).thenReturn(true);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
openNetwork.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
List<WifiConfiguration> networks = new ArrayList<>();
networks.add(openNetwork);
verifyAddNetworkToWifiConfigManager(openNetwork);
- verify(mWcmListener).onSavedNetworkAdded(openNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
reset(mWcmListener);
// Now change the macRandomizationSetting and verify success
@@ -566,6 +593,8 @@ public class WifiConfigManagerTest {
*/
@Test
public void testAddSingleEphemeralNetwork() throws Exception {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
WifiConfiguration ephemeralNetwork = WifiConfigurationTestUtil.createOpenNetwork();
ephemeralNetwork.ephemeral = true;
List<WifiConfiguration> networks = new ArrayList<>();
@@ -580,7 +609,8 @@ public class WifiConfigManagerTest {
// Ensure that this is not returned in the saved network list.
assertTrue(mWifiConfigManager.getSavedNetworks(Process.WIFI_UID).isEmpty());
- verify(mWcmListener, never()).onSavedNetworkAdded(ephemeralNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(ephemeralNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -590,6 +620,8 @@ public class WifiConfigManagerTest {
*/
@Test
public void testAddSinglePasspointNetwork() throws Exception {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
WifiConfiguration passpointNetwork = WifiConfigurationTestUtil.createPasspointNetwork();
verifyAddPasspointNetworkToWifiConfigManager(passpointNetwork);
@@ -598,7 +630,8 @@ public class WifiConfigManagerTest {
// Ensure that this is not returned in the saved network list.
assertTrue(mWifiConfigManager.getSavedNetworks(Process.WIFI_UID).isEmpty());
- verify(mWcmListener, never()).onSavedNetworkAdded(passpointNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(passpointNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -633,6 +666,8 @@ public class WifiConfigManagerTest {
@Test
public void testAddSingleSuggestionNetwork() throws Exception {
WifiConfiguration suggestionNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
suggestionNetwork.ephemeral = true;
suggestionNetwork.fromWifiNetworkSuggestion = true;
List<WifiConfiguration> networks = new ArrayList<>();
@@ -647,7 +682,8 @@ public class WifiConfigManagerTest {
// Ensure that this is not returned in the saved network list.
assertTrue(mWifiConfigManager.getSavedNetworks(Process.WIFI_UID).isEmpty());
- verify(mWcmListener, never()).onSavedNetworkAdded(suggestionNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(suggestionNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -657,6 +693,8 @@ public class WifiConfigManagerTest {
*/
@Test
public void testAddSingleSpecifierNetwork() throws Exception {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
WifiConfiguration suggestionNetwork = WifiConfigurationTestUtil.createOpenNetwork();
suggestionNetwork.ephemeral = true;
suggestionNetwork.fromWifiNetworkSpecifier = true;
@@ -672,7 +710,8 @@ public class WifiConfigManagerTest {
// Ensure that this is not returned in the saved network list.
assertTrue(mWifiConfigManager.getSavedNetworks(Process.WIFI_UID).isEmpty());
- verify(mWcmListener, never()).onSavedNetworkAdded(suggestionNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(suggestionNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -797,8 +836,7 @@ public class WifiConfigManagerTest {
// Configure mock DevicePolicyManager to give Profile Owner permission so that we can modify
// proxy settings on a configuration
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(),
- eq(DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))).thenReturn(true);
+ when(mWifiPermissionsUtil.isProfileOwner(anyInt(), any())).thenReturn(true);
// Change the IpConfiguration now and ensure that the IP configuration flags are set now.
assertAndSetNetworkIpConfiguration(
@@ -819,10 +857,13 @@ public class WifiConfigManagerTest {
*/
@Test
public void testRemoveSingleOpenNetwork() {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
verifyAddNetworkToWifiConfigManager(openNetwork);
- verify(mWcmListener).onSavedNetworkAdded(openNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
reset(mWcmListener);
// Ensure that configured network list is not empty.
@@ -831,7 +872,8 @@ public class WifiConfigManagerTest {
verifyRemoveNetworkFromWifiConfigManager(openNetwork);
// Ensure that configured network list is empty now.
assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
- verify(mWcmListener).onSavedNetworkRemoved(openNetwork.networkId);
+ verify(mWcmListener).onNetworkRemoved(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -842,16 +884,19 @@ public class WifiConfigManagerTest {
public void testRemoveSingleEphemeralNetwork() throws Exception {
WifiConfiguration ephemeralNetwork = WifiConfigurationTestUtil.createOpenNetwork();
ephemeralNetwork.ephemeral = true;
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
verifyAddEphemeralNetworkToWifiConfigManager(ephemeralNetwork);
// Ensure that configured network list is not empty.
assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
- verify(mWcmListener, never()).onSavedNetworkAdded(ephemeralNetwork.networkId);
-
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(ephemeralNetwork.networkId, wifiConfigCaptor.getValue().networkId);
verifyRemoveEphemeralNetworkFromWifiConfigManager(ephemeralNetwork);
// Ensure that configured network list is empty now.
assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
- verify(mWcmListener, never()).onSavedNetworkRemoved(ephemeralNetwork.networkId);
+ verify(mWcmListener).onNetworkRemoved(wifiConfigCaptor.capture());
+ assertEquals(ephemeralNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -860,17 +905,21 @@ public class WifiConfigManagerTest {
*/
@Test
public void testRemoveSinglePasspointNetwork() throws Exception {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
WifiConfiguration passpointNetwork = WifiConfigurationTestUtil.createPasspointNetwork();
verifyAddPasspointNetworkToWifiConfigManager(passpointNetwork);
// Ensure that configured network list is not empty.
assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
- verify(mWcmListener, never()).onSavedNetworkAdded(passpointNetwork.networkId);
+ verify(mWcmListener).onNetworkAdded(wifiConfigCaptor.capture());
+ assertEquals(passpointNetwork.networkId, wifiConfigCaptor.getValue().networkId);
verifyRemovePasspointNetworkFromWifiConfigManager(passpointNetwork);
// Ensure that configured network list is empty now.
assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
- verify(mWcmListener, never()).onSavedNetworkRemoved(passpointNetwork.networkId);
+ verify(mWcmListener).onNetworkRemoved(wifiConfigCaptor.capture());
+ assertEquals(passpointNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -888,7 +937,8 @@ public class WifiConfigManagerTest {
// Ensure that configured network list is not empty.
assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
- assertTrue(mWifiConfigManager.removeNetwork(passpointNetwork.networkId, Process.WIFI_UID));
+ assertTrue(mWifiConfigManager.removeNetwork(
+ passpointNetwork.networkId, Process.WIFI_UID, null));
// Verify keys are not being removed.
verify(mWifiKeyStore, never()).removeKeys(any(WifiEnterpriseConfig.class));
@@ -932,8 +982,7 @@ public class WifiConfigManagerTest {
// Configure mock DevicePolicyManager to give Profile Owner permission so that we can modify
// proxy settings on a configuration
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(),
- eq(DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))).thenReturn(true);
+ when(mWifiPermissionsUtil.isProfileOwner(anyInt(), any())).thenReturn(true);
verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(openNetwork);
verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(pskNetwork);
@@ -958,6 +1007,8 @@ public class WifiConfigManagerTest {
*/
@Test
public void testNetworkSelectionStatus() {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
@@ -975,19 +1026,21 @@ public class WifiConfigManagerTest {
for (int i = 1; i <= assocRejectThreshold; i++) {
verifyUpdateNetworkSelectionStatus(result.getNetworkId(), assocRejectReason, i);
}
- verify(mWcmListener).onSavedNetworkTemporarilyDisabled(
- networkId, NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION);
-
+ verify(mWcmListener).onNetworkTemporarilyDisabled(wifiConfigCaptor.capture(),
+ eq(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION));
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
// Now set it to permanently disabled.
verifyUpdateNetworkSelectionStatus(
result.getNetworkId(), NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER, 0);
- verify(mWcmListener).onSavedNetworkPermanentlyDisabled(
- networkId, NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER);
-
+ verify(mWcmListener).onNetworkPermanentlyDisabled(
+ wifiConfigCaptor.capture(), eq(NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER));
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
// Now set it back to enabled.
verifyUpdateNetworkSelectionStatus(
result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
- verify(mWcmListener, times(2)).onSavedNetworkEnabled(networkId);
+ verify(mWcmListener, times(2))
+ .onNetworkEnabled(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -996,6 +1049,8 @@ public class WifiConfigManagerTest {
*/
@Test
public void testNetworkSelectionStatusTemporarilyDisabledDueToNoInternet() {
+ ArgumentCaptor<WifiConfiguration> wifiConfigCaptor =
+ ArgumentCaptor.forClass(WifiConfiguration.class);
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
@@ -1007,15 +1062,18 @@ public class WifiConfigManagerTest {
// Now set it to temporarily disabled. The threshold for no internet is 1, so
// disable it once to actually mark it temporarily disabled.
- verifyUpdateNetworkSelectionStatus(
- result.getNetworkId(), NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY, 1);
- verify(mWcmListener).onSavedNetworkTemporarilyDisabled(
- networkId, NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY);
-
+ verifyUpdateNetworkSelectionStatus(result.getNetworkId(),
+ NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY, 1);
+ verify(mWcmListener).onNetworkTemporarilyDisabled(
+ wifiConfigCaptor.capture(),
+ eq(NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY));
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
// Now set it back to enabled.
verifyUpdateNetworkSelectionStatus(
result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
- verify(mWcmListener, times(2)).onSavedNetworkEnabled(networkId);
+ verify(mWcmListener, times(2))
+ .onNetworkEnabled(wifiConfigCaptor.capture());
+ assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId);
}
/**
@@ -1143,7 +1201,7 @@ public class WifiConfigManagerTest {
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
assertTrue(mWifiConfigManager.enableNetwork(
- result.getNetworkId(), false, TEST_CREATOR_UID));
+ result.getNetworkId(), false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
WifiConfiguration retrievedNetwork =
mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
@@ -1152,7 +1210,8 @@ public class WifiConfigManagerTest {
mContextConfigStoreMockOrder.verify(mWifiConfigStore).write(eq(true));
// Now set it disabled.
- assertTrue(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.disableNetwork(
+ result.getNetworkId(), TEST_CREATOR_UID, TEST_CREATOR_NAME));
retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
assertTrue(retrievedStatus.isNetworkPermanentlyDisabled());
@@ -1178,7 +1237,7 @@ public class WifiConfigManagerTest {
// Now try to set it enable with |TEST_UPDATE_UID|, it should fail and the network
// should remain disabled.
assertFalse(mWifiConfigManager.enableNetwork(
- result.getNetworkId(), true, TEST_UPDATE_UID));
+ result.getNetworkId(), true, TEST_UPDATE_UID, TEST_UPDATE_NAME));
WifiConfiguration retrievedNetwork =
mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
@@ -1201,13 +1260,14 @@ public class WifiConfigManagerTest {
WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
assertTrue(mWifiConfigManager.enableNetwork(
- result.getNetworkId(), true, TEST_CREATOR_UID));
+ result.getNetworkId(), true, TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertEquals(result.getNetworkId(), mWifiConfigManager.getLastSelectedNetwork());
// Now try to set it disabled with |TEST_UPDATE_UID|, it should fail and the network
// should remain enabled.
- assertFalse(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_UPDATE_UID));
+ assertFalse(mWifiConfigManager.disableNetwork(
+ result.getNetworkId(), TEST_UPDATE_UID, TEST_CREATOR_NAME));
WifiConfiguration retrievedNetwork =
mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
@@ -1220,6 +1280,31 @@ public class WifiConfigManagerTest {
}
/**
+ * Verifies the allowance/disallowance of autojoin to a network using
+ * {@link WifiConfigManager.allowAutojoin(int, boolean)}
+ */
+ @Test
+ public void testAllowDisallowAutojoin() throws Exception {
+ WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+
+ NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
+
+ assertTrue(mWifiConfigManager.allowAutojoin(
+ result.getNetworkId(), true));
+ WifiConfiguration retrievedNetwork =
+ mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+ assertTrue(retrievedNetwork.allowAutojoin);
+ mContextConfigStoreMockOrder.verify(mWifiConfigStore).write(eq(true));
+
+ // Now set it disallow auto-join.
+ assertTrue(mWifiConfigManager.allowAutojoin(
+ result.getNetworkId(), false));
+ retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+ assertFalse(retrievedNetwork.allowAutojoin);
+ mContextConfigStoreMockOrder.verify(mWifiConfigStore).write(eq(true));
+ }
+
+ /**
* Verifies the updation of network's connectUid using
* {@link WifiConfigManager#updateLastConnectUid(int, int)}.
*/
@@ -1257,7 +1342,8 @@ public class WifiConfigManagerTest {
@Test
public void testRemoveNetworkWithEmptyConfigStore() {
int networkId = new Random().nextInt();
- assertFalse(mWifiConfigManager.removeNetwork(networkId, TEST_CREATOR_UID));
+ assertFalse(mWifiConfigManager.removeNetwork(
+ networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME));
}
/**
@@ -1273,7 +1359,8 @@ public class WifiConfigManagerTest {
// Change the networkID to an invalid one.
openNetwork.networkId++;
- assertFalse(mWifiConfigManager.removeNetwork(openNetwork.networkId, TEST_CREATOR_UID));
+ assertFalse(mWifiConfigManager.removeNetwork(
+ openNetwork.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME));
}
/**
@@ -1291,8 +1378,9 @@ public class WifiConfigManagerTest {
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
assertFalse(mWifiConfigManager.enableNetwork(
- result.getNetworkId() + 1, false, TEST_CREATOR_UID));
- assertFalse(mWifiConfigManager.disableNetwork(result.getNetworkId() + 1, TEST_CREATOR_UID));
+ result.getNetworkId() + 1, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertFalse(mWifiConfigManager.disableNetwork(
+ result.getNetworkId() + 1, TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertFalse(mWifiConfigManager.updateNetworkSelectionStatus(
result.getNetworkId() + 1, NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER));
assertFalse(mWifiConfigManager.updateLastConnectUid(
@@ -1901,9 +1989,6 @@ public class WifiConfigManagerTest {
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(config);
- MacAddress testMac = MacAddress.createRandomUnicastAddress();
- mWifiConfigManager.setNetworkRandomizedMacAddress(result.getNetworkId(), testMac);
-
// Verify that randomized MAC address is masked when obtaining saved networks from
// invalid UID
List<WifiConfiguration> configs = mWifiConfigManager.getSavedNetworks(Process.INVALID_UID);
@@ -1914,7 +1999,8 @@ public class WifiConfigManagerTest {
// system UID
configs = mWifiConfigManager.getSavedNetworks(Process.WIFI_UID);
assertEquals(1, configs.size());
- assertEquals(testMac, configs.get(0).getRandomizedMacAddress());
+ String macAddress = configs.get(0).getRandomizedMacAddress().toString();
+ assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, macAddress);
// Verify that randomized MAC address is masked when obtaining saved networks from
// (carrier app) non-creator of the config
@@ -1926,18 +2012,149 @@ public class WifiConfigManagerTest {
// (carrier app) creator of the config
configs = mWifiConfigManager.getSavedNetworks(TEST_CREATOR_UID);
assertEquals(1, configs.size());
- assertEquals(testMac, configs.get(0).getRandomizedMacAddress());
+ assertEquals(macAddress, configs.get(0).getRandomizedMacAddress().toString());
// Verify that randomized MAC address is unmasked when getting list of privileged (with
// password) configurations
WifiConfiguration configWithRandomizedMac = mWifiConfigManager
.getConfiguredNetworkWithPassword(result.getNetworkId());
- assertEquals(testMac, configWithRandomizedMac.getRandomizedMacAddress());
+ assertEquals(macAddress, configs.get(0).getRandomizedMacAddress().toString());
// Ensure that the MAC address is present when asked for config with MAC address.
configWithRandomizedMac = mWifiConfigManager
.getConfiguredNetworkWithoutMasking(result.getNetworkId());
- assertEquals(testMac, configWithRandomizedMac.getRandomizedMacAddress());
+ assertEquals(macAddress, configs.get(0).getRandomizedMacAddress().toString());
+ }
+
+ /**
+ * Verifies that getRandomizedMacAndUpdateIfNeeded updates the randomized MAC address and
+ * |randomizedMacLastModifiedTimeMs| correctly.
+ *
+ * Then verify that getRandomizedMacAndUpdateIfNeeded sets the randomized MAC back to the
+ * persistent MAC.
+ */
+ @Test
+ public void testRandomizedMacUpdateAndRestore() {
+ setUpWifiConfigurationForAggressiveRandomization(true);
+ // get the persistent randomized MAC address.
+ WifiConfiguration config = getFirstInternalWifiConfiguration();
+ final String persistentMacString = config.getRandomizedMacAddress().toString();
+ assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, persistentMacString);
+
+ // verify the new randomized mac should be different from the original mac.
+ when(mClock.getWallClockMillis()).thenReturn(
+ WifiConfigManager.AGGRESSIVE_MAC_REFRESH_MS + 1);
+ MacAddress newMac = mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config);
+
+ // verify internal WifiConfiguration has MacAddress updated correctly by comparing the
+ // MAC address from internal WifiConfiguration with the value returned by API.
+ config = getFirstInternalWifiConfiguration();
+ assertEquals(newMac, config.getRandomizedMacAddress());
+ assertNotEquals(persistentMacString, newMac.toString());
+ assertEquals(WifiConfigManager.AGGRESSIVE_MAC_REFRESH_MS + 1,
+ config.randomizedMacLastModifiedTimeMs);
+
+ // Now disable aggressive randomization and verify the randomized MAC is changed back to
+ // the persistent MAC.
+ Set<String> blacklist = new HashSet<>();
+ blacklist.add(config.SSID);
+ mWifiConfigManager.setAggressiveMacRandomizationBlacklist(blacklist);
+
+ // verify the randomized mac should be set back to the persistent mac.
+ when(mClock.getWallClockMillis()).thenReturn(
+ WifiConfigManager.AGGRESSIVE_MAC_REFRESH_MS * 2);
+ newMac = mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config);
+
+ // verify internal WifiConfiguration has MacAddress updated correctly by comparing the
+ // MAC address from internal WifiConfiguration with the value returned by API.
+ config = getFirstInternalWifiConfiguration();
+ assertEquals(newMac, config.getRandomizedMacAddress());
+ assertEquals(persistentMacString, newMac.toString());
+ assertEquals(WifiConfigManager.AGGRESSIVE_MAC_REFRESH_MS * 2,
+ config.randomizedMacLastModifiedTimeMs);
+ }
+
+ /**
+ * Verifies that the randomized MAC address is not updated when insufficient time have past
+ * since the previous update.
+ */
+ @Test
+ public void testRandomizedMacIsNotUpdatedDueToTimeConstraint() {
+ setUpWifiConfigurationForAggressiveRandomization(true);
+ // get the persistent randomized MAC address.
+ WifiConfiguration config = getFirstInternalWifiConfiguration();
+ final String persistentMacString = config.getRandomizedMacAddress().toString();
+ assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, persistentMacString);
+
+ // verify that the randomized MAC is unchanged.
+ when(mClock.getWallClockMillis()).thenReturn(
+ WifiConfigManager.AGGRESSIVE_MAC_REFRESH_MS);
+ MacAddress newMac = mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config);
+ assertEquals(persistentMacString, newMac.toString());
+ }
+
+ /**
+ * Verifies that the randomized MAC address is not updated when if the network has not been
+ * connected to before.
+ */
+ @Test
+ public void testRandomizedMacIsNotUpdatedDueToHasNotConnected() {
+ setUpWifiConfigurationForAggressiveRandomization(false);
+ // get the persistent randomized MAC address.
+ WifiConfiguration config = getFirstInternalWifiConfiguration();
+ final String persistentMacString = config.getRandomizedMacAddress().toString();
+ assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, persistentMacString);
+
+ // verify that the randomized MAC is unchanged.
+ when(mClock.getWallClockMillis()).thenReturn(
+ WifiConfigManager.AGGRESSIVE_MAC_REFRESH_MS + 1);
+ MacAddress newMac = mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config);
+ assertEquals(persistentMacString, newMac.toString());
+ }
+
+ /**
+ * Verifies that the randomized MAC address is not updated when the aggressive randomization
+ * whitelist feature flag is disabled.
+ */
+ @Test
+ public void testRandomizedMacIsNotUpdatedDueToFeatureDisabled() {
+ setUpWifiConfigurationForAggressiveRandomization(true);
+ // get the persistent randomized MAC address.
+ WifiConfiguration config = getFirstInternalWifiConfiguration();
+ final String persistentMacString = config.getRandomizedMacAddress().toString();
+ assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, persistentMacString);
+
+ // disable the feature flag here.
+ when(mDeviceConfigFacade.isAggressiveMacRandomizationSsidWhitelistEnabled())
+ .thenReturn(false);
+
+ // verify that the randomized MAC is unchanged.
+ when(mClock.getWallClockMillis()).thenReturn(
+ WifiConfigManager.AGGRESSIVE_MAC_REFRESH_MS + 1);
+ MacAddress newMac = mWifiConfigManager.getRandomizedMacAndUpdateIfNeeded(config);
+ assertEquals(persistentMacString, newMac.toString());
+ }
+
+ private WifiConfiguration getFirstInternalWifiConfiguration() {
+ List<WifiConfiguration> configs = mWifiConfigManager.getSavedNetworks(Process.WIFI_UID);
+ assertEquals(1, configs.size());
+ return configs.get(0);
+ }
+
+ private void setUpWifiConfigurationForAggressiveRandomization(boolean hasEverConnected) {
+ // sets up a WifiConfiguration for aggressive randomization.
+ when(mDeviceConfigFacade.isAggressiveMacRandomizationSsidWhitelistEnabled())
+ .thenReturn(true);
+ WifiConfiguration c = WifiConfigurationTestUtil.createOpenNetwork();
+ NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(c);
+ // Adds the WifiConfiguration to aggressive randomization whitelist.
+ Set<String> ssidList = new HashSet<>();
+ ssidList.add(c.SSID);
+ mWifiConfigManager.setAggressiveMacRandomizationWhitelist(ssidList);
+ if (hasEverConnected) {
+ // sets hasEverConnected to true.
+ mWifiConfigManager.updateNetworkAfterConnect(c.networkId);
+ }
}
/**
@@ -1948,9 +2165,6 @@ public class WifiConfigManagerTest {
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(config);
- MacAddress testMac = MacAddress.createRandomUnicastAddress();
- mWifiConfigManager.setNetworkRandomizedMacAddress(result.getNetworkId(), testMac);
-
// Verify macRandomizationSetting is not masked out when feature is supported.
List<WifiConfiguration> configs = mWifiConfigManager.getSavedNetworks(Process.WIFI_UID);
assertEquals(1, configs.size());
@@ -1969,9 +2183,6 @@ public class WifiConfigManagerTest {
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(config);
- MacAddress testMac = MacAddress.createRandomUnicastAddress();
- mWifiConfigManager.setNetworkRandomizedMacAddress(result.getNetworkId(), testMac);
-
// Verify macRandomizationSetting is masked out when feature is unsupported.
List<WifiConfiguration> configs = mWifiConfigManager.getSavedNetworks(Process.WIFI_UID);
assertEquals(1, configs.size());
@@ -2028,9 +2239,12 @@ public class WifiConfigManagerTest {
verifyAddNetworkToWifiConfigManager(network3);
// Enable all of them.
- assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
- assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
- assertTrue(mWifiConfigManager.enableNetwork(network3.networkId, false, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network1.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network2.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network3.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
// Now set scan results in 2 of them to set the corresponding
// {@link NetworkSelectionStatus#mSeenInLastQualifiedNetworkSelection} field.
@@ -2052,7 +2266,8 @@ public class WifiConfigManagerTest {
assertEquals(network2.SSID, pnoNetworks.get(2).ssid);
// Now permanently disable |network3|. This should remove network 3 from the list.
- assertTrue(mWifiConfigManager.disableNetwork(network3.networkId, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.disableNetwork(
+ network3.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME));
// Retrieve the Pno network list again & verify the order of the networks returned.
pnoNetworks = mWifiConfigManager.retrievePnoNetworkList();
@@ -2078,8 +2293,10 @@ public class WifiConfigManagerTest {
verifyAddNetworkToWifiConfigManager(network2);
// Enable all of them.
- assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
- assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network1.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network2.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertTrue(mWifiConfigManager.updateNetworkAfterConnect(network1.networkId));
// Retrieve the Pno network list & verify the order of the networks returned.
@@ -2138,7 +2355,8 @@ public class WifiConfigManagerTest {
mContentObserverPnoChannelCulling.onChange(false);
WifiConfiguration network1 = WifiConfigurationTestUtil.createEapNetwork();
verifyAddNetworkToWifiConfigManager(network1);
- assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network1.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertTrue(mWifiConfigManager.updateNetworkAfterConnect(network1.networkId));
ScanDetail scanDetail1 = createScanDetailForNetwork(network1, TEST_BSSID + "1",
TEST_RSSI, TEST_FREQUENCY_1);
@@ -2169,9 +2387,12 @@ public class WifiConfigManagerTest {
verifyAddNetworkToWifiConfigManager(network3);
// Enable all of them.
- assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
- assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
- assertTrue(mWifiConfigManager.enableNetwork(network3.networkId, false, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network1.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network2.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network3.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
long firstConnectionTimeMillis = 45677;
long secondConnectionTimeMillis = firstConnectionTimeMillis + 45;
@@ -2212,9 +2433,12 @@ public class WifiConfigManagerTest {
verifyAddNetworkToWifiConfigManager(network3);
// Enable all of them.
- assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
- assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
- assertTrue(mWifiConfigManager.enableNetwork(network3.networkId, false, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network1.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network2.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network3.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
long firstConnectionTimeMillis = 45677;
long secondConnectionTimeMillis = firstConnectionTimeMillis + 45;
@@ -2269,9 +2493,12 @@ public class WifiConfigManagerTest {
verifyAddNetworkToWifiConfigManager(network3);
// Enable all of them.
- assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
- assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
- assertTrue(mWifiConfigManager.enableNetwork(network3.networkId, false, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network1.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network2.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
+ assertTrue(mWifiConfigManager.enableNetwork(
+ network3.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
long firstConnectionTimeMillis = 45677;
long secondConnectionTimeMillis = firstConnectionTimeMillis + 45;
@@ -2312,11 +2539,11 @@ public class WifiConfigManagerTest {
// Enable all of them.
assertTrue(mWifiConfigManager.enableNetwork(
- savedOpenNetwork.networkId, false, TEST_CREATOR_UID));
+ savedOpenNetwork.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertTrue(mWifiConfigManager.enableNetwork(
- ephemeralNetwork.networkId, false, TEST_CREATOR_UID));
+ ephemeralNetwork.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertTrue(mWifiConfigManager.enableNetwork(
- passpointNetwork.networkId, false, TEST_CREATOR_UID));
+ passpointNetwork.networkId, false, TEST_CREATOR_UID, TEST_CREATOR_NAME));
// Retrieve the Pno network list & verify the order of the networks returned.
List<WifiScanner.PnoSettings.PnoNetwork> pnoNetworks =
@@ -2886,7 +3113,7 @@ public class WifiConfigManagerTest {
};
setupStoreDataForUserRead(user2Networks, new HashMap<>());
// Now switch the user to user 2 and ensure that shared network's IDs have not changed.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
mWifiConfigManager.handleUserSwitch(user2);
verify(mWifiConfigStore).switchUserStoresAndRead(any(List.class));
@@ -2964,7 +3191,7 @@ public class WifiConfigManagerTest {
};
setupStoreDataForUserRead(user2Networks, new HashMap<>());
// Now switch the user to user 2 and ensure that user 1's private network has been removed.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
Set<Integer> removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
verify(mWifiConfigStore).switchUserStoresAndRead(any(List.class));
assertTrue((removedNetworks.size() == 1) && (removedNetworks.contains(user1NetworkId)));
@@ -2981,7 +3208,7 @@ public class WifiConfigManagerTest {
// Send another user switch indication with the same user 2. This should be ignored and
// hence should not remove any new networks.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
assertTrue(removedNetworks.isEmpty());
}
@@ -3025,7 +3252,7 @@ public class WifiConfigManagerTest {
};
setupStoreDataForUserRead(user2Networks, new HashMap<>());
// Now switch the user to user 2 and ensure that no private network has been removed.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
Set<Integer> removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
verify(mWifiConfigStore).switchUserStoresAndRead(any(List.class));
assertTrue(removedNetworks.isEmpty());
@@ -3089,7 +3316,7 @@ public class WifiConfigManagerTest {
// Now switch the user to user2 and ensure that user 2's private network has been moved to
// the user store.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
mWifiConfigManager.handleUserSwitch(user2);
// Set the expected network list before comparing. user1Network should be in shared data.
// Note: In the real world, user1Network will no longer be visible now because it should
@@ -3179,7 +3406,7 @@ public class WifiConfigManagerTest {
setupStoreDataForUserRead(new ArrayList<>(), new HashMap<>());
// user2 is unlocked and switched to foreground.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
mWifiConfigManager.handleUserSwitch(user2);
// Ensure that the read was invoked.
mContextConfigStoreMockOrder.verify(mWifiConfigStore)
@@ -3201,7 +3428,7 @@ public class WifiConfigManagerTest {
assertTrue(mWifiConfigManager.loadFromStore());
// user2 is locked and switched to foreground.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(false);
mWifiConfigManager.handleUserSwitch(user2);
// Ensure that the read was not invoked.
@@ -3234,7 +3461,7 @@ public class WifiConfigManagerTest {
assertTrue(mWifiConfigManager.loadFromStore());
// Try stopping background user2 first, this should not do anything.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(false);
mWifiConfigManager.handleUserStop(user2);
mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
.switchUserStoresAndRead(any(List.class));
@@ -3458,7 +3685,7 @@ public class WifiConfigManagerTest {
setupStoreDataForUserRead(new ArrayList<>(), new HashMap<>());
// user2 is unlocked and switched to foreground.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
mWifiConfigManager.handleUserSwitch(user2);
// Ensure that the read was invoked.
mContextConfigStoreMockOrder.verify(mWifiConfigStore)
@@ -3499,7 +3726,7 @@ public class WifiConfigManagerTest {
int user2 = TEST_DEFAULT_USER + 1;
setupUserProfiles(user2);
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(false);
mWifiConfigManager.handleUserSwitch(user2);
// Create a network for user2 try adding it. This should be rejected.
@@ -3560,7 +3787,7 @@ public class WifiConfigManagerTest {
setupStoreDataForUserRead(new ArrayList<>(), new HashMap<>());
// Now switch the user to user 2.
- when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true);
mWifiConfigManager.handleUserSwitch(user2);
// Ensure that the read was invoked.
mContextConfigStoreMockOrder.verify(mWifiConfigStore)
@@ -3580,22 +3807,24 @@ public class WifiConfigManagerTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(67L);
assertTrue(mWifiConfigManager.enableNetwork(
- result.getNetworkId(), true, TEST_CREATOR_UID));
+ result.getNetworkId(), true, TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertEquals(result.getNetworkId(), mWifiConfigManager.getLastSelectedNetwork());
assertEquals(67, mWifiConfigManager.getLastSelectedTimeStamp());
// Now disable the network and ensure that the last selected flag is cleared.
- assertTrue(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.disableNetwork(
+ result.getNetworkId(), TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertEquals(
WifiConfiguration.INVALID_NETWORK_ID, mWifiConfigManager.getLastSelectedNetwork());
// Enable it again and remove the network to ensure that the last selected flag was cleared.
assertTrue(mWifiConfigManager.enableNetwork(
- result.getNetworkId(), true, TEST_CREATOR_UID));
+ result.getNetworkId(), true, TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertEquals(result.getNetworkId(), mWifiConfigManager.getLastSelectedNetwork());
assertEquals(openNetwork.configKey(), mWifiConfigManager.getLastSelectedNetworkConfigKey());
- assertTrue(mWifiConfigManager.removeNetwork(result.getNetworkId(), TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.removeNetwork(
+ result.getNetworkId(), TEST_CREATOR_UID, TEST_CREATOR_NAME));
assertEquals(
WifiConfiguration.INVALID_NETWORK_ID, mWifiConfigManager.getLastSelectedNetwork());
}
@@ -3666,14 +3895,16 @@ public class WifiConfigManagerTest {
retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
// Remove network 3 and ensure that the connect choice on network 1 is not removed.
- assertTrue(mWifiConfigManager.removeNetwork(network3.networkId, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.removeNetwork(
+ network3.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME));
retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(network1.networkId);
assertEquals(
network2.configKey(),
retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
// Now remove network 2 and ensure that the connect choice on network 1 is removed..
- assertTrue(mWifiConfigManager.removeNetwork(network2.networkId, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.removeNetwork(
+ network2.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME));
retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(network1.networkId);
assertNotEquals(
network2.configKey(),
@@ -3719,7 +3950,7 @@ public class WifiConfigManagerTest {
}
/**
- * Verifies that Passpoint network corresponding with given FQDN is removed.
+ * Verifies that Passpoint network corresponding with given config key (FQDN) is removed.
*
* @throws Exception
*/
@@ -3729,7 +3960,22 @@ public class WifiConfigManagerTest {
verifyAddPasspointNetworkToWifiConfigManager(passpointNetwork);
assertTrue(mWifiConfigManager.removePasspointConfiguredNetwork(
- WifiConfigurationTestUtil.TEST_FQDN));
+ passpointNetwork.configKey()));
+ }
+
+ /**
+ * Verifies that suggested network corresponding with given config key is removed.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testRemoveSuggestionConfiguredNetwork() throws Exception {
+ WifiConfiguration suggestedNetwork = WifiConfigurationTestUtil.createEphemeralNetwork();
+ suggestedNetwork.fromWifiNetworkSuggestion = true;
+ verifyAddEphemeralNetworkToWifiConfigManager(suggestedNetwork);
+
+ assertTrue(mWifiConfigManager.removeSuggestionConfiguredNetwork(
+ suggestedNetwork.configKey()));
}
/**
@@ -4298,31 +4544,6 @@ public class WifiConfigManagerTest {
}
/**
- * Verifies that the method setNetworkRandomizedMacAddress changes the randomized MAC
- * address variable in the internal configuration.
- */
- @Test
- public void testSetNetworkRandomizedMacAddressUpdatesInternalMacAddress() {
- WifiConfiguration originalConfig = WifiConfigurationTestUtil.createOpenNetwork();
- NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(originalConfig);
-
- // Verify that internal randomized MAC address does not change from
- // from setting external randomized MAC address
- MacAddress originalMac = originalConfig.getOrCreateRandomizedMacAddress();
- WifiConfiguration retrievedConfig = mWifiConfigManager
- .getConfiguredNetworkWithoutMasking(result.getNetworkId());
- assertNotEquals(originalMac, retrievedConfig.getRandomizedMacAddress());
-
- // Verify that changing randomized MAC address through setNetworkRandomizedMacAddress
- // changes the internal randomized MAC address
- MacAddress newMac = MacAddress.createRandomUnicastAddress();
- mWifiConfigManager.setNetworkRandomizedMacAddress(result.getNetworkId(), newMac);
- retrievedConfig = mWifiConfigManager
- .getConfiguredNetworkWithoutMasking(result.getNetworkId());
- assertEquals(newMac, retrievedConfig.getRandomizedMacAddress());
- }
-
- /**
* Verifies that the method resetSimNetworks updates SIM presence status and SIM configs.
*/
@Test
@@ -4544,11 +4765,15 @@ public class WifiConfigManagerTest {
currentTimeMs = disableTimeMs + WifiConfigManager.DELETED_EPHEMERAL_SSID_EXPIRY_MS - 1;
when(mClock.getWallClockMillis()).thenReturn(currentTimeMs);
assertTrue(mWifiConfigManager.wasEphemeralNetworkDeleted(config.SSID));
+ assertTrue(mWifiConfigManager.getConfiguredNetwork(config.networkId)
+ .getNetworkSelectionStatus().isNetworkPermanentlyDisabled());
// After the expiry of timeout.
currentTimeMs = disableTimeMs + WifiConfigManager.DELETED_EPHEMERAL_SSID_EXPIRY_MS + 1;
when(mClock.getWallClockMillis()).thenReturn(currentTimeMs);
assertFalse(mWifiConfigManager.wasEphemeralNetworkDeleted(config.SSID));
+ assertFalse(mWifiConfigManager.getConfiguredNetwork(config.networkId)
+ .getNetworkSelectionStatus().isNetworkPermanentlyDisabled());
}
private NetworkUpdateResult verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
@@ -4578,12 +4803,10 @@ public class WifiConfigManagerTest {
network = mWifiConfigManager.getConfiguredNetwork(networkId);
}
network.setIpConfiguration(ipConfiguration);
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(),
- eq(DeviceAdminInfo.USES_POLICY_PROFILE_OWNER)))
- .thenReturn(withProfileOwnerPolicy);
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(),
- eq(DeviceAdminInfo.USES_POLICY_DEVICE_OWNER)))
+ when(mWifiPermissionsUtil.isDeviceOwner(anyInt(), any()))
.thenReturn(withDeviceOwnerPolicy);
+ when(mWifiPermissionsUtil.isProfileOwner(anyInt(), any()))
+ .thenReturn(withProfileOwnerPolicy);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt()))
.thenReturn(withNetworkSettings);
when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt()))
@@ -4604,7 +4827,7 @@ public class WifiConfigManagerTest {
mWifiPermissionsUtil, mWifiPermissionsWrapper, mWifiInjector,
mNetworkListSharedStoreData, mNetworkListUserStoreData,
mDeletedEphemeralSsidsStoreData, mRandomizedMacStoreData,
- mFrameworkFacade, mLooper.getLooper());
+ mFrameworkFacade, new Handler(mLooper.getLooper()), mDeviceConfigFacade);
mWifiConfigManager.enableVerboseLogging(1);
}
@@ -5073,7 +5296,8 @@ public class WifiConfigManagerTest {
*/
private void verifyRemoveNetworkFromWifiConfigManager(
WifiConfiguration configuration) {
- assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.removeNetwork(
+ configuration.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME));
verifyNetworkRemoveBroadcast(configuration);
// Verify if the config store write was triggered without this new configuration.
@@ -5085,7 +5309,8 @@ public class WifiConfigManagerTest {
*/
private void verifyRemoveEphemeralNetworkFromWifiConfigManager(
WifiConfiguration configuration) throws Exception {
- assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.removeNetwork(
+ configuration.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME));
verifyNetworkRemoveBroadcast(configuration);
// Ensure that the write was not invoked for ephemeral network remove.
@@ -5097,7 +5322,8 @@ public class WifiConfigManagerTest {
*/
private void verifyRemovePasspointNetworkFromWifiConfigManager(
WifiConfiguration configuration) throws Exception {
- assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
+ assertTrue(mWifiConfigManager.removeNetwork(
+ configuration.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME));
// Verify keys are not being removed.
verify(mWifiKeyStore, never()).removeKeys(any(WifiEnterpriseConfig.class));
@@ -5279,11 +5505,7 @@ public class WifiConfigManagerTest {
* @param userId Id of the user.
*/
private void setupUserProfiles(int userId) {
- final UserInfo userInfo =
- new UserInfo(userId, Integer.toString(userId), UserInfo.FLAG_PRIMARY);
- List<UserInfo> userProfiles = Arrays.asList(userInfo);
- when(mUserManager.getProfiles(userId)).thenReturn(userProfiles);
- when(mUserManager.isUserUnlockingOrUnlocked(userId)).thenReturn(true);
+ when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(userId))).thenReturn(true);
}
private void verifyRemoveNetworksForApp() {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
index b59e367dd2..799ad70f0e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.net.MacAddress;
import android.net.wifi.WifiConfiguration;
+import android.os.Handler;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
@@ -63,7 +64,7 @@ import java.util.Random;
* Unit tests for {@link com.android.server.wifi.WifiConfigStore}.
*/
@SmallTest
-public class WifiConfigStoreTest {
+public class WifiConfigStoreTest extends WifiBaseTest {
private static final String TEST_USER_DATA = "UserData";
private static final String TEST_SHARE_DATA = "ShareData";
private static final String TEST_CREATOR_NAME = "CreatorName";
@@ -87,6 +88,7 @@ public class WifiConfigStoreTest {
+ "<string name=\"SSID\">%s</string>\n"
+ "<null name=\"BSSID\" />\n"
+ "<null name=\"PreSharedKey\" />\n"
+ + "<null name=\"SaePasswordId\" />\n"
+ "<null name=\"WEPKeys\" />\n"
+ "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+ "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
@@ -218,8 +220,8 @@ public class WifiConfigStoreTest {
public void setUp() throws Exception {
setupMocks();
- mWifiConfigStore = new WifiConfigStore(mContext, mLooper.getLooper(), mClock, mWifiMetrics,
- mSharedStore);
+ mWifiConfigStore = new WifiConfigStore(mContext, new Handler(mLooper.getLooper()), mClock,
+ mWifiMetrics, mSharedStore);
// Enable verbose logging before tests.
mWifiConfigStore.enableVerboseLogging(true);
}
@@ -745,13 +747,10 @@ public class WifiConfigStoreTest {
}
/**
- * Verify that a XmlPullParserException will be thrown when reading an user store file
- * containing unknown data.
- *
- * @throws Exception
+ * Verify that we gracefully skip unknown section when reading an user store file.
*/
- @Test(expected = XmlPullParserException.class)
- public void testReadUserStoreContainedUnknownData() throws Exception {
+ @Test
+ public void testReadUserStoreContainedUnknownSection() throws Exception {
String storeFileData =
"<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<WifiConfigStoreData>\n"
@@ -764,13 +763,10 @@ public class WifiConfigStoreTest {
}
/**
- * Verify that a XmlPullParserException will be thrown when reading the share store file
- * containing unknown data.
- *
- * @throws Exception
+ * Verify that we gracefully skip unknown section when reading a shared store file.
*/
- @Test(expected = XmlPullParserException.class)
- public void testReadShareStoreContainedUnknownData() throws Exception {
+ @Test
+ public void testReadShareStoreContainedUnknownSection() throws Exception {
String storeFileData =
"<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<WifiConfigStoreData>\n"
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
index 056df7c370..9e2783e1b2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
@@ -508,8 +508,7 @@ public class WifiConfigurationTestUtil {
/**
* Gets scan result capabilities for a WPA2/WPA3-Transition mode network configuration
*/
- private static String
- getScanResultCapsForWpa2Wpa3TransitionNetwork(WifiConfiguration configuration) {
+ public static String getScanResultCapsForWpa2Wpa3TransitionNetwork() {
String caps = "[RSN-PSK+SAE-CCMP]";
return caps;
}
@@ -532,7 +531,7 @@ public class WifiConfigurationTestUtil {
public static ScanDetail createScanDetailForWpa2Wpa3TransitionModeNetwork(
WifiConfiguration configuration, String bssid, int level, int frequency,
long tsf, long seen) {
- String caps = getScanResultCapsForWpa2Wpa3TransitionNetwork(configuration);
+ String caps = getScanResultCapsForWpa2Wpa3TransitionNetwork();
WifiSsid ssid = WifiSsid.createFromAsciiEncoded(configuration.getPrintableSsid());
return new ScanDetail(ssid, bssid, caps, level, frequency, tsf, seen);
}
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 c1640ce919..a241a1c42f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
@@ -25,8 +25,8 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiScanner;
+import android.os.Binder;
import android.os.PatternMatcher;
-import android.os.UserHandle;
import android.util.Pair;
import androidx.test.filters.SmallTest;
@@ -39,11 +39,13 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import javax.crypto.Mac;
+
/**
* Unit tests for {@link com.android.server.wifi.WifiConfigurationUtil}.
*/
@SmallTest
-public class WifiConfigurationUtilTest {
+public class WifiConfigurationUtilTest extends WifiBaseTest {
static final int CURRENT_USER_ID = 0;
static final int CURRENT_USER_MANAGED_PROFILE_USER_ID = 10;
static final int OTHER_USER_ID = 11;
@@ -58,29 +60,6 @@ public class WifiConfigurationUtilTest {
new UserInfo(CURRENT_USER_MANAGED_PROFILE_USER_ID, "managed profile", 0));
/**
- * Test for {@link WifiConfigurationUtil.isVisibleToAnyProfile}.
- */
- @Test
- public void isVisibleToAnyProfile() {
- // Shared network configuration created by another user.
- final WifiConfiguration configuration = new WifiConfiguration();
- configuration.creatorUid = UserHandle.getUid(OTHER_USER_ID, 0);
- assertTrue(WifiConfigurationUtil.isVisibleToAnyProfile(configuration, PROFILES));
-
- // Private network configuration created by another user.
- configuration.shared = false;
- assertFalse(WifiConfigurationUtil.isVisibleToAnyProfile(configuration, PROFILES));
-
- // Private network configuration created by the current user.
- configuration.creatorUid = UserHandle.getUid(CURRENT_USER_ID, 0);
- assertTrue(WifiConfigurationUtil.isVisibleToAnyProfile(configuration, PROFILES));
-
- // Private network configuration created by the current user's managed profile.
- configuration.creatorUid = UserHandle.getUid(CURRENT_USER_MANAGED_PROFILE_USER_ID, 0);
- assertTrue(WifiConfigurationUtil.isVisibleToAnyProfile(configuration, PROFILES));
- }
-
- /**
* Verify that new WifiEnterpriseConfig is detected.
*/
@Test
@@ -961,6 +940,32 @@ public class WifiConfigurationUtilTest {
existingConfig, newConfig));
}
+ /**
+ * Verifies that calculatePersistentMacForConfiguration produces persistent, locally generated
+ * MAC addresses that are valid for MAC randomization.
+ */
+ @Test
+ public void testCalculatePersistentMacForConfiguration() {
+ // verify null inputs
+ assertNull(WifiConfigurationUtil.calculatePersistentMacForConfiguration(null, null));
+
+ // Verify that a the MAC address calculated is valid
+ int uid = Binder.getCallingUid();
+ for (int i = 0; i < 10; i++) {
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ Mac hashFunction = WifiConfigurationUtil.obtainMacRandHashFunction(uid);
+ MacAddress macAddress = WifiConfigurationUtil.calculatePersistentMacForConfiguration(
+ config, hashFunction);
+ assertTrue(WifiConfiguration.isValidMacAddressForRandomization(macAddress));
+
+ // Verify that the secret used to generate MAC address is persistent
+ Mac hashFunction2 = WifiConfigurationUtil.obtainMacRandHashFunction(uid);
+ MacAddress macAddress2 = WifiConfigurationUtil.calculatePersistentMacForConfiguration(
+ config, hashFunction2);
+ assertEquals(macAddress, macAddress2);
+ }
+ }
+
private static class EnterpriseConfig {
public String eap;
public String phase2;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityHelperTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityHelperTest.java
index 786e257ac0..bd74f51bc6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityHelperTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityHelperTest.java
@@ -39,7 +39,7 @@ import java.util.ArrayList;
* Unit tests for {@link com.android.server.wifi.WifiConnectivityHelper}.
*/
@SmallTest
-public class WifiConnectivityHelperTest {
+public class WifiConnectivityHelperTest extends WifiBaseTest {
/** Sets up test. */
@Before
public void setUp() throws Exception {
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 c1686b48d6..d32a312051 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -16,9 +16,6 @@
package com.android.server.wifi;
-import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE;
-import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY;
-
import static com.android.server.wifi.ClientModeImpl.WIFI_WORK_SOURCE;
import static com.android.server.wifi.WifiConfigurationTestUtil.generateWifiConfig;
@@ -45,6 +42,7 @@ 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.Handler;
import android.os.Process;
import android.os.SystemClock;
import android.os.WorkSource;
@@ -77,7 +75,7 @@ import java.util.stream.Collectors;
* Unit tests for {@link com.android.server.wifi.WifiConnectivityManager}.
*/
@SmallTest
-public class WifiConnectivityManagerTest {
+public class WifiConnectivityManagerTest extends WifiBaseTest {
/**
* Called before each test
*/
@@ -101,7 +99,7 @@ public class WifiConnectivityManagerTest {
when(mWifiNetworkSuggestionsManager.retrieveHiddenNetworkList())
.thenReturn(new ArrayList<>());
mWifiConnectivityManager = createConnectivityManager();
- verify(mWifiConfigManager).setOnSavedNetworkUpdateListener(anyObject());
+ verify(mWifiConfigManager).addOnNetworkUpdateListener(anyObject());
mWifiConnectivityManager.setTrustedConnectionAllowed(true);
mWifiConnectivityManager.setWifiEnabled(true);
when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
@@ -140,7 +138,6 @@ public class WifiConnectivityManagerTest {
@Mock private Clock mClock;
@Mock private WifiLastResortWatchdog mWifiLastResortWatchdog;
@Mock private OpenNetworkNotifier mOpenNetworkNotifier;
- @Mock private CarrierNetworkNotifier mCarrierNetworkNotifier;
@Mock private CarrierNetworkConfig mCarrierNetworkConfig;
@Mock private WifiMetrics mWifiMetrics;
@Mock private WifiNetworkScoreCache mScoreCache;
@@ -148,8 +145,8 @@ public class WifiConnectivityManagerTest {
@Captor ArgumentCaptor<ScanResult> mCandidateScanResultCaptor;
@Captor ArgumentCaptor<ArrayList<String>> mBssidBlacklistCaptor;
@Captor ArgumentCaptor<ArrayList<String>> mSsidWhitelistCaptor;
- @Captor ArgumentCaptor<WifiConfigManager.OnSavedNetworkUpdateListener>
- mSavedNetworkUpdateListenerCaptor;
+ @Captor ArgumentCaptor<WifiConfigManager.OnNetworkUpdateListener>
+ mNetworkUpdateListenerCaptor;
private MockResources mResources;
private int mFullScanMaxTxPacketRate;
private int mFullScanMaxRxPacketRate;
@@ -315,8 +312,8 @@ public class WifiConnectivityManagerTest {
pnoNetworkList.add(pnoNetwork);
when(wifiConfigManager.retrievePnoNetworkList()).thenReturn(pnoNetworkList);
when(wifiConfigManager.retrievePnoNetworkList()).thenReturn(pnoNetworkList);
- doNothing().when(wifiConfigManager).setOnSavedNetworkUpdateListener(
- mSavedNetworkUpdateListenerCaptor.capture());
+ doNothing().when(wifiConfigManager).addOnNetworkUpdateListener(
+ mNetworkUpdateListenerCaptor.capture());
return wifiConfigManager;
}
@@ -326,8 +323,9 @@ public class WifiConnectivityManagerTest {
new ScoringParams(mContext),
mClientModeImpl, mWifiInjector,
mWifiConfigManager, mWifiInfo, mWifiNS, mWifiConnectivityHelper,
- mWifiLastResortWatchdog, mOpenNetworkNotifier, mCarrierNetworkNotifier,
- mCarrierNetworkConfig, mWifiMetrics, mLooper.getLooper(), mClock, mLocalLog);
+ mWifiLastResortWatchdog, mOpenNetworkNotifier,
+ mCarrierNetworkConfig, mWifiMetrics, new Handler(mLooper.getLooper()), mClock,
+ mLocalLog);
}
/**
@@ -757,150 +755,6 @@ public class WifiConnectivityManagerTest {
}
/**
- * {@link CarrierNetworkNotifier} handles scan results on network selection.
- *
- * Expected behavior: CarrierNetworkNotifier handles scan results
- */
- @Test
- public void wifiDisconnected_noConnectionCandidate_CarrierNetworkNotifierScanResultsHandled() {
- // no connection candidate selected
- when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(null);
-
- List<ScanDetail> expectedCarrierNetworks = new ArrayList<>();
- expectedCarrierNetworks.add(
- new ScanDetail(
- new ScanResult(WifiSsid.createFromAsciiEncoded(CANDIDATE_SSID),
- CANDIDATE_SSID, CANDIDATE_BSSID, 1245, 0, "[EAP][ESS]", -78, 2450,
- 1025, 22, 33, 20, 0, 0, true), null));
-
- when(mWifiNS.getFilteredScanDetailsForCarrierUnsavedNetworks(any()))
- .thenReturn(expectedCarrierNetworks);
-
- // Set WiFi to disconnected state to trigger PNO scan
- mWifiConnectivityManager.handleConnectionStateChanged(
- WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
- verify(mCarrierNetworkNotifier).handleScanResults(expectedCarrierNetworks);
- }
-
- /**
- * {@link CarrierNetworkNotifier} does not handle scan results on network selection if carrier
- * encryption info is not available.
- *
- * Expected behavior: CarrierNetworkNotifier does not handle scan results
- */
- @Test
- public void whenNoEncryptionInfoAvailable_CarrierNetworkNotifierDoesNotHandleScanResults() {
- // no connection candidate selected
- when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(),
- anyBoolean(), anyBoolean())).thenReturn(null);
-
- List<ScanDetail> expectedCarrierNetworks = new ArrayList<>();
- expectedCarrierNetworks.add(
- new ScanDetail(
- new ScanResult(WifiSsid.createFromAsciiEncoded(CANDIDATE_SSID),
- CANDIDATE_SSID, CANDIDATE_BSSID, 1245, 0, "[EAP][ESS]", -78, 2450,
- 1025, 22, 33, 20, 0, 0, true), null));
-
- when(mWifiNS.getFilteredScanDetailsForCarrierUnsavedNetworks(any()))
- .thenReturn(expectedCarrierNetworks);
- when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(false);
-
- // Set WiFi to disconnected state to trigger PNO scan
- mWifiConnectivityManager.handleConnectionStateChanged(
- WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
- verify(mCarrierNetworkNotifier, never()).handleScanResults(expectedCarrierNetworks);
- }
-
- /**
- * When wifi is connected, {@link CarrierNetworkNotifier} handles the Wi-Fi connected behavior.
- *
- * Expected behavior: CarrierNetworkNotifier handles connected behavior
- */
- @Test
- public void wifiConnected_carrierNetworkNotifierHandlesConnection() {
- // Set WiFi to connected state
- mWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(CANDIDATE_SSID));
- mWifiConnectivityManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE);
- verify(mCarrierNetworkNotifier).handleWifiConnected(CANDIDATE_SSID);
- }
-
- /**
- * When wifi is connected, {@link CarrierNetworkNotifier} handles connection state
- * change.
- *
- * Expected behavior: CarrierNetworkNotifer does not clear pending notification.
- */
- @Test
- public void wifiDisconnected_carrierNetworkNotifierDoesNotClearPendingNotification() {
- // Set WiFi to disconnected state
- mWifiConnectivityManager.handleConnectionStateChanged(
- WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
-
- verify(mCarrierNetworkNotifier, never()).clearPendingNotification(anyBoolean());
- }
-
- /**
- * When a Wi-Fi connection attempt ends, {@link CarrierNetworkNotifier} handles the connection
- * failure. A failure code that is not {@link WifiMetrics.ConnectionEvent#FAILURE_NONE}
- * represents a connection failure.
- *
- * Expected behavior: CarrierNetworkNotifier handles connection failure.
- */
- @Test
- public void wifiConnectionEndsWithFailure_carrierNetworkNotifierHandlesConnectionFailure() {
- mWifiConnectivityManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED);
-
- verify(mCarrierNetworkNotifier).handleConnectionFailure();
- }
-
- /**
- * When a Wi-Fi connection attempt ends, {@link CarrierNetworkNotifier} does not handle
- * connection failure after a successful connection.
- * {@link WifiMetrics.ConnectionEvent#FAILURE_NONE} represents a successful connection.
- *
- * Expected behavior: CarrierNetworkNotifier does nothing.
- */
- @Test
- public void
- wifiConnectionEndsWithSuccess_carrierNetworkNotifierDoesNotHandleConnectionFailure() {
- mWifiConnectivityManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE);
-
- verify(mCarrierNetworkNotifier, never()).handleConnectionFailure();
- }
-
- /**
- * When Wi-Fi is disabled, clear the pending notification and reset notification repeat delay.
- *
- * Expected behavior: clear pending notification and reset notification repeat delay
- * */
- @Test
- public void carrierNetworkNotifierClearsPendingNotificationOnWifiDisabled() {
- mWifiConnectivityManager.setWifiEnabled(false);
-
- verify(mCarrierNetworkNotifier).clearPendingNotification(true /* resetRepeatDelay */);
- }
-
- /**
- * Verify that the CarrierNetworkNotifier tracks screen state changes.
- */
- @Test
- public void carrierNetworkNotifierTracksScreenStateChanges() {
- mWifiConnectivityManager.handleScreenStateChanged(false);
-
- verify(mCarrierNetworkNotifier).handleScreenStateChanged(false);
-
- mWifiConnectivityManager.handleScreenStateChanged(true);
-
- verify(mCarrierNetworkNotifier).handleScreenStateChanged(true);
- }
-
- /**
* Verify that scan interval for screen on and wifi disconnected scenario
* is in the exponential backoff fashion.
*
@@ -2115,23 +1969,6 @@ public class WifiConnectivityManagerTest {
}
/**
- * Disabling the network temporarily due to lack of internet is a special reason for which we
- * don't want WCM to trigger a disconnect (by removing the network from supplicant).
- */
- @Test
- public void dontDisconnectIfNetworkTemporarilyDisabledDueToNoInternet() {
- assertNotNull(mSavedNetworkUpdateListenerCaptor.getValue());
-
- mSavedNetworkUpdateListenerCaptor.getValue()
- .onSavedNetworkPermanentlyDisabled(0, DISABLED_AUTHENTICATION_FAILURE);
- verify(mWifiConnectivityHelper).removeNetworkIfCurrent(0);
-
- mSavedNetworkUpdateListenerCaptor.getValue()
- .onSavedNetworkPermanentlyDisabled(0, DISABLED_NO_INTERNET_TEMPORARY);
- // Don't remove network.
- }
-
- /**
* Verify the various WifiConnectivityManager enable/disable sequences.
*
* Expected behavior: WifiConnectivityManager is turned on as a long as there is
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java
deleted file mode 100644
index 18f7ea5df3..0000000000
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java
+++ /dev/null
@@ -1,1126 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import static com.android.server.wifi.WifiController.CMD_AP_STOPPED;
-import static com.android.server.wifi.WifiController.CMD_EMERGENCY_CALL_STATE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_EMERGENCY_MODE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_RECOVERY_DISABLE_WIFI;
-import static com.android.server.wifi.WifiController.CMD_RECOVERY_RESTART_WIFI;
-import static com.android.server.wifi.WifiController.CMD_SCANNING_STOPPED;
-import static com.android.server.wifi.WifiController.CMD_SCAN_ALWAYS_MODE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_SET_AP;
-import static com.android.server.wifi.WifiController.CMD_STA_STOPPED;
-import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.location.LocationManager;
-import android.net.wifi.WifiManager;
-import android.os.test.TestLooper;
-import android.util.Log;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.R;
-import com.android.internal.util.IState;
-import com.android.internal.util.StateMachine;
-import com.android.server.wifi.util.WifiPermissionsUtil;
-
-import org.junit.After;
-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 java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-import java.lang.reflect.Method;
-
-/**
- * Test WifiController for changes in and out of ECM and SoftAP modes.
- */
-@SmallTest
-public class WifiControllerTest {
-
- private static final String TAG = "WifiControllerTest";
-
- private static final int TEST_WIFI_RECOVERY_DELAY_MS = 2000;
-
- private void dumpState() {
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- PrintWriter writer = new PrintWriter(stream);
- mWifiController.dump(null, writer, null);
- writer.flush();
- Log.d(TAG, "ClientModeImpl state -" + stream.toString());
- }
-
- private IState getCurrentState() throws Exception {
- Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
- method.setAccessible(true);
- return (IState) method.invoke(mWifiController);
- }
-
- private void initializeSettingsStore() throws Exception {
- when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
- }
-
- TestLooper mLooper;
- @Mock Context mContext;
- @Mock Resources mResources;
- @Mock FrameworkFacade mFacade;
- @Mock WifiSettingsStore mSettingsStore;
- @Mock ClientModeImpl mClientModeImpl;
- @Mock ActiveModeWarden mActiveModeWarden;
- @Mock WifiPermissionsUtil mWifiPermissionsUtil;
-
- WifiController mWifiController;
-
- private BroadcastReceiver mBroadcastReceiver;
-
- private ClientModeManager.Listener mClientModeCallback;
- private ScanOnlyModeManager.Listener mScanOnlyModeCallback;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- mLooper = new TestLooper();
-
- initializeSettingsStore();
-
- when(mContext.getResources()).thenReturn(mResources);
-
- when(mResources.getInteger(R.integer.config_wifi_framework_recovery_timeout_delay))
- .thenReturn(TEST_WIFI_RECOVERY_DELAY_MS);
- when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
-
- mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(),
- mSettingsStore, mLooper.getLooper(), mFacade, mActiveModeWarden,
- mWifiPermissionsUtil);
- mWifiController.start();
- mLooper.dispatchAll();
-
- ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class));
- mBroadcastReceiver = bcastRxCaptor.getValue();
-
- ArgumentCaptor<ClientModeManager.Listener> clientModeCallbackCaptor =
- ArgumentCaptor.forClass(ClientModeManager.Listener.class);
- verify(mActiveModeWarden).registerClientModeCallback(clientModeCallbackCaptor.capture());
- mClientModeCallback = clientModeCallbackCaptor.getValue();
-
- ArgumentCaptor<ScanOnlyModeManager.Listener> scanOnlyModeCallbackCaptor =
- ArgumentCaptor.forClass(ScanOnlyModeManager.Listener.class);
- verify(mActiveModeWarden).registerScanOnlyCallback(scanOnlyModeCallbackCaptor.capture());
- mScanOnlyModeCallback = scanOnlyModeCallbackCaptor.getValue();
-
- }
-
- @After
- public void cleanUp() {
- mLooper.dispatchAll();
- }
-
- /**
- * Verify that toggling wifi from disabled starts client mode.
- */
- @Test
- public void enableWifi() throws Exception {
- assertEquals("StaDisabledState", getCurrentState().getName());
-
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
- mWifiController.sendMessage(CMD_WIFI_TOGGLED);
- mLooper.dispatchAll();
- assertEquals("StaEnabledState", getCurrentState().getName());
- }
-
- /**
- * Test verifying that we can enter scan mode when the scan mode changes
- */
- @Test
- public void enableScanMode() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
- mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterScanOnlyMode();
- }
-
- /**
- * Verify that if scanning is enabled at startup, we enter scan mode
- */
- @Test
- public void testEnterScanModeAtStartWhenSet() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
-
- // reset to avoid the default behavior
- reset(mActiveModeWarden);
-
- WifiController wifiController =
- new WifiController(mContext, mClientModeImpl, mLooper.getLooper(),
- mSettingsStore, mLooper.getLooper(), mFacade,
- mActiveModeWarden, mWifiPermissionsUtil);
-
- wifiController.start();
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden, never()).disableWifi();
- verify(mActiveModeWarden).enterScanOnlyMode();
- }
-
- /**
- * Do not enter scan mode if location mode disabled.
- */
- @Test
- public void testDoesNotEnterScanModeWhenLocationModeDisabled() throws Exception {
- // Start a new WifiController with wifi disabled
- when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
- when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
-
- mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(),
- mSettingsStore, mLooper.getLooper(), mFacade, mActiveModeWarden,
- mWifiPermissionsUtil);
-
- reset(mActiveModeWarden);
- mWifiController.start();
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).disableWifi();
-
- // toggling scan always available is not sufficient for scan mode
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
- mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden, never()).enterScanOnlyMode();
-
- }
-
- /**
- * Only enter scan mode if location mode enabled
- */
- @Test
- public void testEnterScanModeWhenLocationModeEnabled() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
- when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
-
- reset(mContext, mActiveModeWarden);
- when(mContext.getResources()).thenReturn(mResources);
- mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(),
- mSettingsStore, mLooper.getLooper(), mFacade, mActiveModeWarden,
- mWifiPermissionsUtil);
-
- mWifiController.start();
- mLooper.dispatchAll();
-
- ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class));
- mBroadcastReceiver = bcastRxCaptor.getValue();
-
- verify(mActiveModeWarden).disableWifi();
-
- when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
- Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION);
-
- mBroadcastReceiver.onReceive(mContext, intent);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterScanOnlyMode();
- }
-
-
-
- /**
- * Disabling location mode when in scan mode will disable wifi
- */
- @Test
- public void testExitScanModeWhenLocationModeDisabled() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
- when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
-
- reset(mContext, mActiveModeWarden);
- when(mContext.getResources()).thenReturn(mResources);
- mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(),
- mSettingsStore, mLooper.getLooper(), mFacade, mActiveModeWarden,
- mWifiPermissionsUtil);
- mWifiController.start();
- mLooper.dispatchAll();
-
- ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- verify(mContext).registerReceiver(bcastRxCaptor.capture(), any(IntentFilter.class));
- mBroadcastReceiver = bcastRxCaptor.getValue();
-
- verify(mActiveModeWarden).enterScanOnlyMode();
-
- when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
- Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION);
-
- mBroadcastReceiver.onReceive(mContext, intent);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).disableWifi();
- }
-
- /**
- * When in Client mode, make sure ECM triggers wifi shutdown.
- */
- @Test
- public void testEcmOnFromClientMode() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
- enableWifi();
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).shutdownWifi();
- }
-
- /**
- * ECM disabling messages, when in client mode (not expected) do not trigger state changes.
- */
- @Test
- public void testEcmOffInClientMode() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
- enableWifi();
-
- // Test with WifiDisableInECBM turned off
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden, never()).shutdownWifi();
- verify(mActiveModeWarden).stopSoftAPMode(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- }
-
- /**
- * When ECM activates and we are in client mode, disabling ECM should return us to client mode.
- */
- @Test
- public void testEcmDisabledReturnsToClientMode() throws Exception {
- enableWifi();
- verify(mActiveModeWarden).enterClientMode();
-
- reset(mActiveModeWarden);
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).shutdownWifi();
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).enterClientMode();
- }
-
- /**
- * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed
- * update.
- */
- @Test
- public void testEcmOnFromScanMode() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
- mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterScanOnlyMode();
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
- verify(mActiveModeWarden).enterScanOnlyMode();
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).shutdownWifi();
- }
-
- /**
- * When Ecm mode is disabled, we should not shut down scan mode if we get an emergency mode
- * changed update, but we should turn off soft AP
- */
- @Test
- public void testEcmOffInScanMode() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
- mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterScanOnlyMode();
-
- // Test with WifiDisableInECBM turned off:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false);
- verify(mActiveModeWarden).enterScanOnlyMode();
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden, never()).shutdownWifi();
- verify(mActiveModeWarden).stopSoftAPMode(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- }
-
- /**
- * When ECM is disabled, we should return to scan mode
- */
- @Test
- public void testEcmDisabledReturnsToScanMode() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
- mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterScanOnlyMode();
-
- reset(mActiveModeWarden);
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).shutdownWifi();
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).enterScanOnlyMode();
- }
-
- /**
- * When Ecm mode is enabled, we should shut down wifi when we get an emergency mode changed
- * update.
- */
- @Test
- public void testEcmOnFromSoftApMode() throws Exception {
- mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget();
- mLooper.dispatchAll();
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
- verify(mActiveModeWarden).enterSoftAPMode(any());
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).shutdownWifi();
- }
-
- /**
- * When Ecm mode is disabled, we should shut down softap mode if we get an emergency mode
- * changed update
- */
- @Test
- public void testEcmOffInSoftApMode() throws Exception {
- mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget();
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterSoftAPMode(any());
-
- // Test with WifiDisableInECBM turned off:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(false);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).stopSoftAPMode(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- }
-
- /**
- * When ECM is activated and we were in softap mode, we should just return to wifi off when ECM
- * ends
- */
- @Test
- public void testEcmDisabledRemainsDisabledWhenSoftApHadBeenOn() throws Exception {
- verify(mActiveModeWarden).disableWifi();
-
- mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget();
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterSoftAPMode(any());
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
-
- reset(mActiveModeWarden);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden).disableWifi();
- // no additional calls to enable softap
- verify(mActiveModeWarden, never()).enterSoftAPMode(any());
- }
-
- /**
- * Wifi should remain off when already disabled and we enter ECM.
- */
- @Test
- public void testEcmOnFromDisabledMode() throws Exception {
- verify(mActiveModeWarden, never()).enterSoftAPMode(any());
- verify(mActiveModeWarden, never()).enterClientMode();
- verify(mActiveModeWarden, never()).enterScanOnlyMode();
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- assertEquals("EcmState", getCurrentState().getName());
-
- verify(mActiveModeWarden).shutdownWifi();
- }
-
-
- /**
- * Updates about call state change also trigger entry of ECM mode.
- */
- @Test
- public void testEnterEcmOnEmergencyCallStateChange() throws Exception {
- verify(mActiveModeWarden).disableWifi();
-
- enableWifi();
- verify(mActiveModeWarden).enterClientMode();
-
- reset(mActiveModeWarden);
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test call state changed
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
-
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterClientMode();
- }
-
- /**
- * Updates about call state change with an invalid state do not change modes.
- */
- @Test
- public void testEnterEcmOnEmergencyCallStateChangeAndUpdateWithInvalidState() throws Exception {
- verify(mActiveModeWarden).disableWifi();
-
- enableWifi();
- verify(mActiveModeWarden).enterClientMode();
-
- reset(mActiveModeWarden);
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test call state changed
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
-
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 2);
- mLooper.dispatchAll();
- verifyNoMoreInteractions(mActiveModeWarden);
- }
-
- /**
- * Updates about emergency mode change with an invalid state do not change modes.
- */
- @Test
- public void testEnterEcmOnEmergencyModeChangeAndUpdateWithInvalidState() throws Exception {
- verify(mActiveModeWarden).disableWifi();
-
- enableWifi();
- verify(mActiveModeWarden).enterClientMode();
-
- reset(mActiveModeWarden);
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test call state changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
-
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 2);
- mLooper.dispatchAll();
- verifyNoMoreInteractions(mActiveModeWarden);
- }
-
- /**
- * Verify when both ECM and call state changes arrive, we enter ECM mode
- */
- @Test
- public void testEnterEcmWithBothSignals() throws Exception {
- verify(mActiveModeWarden).disableWifi();
-
- enableWifi();
- verify(mActiveModeWarden).enterClientMode();
-
- reset(mActiveModeWarden);
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
-
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- // still only 1 shutdown
- verify(mActiveModeWarden).shutdownWifi();
-
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0);
- mLooper.dispatchAll();
- // stay in ecm, do not send an additional client mode trigger
- verify(mActiveModeWarden, never()).enterClientMode();
-
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0);
- mLooper.dispatchAll();
- // now we can re-enable wifi
- verify(mActiveModeWarden).enterClientMode();
- }
-
- /**
- * Verify when both ECM and call state changes arrive but out of order, we enter ECM mode
- */
- @Test
- public void testEnterEcmWithBothSignalsOutOfOrder() throws Exception {
- verify(mActiveModeWarden).disableWifi();
-
- enableWifi();
- verify(mActiveModeWarden).enterClientMode();
-
- reset(mActiveModeWarden);
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
-
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1);
- mLooper.dispatchAll();
- // still only 1 shutdown
- verify(mActiveModeWarden).shutdownWifi();
-
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0);
- mLooper.dispatchAll();
- // stay in ecm, do not send an additional client mode trigger
- verify(mActiveModeWarden, never()).enterClientMode();
-
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0);
- mLooper.dispatchAll();
- // now we can re-enable wifi
- verify(mActiveModeWarden).enterClientMode();
- }
-
- /**
- * Verify when both ECM and call state changes arrive but completely out of order,
- * we still enter and properly exit ECM mode
- */
- @Test
- public void testEnterEcmWithBothSignalsOppositeOrder() throws Exception {
- verify(mActiveModeWarden).disableWifi();
-
- enableWifi();
- verify(mActiveModeWarden).enterClientMode();
-
- reset(mActiveModeWarden);
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
-
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- // still only 1 shutdown
- verify(mActiveModeWarden).shutdownWifi();
-
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0);
- mLooper.dispatchAll();
- // stay in ecm, do not send an additional client mode trigger
- verify(mActiveModeWarden, never()).enterClientMode();
-
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0);
- mLooper.dispatchAll();
- // now we can re-enable wifi
- verify(mActiveModeWarden).enterClientMode();
- }
-
-
- /**
- * When ECM is active, we might get addition signals of ECM mode, we must not exit until they
- * are all cleared.
- */
- @Test
- public void testProperExitFromEcmModeWithMultipleMessages() throws Exception {
- verify(mActiveModeWarden).disableWifi();
-
- enableWifi();
- verify(mActiveModeWarden).enterClientMode();
-
- reset(mActiveModeWarden);
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1);
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1);
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
-
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0);
- mLooper.dispatchAll();
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0);
- mLooper.dispatchAll();
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 0);
- mLooper.dispatchAll();
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0);
- mLooper.dispatchAll();
- verify(mActiveModeWarden, never()).enterClientMode();
-
- // now we will exit ECM
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 0);
- mLooper.dispatchAll();
-
- // now we can re-enable wifi
- verify(mActiveModeWarden).enterClientMode();
- }
-
- /**
- * Toggling wifi when in ECM does not exit ecm mode and enable wifi
- */
- @Test
- public void testWifiDoesNotToggleOnWhenInEcm() throws Exception {
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- assertEquals("EcmState", getCurrentState().getName());
-
- verify(mActiveModeWarden).shutdownWifi();
-
- // now toggle wifi and verify we do not start wifi
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
- mWifiController.sendMessage(CMD_WIFI_TOGGLED);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden, never()).enterClientMode();
- }
-
- /**
- * Toggling scan mode when in ECM does not exit ecm mode and enable scan mode
- */
- @Test
- public void testScanModeDoesNotToggleOnWhenInEcm() throws Exception {
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- assertEquals("EcmState", getCurrentState().getName());
-
- verify(mActiveModeWarden).shutdownWifi();
-
- // now enable scanning and verify we do not start wifi
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
-
- mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden, never()).enterScanOnlyMode();
- }
-
- /**
- * Toggling softap mode when in ECM does not exit ecm mode and enable softap
- */
- @Test
- public void testSoftApModeDoesNotToggleOnWhenInEcm() throws Exception {
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- assertEquals("EcmState", getCurrentState().getName());
-
- verify(mActiveModeWarden).shutdownWifi();
-
- mWifiController.sendMessage(CMD_SET_AP);
- mLooper.dispatchAll();
-
- verify(mActiveModeWarden, never()).enterSoftAPMode(any());
- }
-
- /**
- * Toggling off softap mode when in ECM does not induce a mode change
- */
- @Test
- public void testSoftApStoppedDoesNotSwitchModesWhenInEcm() throws Exception {
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- assertEquals("EcmState", getCurrentState().getName());
-
- verify(mActiveModeWarden).shutdownWifi();
-
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_AP_STOPPED);
- mLooper.dispatchAll();
-
- verifyNoMoreInteractions(mActiveModeWarden);
- }
-
- /**
- * Toggling softap mode when in airplane mode needs to enable softap
- */
- @Test
- public void testSoftApModeToggleWhenInAirplaneMode() throws Exception {
- // Test with airplane mode turned on:
- when(mSettingsStore.isAirplaneModeOn()).thenReturn(true);
-
- // Turn on SoftAp.
- mWifiController.sendMessage(CMD_SET_AP, 1);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterSoftAPMode(any());
-
- // Turn off SoftAp.
- mWifiController.sendMessage(CMD_SET_AP, 0, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).stopSoftAPMode(WifiManager.IFACE_IP_MODE_UNSPECIFIED);
- }
-
- /**
- * Toggling off scan mode when in ECM does not induce a mode change
- */
- @Test
- public void testScanModeStoppedDoesNotSwitchModesWhenInEcm() throws Exception {
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- assertEquals("EcmState", getCurrentState().getName());
-
- verify(mActiveModeWarden).shutdownWifi();
-
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_SCANNING_STOPPED);
- mLooper.dispatchAll();
-
- verifyNoMoreInteractions(mActiveModeWarden);
- }
-
- /**
- * Toggling off client mode when in ECM does not induce a mode change
- */
- @Test
- public void testClientModeStoppedDoesNotSwitchModesWhenInEcm() throws Exception {
-
- // Test with WifiDisableInECBM turned on:
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- // test ecm changed
- mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, 1);
- mLooper.dispatchAll();
- assertEquals("EcmState", getCurrentState().getName());
-
- verify(mActiveModeWarden).shutdownWifi();
-
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_STA_STOPPED);
- mLooper.dispatchAll();
-
- verifyNoMoreInteractions(mActiveModeWarden);
- }
-
-
- /**
- * When AP mode is enabled and wifi was previously in AP mode, we should return to
- * StaEnabledState after the AP is disabled.
- * Enter StaEnabledState, activate AP mode, disable AP mode.
- * <p>
- * Expected: AP should successfully start and exit, then return to StaEnabledState.
- */
- @Test
- public void testReturnToStaEnabledStateAfterAPModeShutdown() throws Exception {
- enableWifi();
- assertEquals("StaEnabledState", getCurrentState().getName());
-
- mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget();
- // add an "unexpected" sta mode stop to simulate a single interface device
- mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
- mLooper.dispatchAll();
-
- when(mSettingsStore.getWifiSavedState()).thenReturn(1);
- mWifiController.obtainMessage(CMD_AP_STOPPED).sendToTarget();
- mLooper.dispatchAll();
-
- InOrder inOrder = inOrder(mActiveModeWarden);
- inOrder.verify(mActiveModeWarden).enterClientMode();
- assertEquals("StaEnabledState", getCurrentState().getName());
- }
-
- /**
- * When AP mode is enabled and wifi is toggled on, we should transition to
- * StaEnabledState after the AP is disabled.
- * Enter StaEnabledState, activate AP mode, toggle WiFi.
- * <p>
- * Expected: AP should successfully start and exit, then return to StaEnabledState.
- */
- @Test
- public void testReturnToStaEnabledStateAfterWifiEnabledShutdown() throws Exception {
- enableWifi();
- assertEquals("StaEnabledState", getCurrentState().getName());
-
- mWifiController.obtainMessage(CMD_SET_AP, 1, 0).sendToTarget();
- mLooper.dispatchAll();
-
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
- mWifiController.obtainMessage(CMD_WIFI_TOGGLED).sendToTarget();
- mWifiController.obtainMessage(CMD_AP_STOPPED).sendToTarget();
- mLooper.dispatchAll();
-
- InOrder inOrder = inOrder(mActiveModeWarden);
- inOrder.verify(mActiveModeWarden).enterClientMode();
- assertEquals("StaEnabledState", getCurrentState().getName());
- }
-
- @Test
- public void testRestartWifiStackInStaEnabledStateTriggersBugReport() throws Exception {
- enableWifi();
- mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI,
- SelfRecovery.REASON_WIFINATIVE_FAILURE);
- mLooper.dispatchAll();
- verify(mClientModeImpl).takeBugReport(anyString(), anyString());
- }
-
- @Test
- public void testRestartWifiWatchdogDoesNotTriggerBugReport() throws Exception {
- enableWifi();
- mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI,
- SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
- mLooper.dispatchAll();
- verify(mClientModeImpl, never()).takeBugReport(anyString(), anyString());
- }
-
- /**
- * When in sta mode, CMD_RECOVERY_DISABLE_WIFI messages should trigger wifi to disable.
- */
- @Test
- public void testRecoveryDisabledTurnsWifiOff() throws Exception {
- enableWifi();
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_RECOVERY_DISABLE_WIFI);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).disableWifi();
- }
-
- /**
- * When wifi is disabled, CMD_RECOVERY_DISABLE_WIFI should not trigger a state change.
- */
- @Test
- public void testRecoveryDisabledWhenWifiAlreadyOff() throws Exception {
- assertEquals("StaDisabledState", getCurrentState().getName());
- mWifiController.sendMessage(CMD_RECOVERY_DISABLE_WIFI);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
- }
-
- /**
- * The command to trigger a WiFi reset should not trigger any action by WifiController if we
- * are not in STA mode.
- * WiFi is not in connect mode, so any calls to reset the wifi stack due to connection failures
- * should be ignored.
- * Create and start WifiController in StaDisabledState, send command to restart WiFi
- * <p>
- * Expected: WiFiController should not call ActiveModeWarden.disableWifi()
- */
- @Test
- public void testRestartWifiStackInStaDisabledState() throws Exception {
- // Start a new WifiController with wifi disabled
- when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(false);
-
- mWifiController = new WifiController(mContext, mClientModeImpl, mLooper.getLooper(),
- mSettingsStore, mLooper.getLooper(), mFacade, mActiveModeWarden,
- mWifiPermissionsUtil);
-
- mWifiController.start();
- mLooper.dispatchAll();
-
- reset(mClientModeImpl);
- assertEquals("StaDisabledState", getCurrentState().getName());
-
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).disableWifi();
- }
-
- /**
- * The command to trigger a WiFi reset should not trigger any action by WifiController if we
- * are not in STA mode, even if scans are allowed.
- * WiFi is not in connect mode, so any calls to reset the wifi stack due to connection failures
- * should be ignored.
- * Create and start WifiController in StaDisabledState, send command to restart WiFi
- * <p>
- * Expected: WiFiController should not call ActiveModeWarden.disableWifi() or
- * ActiveModeWarden.shutdownWifi().
- */
- @Test
- public void testRestartWifiStackInStaDisabledWithScanState() throws Exception {
- when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
- mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterScanOnlyMode();
-
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI);
- mLooper.dispatchAll();
- mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS);
- mLooper.dispatchAll();
- InOrder inOrder = inOrder(mActiveModeWarden);
- verify(mActiveModeWarden).disableWifi();
- verify(mActiveModeWarden).enterScanOnlyMode();
- }
-
- /**
- * The command to trigger a WiFi reset should trigger a wifi reset in ClientModeImpl through
- * the ActiveModeWarden.shutdownWifi() call when in STA mode.
- * WiFi is in connect mode, calls to reset the wifi stack due to connection failures
- * should trigger a supplicant stop, and subsequently, a driver reload.
- * Create and start WifiController in StaEnabledState, send command to restart WiFi
- * <p>
- * Expected: WiFiController should call ActiveModeWarden.shutdownWifi() and
- * ActiveModeWarden should enter CONNECT_MODE and the wifi driver should be started.
- */
- @Test
- public void testRestartWifiStackInStaEnabledState() throws Exception {
- enableWifi();
- assertEquals("StaEnabledState", getCurrentState().getName());
-
- mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI);
- mLooper.dispatchAll();
- mLooper.moveTimeForward(TEST_WIFI_RECOVERY_DELAY_MS);
- mLooper.dispatchAll();
-
- InOrder inOrder = inOrder(mActiveModeWarden);
- inOrder.verify(mActiveModeWarden).shutdownWifi();
- inOrder.verify(mActiveModeWarden).enterClientMode();
- assertEquals("StaEnabledState", getCurrentState().getName());
- }
-
- /**
- * The command to trigger a WiFi reset should not trigger a reset when in ECM mode.
- * Enable wifi and enter ECM state, send command to restart wifi.
- * <p>
- * Expected: The command to trigger a wifi reset should be ignored and we should remain in ECM
- * mode.
- */
- @Test
- public void testRestartWifiStackDoesNotExitECMMode() throws Exception {
- enableWifi();
- assertEquals("StaEnabledState", getCurrentState().getName());
- when(mFacade.getConfigWiFiDisableInECBM(mContext)).thenReturn(true);
-
- mWifiController.sendMessage(CMD_EMERGENCY_CALL_STATE_CHANGED, 1);
- mLooper.dispatchAll();
- assertEquals("EcmState", getCurrentState().getName());
- verify(mActiveModeWarden).shutdownWifi();
-
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI);
- mLooper.dispatchAll();
- assertEquals("EcmState", getCurrentState().getName());
-
- verifyZeroInteractions(mActiveModeWarden);
- }
-
- /**
- * The command to trigger a WiFi reset should trigger a reset when in AP mode.
- * Enter AP mode, send command to restart wifi.
- * <p>
- * Expected: The command to trigger a wifi reset should trigger wifi shutdown.
- */
- @Test
- public void testRestartWifiStackFullyStopsWifi() throws Exception {
- mWifiController.obtainMessage(CMD_SET_AP, 1).sendToTarget();
- mLooper.dispatchAll();
- verify(mActiveModeWarden).enterSoftAPMode(any());
-
- reset(mActiveModeWarden);
- mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI);
- mLooper.dispatchAll();
- verify(mActiveModeWarden).shutdownWifi();
- }
-}
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 e0acd1f80c..3a2583bdbe 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
@@ -20,14 +20,22 @@ import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.telephony.TelephonyManager;
+
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -39,13 +47,18 @@ import java.util.Locale;
* Unit tests for {@link com.android.server.wifi.WifiCountryCode}.
*/
@SmallTest
-public class WifiCountryCodeTest {
+public class WifiCountryCodeTest extends WifiBaseTest {
private static final String TAG = "WifiCountryCodeTest";
private String mDefaultCountryCode = "US";
private String mTelephonyCountryCode = "JP";
private boolean mRevertCountryCodeOnCellularLoss = true;
+ @Mock Context mContext;
+ @Mock TelephonyManager mTelephonyManager;
+ @Mock Handler mHandler;
@Mock WifiNative mWifiNative;
+ private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
private WifiCountryCode mWifiCountryCode;
/**
@@ -56,11 +69,28 @@ public class WifiCountryCodeTest {
MockitoAnnotations.initMocks(this);
when(mWifiNative.setCountryCode(any(), anyString())).thenReturn(true);
+ when(mContext.getSystemService(Context.TELEPHONY_SERVICE))
+ .thenReturn(mTelephonyManager);
+
+ createWifiCountryCode();
+ }
+ private void createWifiCountryCode() {
mWifiCountryCode = new WifiCountryCode(
+ mContext,
+ mHandler,
mWifiNative,
mDefaultCountryCode,
mRevertCountryCodeOnCellularLoss);
+ verify(mContext, atLeastOnce()).registerReceiver(
+ mBroadcastReceiverCaptor.capture(), any(), any(), any());
+ }
+
+ private void sendCountryCodeChangedBroadcast(String countryCode) {
+ Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
+ intent.putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, countryCode);
+ assertNotNull(mBroadcastReceiverCaptor.getValue());
+ mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
}
/**
@@ -78,12 +108,27 @@ public class WifiCountryCodeTest {
}
/**
+ * Test that we read the country code from telephony at bootup.
+ * @throws Exception
+ */
+ @Test
+ public void useTelephonyCountryCodeOnBootup() throws Exception {
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn(mTelephonyCountryCode);
+ // Supplicant started.
+ mWifiCountryCode.setReadyForChange(true);
+ // Wifi get L2 connected.
+ mWifiCountryCode.setReadyForChange(false);
+ verify(mWifiNative).setCountryCode(any(), anyString());
+ assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCountryCodeSentToDriver());
+ }
+
+ /**
* Test if we receive country code from Telephony before supplicant starts.
* @throws Exception
*/
@Test
- public void useTelephonyCountryCode() throws Exception {
- mWifiCountryCode.setCountryCode(mTelephonyCountryCode);
+ public void useTelephonyCountryCodeOnChange() throws Exception {
+ sendCountryCodeChangedBroadcast(mTelephonyCountryCode);
assertEquals(null, mWifiCountryCode.getCountryCodeSentToDriver());
// Supplicant started.
mWifiCountryCode.setReadyForChange(true);
@@ -98,12 +143,12 @@ public class WifiCountryCodeTest {
* @throws Exception
*/
@Test
- public void setTelephonyCountryCodeAfterSupplicantStarts() throws Exception {
+ public void telephonyCountryCodeChangeAfterSupplicantStarts() throws Exception {
// Supplicant starts.
mWifiCountryCode.setReadyForChange(true);
assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCodeSentToDriver());
// Telephony country code arrives.
- mWifiCountryCode.setCountryCode(mTelephonyCountryCode);
+ sendCountryCodeChangedBroadcast(mTelephonyCountryCode);
// Wifi get L2 connected.
mWifiCountryCode.setReadyForChange(false);
verify(mWifiNative, times(2)).setCountryCode(any(), anyString());
@@ -115,13 +160,13 @@ public class WifiCountryCodeTest {
* @throws Exception
*/
@Test
- public void setTelephonyCountryCodeAfterL2Connected() throws Exception {
+ public void telephonyCountryCodeChangeAfterL2Connected() throws Exception {
// Supplicant starts.
mWifiCountryCode.setReadyForChange(true);
// Wifi get L2 connected.
mWifiCountryCode.setReadyForChange(false);
// Telephony country code arrives.
- mWifiCountryCode.setCountryCode(mTelephonyCountryCode);
+ sendCountryCodeChangedBroadcast(mTelephonyCountryCode);
// Telephony coutry code won't be applied at this time.
assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCodeSentToDriver());
mWifiCountryCode.setReadyForChange(true);
@@ -140,10 +185,10 @@ public class WifiCountryCodeTest {
@Test
public void resetCountryCodeWhenOutOfService() throws Exception {
assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCode());
- mWifiCountryCode.setCountryCode(mTelephonyCountryCode);
+ sendCountryCodeChangedBroadcast(mTelephonyCountryCode);
assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCountryCode());
// Out of service.
- mWifiCountryCode.setCountryCode("");
+ sendCountryCodeChangedBroadcast("");
assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCode());
}
@@ -158,16 +203,14 @@ public class WifiCountryCodeTest {
public void doNotResetCountryCodeWhenOutOfService() throws Exception {
// Refresh mWifiCountryCode with |config_wifi_revert_country_code_on_cellular_loss|
// setting to false.
- mWifiCountryCode = new WifiCountryCode(
- mWifiNative,
- mDefaultCountryCode,
- false /* config_wifi_revert_country_code_on_cellular_loss */);
+ mRevertCountryCodeOnCellularLoss = false;
+ createWifiCountryCode();
assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCode());
- mWifiCountryCode.setCountryCode(mTelephonyCountryCode);
+ sendCountryCodeChangedBroadcast(mTelephonyCountryCode);
assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCountryCode());
// Out of service.
- mWifiCountryCode.setCountryCode("");
+ sendCountryCodeChangedBroadcast("");
assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCountryCode());
}
@@ -182,10 +225,8 @@ public class WifiCountryCodeTest {
String telephonyCountryCodeLower = "il";
String telephonyCountryCodeUpper = "IL";
- mWifiCountryCode = new WifiCountryCode(
- mWifiNative,
- oemCountryCodeLower,
- mRevertCountryCodeOnCellularLoss);
+ mDefaultCountryCode = oemCountryCodeLower;
+ createWifiCountryCode();
// Set the default locale to "tr" (Non US).
Locale.setDefault(new Locale("tr"));
@@ -195,7 +236,7 @@ public class WifiCountryCodeTest {
verify(mWifiNative).setCountryCode(any(), eq(oemCountryCodeUpper));
// Now trigger a country code change using the telephony country code.
- mWifiCountryCode.setCountryCode(telephonyCountryCodeLower);
+ sendCountryCodeChangedBroadcast(telephonyCountryCodeLower);
verify(mWifiNative).setCountryCode(any(), eq(telephonyCountryCodeUpper));
}
/**
@@ -207,7 +248,9 @@ public class WifiCountryCodeTest {
PrintWriter pw = new PrintWriter(sw);
mWifiCountryCode = new WifiCountryCode(
- null,
+ mContext,
+ mHandler,
+ mWifiNative,
null,
false /* config_wifi_revert_country_code_on_cellular_loss */);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
index 71b658923a..898409f1ad 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
@@ -17,7 +17,6 @@
package com.android.server.wifi;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.never;
@@ -26,8 +25,6 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.net.wifi.WifiInfo;
-import android.os.Looper;
-import android.provider.DeviceConfig.OnPropertiesChangedListener;
import android.provider.Settings;
import androidx.test.filters.SmallTest;
@@ -36,7 +33,6 @@ import com.android.server.wifi.nano.WifiMetricsProto.WifiIsUnusableEvent;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -44,7 +40,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WifiDataStall}.
*/
@SmallTest
-public class WifiDataStallTest {
+public class WifiDataStallTest extends WifiBaseTest {
@Mock Context mContext;
@Mock FrameworkFacade mFacade;
@@ -52,13 +48,10 @@ public class WifiDataStallTest {
WifiDataStall mWifiDataStall;
@Mock Clock mClock;
@Mock DeviceConfigFacade mDeviceConfigFacade;
- @Mock Looper mClientModeImplLooper;
@Mock WifiInfo mWifiInfo;
private final WifiLinkLayerStats mOldLlStats = new WifiLinkLayerStats();
private final WifiLinkLayerStats mNewLlStats = new WifiLinkLayerStats();
- final ArgumentCaptor<OnPropertiesChangedListener> mOnPropertiesChangedListenerCaptor =
- ArgumentCaptor.forClass(OnPropertiesChangedListener.class);
/**
* Sets up for unit test
@@ -76,10 +69,10 @@ public class WifiDataStallTest {
.thenReturn(WifiDataStall.MIN_TX_SUCCESS_WITHOUT_RX_DEFAULT);
when(mDeviceConfigFacade.getDataStallDurationMs()).thenReturn(
DeviceConfigFacade.DEFAULT_DATA_STALL_DURATION_MS);
- when(mDeviceConfigFacade.getDataStallTxTputThrMbps()).thenReturn(
- DeviceConfigFacade.DEFAULT_DATA_STALL_TX_TPUT_THR_MBPS);
- when(mDeviceConfigFacade.getDataStallRxTputThrMbps()).thenReturn(
- DeviceConfigFacade.DEFAULT_DATA_STALL_RX_TPUT_THR_MBPS);
+ when(mDeviceConfigFacade.getDataStallTxTputThrKbps()).thenReturn(
+ DeviceConfigFacade.DEFAULT_DATA_STALL_TX_TPUT_THR_KBPS);
+ when(mDeviceConfigFacade.getDataStallRxTputThrKbps()).thenReturn(
+ DeviceConfigFacade.DEFAULT_DATA_STALL_RX_TPUT_THR_KBPS);
when(mDeviceConfigFacade.getDataStallTxPerThr()).thenReturn(
DeviceConfigFacade.DEFAULT_DATA_STALL_TX_PER_THR);
when(mDeviceConfigFacade.getDataStallCcaLevelThr()).thenReturn(
@@ -90,7 +83,7 @@ public class WifiDataStallTest {
when(mWifiInfo.getBSSID()).thenReturn("5G_WiFi");
mWifiDataStall = new WifiDataStall(mContext, mFacade, mWifiMetrics, mDeviceConfigFacade,
- mClientModeImplLooper, mClock);
+ mClock);
mOldLlStats.txmpdu_be = 1000;
mOldLlStats.retries_be = 1000;
@@ -104,8 +97,6 @@ public class WifiDataStallTest {
mNewLlStats.rxmpdu_be = mOldLlStats.rxmpdu_be;
mNewLlStats.timeStampInMs = mOldLlStats.timeStampInMs
+ WifiDataStall.MAX_MS_DELTA_FOR_DATA_STALL - 1;
- verify(mDeviceConfigFacade).addOnPropertiesChangedListener(any(),
- mOnPropertiesChangedListenerCaptor.capture());
}
/**
@@ -138,6 +129,26 @@ public class WifiDataStallTest {
}
/**
+ * Verify there is no data stall if tx tput is above the threshold
+ */
+ @Test
+ public void verifyNoDataStallTxFailureWhenTxTputIsHigh() throws Exception {
+ when(mWifiInfo.getLinkSpeed()).thenReturn(867);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(10L);
+ mNewLlStats.retries_be = mOldLlStats.retries_be;
+
+ assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
+ mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats, mWifiInfo));
+ verifyUpdateWifiIsUnusableLinkLayerStats();
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(
+ 10L + DeviceConfigFacade.DEFAULT_DATA_STALL_DURATION_MS);
+ assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
+ mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats, mWifiInfo));
+ verify(mWifiMetrics, never()).logWifiIsUnusableEvent(
+ WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX);
+ }
+
+ /**
* Verify there is no data stall from tx failures if tx failures are not consecutively bad
*/
@Test
@@ -203,8 +214,6 @@ public class WifiDataStallTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(10L);
when(mDeviceConfigFacade.getDataStallDurationMs()).thenReturn(
DeviceConfigFacade.DEFAULT_DATA_STALL_DURATION_MS + 1);
- mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
-
assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats, mWifiInfo));
verifyUpdateWifiIsUnusableLinkLayerStats();
@@ -225,8 +234,6 @@ public class WifiDataStallTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(10L);
when(mDeviceConfigFacade.getDataStallTxPerThr()).thenReturn(
DeviceConfigFacade.DEFAULT_DATA_STALL_TX_PER_THR + 1);
- mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
-
assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
mWifiDataStall.checkForDataStall(mOldLlStats, mNewLlStats, mWifiInfo));
verifyUpdateWifiIsUnusableLinkLayerStats();
@@ -256,6 +263,7 @@ public class WifiDataStallTest {
*/
@Test
public void verifyNoDataStallBigTimeGap() throws Exception {
+ mNewLlStats.lostmpdu_be = mOldLlStats.lostmpdu_be + WifiDataStall.MIN_TX_BAD_DEFAULT;
mNewLlStats.timeStampInMs = mOldLlStats.timeStampInMs
+ WifiDataStall.MAX_MS_DELTA_FOR_DATA_STALL + 1;
assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN,
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java
index 9883737951..e4b1d70296 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java
@@ -59,7 +59,7 @@ import java.util.regex.Pattern;
* Unit tests for {@link WifiDiagnostics}.
*/
@SmallTest
-public class WifiDiagnosticsTest {
+public class WifiDiagnosticsTest extends WifiBaseTest {
@Mock WifiNative mWifiNative;
@Mock BuildProperties mBuildProperties;
@Mock Context mContext;
@@ -82,9 +82,9 @@ public class WifiDiagnosticsTest {
private static final int ALERT_REASON_CODE = 1;
private static final byte[] ALERT_DATA = {0 , 4, 5};
/** Mock resource for fatal firmware alert list */
- private static final int[] FATAL_FW_ALART_LIST = {256, 257, 258};
+ private static final int[] FATAL_FW_ALERT_LIST = {256, 257, 258};
/** Mock a non fatal firmware alert */
- private static final int NON_FATAL_FW_ALART = 0;
+ private static final int NON_FATAL_FW_ALERT = 0;
private WifiNative.RingBufferStatus mFakeRbs;
/**
@@ -124,7 +124,7 @@ public class WifiDiagnosticsTest {
resources.setInteger(R.integer.config_wifi_logger_ring_buffer_verbose_size_limit_kb,
LARGE_RING_BUFFER_SIZE_KB);
resources.setIntArray(R.array.config_wifi_fatal_firmware_alert_error_code_list,
- FATAL_FW_ALART_LIST);
+ FATAL_FW_ALERT_LIST);
when(mContext.getResources()).thenReturn(resources);
when(mWifiInjector.makeLog(anyString())).thenReturn(mLog);
when(mWifiInjector.getJavaRuntime()).thenReturn(mJavaRuntime);
@@ -896,7 +896,7 @@ public class WifiDiagnosticsTest {
when(mBuildProperties.isUserBuild()).thenReturn(false);
when(mWifiNative.flushRingBufferData()).thenReturn(true);
/** captureAlertData with mock fatal firmware alert*/
- mWifiDiagnostics.captureAlertData(FATAL_FW_ALART_LIST[0], ALERT_DATA);
+ mWifiDiagnostics.captureAlertData(FATAL_FW_ALERT_LIST[0], ALERT_DATA);
verify(mWifiNative).flushRingBufferData();
}
@@ -906,7 +906,7 @@ public class WifiDiagnosticsTest {
when(mBuildProperties.isUserBuild()).thenReturn(false);
when(mWifiNative.flushRingBufferData()).thenReturn(true);
/** captureAlertData with mock non fatal firmware alert*/
- mWifiDiagnostics.captureAlertData(NON_FATAL_FW_ALART, ALERT_DATA);
+ mWifiDiagnostics.captureAlertData(NON_FATAL_FW_ALERT, ALERT_DATA);
verify(mWifiNative, never()).flushRingBufferData();
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java
index 392466412e..2c73d09ae9 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java
@@ -29,7 +29,7 @@ import org.mockito.MockitoAnnotations;
/** Unit tests for {@link WifiInjector}. */
@SmallTest
-public class WifiInjectorTest {
+public class WifiInjectorTest extends WifiBaseTest {
@Mock private Context mContext;
private WifiInjector mInjector;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java
index 7079a2d535..1cb432ef83 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java
@@ -38,7 +38,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WifiConfigManager}.
*/
@SmallTest
-public class WifiKeyStoreTest {
+public class WifiKeyStoreTest extends WifiBaseTest {
@Mock private WifiEnterpriseConfig mWifiEnterpriseConfig;
@Mock private KeyStore mKeyStore;
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 7c55228caf..023fddb177 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java
@@ -27,14 +27,12 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiSsid;
import android.os.Handler;
import android.os.test.TestLooper;
-import android.provider.DeviceConfig.OnPropertiesChangedListener;
import android.util.Pair;
import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import java.util.ArrayList;
@@ -45,9 +43,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.WifiLastResortWatchdog}.
*/
@SmallTest
-public class WifiLastResortWatchdogTest {
- final ArgumentCaptor<OnPropertiesChangedListener> mOnPropertiesChangedListenerCaptor =
- ArgumentCaptor.forClass(OnPropertiesChangedListener.class);
+public class WifiLastResortWatchdogTest extends WifiBaseTest {
WifiLastResortWatchdog mLastResortWatchdog;
@Mock WifiInjector mWifiInjector;
@Mock WifiMetrics mWifiMetrics;
@@ -79,14 +75,13 @@ public class WifiLastResortWatchdogTest {
when(mDeviceConfigFacade.isAbnormalConnectionBugreportEnabled()).thenReturn(true);
when(mDeviceConfigFacade.getAbnormalConnectionDurationMs()).thenReturn(
DEFAULT_ABNORMAL_CONNECTION_DURATION_MS);
+ WifiThreadRunner wifiThreadRunner = new WifiThreadRunner(new Handler(mLooper.getLooper()));
mLastResortWatchdog = new WifiLastResortWatchdog(mWifiInjector, mContext, mClock,
- mWifiMetrics, mClientModeImpl, mLooper.getLooper(), mDeviceConfigFacade);
+ mWifiMetrics, mClientModeImpl, mLooper.getLooper(), mDeviceConfigFacade,
+ wifiThreadRunner);
mLastResortWatchdog.setBugReportProbability(1);
when(mClientModeImpl.getWifiInfo()).thenReturn(mWifiInfo);
when(mWifiInfo.getSSID()).thenReturn(TEST_NETWORK_SSID);
- when(mWifiInjector.getClientModeImplHandler()).thenReturn(mLastResortWatchdog.getHandler());
- verify(mDeviceConfigFacade).addOnPropertiesChangedListener(any(),
- mOnPropertiesChangedListenerCaptor.capture());
}
private List<Pair<ScanDetail, WifiConfiguration>> createFilteredQnsCandidates(String[] ssids,
@@ -1520,8 +1515,9 @@ public class WifiLastResortWatchdogTest {
verify(mWifiMetrics, times(1)).addCountToNumLastResortWatchdogBadDhcpNetworksTotal(3);
verify(mWifiMetrics, times(1)).incrementNumLastResortWatchdogTriggersWithBadDhcp();
- // set connection to ssids[0]
+ // set connection to ssids[0]/bssids[0]
when(mWifiInfo.getSSID()).thenReturn(ssids[0]);
+ when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
// Simulate wifi connecting after triggering
mLastResortWatchdog.connectedStateTransition(true);
@@ -1859,8 +1855,9 @@ public class WifiLastResortWatchdogTest {
// Simulate wifi disconnecting
mLastResortWatchdog.connectedStateTransition(false);
- // set connection to ssids[0]
+ // set connection to ssids[0]/bssids[0]
when(mWifiInfo.getSSID()).thenReturn(ssids[0]);
+ when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
// Test another round, and this time successfully connect after restart trigger
for (int i = 0; i < ssids.length; i++) {
@@ -2073,8 +2070,9 @@ public class WifiLastResortWatchdogTest {
verify(mWifiMetrics, times(1)).incrementNumLastResortWatchdogTriggers();
// Age out network
+ candidates = new ArrayList<>();
for (int i = 0; i < WifiLastResortWatchdog.MAX_BSSID_AGE; i++) {
- mLastResortWatchdog.updateAvailableNetworks(null);
+ mLastResortWatchdog.updateAvailableNetworks(candidates);
}
assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 0);
@@ -2145,8 +2143,9 @@ public class WifiLastResortWatchdogTest {
// Simulate wifi disconnecting
mLastResortWatchdog.connectedStateTransition(false);
- // set connection to ssids[0]
+ // set connection to ssids[0]/bssids[0]
when(mWifiInfo.getSSID()).thenReturn(ssids[0]);
+ when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
// Test another round, and this time successfully connect after restart trigger
for (int i = 0; i < ssids.length; i++) {
@@ -2208,16 +2207,14 @@ public class WifiLastResortWatchdogTest {
}
/**
- * Changes |mAbnormalConnectionDurationMs| to a new value, and then verify that a bugreport is
+ * Changes the abnormal connection duration to a new value, and then verify that a bugreport is
* taken for a connection that takes longer than the new threshold.
* @throws Exception
*/
@Test
public void testGServicesSetDuration() throws Exception {
final int testDurationMs = 10 * 1000; // 10 seconds
- // changes the abnormal connection duration to |testDurationMs|.
when(mDeviceConfigFacade.getAbnormalConnectionDurationMs()).thenReturn(testDurationMs);
- mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
// verifies that bugreport is taken for connections that take longer than |testDurationMs|.
when(mClock.getElapsedSinceBootMillis()).thenReturn(1L);
@@ -2233,14 +2230,12 @@ public class WifiLastResortWatchdogTest {
/**
* Verifies that bugreports are not triggered even when conditions are met after the
- * |mAbnormalConnectionBugreportEnabled| flag is changed to false.
+ * applicable flag is changed to false.
* @throws Exception
*/
@Test
public void testGServicesFlagDisable() throws Exception {
- // changes |mAbnormalConnectionBugreportEnabled| to false.
when(mDeviceConfigFacade.isAbnormalConnectionBugreportEnabled()).thenReturn(false);
- mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
// verifies that bugreports are not taken.
when(mClock.getElapsedSinceBootMillis()).thenReturn(1L);
@@ -2254,4 +2249,59 @@ public class WifiLastResortWatchdogTest {
mLooper.dispatchAll();
verify(mClientModeImpl, never()).takeBugReport(anyString(), anyString());
}
+
+ /**
+ * Verifies that bugreports are not triggered if device connected back to a new BSSID
+ * after recovery.
+ */
+ @Test
+ public void testNotTriggerBugreportIfConnectedToNewBssid() {
+ int associationRejections = 4;
+ int authenticationFailures = 3;
+ String[] ssids = {"\"test1\"", "\"test1\"", "\"test1\""};
+ String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4", "de:ad:ba:b1:e5:55"};
+ int[] frequencies = {2437, 5180, 5180};
+ String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
+ int[] levels = {-60, -86, -50};
+ boolean[] isEphemeral = {false, false, false};
+ boolean[] hasEverConnected = {true, true, true};
+ // Buffer potential candidates 1,2,& 3
+ List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(ssids,
+ bssids, frequencies, caps, levels, isEphemeral, hasEverConnected);
+ mLastResortWatchdog.updateAvailableNetworks(candidates);
+
+ // Ensure new networks have zero'ed failure counts
+ for (int i = 0; i < ssids.length; i++) {
+ assertFailureCountEquals(bssids[i], 0, 0, 0);
+ }
+
+ long timeAtFailure = 100;
+ long timeAtReconnect = 5000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(timeAtFailure, timeAtReconnect);
+
+ //Increment failure counts
+ for (int i = 0; i < associationRejections; i++) {
+ mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(ssids[1], bssids[1],
+ WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION);
+ }
+ for (int i = 0; i < authenticationFailures; i++) {
+ mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(ssids[2], bssids[2],
+ WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION);
+ }
+
+ // Verify watchdog has triggered a restart
+ verify(mWifiMetrics, times(1)).incrementNumLastResortWatchdogTriggers();
+
+ // set connection to ssids[0]/bssids[0]
+ when(mWifiInfo.getSSID()).thenReturn(ssids[0]);
+ when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
+
+ // Simulate wifi connecting after triggering
+ mLastResortWatchdog.connectedStateTransition(true);
+
+ // Verify takeBugReport is not called
+ mLooper.dispatchAll();
+ verify(mWifiMetrics, never()).incrementNumLastResortWatchdogSuccesses();
+ verify(mClientModeImpl, never()).takeBugReport(anyString(), anyString());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java
index ecb72c08b2..d551680e4f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java
@@ -30,7 +30,7 @@ import java.util.Random;
* Unit tests for {@link com.android.server.wifi.WifiLinkLayerStats}.
*/
@SmallTest
-public class WifiLinkLayerStatsTest {
+public class WifiLinkLayerStatsTest extends WifiBaseTest {
ExtendedWifiInfo mWifiInfo;
WifiLinkLayerStats mWifiLinkLayerStats;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java
index a40de55e99..396a853068 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java
@@ -45,7 +45,7 @@ import java.io.StringWriter;
/** Unit tests for {@link WifiLockManager}. */
@SmallTest
-public class WifiLockManagerTest {
+public class WifiLockManagerTest extends WifiBaseTest {
private static final int DEFAULT_TEST_UID_1 = 52;
private static final int DEFAULT_TEST_UID_2 = 53;
@@ -669,7 +669,7 @@ public class WifiLockManagerTest {
public void testForegroundAppAcquireLowLatencyScreenOn() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "",
mBinder, mWorkSource);
@@ -687,7 +687,7 @@ public class WifiLockManagerTest {
public void testForegroundAppAcquireLowLatencyScreenOff() throws Exception {
// Set screen off, and app is foreground
mWifiLockManager.handleScreenStateChanged(false);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
"", mBinder, mWorkSource));
@@ -703,7 +703,7 @@ public class WifiLockManagerTest {
public void testBackgroundAppAcquireLowLatencyScreenOn() throws Exception {
// Set screen on, and app is background
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(false);
assertTrue(mWifiLockManager.acquireWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
"", mBinder, mWorkSource));
@@ -719,7 +719,7 @@ public class WifiLockManagerTest {
public void testLatencyLockAcquireCauseLlEnableNew() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
@@ -739,7 +739,7 @@ public class WifiLockManagerTest {
public void testLatencyLockAcquireCauseLL_enableLegacy() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_TX_POWER_LIMIT);
@@ -758,7 +758,7 @@ public class WifiLockManagerTest {
public void testLatencyLockReleaseCauseLlDisable() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
@@ -792,7 +792,7 @@ public class WifiLockManagerTest {
// Set screen on, and app is foreground
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
@@ -821,7 +821,7 @@ public class WifiLockManagerTest {
// Set screen on, and app is foreground
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
@@ -847,7 +847,7 @@ public class WifiLockManagerTest {
public void testLatencyLockGoScreenOff() throws Exception {
// Set screen on, app foreground
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
@@ -881,7 +881,7 @@ public class WifiLockManagerTest {
public void testLatencyLockGoBackground() throws Exception {
// Initially, set screen on, app foreground
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
@@ -920,7 +920,7 @@ public class WifiLockManagerTest {
public void testLatencyLockGoForeground() throws Exception {
// Initially, set screen on, and app background
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(false);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
// Make sure setLowLatencyMode() is successful
@@ -959,7 +959,7 @@ public class WifiLockManagerTest {
public void testLatencyHiPerfLocks() throws Exception {
// Initially, set screen on, and app background
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(false);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
mWifiLockManager.updateWifiClientConnected(true);
@@ -1070,7 +1070,7 @@ public class WifiLockManagerTest {
when(mClientModeImpl.setLowLatencyMode(anyBoolean())).thenReturn(true);
when(mClientModeImpl.setPowerSave(anyBoolean())).thenReturn(true);
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
@@ -1246,7 +1246,7 @@ public class WifiLockManagerTest {
public void testAcquireLockWhileConnectedDisconnect() throws Exception {
// Set screen on, and app foreground
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "", mBinder, mWorkSource);
mWifiLockManager.updateWifiClientConnected(false);
@@ -1314,7 +1314,7 @@ public class WifiLockManagerTest {
// Set condition for activation of low-latency (except connection to AP)
mWifiLockManager.handleScreenStateChanged(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mWifiNative.getSupportedFeatureSet(INTERFACE_NAME))
.thenReturn((long) WifiManager.WIFI_FEATURE_LOW_LATENCY);
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 73ac30f417..b3f1ed12e8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -69,7 +69,6 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.test.TestLooper;
import android.provider.Settings;
-import android.telephony.TelephonyManager;
import android.util.Base64;
import android.util.Pair;
import android.util.SparseIntArray;
@@ -129,7 +128,7 @@ import java.util.regex.Pattern;
* Unit tests for {@link com.android.server.wifi.WifiMetrics}.
*/
@SmallTest
-public class WifiMetricsTest {
+public class WifiMetricsTest extends WifiBaseTest {
WifiMetrics mWifiMetrics;
WifiMetricsProto.WifiLog mDecodedProto;
@@ -151,19 +150,16 @@ public class WifiMetricsTest {
@Mock ExternalCallbackTracker<IOnWifiUsabilityStatsListener> mListenerTracker;
@Mock WifiP2pMetrics mWifiP2pMetrics;
@Mock DppMetrics mDppMetrics;
- @Mock CellularLinkLayerStatsCollector mCellularLinkLayerStatsCollector;
- @Mock CellularLinkLayerStats mCellularLinkLayerStats;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mDecodedProto = null;
when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
- when(mCellularLinkLayerStatsCollector.update()).thenReturn(mCellularLinkLayerStats);
mTestLooper = new TestLooper();
mWifiMetrics = new WifiMetrics(mContext, mFacade, mClock, mTestLooper.getLooper(),
new WifiAwareMetrics(mClock), new RttMetrics(mClock), mWifiPowerMetrics,
- mWifiP2pMetrics, mDppMetrics, mCellularLinkLayerStatsCollector);
+ mWifiP2pMetrics, mDppMetrics);
mWifiMetrics.setWifiConfigManager(mWcm);
mWifiMetrics.setPasspointManager(mPpm);
mWifiMetrics.setScoringParams(mScoringParams);
@@ -383,8 +379,6 @@ public class WifiMetricsTest {
private static final int NUM_PARTIAL_SCAN_RESULTS = 73;
private static final int NUM_PNO_SCAN_ATTEMPTS = 20;
private static final int NUM_PNO_SCAN_FAILED = 5;
- private static final int NUM_PNO_SCAN_STARTED_OVER_OFFLOAD = 17;
- private static final int NUM_PNO_SCAN_FAILED_OVER_OFFLOAD = 8;
private static final int NUM_PNO_FOUND_NETWORK_EVENTS = 10;
private static final int NUM_WPS_ATTEMPTS = 17;
private static final int NUM_WPS_SUCCESS = 21;
@@ -801,12 +795,6 @@ public class WifiMetricsTest {
for (int i = 0; i < NUM_PNO_SCAN_FAILED; i++) {
mWifiMetrics.incrementPnoScanFailedCount();
}
- for (int i = 0; i < NUM_PNO_SCAN_STARTED_OVER_OFFLOAD; i++) {
- mWifiMetrics.incrementPnoScanStartedOverOffloadCount();
- }
- for (int i = 0; i < NUM_PNO_SCAN_FAILED_OVER_OFFLOAD; i++) {
- mWifiMetrics.incrementPnoScanFailedOverOffloadCount();
- }
for (int i = 0; i < NUM_PNO_FOUND_NETWORK_EVENTS; i++) {
mWifiMetrics.incrementPnoFoundNetworkEventCount();
}
@@ -1156,8 +1144,6 @@ public class WifiMetricsTest {
assertNotNull(pno_metrics);
assertEquals(NUM_PNO_SCAN_ATTEMPTS, pno_metrics.numPnoScanAttempts);
assertEquals(NUM_PNO_SCAN_FAILED, pno_metrics.numPnoScanFailed);
- assertEquals(NUM_PNO_SCAN_STARTED_OVER_OFFLOAD, pno_metrics.numPnoScanStartedOverOffload);
- assertEquals(NUM_PNO_SCAN_FAILED_OVER_OFFLOAD, pno_metrics.numPnoScanFailedOverOffload);
assertEquals(NUM_PNO_FOUND_NETWORK_EVENTS, pno_metrics.numPnoFoundNetworkEvents);
for (ConnectToNetworkNotificationAndActionCount notificationCount
@@ -1799,8 +1785,8 @@ public class WifiMetricsTest {
{WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0},
{WifiMonitor.NETWORK_DISCONNECTION_EVENT, LOCAL_GEN, DEAUTH_REASON},
{WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0},
- {ClientModeImpl.CMD_ASSOCIATED_BSSID, 0, 0},
- {ClientModeImpl.CMD_TARGET_BSSID, 0, 0},
+ {WifiMonitor.ASSOCIATED_BSSID_EVENT, 0, 0},
+ {WifiMonitor.TARGET_BSSID_EVENT, 0, 0},
{WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0},
{WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0}
};
@@ -2869,16 +2855,6 @@ public class WifiMetricsTest {
when(info.getBSSID()).thenReturn("Wifi");
when(info.getFrequency()).thenReturn(5745);
- int signalStrengthDbm = -50;
- int signalStrengthDb = -10;
- boolean isSameRegisteredCell = true;
- CellularLinkLayerStats cellularStats = new CellularLinkLayerStats();
- cellularStats.setIsSameRegisteredCell(isSameRegisteredCell);
- cellularStats.setDataNetworkType(TelephonyManager.NETWORK_TYPE_LTE);
- cellularStats.setSignalStrengthDbm(signalStrengthDbm);
- cellularStats.setSignalStrengthDb(signalStrengthDb);
- when(mCellularLinkLayerStatsCollector.update()).thenReturn(cellularStats);
-
WifiLinkLayerStats stats1 = nextRandomStats(new WifiLinkLayerStats());
WifiLinkLayerStats stats2 = nextRandomStats(stats1);
mWifiMetrics.incrementWifiScoreCount(60);
@@ -2931,14 +2907,6 @@ public class WifiMetricsTest {
.stats[1].probeElapsedTimeSinceLastUpdateMs);
assertEquals(-1, mDecodedProto.wifiUsabilityStatsList[0]
.stats[0].probeElapsedTimeSinceLastUpdateMs);
- assertEquals(WifiUsabilityStatsEntry.NETWORK_TYPE_LTE,
- mDecodedProto.wifiUsabilityStatsList[0].stats[0].cellularDataNetworkType);
- assertEquals(signalStrengthDbm,
- mDecodedProto.wifiUsabilityStatsList[0].stats[0].cellularSignalStrengthDbm);
- assertEquals(signalStrengthDb,
- mDecodedProto.wifiUsabilityStatsList[0].stats[0].cellularSignalStrengthDb);
- assertEquals(isSameRegisteredCell,
- mDecodedProto.wifiUsabilityStatsList[0].stats[0].isSameRegisteredCell);
assertEquals(DEVICE_MOBILITY_STATE_HIGH_MVMT, mDecodedProto.wifiUsabilityStatsList[1]
.stats[mDecodedProto.wifiUsabilityStatsList[1].stats.length - 1]
.deviceMobilityState);
@@ -3237,13 +3205,6 @@ public class WifiMetricsTest {
when(info.getRssi()).thenReturn(nextRandInt());
when(info.getLinkSpeed()).thenReturn(nextRandInt());
- CellularLinkLayerStats cellularStats = new CellularLinkLayerStats();
- cellularStats.setIsSameRegisteredCell(false);
- cellularStats.setDataNetworkType(TelephonyManager.NETWORK_TYPE_UMTS);
- cellularStats.setSignalStrengthDbm(-100);
- cellularStats.setSignalStrengthDb(-20);
- when(mCellularLinkLayerStatsCollector.update()).thenReturn(cellularStats);
-
WifiLinkLayerStats linkLayerStats = nextRandomStats(new WifiLinkLayerStats());
mWifiMetrics.updateWifiUsabilityStatsEntries(info, linkLayerStats);
@@ -3257,10 +3218,6 @@ public class WifiMetricsTest {
assertEquals(usabilityStats.getValue().getTimeStampMillis(), linkLayerStats.timeStampInMs);
assertEquals(usabilityStats.getValue().getTotalRoamScanTimeMillis(),
linkLayerStats.on_time_roam_scan);
- assertEquals(usabilityStats.getValue().getCellularDataNetworkType(),
- TelephonyManager.NETWORK_TYPE_UMTS);
- assertEquals(usabilityStats.getValue().getCellularSignalStrengthDbm(), -100);
- assertEquals(usabilityStats.getValue().getCellularSignalStrengthDb(), -20);
}
/**
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 5439b0ea5b..ba81cb3943 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java
@@ -48,7 +48,7 @@ import org.mockito.ArgumentCaptor;
* Unit tests for {@link com.android.server.wifi.WifiMonitor}.
*/
@SmallTest
-public class WifiMonitorTest {
+public class WifiMonitorTest extends WifiBaseTest {
private static final String WLAN_IFACE_NAME = "wlan0";
private static final String SECOND_WLAN_IFACE_NAME = "wlan1";
private static final String[] GSM_AUTH_DATA = { "45adbc", "fead45", "0x3452"};
@@ -403,14 +403,14 @@ public class WifiMonitorTest {
@Test
public void testBroadcastAssociatedBssidEvent() {
mWifiMonitor.registerHandler(
- WLAN_IFACE_NAME, ClientModeImpl.CMD_ASSOCIATED_BSSID, mHandlerSpy);
+ WLAN_IFACE_NAME, WifiMonitor.ASSOCIATED_BSSID_EVENT, mHandlerSpy);
String bssid = BSSID;
mWifiMonitor.broadcastAssociatedBssidEvent(WLAN_IFACE_NAME, bssid);
mLooper.dispatchAll();
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
verify(mHandlerSpy).handleMessage(messageCaptor.capture());
- assertEquals(ClientModeImpl.CMD_ASSOCIATED_BSSID, messageCaptor.getValue().what);
+ assertEquals(WifiMonitor.ASSOCIATED_BSSID_EVENT, messageCaptor.getValue().what);
assertEquals(bssid, (String) messageCaptor.getValue().obj);
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiMulticastLockManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiMulticastLockManagerTest.java
index 5298ba4c89..9b0f325042 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiMulticastLockManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiMulticastLockManagerTest.java
@@ -36,7 +36,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WifiConfigStoreData}.
*/
@SmallTest
-public class WifiMulticastLockManagerTest {
+public class WifiMulticastLockManagerTest extends WifiBaseTest {
private static final String WL_1_TAG = "Wakelock-1";
private static final String WL_2_TAG = "Wakelock-2";
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 c7a66e31a7..ccd81856b8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
@@ -37,8 +37,6 @@ import static org.mockito.Mockito.when;
import android.app.test.MockAnswerUtil;
import android.net.InterfaceConfiguration;
-import android.net.wifi.IApInterface;
-import android.net.wifi.IClientInterface;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiScanner;
import android.os.Handler;
@@ -53,6 +51,8 @@ import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
import com.android.server.wifi.WifiNative.SupplicantDeathEventHandler;
import com.android.server.wifi.WifiNative.VendorHalDeathEventHandler;
import com.android.server.wifi.WifiNative.WificondDeathEventHandler;
+import com.android.server.wifi.wificond.IApInterface;
+import com.android.server.wifi.wificond.IClientInterface;
import org.junit.After;
import org.junit.Before;
@@ -62,12 +62,15 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Arrays;
+import java.util.HashSet;
+
/**
* Unit tests for the interface management operations in
* {@link com.android.server.wifi.WifiNative}.
*/
@SmallTest
-public class WifiNativeInterfaceManagementTest {
+public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
private static final String IFACE_NAME_0 = "mockWlan0";
private static final String IFACE_NAME_1 = "mockWlan1";
@@ -1277,6 +1280,85 @@ public class WifiNativeInterfaceManagementTest {
mInOrder.verify(mWifiMetrics).incrementNumRadioModeChangeToDbs();
}
+ /**
+ * Verifies the switch of existing client interface in connectivity mode to scan mode.
+ */
+ @Test
+ public void testSwitchClientInterfaceToScanMode() throws Exception {
+ executeAndValidateSetupClientInterface(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0);
+ assertTrue(mWifiNative.switchClientInterfaceToScanMode(IFACE_NAME_0));
+
+ mInOrder.verify(mSupplicantStaIfaceHal).teardownIface(IFACE_NAME_0);
+ mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler();
+ mInOrder.verify(mSupplicantStaIfaceHal).terminate();
+ mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedKeyMgmtCapabilities(IFACE_NAME_0);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
+ }
+
+ /**
+ * Verifies that a switch to scan mode when already in scan mode is rejected.
+ */
+ @Test
+ public void testSwitchClientInterfaceToScanModeFailsWhenAlreadyInScanMode() throws Exception {
+ executeAndValidateSetupClientInterfaceForScan(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0);
+ assertTrue(mWifiNative.switchClientInterfaceToScanMode(IFACE_NAME_0));
+ }
+
+ /**
+ * Verifies the switch of existing client interface in scan mode to connectivity mode.
+ */
+ @Test
+ public void testSwitchClientInterfaceToConnectivityMode() throws Exception {
+ executeAndValidateSetupClientInterfaceForScan(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0);
+ assertTrue(mWifiNative.switchClientInterfaceToConnectivityMode(IFACE_NAME_0));
+
+ 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).getAdvancedKeyMgmtCapabilities(IFACE_NAME_0);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(IFACE_NAME_0);
+ }
+
+ /**
+ * Verifies that a switch to connectivity mode when already in connectivity mode is rejected.
+ */
+ @Test
+ public void testSwitchClientInterfaceToConnectivityModeFailsWhenAlreadyInConnectivityMode()
+ throws Exception {
+ executeAndValidateSetupClientInterface(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0);
+ assertTrue(mWifiNative.switchClientInterfaceToConnectivityMode(IFACE_NAME_0));
+ }
+
+ /**
+ * Verifies the setup of two client interfaces.
+ */
+ @Test
+ public void testSetupTwoClientInterfaces() throws Exception {
+ executeAndValidateSetupClientInterface(
+ false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0,
+ mNetworkObserverCaptor0);
+ assertEquals(new HashSet<>(Arrays.asList(IFACE_NAME_0)),
+ mWifiNative.getClientInterfaceNames());
+
+ executeAndValidateSetupClientInterface(
+ true, false, IFACE_NAME_1, mIfaceCallback1, mIfaceDestroyedListenerCaptor1,
+ mNetworkObserverCaptor1);
+ assertEquals(new HashSet<>(Arrays.asList(IFACE_NAME_0, IFACE_NAME_1)),
+ mWifiNative.getClientInterfaceNames());
+ }
+
+
private void executeAndValidateSetupClientInterface(
boolean existingStaIface, boolean existingApIface,
String ifaceName, @Mock WifiNative.InterfaceCallback callback,
@@ -1382,7 +1464,7 @@ public class WifiNativeInterfaceManagementTest {
mInOrder.verify(mWifiVendorHal).startVendorHal();
}
mInOrder.verify(mWifiVendorHal).isVendorHalSupported();
- mInOrder.verify(mWifiVendorHal).createStaIface(eq(true),
+ mInOrder.verify(mWifiVendorHal).createStaIface(eq(false),
destroyedListenerCaptor.capture());
mInOrder.verify(mWificondControl).setupInterfaceForClientMode(ifaceName);
mInOrder.verify(mNwManagementService).registerObserver(networkObserverCaptor.capture());
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 ab9d6f566a..1660c23cb9 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
@@ -50,7 +50,7 @@ import java.util.regex.Pattern;
* Unit tests for {@link com.android.server.wifi.WifiNative}.
*/
@SmallTest
-public class WifiNativeTest {
+public class WifiNativeTest extends WifiBaseTest {
private static final String WIFI_IFACE_NAME = "mockWlan";
private static final long FATE_REPORT_DRIVER_TIMESTAMP_USEC = 12345;
private static final byte[] FATE_REPORT_FRAME_BYTES = new byte[] {
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 222c4953a8..c9e7db2f99 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -41,6 +41,7 @@ import android.net.MacAddress;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkRequest;
+import android.net.wifi.IActionListener;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.INetworkRequestUserSelectionCallback;
import android.net.wifi.ScanResult;
@@ -50,6 +51,7 @@ import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiScanner.ScanListener;
import android.net.wifi.WifiScanner.ScanSettings;
+import android.os.Binder;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
@@ -97,7 +99,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.WifiNetworkFactory}.
*/
@SmallTest
-public class WifiNetworkFactoryTest {
+public class WifiNetworkFactoryTest extends WifiBaseTest {
private static final int TEST_NETWORK_ID_1 = 104;
private static final int TEST_UID_1 = 10423;
private static final int TEST_UID_2 = 10424;
@@ -152,6 +154,8 @@ public class WifiNetworkFactoryTest {
ArgumentCaptor.forClass(OnAlarmListener.class);
ArgumentCaptor<ScanListener> mScanListenerArgumentCaptor =
ArgumentCaptor.forClass(ScanListener.class);
+ ArgumentCaptor<IActionListener> mConnectListenerArgumentCaptor =
+ ArgumentCaptor.forClass(IActionListener.class);
InOrder mInOrder;
private WifiNetworkFactory mWifiNetworkFactory;
@@ -175,7 +179,7 @@ public class WifiNetworkFactoryTest {
.thenReturn(mConnectivityManager);
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(), anyInt()))
+ when(mPackageManager.getApplicationInfoAsUser(any(), anyInt(), any()))
.thenReturn(new ApplicationInfo());
when(mPackageManager.getApplicationLabel(any())).thenReturn(TEST_APP_NAME);
when(mActivityManager.getPackageImportance(TEST_PACKAGE_NAME_1))
@@ -744,6 +748,49 @@ public class WifiNetworkFactoryTest {
}
/**
+ * Verify network specifier matching for a specifier containing a specific SSID match using
+ * 4 WPA_PSK + SAE transition scan results, each with unique SSID.
+ */
+ @Test
+ public void testNetworkSpecifierMatchSuccessUsingLiteralSsidMatchForSaeTransitionScanResult()
+ throws Exception {
+ setupScanData(SCAN_RESULT_TYPE_WPA_PSK_SAE_TRANSITION,
+ TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
+
+ // Setup network specifier for open networks.
+ PatternMatcher ssidPatternMatch =
+ new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
+ Pair<MacAddress, MacAddress> bssidPatternMatch =
+ Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
+ ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
+ TEST_PACKAGE_NAME_1);
+
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+
+ validateUiStartParams(true);
+
+ mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
+ TEST_CALLBACK_IDENTIFIER);
+
+ verifyPeriodicScans(0, PERIODIC_SCAN_INTERVAL_MS);
+
+ ArgumentCaptor<List<ScanResult>> matchedScanResultsCaptor =
+ ArgumentCaptor.forClass(List.class);
+ verify(mNetworkRequestMatchCallback).onMatch(matchedScanResultsCaptor.capture());
+
+ assertNotNull(matchedScanResultsCaptor.getValue());
+ // We only expect 1 network match in this case.
+ validateScanResults(matchedScanResultsCaptor.getValue(), mTestScanDatas[0].getResults()[0]);
+
+ verify(mWifiMetrics).incrementNetworkRequestApiMatchSizeHistogram(
+ matchedScanResultsCaptor.getValue().size());
+ }
+
+ /**
* Verify network specifier matching for a specifier containing a Prefix SSID match using
* 4 open scan results, each with unique SSID.
*/
@@ -1076,14 +1123,8 @@ public class WifiNetworkFactoryTest {
eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
verify(mClientModeImpl).disconnectCommand();
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mClientModeImpl).sendMessage(messageCaptor.capture());
-
- Message message = messageCaptor.getValue();
- assertNotNull(message);
-
- assertEquals(WifiManager.CONNECT_NETWORK, message.what);
- assertEquals(TEST_NETWORK_ID_1, message.arg1);
+ verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID_1), any(Binder.class),
+ mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -1187,14 +1228,8 @@ public class WifiNetworkFactoryTest {
verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt(), anyString());
verify(mClientModeImpl).disconnectCommand();
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mClientModeImpl).sendMessage(messageCaptor.capture());
-
- Message message = messageCaptor.getValue();
- assertNotNull(message);
-
- assertEquals(WifiManager.CONNECT_NETWORK, message.what);
- assertEquals(TEST_NETWORK_ID_1, message.arg1);
+ verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID_1), any(Binder.class),
+ mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -1244,15 +1279,8 @@ public class WifiNetworkFactoryTest {
eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
verify(mClientModeImpl).disconnectCommand();
- // Verify connection message.
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mClientModeImpl).sendMessage(messageCaptor.capture());
-
- Message message = messageCaptor.getValue();
- assertNotNull(message);
-
- assertEquals(WifiManager.CONNECT_NETWORK, message.what);
- assertEquals(TEST_NETWORK_ID_1, message.arg1);
+ verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID_1), any(Binder.class),
+ mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -1303,15 +1331,8 @@ public class WifiNetworkFactoryTest {
eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
verify(mClientModeImpl).disconnectCommand();
- // Verify connection message.
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mClientModeImpl).sendMessage(messageCaptor.capture());
-
- Message message = messageCaptor.getValue();
- assertNotNull(message);
-
- assertEquals(WifiManager.CONNECT_NETWORK, message.what);
- assertEquals(TEST_NETWORK_ID_1, message.arg1);
+ verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID_1), any(Binder.class),
+ mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -1374,15 +1395,14 @@ public class WifiNetworkFactoryTest {
*/
@Test
public void testNetworkSpecifierHandleConnectionTriggerFailure() throws Exception {
- Messenger replyToMsgr = sendNetworkRequestAndSetupForConnectionStatus();
+ sendNetworkRequestAndSetupForConnectionStatus();
// Send failure message beyond the retry limit to trigger the failure handling.
for (int i = 0; i <= WifiNetworkFactory.USER_SELECTED_NETWORK_CONNECT_RETRY_MAX; i++) {
- Message failureMsg = Message.obtain();
- failureMsg.what = WifiManager.CONNECT_NETWORK_FAILED;
- replyToMsgr.send(failureMsg);
- mLooper.dispatchAll();
+ assertNotNull(mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
+ mConnectListenerArgumentCaptor.getValue().onFailure(WifiManager.ERROR);
}
+ mLooper.dispatchAll();
mInOrder = inOrder(mAlarmManager, mClientModeImpl);
validateConnectionRetryAttempts();
@@ -1611,6 +1631,7 @@ public class WifiNetworkFactoryTest {
WifiConfiguration wcmNetwork = new WifiConfiguration(mSelectedNetwork);
wcmNetwork.networkId = TEST_NETWORK_ID_1;
wcmNetwork.creatorUid = TEST_UID_1;
+ wcmNetwork.creatorName = TEST_PACKAGE_NAME_1;
wcmNetwork.fromWifiNetworkSpecifier = true;
wcmNetwork.ephemeral = true;
when(mWifiConfigManager.getConfiguredNetwork(mSelectedNetwork.configKey()))
@@ -1618,7 +1639,8 @@ public class WifiNetworkFactoryTest {
mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
// Verify that we triggered a disconnect.
verify(mClientModeImpl, times(2)).disconnectCommand();
- verify(mWifiConfigManager).removeNetwork(TEST_NETWORK_ID_1, TEST_UID_1);
+ verify(mWifiConfigManager).removeNetwork(
+ TEST_NETWORK_ID_1, TEST_UID_1, TEST_PACKAGE_NAME_1);
// Re-enable connectivity manager .
verify(mWifiConnectivityManager).setSpecificNetworkRequestInProgress(false);
}
@@ -2124,7 +2146,8 @@ public class WifiNetworkFactoryTest {
// Verify we did not trigger the match callback.
verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
// Verify that we sent a connection attempt to ClientModeImpl
- verify(mClientModeImpl).sendMessage(any());
+ verify(mClientModeImpl).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
}
@@ -2170,7 +2193,8 @@ public class WifiNetworkFactoryTest {
assertNotNull(matchedScanResultsCaptor.getValue());
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ClientModeImpl.
- verify(mClientModeImpl, never()).sendMessage(any());
+ verify(mClientModeImpl, never()).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -2211,7 +2235,8 @@ public class WifiNetworkFactoryTest {
assertNotNull(matchedScanResultsCaptor.getValue());
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ClientModeImpl.
- verify(mClientModeImpl, never()).sendMessage(any());
+ verify(mClientModeImpl, never()).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -2250,7 +2275,8 @@ public class WifiNetworkFactoryTest {
assertNotNull(matchedScanResultsCaptor.getValue());
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ClientModeImpl.
- verify(mClientModeImpl, never()).sendMessage(any());
+ verify(mClientModeImpl, never()).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -2293,7 +2319,8 @@ public class WifiNetworkFactoryTest {
assertNotNull(matchedScanResultsCaptor.getValue());
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ClientModeImpl.
- verify(mClientModeImpl, never()).sendMessage(any());
+ verify(mClientModeImpl, never()).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -2335,7 +2362,8 @@ public class WifiNetworkFactoryTest {
assertNotNull(matchedScanResultsCaptor.getValue());
validateScanResults(matchedScanResultsCaptor.getValue(), matchingScanResult);
// Verify that we did not send a connection attempt to ClientModeImpl.
- verify(mClientModeImpl, never()).sendMessage(any());
+ verify(mClientModeImpl, never()).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -2404,7 +2432,8 @@ public class WifiNetworkFactoryTest {
// Verify we did not trigger the match callback.
verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
// Verify that we sent a connection attempt to ClientModeImpl
- verify(mClientModeImpl).sendMessage(any());
+ verify(mClientModeImpl).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
}
/**
@@ -2475,7 +2504,8 @@ public class WifiNetworkFactoryTest {
// Verify we did not trigger the match callback.
verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
// Verify that we sent a connection attempt to ClientModeImpl
- verify(mClientModeImpl).sendMessage(any());
+ verify(mClientModeImpl).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
}
@@ -2537,7 +2567,8 @@ public class WifiNetworkFactoryTest {
// Verify we did not trigger the match callback.
verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
// Verify that we sent a connection attempt to ClientModeImpl
- verify(mClientModeImpl).sendMessage(any());
+ verify(mClientModeImpl).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
}
@@ -2589,12 +2620,12 @@ public class WifiNetworkFactoryTest {
matchedScanResultsCaptor.getValue().size());
}
- private Messenger sendNetworkRequestAndSetupForConnectionStatus() throws RemoteException {
- return sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
+ private void sendNetworkRequestAndSetupForConnectionStatus() throws RemoteException {
+ sendNetworkRequestAndSetupForConnectionStatus(TEST_SSID_1);
}
// Helper method to setup the necessary pre-requisite steps for tracking connection status.
- private Messenger sendNetworkRequestAndSetupForConnectionStatus(String targetSsid)
+ private void sendNetworkRequestAndSetupForConnectionStatus(String targetSsid)
throws RemoteException {
when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
@@ -2618,19 +2649,14 @@ public class WifiNetworkFactoryTest {
verify(mWifiMetrics).incrementNetworkRequestApiNumApps();
verify(mClientModeImpl, atLeastOnce()).disconnectCommand();
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mClientModeImpl, atLeastOnce()).sendMessage(messageCaptor.capture());
-
- Message message = messageCaptor.getValue();
- assertNotNull(message);
+ verify(mClientModeImpl, atLeastOnce()).connect(eq(null), eq(TEST_NETWORK_ID_1),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
// 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());
-
- return message.replyTo;
}
private void sendNetworkRequestAndSetupForUserSelection() throws RemoteException {
@@ -2739,6 +2765,7 @@ public class WifiNetworkFactoryTest {
private static final int SCAN_RESULT_TYPE_OPEN = 0;
private static final int SCAN_RESULT_TYPE_WPA_PSK = 1;
private static final int SCAN_RESULT_TYPE_WPA_EAP = 2;
+ private static final int SCAN_RESULT_TYPE_WPA_PSK_SAE_TRANSITION = 3;
private String getScanResultCapsForType(int scanResultType) {
switch (scanResultType) {
@@ -2751,6 +2778,8 @@ public class WifiNetworkFactoryTest {
case SCAN_RESULT_TYPE_WPA_EAP:
return WifiConfigurationTestUtil.getScanResultCapsForNetwork(
WifiConfigurationTestUtil.createEapNetwork());
+ case SCAN_RESULT_TYPE_WPA_PSK_SAE_TRANSITION:
+ return WifiConfigurationTestUtil.getScanResultCapsForWpa2Wpa3TransitionNetwork();
}
fail("Invalid scan result type " + scanResultType);
return "";
@@ -2805,11 +2834,9 @@ public class WifiNetworkFactoryTest {
mConnectionTimeoutAlarmListenerArgumentCaptor.getValue());
// Trigger new connection.
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- mInOrder.verify(mClientModeImpl).sendMessage(messageCaptor.capture());
- Message message = messageCaptor.getValue();
- assertNotNull(message);
- assertEquals(WifiManager.CONNECT_NETWORK, message.what);
+ mInOrder.verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID_1),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(),
+ anyInt());
// Start the new connection timeout alarm.
mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
index bd7256a769..adb1be81c5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
@@ -60,7 +60,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.WifiNetworkSelector}.
*/
@SmallTest
-public class WifiNetworkSelectorTest {
+public class WifiNetworkSelectorTest extends WifiBaseTest {
private static final int RSSI_BUMP = 1;
private static final int DUMMY_EVALUATOR_ID_1 = -2; // lowest index
@@ -1379,166 +1379,6 @@ public class WifiNetworkSelectorTest {
}
/**
- * {@link WifiNetworkSelector#getFilteredScanDetailsForCarrierUnsavedNetworks()} should filter
- * out networks that are not EAP after network selection is made.
- *
- * Expected behavior: return EAP networks only
- */
- @Test
- public void getfilterCarrierUnsavedNetworks_filtersForEapNetworks() {
- 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-EAP-CCMP][ESS]", "[ESS]"};
- int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
- mDummyEvaluator.setEvaluatorToSelectCandidate(false);
-
- List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
- ssids, bssids, freqs, caps, levels, mClock);
- HashSet<String> blacklist = new HashSet<>();
-
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
- List<ScanDetail> expectedCarrierUnsavedNetworks = new ArrayList<>();
- expectedCarrierUnsavedNetworks.add(scanDetails.get(0));
- assertEquals("Expect carrier unsaved networks",
- expectedCarrierUnsavedNetworks,
- mWifiNetworkSelector.getFilteredScanDetailsForCarrierUnsavedNetworks(
- mCarrierNetworkConfig));
- }
-
- /**
- * {@link WifiNetworkSelector#getFilteredScanDetailsForCarrierUnsavedNetworks()} should filter
- * out saved networks after network selection is made. This should return an empty list when
- * there are no unsaved networks available.
- *
- * Expected behavior: return unsaved networks only. Return empty list if there are no unsaved
- * networks.
- */
- @Test
- public void getfilterCarrierUnsavedNetworks_filtersOutSavedNetworks() {
- String[] ssids = {"\"test1\""};
- String[] bssids = {"6c:f3:7f:ae:8c:f3"};
- int[] freqs = {2437, 5180};
- String[] caps = {"[WPA2-EAP-CCMP][ESS]"};
- int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP};
- int[] securities = {SECURITY_EAP};
- mDummyEvaluator.setEvaluatorToSelectCandidate(false);
-
- List<ScanDetail> unSavedScanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
- ssids, bssids, freqs, caps, levels, mClock);
- HashSet<String> blacklist = new HashSet<>();
-
- mWifiNetworkSelector.selectNetwork(
- unSavedScanDetails, blacklist, mWifiInfo, false, true, false);
- assertEquals("Expect carrier unsaved networks",
- unSavedScanDetails,
- mWifiNetworkSelector.getFilteredScanDetailsForCarrierUnsavedNetworks(
- mCarrierNetworkConfig));
-
- ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
- WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
- freqs, caps, levels, securities, mWifiConfigManager, mClock);
- List<ScanDetail> savedScanDetails = scanDetailsAndConfigs.getScanDetails();
-
- mWifiNetworkSelector.selectNetwork(
- savedScanDetails, blacklist, mWifiInfo, false, true, false);
- // Saved networks are filtered out.
- assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForCarrierUnsavedNetworks(
- mCarrierNetworkConfig).isEmpty());
- }
-
- /**
- * {@link WifiNetworkSelector#getFilteredScanDetailsForCarrierUnsavedNetworks()} should filter
- * out bssid blacklisted networks.
- *
- * Expected behavior: do not return blacklisted network
- */
- @Test
- public void getfilterCarrierUnsavedNetworks_filtersOutBlacklistedNetworks() {
- String[] ssids = {"\"test1\"", "\"test2\""};
- String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
- int[] freqs = {2437, 5180};
- String[] caps = {"[EAP][ESS]", "[EAP]"};
- int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
- mDummyEvaluator.setEvaluatorToSelectCandidate(false);
-
- List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
- ssids, bssids, freqs, caps, levels, mClock);
- HashSet<String> blacklist = new HashSet<>();
- blacklist.add(bssids[0]);
-
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
- List<ScanDetail> expectedCarrierUnsavedNetworks = new ArrayList<>();
- expectedCarrierUnsavedNetworks.add(scanDetails.get(1));
- assertEquals("Expect carrier unsaved networks",
- expectedCarrierUnsavedNetworks,
- mWifiNetworkSelector.getFilteredScanDetailsForCarrierUnsavedNetworks(
- mCarrierNetworkConfig));
- }
-
- /**
- * {@link WifiNetworkSelector#getFilteredScanDetailsForCarrierUnsavedNetworks()} should return
- * empty list when there are no EAP encrypted networks after network selection is made.
- *
- * Expected behavior: return empty list
- */
- @Test
- public void getfilterCarrierUnsavedNetworks_returnsEmptyListWhenNoEAPNetworksPresent() {
- String[] ssids = {"\"test1\"", "\"test2\""};
- String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
- int[] freqs = {2437, 5180};
- String[] caps = {"[ESS]", "[WPA2-CCMP][ESS]"};
- int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
- mDummyEvaluator.setEvaluatorToSelectCandidate(false);
-
- List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
- ssids, bssids, freqs, caps, levels, mClock);
- HashSet<String> blacklist = new HashSet<>();
-
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
- assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForCarrierUnsavedNetworks(
- mCarrierNetworkConfig).isEmpty());
- }
-
- /**
- * {@link WifiNetworkSelector#getFilteredScanDetailsForCarrierUnsavedNetworks()} should return
- * empty list when there are no carrier networks after network selection is made.
- *
- * Expected behavior: return empty list
- */
- @Test
- public void getfilterCarrierUnsavedNetworks_returnsEmptyListWhenNoCarrierNetworksPresent() {
- String[] ssids = {"\"test1\"", "\"test2\""};
- String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
- int[] freqs = {2437, 5180};
- String[] caps = {"[EAP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
- int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
- mDummyEvaluator.setEvaluatorToSelectCandidate(false);
-
- List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
- ssids, bssids, freqs, caps, levels, mClock);
- HashSet<String> blacklist = new HashSet<>();
-
- mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
-
- when(mCarrierNetworkConfig.isCarrierNetwork(any())).thenReturn(false);
- assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForCarrierUnsavedNetworks(
- mCarrierNetworkConfig).isEmpty());
- }
-
- /**
- * {@link WifiNetworkSelector#getFilteredScanDetailsForCarrierUnsavedNetworks()} should return
- * empty list when no network selection has been made.
- *
- * Expected behavior: return empty list
- */
- @Test
- public void getfilterCarrierUnsavedNetworks_returnsEmptyListWhenNoNetworkSelectionMade() {
- assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForCarrierUnsavedNetworks(
- mCarrierNetworkConfig).isEmpty());
- }
-
- /**
* Test registerCandidateScorer.
*
* Just make sure it does not crash, for now.
@@ -1640,12 +1480,7 @@ public class WifiNetworkSelectorTest {
@Override
public WifiCandidates.ScoredCandidate scoreCandidates(
Collection<WifiCandidates.Candidate> group) {
- return new WifiCandidates.ScoredCandidate(0, 0, null);
- }
-
- @Override
- public boolean userConnectChoiceOverrideWanted() {
- return false;
+ return new WifiCandidates.ScoredCandidate(0, 0, false, null);
}
};
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
index 612fdf5757..0726514bb6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -19,7 +19,6 @@ package com.android.server.wifi;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.OPSTR_CHANGE_WIFI_STATE;
-import static android.app.AppOpsManager.OP_CHANGE_WIFI_STATE;
import static android.app.Notification.EXTRA_BIG_TEXT;
import static com.android.server.wifi.WifiNetworkSuggestionsManager.NOTIFICATION_USER_ALLOWED_APP_INTENT_ACTION;
@@ -49,6 +48,8 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Handler;
import android.os.UserHandle;
import android.os.test.TestLooper;
@@ -58,6 +59,7 @@ import com.android.internal.R;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.server.wifi.WifiNetworkSuggestionsManager.ExtendedWifiNetworkSuggestion;
import com.android.server.wifi.WifiNetworkSuggestionsManager.PerAppInfo;
+import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.util.WifiPermissionsUtil;
import org.junit.Before;
@@ -80,12 +82,13 @@ import java.util.stream.Collectors;
* Unit tests for {@link com.android.server.wifi.WifiNetworkSuggestionsManager}.
*/
@SmallTest
-public class WifiNetworkSuggestionsManagerTest {
+public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
private static final String TEST_PACKAGE_1 = "com.test12345";
private static final String TEST_PACKAGE_2 = "com.test54321";
private static final String TEST_APP_NAME_1 = "test12345";
private static final String TEST_APP_NAME_2 = "test54321";
private static final String TEST_BSSID = "00:11:22:33:44:55";
+ private static final String TEST_FQDN = "FQDN";
private static final int TEST_UID_1 = 5667;
private static final int TEST_UID_2 = 4537;
@@ -100,8 +103,8 @@ public class WifiNetworkSuggestionsManagerTest {
private @Mock WifiConfigStore mWifiConfigStore;
private @Mock WifiConfigManager mWifiConfigManager;
private @Mock NetworkSuggestionStoreData mNetworkSuggestionStoreData;
- private @Mock ClientModeImpl mClientModeImpl;
private @Mock WifiMetrics mWifiMetrics;
+ private @Mock PasspointManager mPasspointManager;
private TestLooper mLooper;
private ArgumentCaptor<AppOpsManager.OnOpChangedListener> mAppOpChangedListenerCaptor =
ArgumentCaptor.forClass(AppOpsManager.OnOpChangedListener.class);
@@ -126,7 +129,7 @@ public class WifiNetworkSuggestionsManagerTest {
when(mWifiInjector.makeNetworkSuggestionStoreData(any()))
.thenReturn(mNetworkSuggestionStoreData);
when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade);
- when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl);
+ when(mWifiInjector.getPasspointManager()).thenReturn(mPasspointManager);
when(mFrameworkFacade.getBroadcast(any(), anyInt(), any(), anyInt()))
.thenReturn(mock(PendingIntent.class));
when(mContext.getResources()).thenReturn(mResources);
@@ -150,11 +153,11 @@ public class WifiNetworkSuggestionsManagerTest {
when(mContext.getApplicationInfo()).thenReturn(ourAppInfo);
// test app info
ApplicationInfo appInfO1 = new ApplicationInfo();
- when(mPackageManager.getApplicationInfoAsUser(eq(TEST_PACKAGE_1), eq(0), anyInt()))
+ when(mPackageManager.getApplicationInfoAsUser(eq(TEST_PACKAGE_1), eq(0), any()))
.thenReturn(appInfO1);
when(mPackageManager.getApplicationLabel(appInfO1)).thenReturn(TEST_APP_NAME_1);
ApplicationInfo appInfO2 = new ApplicationInfo();
- when(mPackageManager.getApplicationInfoAsUser(eq(TEST_PACKAGE_2), eq(0), anyInt()))
+ when(mPackageManager.getApplicationInfoAsUser(eq(TEST_PACKAGE_2), eq(0), any()))
.thenReturn(appInfO2);
when(mPackageManager.getApplicationLabel(appInfO2)).thenReturn(TEST_APP_NAME_2);
@@ -183,11 +186,17 @@ public class WifiNetworkSuggestionsManagerTest {
*/
@Test
public void testAddNetworkSuggestionsSuccess() {
+ PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn(TEST_FQDN);
+ passpointConfiguration.setHomeSp(homeSp);
+ WifiConfiguration dummyConfiguration = new WifiConfiguration();
+ dummyConfiguration.FQDN = TEST_FQDN;
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_2,
+ dummyConfiguration, passpointConfiguration, false, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -198,13 +207,16 @@ public class WifiNetworkSuggestionsManagerTest {
new ArrayList<WifiNetworkSuggestion>() {{
add(networkSuggestion2);
}};
-
+ when(mPasspointManager.addOrUpdateProvider(any(PasspointConfiguration.class),
+ anyInt(), anyString(), eq(true))).thenReturn(true);
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.add(networkSuggestionList1, TEST_UID_1,
TEST_PACKAGE_1));
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.add(networkSuggestionList2, TEST_UID_2,
TEST_PACKAGE_2));
+ verify(mPasspointManager).addOrUpdateProvider(
+ passpointConfiguration, TEST_UID_2, TEST_PACKAGE_2, true);
Set<WifiNetworkSuggestion> allNetworkSuggestions =
mWifiNetworkSuggestionsManager.getAllNetworkSuggestions();
@@ -228,11 +240,17 @@ public class WifiNetworkSuggestionsManagerTest {
*/
@Test
public void testRemoveNetworkSuggestionsSuccess() {
+ PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn(TEST_FQDN);
+ passpointConfiguration.setHomeSp(homeSp);
+ WifiConfiguration dummyConfiguration = new WifiConfiguration();
+ dummyConfiguration.FQDN = TEST_FQDN;
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_2,
+ dummyConfiguration, passpointConfiguration, false, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -243,7 +261,8 @@ public class WifiNetworkSuggestionsManagerTest {
new ArrayList<WifiNetworkSuggestion>() {{
add(networkSuggestion2);
}};
-
+ when(mPasspointManager.addOrUpdateProvider(any(PasspointConfiguration.class),
+ anyInt(), anyString(), eq(true))).thenReturn(true);
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.add(networkSuggestionList1, TEST_UID_1,
TEST_PACKAGE_1));
@@ -258,6 +277,7 @@ public class WifiNetworkSuggestionsManagerTest {
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.remove(networkSuggestionList2,
TEST_UID_1, TEST_PACKAGE_2));
+ verify(mPasspointManager).removeProvider(TEST_UID_2, false, TEST_FQDN);
assertTrue(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions().isEmpty());
@@ -274,13 +294,20 @@ public class WifiNetworkSuggestionsManagerTest {
*/
@Test
public void testRemoveAllNetworkSuggestionsSuccess() {
+ PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn(TEST_FQDN);
+ passpointConfiguration.setHomeSp(homeSp);
+ WifiConfiguration dummyConfiguration = new WifiConfiguration();
+ dummyConfiguration.FQDN = TEST_FQDN;
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_2,
+ dummyConfiguration, passpointConfiguration, false, false, TEST_UID_2,
TEST_PACKAGE_2);
+
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
add(networkSuggestion1);
@@ -290,6 +317,8 @@ public class WifiNetworkSuggestionsManagerTest {
add(networkSuggestion2);
}};
+ when(mPasspointManager.addOrUpdateProvider(any(PasspointConfiguration.class),
+ anyInt(), anyString(), eq(true))).thenReturn(true);
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.add(networkSuggestionList1, TEST_UID_1,
TEST_PACKAGE_1));
@@ -304,6 +333,7 @@ public class WifiNetworkSuggestionsManagerTest {
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.remove(new ArrayList<>(), TEST_UID_2,
TEST_PACKAGE_2));
+ verify(mPasspointManager).removeProvider(TEST_UID_2, false, TEST_FQDN);
assertTrue(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions().isEmpty());
}
@@ -314,7 +344,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testReplaceNetworkSuggestionsSuccess() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -342,12 +372,12 @@ public class WifiNetworkSuggestionsManagerTest {
}
/**
- * Verify that an attempt to modify networks that are already active is rejected.
+ * Verify that modify networks that are already active is allowed.
*/
@Test
- public void testAddNetworkSuggestionsFailureOnInPlaceModification() {
+ public void testAddNetworkSuggestionsSuccessOnInPlaceModification() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -362,10 +392,13 @@ public class WifiNetworkSuggestionsManagerTest {
networkSuggestion.wifiConfiguration.meteredOverride =
WifiConfiguration.METERED_OVERRIDE_METERED;
- // Replace attempt should fail.
- assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE,
+ // Replace attempt should success.
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.add(networkSuggestionList1, TEST_UID_1,
TEST_PACKAGE_1));
+ assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED,
+ mWifiNetworkSuggestionsManager
+ .get(TEST_PACKAGE_1).get(0).wifiConfiguration.meteredOverride);
}
/**
@@ -377,7 +410,7 @@ public class WifiNetworkSuggestionsManagerTest {
List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
for (int i = 0; i < WifiManager.NETWORK_SUGGESTIONS_MAX_PER_APP; i++) {
networkSuggestionList.add(new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1));
}
// The first add should succeed.
@@ -390,7 +423,7 @@ public class WifiNetworkSuggestionsManagerTest {
networkSuggestionList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
networkSuggestionList.add(new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1));
}
// The second add should fail.
@@ -412,7 +445,7 @@ public class WifiNetworkSuggestionsManagerTest {
networkSuggestionList = new ArrayList<>();
for (int i = 0; i < 2; i++) {
networkSuggestionList.add(new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1));
}
// This add should now succeed.
@@ -427,10 +460,10 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testRemoveNetworkSuggestionsFailureOnInvalid() {
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -457,7 +490,7 @@ public class WifiNetworkSuggestionsManagerTest {
public void
testGetNetworkSuggestionsForScanDetailSuccessWithOneMatchForCarrierProvisioningApp() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -488,7 +521,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testGetNetworkSuggestionsForScanDetailSuccessWithOneMatch() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -517,11 +550,11 @@ public class WifiNetworkSuggestionsManagerTest {
public void testGetNetworkSuggestionsForScanDetailSuccessWithMultipleMatch() {
WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createOpenNetwork();
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- wifiConfiguration, false, false, TEST_UID_1,
+ wifiConfiguration, null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
// Reuse the same network credentials to ensure they both match.
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- wifiConfiguration, false, false, TEST_UID_2,
+ wifiConfiguration, null, false, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -564,7 +597,7 @@ public class WifiNetworkSuggestionsManagerTest {
wifiConfiguration.BSSID = scanDetail.getBSSIDString();
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- wifiConfiguration, false, false, TEST_UID_1,
+ wifiConfiguration, null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -594,11 +627,11 @@ public class WifiNetworkSuggestionsManagerTest {
wifiConfiguration.BSSID = scanDetail.getBSSIDString();
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- wifiConfiguration, false, false, TEST_UID_1,
+ wifiConfiguration, null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
// Reuse the same network credentials to ensure they both match.
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- wifiConfiguration, false, false, TEST_UID_2,
+ wifiConfiguration, null, false, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -641,11 +674,11 @@ public class WifiNetworkSuggestionsManagerTest {
wifiConfiguration.BSSID = scanDetail.getBSSIDString();
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- wifiConfiguration, false, false, TEST_UID_1,
+ wifiConfiguration, null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
// Reuse the same network credentials to ensure they both match.
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- wifiConfiguration, false, false, TEST_UID_1,
+ wifiConfiguration, null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
@@ -681,11 +714,11 @@ public class WifiNetworkSuggestionsManagerTest {
wifiConfiguration2.BSSID = scanDetail.getBSSIDString();
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- wifiConfiguration1, false, false, TEST_UID_1,
+ wifiConfiguration1, null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
// Reuse the same network credentials to ensure they both match.
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- wifiConfiguration2, false, false, TEST_UID_2,
+ wifiConfiguration2, null, false, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -735,7 +768,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testGetNetworkSuggestionsForScanDetailFailureOnAppNotApproved() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -758,7 +791,7 @@ public class WifiNetworkSuggestionsManagerTest {
public void testGetNetworkSuggestionsForScanDetailFailureOnSuggestionRemoval() {
WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createOpenNetwork();
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- wifiConfiguration, false, false, TEST_UID_1,
+ wifiConfiguration, null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
ScanDetail scanDetail = createScanDetailForNetwork(wifiConfiguration);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -787,7 +820,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testGetNetworkSuggestionsForScanDetailFailureOnWrongNetwork() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -815,7 +848,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testOnNetworkConnectionSuccessWithOneMatch() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -827,9 +860,13 @@ public class WifiNetworkSuggestionsManagerTest {
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
// Simulate connecting to the network.
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, networkSuggestion.wifiConfiguration,
- TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
verify(mWifiMetrics).incrementNetworkSuggestionApiNumConnectSuccess();
@@ -849,7 +886,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testOnNetworkConnectionFailureWithOneMatch() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -859,11 +896,14 @@ public class WifiNetworkSuggestionsManagerTest {
mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
TEST_PACKAGE_1));
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
-
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
// Simulate connecting to the network.
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_DHCP, networkSuggestion.wifiConfiguration,
- TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_DHCP, connectNetwork, TEST_BSSID);
verify(mWifiMetrics).incrementNetworkSuggestionApiNumConnectFailure();
@@ -886,14 +926,14 @@ public class WifiNetworkSuggestionsManagerTest {
public void testOnNetworkConnectionSuccessWithMultipleMatch() {
WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createOpenNetwork();
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- wifiConfiguration, true, false, TEST_UID_1,
+ wifiConfiguration, null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
add(networkSuggestion1);
}};
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- wifiConfiguration, true, false, TEST_UID_2,
+ wifiConfiguration, null, true, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList2 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -909,9 +949,15 @@ public class WifiNetworkSuggestionsManagerTest {
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_2);
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion1.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
+
// Simulate connecting to the network.
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, wifiConfiguration, TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
verify(mWifiMetrics).incrementNetworkSuggestionApiNumConnectSuccess();
@@ -948,14 +994,14 @@ public class WifiNetworkSuggestionsManagerTest {
WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createOpenNetwork();
wifiConfiguration.BSSID = TEST_BSSID;
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- wifiConfiguration, true, false, TEST_UID_1,
+ wifiConfiguration, null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
add(networkSuggestion1);
}};
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- wifiConfiguration, true, false, TEST_UID_2,
+ wifiConfiguration, null, true, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList2 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -970,10 +1016,14 @@ public class WifiNetworkSuggestionsManagerTest {
TEST_PACKAGE_2));
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_2);
-
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion1.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
// Simulate connecting to the network.
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, wifiConfiguration, TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
verify(mWifiMetrics).incrementNetworkSuggestionApiNumConnectSuccess();
@@ -1011,14 +1061,14 @@ public class WifiNetworkSuggestionsManagerTest {
WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
wifiConfiguration2.BSSID = TEST_BSSID;
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- wifiConfiguration1, true, false, TEST_UID_1,
+ wifiConfiguration1, null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
add(networkSuggestion1);
}};
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- wifiConfiguration2, true, false, TEST_UID_2,
+ wifiConfiguration2, null, true, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList2 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1034,9 +1084,15 @@ public class WifiNetworkSuggestionsManagerTest {
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_2);
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion1.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
+
// Simulate connecting to the network.
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, wifiConfiguration1, TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
verify(mWifiMetrics).incrementNetworkSuggestionApiNumConnectSuccess();
@@ -1072,7 +1128,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testOnNetworkConnectionWhenAppNotApproved() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1084,10 +1140,15 @@ public class WifiNetworkSuggestionsManagerTest {
verify(mWifiPermissionsUtil).checkNetworkCarrierProvisioningPermission(TEST_UID_1);
assertFalse(mWifiNetworkSuggestionsManager.hasUserApprovedForApp(TEST_PACKAGE_1));
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
+
// Simulate connecting to the network.
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, networkSuggestion.wifiConfiguration,
- TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
// Verify no broadcast was sent out.
mInorder.verify(mWifiPermissionsUtil, never()).enforceCanAccessScanResults(
@@ -1106,7 +1167,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testOnNetworkConnectionWhenIsAppInteractionRequiredNotSet() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1118,10 +1179,15 @@ public class WifiNetworkSuggestionsManagerTest {
verify(mWifiPermissionsUtil).checkNetworkCarrierProvisioningPermission(TEST_UID_1);
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
+
// Simulate connecting to the network.
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, networkSuggestion.wifiConfiguration,
- TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
// Verify no broadcast was sent out.
mInorder.verify(mWifiPermissionsUtil, never()).enforceCanAccessScanResults(
@@ -1140,7 +1206,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testOnNetworkConnectionWhenAppDoesNotHoldLocationPermission() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1155,10 +1221,15 @@ public class WifiNetworkSuggestionsManagerTest {
doThrow(new SecurityException())
.when(mWifiPermissionsUtil).enforceCanAccessScanResults(TEST_PACKAGE_1, TEST_UID_1);
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
+
// Simulate connecting to the network.
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, networkSuggestion.wifiConfiguration,
- TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
mInorder.verify(mWifiPermissionsUtil)
.enforceCanAccessScanResults(TEST_PACKAGE_1, TEST_UID_1);
@@ -1173,7 +1244,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testAddNetworkSuggestionsConfigStoreWrite() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
@@ -1215,7 +1286,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testRemoveNetworkSuggestionsConfigStoreWrite() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
@@ -1250,13 +1321,24 @@ public class WifiNetworkSuggestionsManagerTest {
*/
@Test
public void testNetworkSuggestionsConfigStoreLoad() {
+ PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn(TEST_FQDN);
+ passpointConfiguration.setHomeSp(homeSp);
+ WifiConfiguration dummyConfiguration = new WifiConfiguration();
+ dummyConfiguration.FQDN = TEST_FQDN;
PerAppInfo appInfo = new PerAppInfo(TEST_PACKAGE_1);
appInfo.hasUserApproved = true;
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
+ TEST_PACKAGE_1);
+ WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
+ dummyConfiguration, passpointConfiguration, false, false, TEST_UID_1,
TEST_PACKAGE_1);
appInfo.extNetworkSuggestions.add(
ExtendedWifiNetworkSuggestion.fromWns(networkSuggestion, appInfo));
+ appInfo.extNetworkSuggestions.add(
+ ExtendedWifiNetworkSuggestion.fromWns(networkSuggestion1, appInfo));
mDataSource.fromDeserialized(new HashMap<String, PerAppInfo>() {{
put(TEST_PACKAGE_1, appInfo);
}});
@@ -1266,6 +1348,7 @@ public class WifiNetworkSuggestionsManagerTest {
Set<WifiNetworkSuggestion> expectedAllNetworkSuggestions =
new HashSet<WifiNetworkSuggestion>() {{
add(networkSuggestion);
+ add(networkSuggestion1);
}};
assertEquals(expectedAllNetworkSuggestions, allNetworkSuggestions);
@@ -1278,6 +1361,18 @@ public class WifiNetworkSuggestionsManagerTest {
add(networkSuggestion);
}};
assertEquals(expectedMatchingNetworkSuggestions, matchingNetworkSuggestions);
+
+ // Ensure we can lookup the passpoint network.
+ WifiConfiguration connectNetwork = WifiConfigurationTestUtil.createPasspointNetwork();
+ connectNetwork.FQDN = TEST_FQDN;
+ Set<ExtendedWifiNetworkSuggestion> matchingExtNetworkSuggestions =
+ mWifiNetworkSuggestionsManager
+ .getNetworkSuggestionsForWifiConfiguration(connectNetwork, null);
+ Set<ExtendedWifiNetworkSuggestion> expectedMatchingExtNetworkSuggestions =
+ new HashSet<ExtendedWifiNetworkSuggestion>() {{
+ add(ExtendedWifiNetworkSuggestion.fromWns(networkSuggestion1, appInfo));
+ }};
+ assertEquals(expectedMatchingExtNetworkSuggestions, matchingExtNetworkSuggestions);
}
/**
@@ -1289,7 +1384,7 @@ public class WifiNetworkSuggestionsManagerTest {
PerAppInfo appInfo1 = new PerAppInfo(TEST_PACKAGE_1);
appInfo1.hasUserApproved = true;
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
appInfo1.extNetworkSuggestions.add(
ExtendedWifiNetworkSuggestion.fromWns(networkSuggestion1, appInfo1));
@@ -1303,7 +1398,7 @@ public class WifiNetworkSuggestionsManagerTest {
PerAppInfo appInfo2 = new PerAppInfo(TEST_PACKAGE_2);
appInfo2.hasUserApproved = true;
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
appInfo2.extNetworkSuggestions.add(
ExtendedWifiNetworkSuggestion.fromWns(networkSuggestion2, appInfo2));
@@ -1335,102 +1430,73 @@ public class WifiNetworkSuggestionsManagerTest {
}
/**
- * Verify that we don't disconnect from the network if the only network suggestion matching the
- * connected network is removed when App doesn't have NetworkCarrierProvisioningPermission.
- */
- @Test
- public void
- testRemoveNetworkSuggestionsMatchingConnectionSuccessWithOneMatchNoCarrierProvision() {
- WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
- TEST_PACKAGE_1);
- List<WifiNetworkSuggestion> networkSuggestionList =
- new ArrayList<WifiNetworkSuggestion>() {{
- add(networkSuggestion);
- }};
- when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
- .thenReturn(false);
- assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
- TEST_PACKAGE_1));
- mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
-
- // Simulate connecting to the network.
- mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, networkSuggestion.wifiConfiguration,
- TEST_BSSID);
-
- // Now remove the network suggestion and ensure we did not trigger a disconnect.
- assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiNetworkSuggestionsManager.remove(networkSuggestionList, TEST_UID_1,
- TEST_PACKAGE_1));
- verify(mClientModeImpl, never()).disconnectCommand();
- }
-
- /**
* Verify that we will disconnect from the network if the only network suggestion matching the
- * connected network is removed when App has NetworkCarrierProvisioningPermission.
+ * connected network is removed.
*/
@Test
public void
- testRemoveNetworkSuggestionsMatchingConnectionSuccessWithOneMatchCarrierProvision() {
+ testRemoveNetworkSuggestionsMatchingConnectionSuccessWithOneMatch() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
add(networkSuggestion);
}};
- when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
- .thenReturn(true);
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
TEST_PACKAGE_1));
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
-
// Simulate connecting to the network.
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, networkSuggestion.wifiConfiguration,
- TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
// Now remove the network suggestion and ensure we did trigger a disconnect.
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.remove(networkSuggestionList, TEST_UID_1,
TEST_PACKAGE_1));
- verify(mClientModeImpl).disconnectCommand();
+ verify(mWifiConfigManager).removeSuggestionConfiguredNetwork(
+ networkSuggestion.wifiConfiguration.configKey());
}
/**
- * Verify that we will disconnect from network when App has NetworkCarrierProvisioningPermission
- * and removed all its suggestions by remove empty list.
+ * Verify that we will disconnect from network when App removed all its suggestions by remove
+ * empty list.
*/
@Test
public void
- testRemoveAllNetworkSuggestionsMatchingConnectionSuccessWithOneMatchCarrierProvision() {
+ testRemoveAllNetworkSuggestionsMatchingConnectionSuccessWithOneMatch() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
add(networkSuggestion);
}};
- when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
- .thenReturn(true);
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
TEST_PACKAGE_1));
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
-
// Simulate connecting to the network.
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, networkSuggestion.wifiConfiguration,
- TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
// Now remove all network suggestion and ensure we did trigger a disconnect.
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.remove(new ArrayList<>(), TEST_UID_1,
TEST_PACKAGE_1));
- verify(mClientModeImpl).disconnectCommand();
+ verify(mWifiConfigManager).removeSuggestionConfiguredNetwork(
+ networkSuggestion.wifiConfiguration.configKey());
}
@@ -1442,14 +1508,14 @@ public class WifiNetworkSuggestionsManagerTest {
public void testRemoveAppMatchingConnectionSuccessWithMultipleMatch() {
WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createOpenNetwork();
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- wifiConfiguration, true, false, TEST_UID_1,
+ wifiConfiguration, null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
add(networkSuggestion1);
}};
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- wifiConfiguration, true, false, TEST_UID_2,
+ wifiConfiguration, null, true, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList2 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1466,16 +1532,22 @@ public class WifiNetworkSuggestionsManagerTest {
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_2);
// Simulate connecting to the network.
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_NONE, wifiConfiguration, TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
// Now remove one of the apps and ensure we did not trigger a disconnect.
mWifiNetworkSuggestionsManager.removeApp(TEST_PACKAGE_1);
- verify(mClientModeImpl, never()).disconnectCommand();
+ verify(mWifiConfigManager, never()).removeSuggestionConfiguredNetwork(anyString());
// Now remove the other app and ensure we trigger a disconnect.
mWifiNetworkSuggestionsManager.removeApp(TEST_PACKAGE_2);
- verify(mClientModeImpl).disconnectCommand();
+ verify(mWifiConfigManager).removeSuggestionConfiguredNetwork(
+ networkSuggestion2.wifiConfiguration.configKey());
}
/**
@@ -1485,7 +1557,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testRemoveAppNotMatchingConnectionSuccess() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1503,7 +1575,7 @@ public class WifiNetworkSuggestionsManagerTest {
// Now remove the app and ensure we did not trigger a disconnect.
mWifiNetworkSuggestionsManager.removeApp(TEST_PACKAGE_1);
- verify(mClientModeImpl, never()).disconnectCommand();
+ verify(mWifiConfigManager, never()).removeSuggestionConfiguredNetwork(anyString());
}
/**
@@ -1513,7 +1585,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testRemoveNetworkSuggestionsNotMatchingConnectionSuccessAfterConnectionFailure() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1523,11 +1595,14 @@ public class WifiNetworkSuggestionsManagerTest {
mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
TEST_PACKAGE_1));
mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
-
+ WifiConfiguration connectNetwork =
+ new WifiConfiguration(networkSuggestion.wifiConfiguration);
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
// Simulate failing connection to the network.
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
- WifiMetrics.ConnectionEvent.FAILURE_DHCP, networkSuggestion.wifiConfiguration,
- TEST_BSSID);
+ WifiMetrics.ConnectionEvent.FAILURE_DHCP, connectNetwork, TEST_BSSID);
// Simulate connecting to some other network.
mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
@@ -1536,7 +1611,7 @@ public class WifiNetworkSuggestionsManagerTest {
// Now remove the app and ensure we did not trigger a disconnect.
mWifiNetworkSuggestionsManager.removeApp(TEST_PACKAGE_1);
- verify(mClientModeImpl, never()).disconnectCommand();
+ verify(mWifiConfigManager, never()).removeSuggestionConfiguredNetwork(anyString());
}
/**
@@ -1546,10 +1621,10 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testAddRemoveNetworkSuggestionsStartStopAppOpsWatch() {
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_2,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -1595,7 +1670,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testAppOpsChangeAfterSuggestionsAdd() {
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1647,7 +1722,7 @@ public class WifiNetworkSuggestionsManagerTest {
public void testAppOpsChangeAfterConfigStoreLoad() {
PerAppInfo appInfo = new PerAppInfo(TEST_PACKAGE_1);
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
appInfo.extNetworkSuggestions.add(
ExtendedWifiNetworkSuggestion.fromWns(networkSuggestion, appInfo));
@@ -1694,7 +1769,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testAppOpsChangeWrongUid() {
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1737,10 +1812,10 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testRemoveApp() {
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_2,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -1803,10 +1878,10 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testClear() {
WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
TEST_PACKAGE_1);
WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), false, false, TEST_UID_2,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList1 =
@@ -1860,7 +1935,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testUserApprovalNotificationDismissalWhenGetScanResult() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1901,7 +1976,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testUserApprovalNotificationClickOnAllowWhenGetScanResult() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1947,7 +2022,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testUserApprovalNotificationClickOnDisallowWhenGetScanResult() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -1976,8 +2051,7 @@ public class WifiNetworkSuggestionsManagerTest {
NOTIFICATION_USER_DISALLOWED_APP_INTENT_ACTION, TEST_PACKAGE_1, TEST_UID_1);
// Ensure we turn off CHANGE_WIFI_STATE app-ops.
verify(mAppOpsManager).setMode(
- OP_CHANGE_WIFI_STATE, TEST_UID_1,
- TEST_PACKAGE_1, MODE_IGNORED);
+ OPSTR_CHANGE_WIFI_STATE, TEST_UID_1, TEST_PACKAGE_1, MODE_IGNORED);
// Cancel the notification.
verify(mNotificationManger).cancel(SystemMessage.NOTE_NETWORK_SUGGESTION_AVAILABLE);
@@ -2017,7 +2091,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testUserApprovalNotificationWhilePreviousNotificationActive() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -2042,19 +2116,68 @@ public class WifiNetworkSuggestionsManagerTest {
}
/**
+ * Verify get network suggestion return the right result
+ * 1. App never suggested, should return empty list.
+ * 2. App has network suggestions, return all its suggestion.
+ * 3. App suggested and remove them all, should return empty list.
+ */
+ @Test
+ public void testGetNetworkSuggestions() {
+ // test App never suggested.
+ List<WifiNetworkSuggestion> storedNetworkSuggestionListPerApp =
+ mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1);
+ assertEquals(storedNetworkSuggestionListPerApp.size(), 0);
+
+ // App add network suggestions then get stored suggestions.
+ WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion(
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, TEST_UID_1,
+ TEST_PACKAGE_1);
+ WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion(
+ WifiConfigurationTestUtil.createOweNetwork(), null, false, false, TEST_UID_1,
+ TEST_PACKAGE_1);
+ WifiNetworkSuggestion networkSuggestion3 = new WifiNetworkSuggestion(
+ WifiConfigurationTestUtil.createSaeNetwork(), null, false, false, TEST_UID_1,
+ TEST_PACKAGE_1);
+ WifiNetworkSuggestion networkSuggestion4 = new WifiNetworkSuggestion(
+ WifiConfigurationTestUtil.createPskNetwork(), null, false, false, TEST_UID_1,
+ TEST_PACKAGE_1);
+ List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
+ networkSuggestionList.add(networkSuggestion1);
+ networkSuggestionList.add(networkSuggestion2);
+ networkSuggestionList.add(networkSuggestion3);
+ networkSuggestionList.add(networkSuggestion4);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+ mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
+ TEST_PACKAGE_1));
+ mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
+ storedNetworkSuggestionListPerApp =
+ mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1);
+ assertEquals(new HashSet<>(networkSuggestionList),
+ new HashSet<>(storedNetworkSuggestionListPerApp));
+
+ // App remove all network suggestions, expect empty list.
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+ mWifiNetworkSuggestionsManager.remove(new ArrayList<>(), TEST_UID_1,
+ TEST_PACKAGE_1));
+ storedNetworkSuggestionListPerApp =
+ mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1);
+ assertEquals(storedNetworkSuggestionListPerApp.size(), 0);
+ }
+
+ /**
* Verify get hidden networks from All user approve network suggestions
*/
@Test
public void testGetHiddenNetworks() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
WifiNetworkSuggestion hiddenNetworkSuggestion1 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createPskHiddenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createPskHiddenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
WifiNetworkSuggestion hiddenNetworkSuggestion2 = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createPskHiddenNetwork(), true, false, TEST_UID_2,
+ WifiConfigurationTestUtil.createPskHiddenNetwork(), null, true, false, TEST_UID_2,
TEST_PACKAGE_2);
List<WifiNetworkSuggestion> networkSuggestionList1 =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -2086,7 +2209,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testUserApprovalNotificationClickOnAllowDuringAddingSuggestions() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -2121,7 +2244,7 @@ public class WifiNetworkSuggestionsManagerTest {
@Test
public void testUserApprovalNotificationClickOnDisallowWhenAddSuggestions() {
WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
- WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1,
+ WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, TEST_UID_1,
TEST_PACKAGE_1);
List<WifiNetworkSuggestion> networkSuggestionList =
new ArrayList<WifiNetworkSuggestion>() {{
@@ -2139,8 +2262,7 @@ public class WifiNetworkSuggestionsManagerTest {
NOTIFICATION_USER_DISALLOWED_APP_INTENT_ACTION, TEST_PACKAGE_1, TEST_UID_1);
// Ensure we turn off CHANGE_WIFI_STATE app-ops.
verify(mAppOpsManager).setMode(
- OP_CHANGE_WIFI_STATE, TEST_UID_1,
- TEST_PACKAGE_1, MODE_IGNORED);
+ OPSTR_CHANGE_WIFI_STATE, TEST_UID_1, TEST_PACKAGE_1, MODE_IGNORED);
// Cancel the notification.
verify(mNotificationManger).cancel(SystemMessage.NOTE_NETWORK_SUGGESTION_AVAILABLE);
@@ -2170,6 +2292,57 @@ public class WifiNetworkSuggestionsManagerTest {
}
/**
+ * Verify a successful lookup of a single passpoint network suggestion matching the
+ * connected network.
+ * a) The corresponding network suggestion has the
+ * {@link WifiNetworkSuggestion#isAppInteractionRequired} flag set.
+ * b) The app holds location permission.
+ * This should trigger a broadcast to the app.
+ */
+ @Test
+ public void testOnPasspointNetworkConnectionSuccessWithOneMatch() {
+ PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn(TEST_FQDN);
+ passpointConfiguration.setHomeSp(homeSp);
+ WifiConfiguration dummyConfiguration = new WifiConfiguration();
+ dummyConfiguration.FQDN = TEST_FQDN;
+ WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
+ dummyConfiguration, passpointConfiguration, true, false, TEST_UID_1,
+ TEST_PACKAGE_1);
+ List<WifiNetworkSuggestion> networkSuggestionList =
+ new ArrayList<WifiNetworkSuggestion>() {{
+ add(networkSuggestion);
+ }};
+ when(mPasspointManager.addOrUpdateProvider(any(), anyInt(), anyString(), anyBoolean()))
+ .thenReturn(true);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+ mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
+ TEST_PACKAGE_1));
+
+ mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1);
+
+ // Simulate connecting to the network.
+ WifiConfiguration connectNetwork = WifiConfigurationTestUtil.createPasspointNetwork();
+ connectNetwork.FQDN = TEST_FQDN;
+ connectNetwork.fromWifiNetworkSuggestion = true;
+ connectNetwork.ephemeral = true;
+ connectNetwork.creatorName = TEST_APP_NAME_1;
+ mWifiNetworkSuggestionsManager.handleConnectionAttemptEnded(
+ WifiMetrics.ConnectionEvent.FAILURE_NONE, connectNetwork, TEST_BSSID);
+
+ verify(mWifiMetrics).incrementNetworkSuggestionApiNumConnectSuccess();
+
+ // Verify that the correct broadcast was sent out.
+ mInorder.verify(mWifiPermissionsUtil)
+ .enforceCanAccessScanResults(TEST_PACKAGE_1, TEST_UID_1);
+ validatePostConnectionBroadcastSent(TEST_PACKAGE_1, networkSuggestion);
+
+ // Verify no more broadcast were sent out.
+ mInorder.verifyNoMoreInteractions();
+ }
+
+ /**
* Creates a scan detail corresponding to the provided network values.
*/
private ScanDetail createScanDetailForNetwork(WifiConfiguration configuration) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiPowerMetricsTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiPowerMetricsTest.java
index b463171f0f..81ef3d65b5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiPowerMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiPowerMetricsTest.java
@@ -40,7 +40,7 @@ import java.io.PrintWriter;
* Unit tests for {@link com.android.server.wifi.WifiPowerMetrics}.
*/
@SmallTest
-public class WifiPowerMetricsTest {
+public class WifiPowerMetricsTest extends WifiBaseTest {
@Mock IBatteryStats mBatteryStats;
WifiPowerMetrics mWifiPowerMetrics;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardProtoTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardProtoTest.java
index c7bf909777..d02ae2ed4c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardProtoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardProtoTest.java
@@ -30,7 +30,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WifiScoreCardProto}.
*/
@SmallTest
-public class WifiScoreCardProtoTest {
+public class WifiScoreCardProtoTest extends WifiBaseTest {
/**
* Sets up for unit test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java
index 577f5bc65b..e649b28089 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java
@@ -47,7 +47,7 @@ import java.util.Arrays;
* Unit tests for {@link com.android.server.wifi.WifiScoreCard}.
*/
@SmallTest
-public class WifiScoreCardTest {
+public class WifiScoreCardTest extends WifiBaseTest {
static final WifiSsid TEST_SSID_1 = WifiSsid.createFromAsciiEncoded("Joe's Place");
static final WifiSsid TEST_SSID_2 = WifiSsid.createFromAsciiEncoded("Poe's Raven");
@@ -494,4 +494,38 @@ public class WifiScoreCardTest {
assertEquals(0, leftovers.length);
}
+ /**
+ * Test that older items are evicted from memory.
+ */
+ @Test
+ public void testOlderItemsShouldBeEvicted() throws Exception {
+ mWifiInfo.setRssi(-55);
+ mWifiInfo.setFrequency(5805);
+ mWifiInfo.setLinkSpeed(384);
+ mWifiScoreCard.installMemoryStore(mMemoryStore);
+ for (int i = 0; i < 256; i++) {
+ MacAddress bssid = MacAddress.fromBytes(new byte[]{2, 2, 2, 2, 2, (byte) i});
+ mWifiInfo.setBSSID(bssid.toString());
+ mWifiScoreCard.noteSignalPoll(mWifiInfo);
+ }
+
+ verify(mMemoryStore, times(256)).read(any(), any());
+ verify(mMemoryStore, atLeastOnce()).write(any(), any()); // Assumes target size < 256
+ reset(mMemoryStore);
+
+ for (int i = 256 - 3; i < 256; i++) {
+ MacAddress bssid = MacAddress.fromBytes(new byte[]{2, 2, 2, 2, 2, (byte) i});
+ mWifiInfo.setBSSID(bssid.toString());
+ mWifiScoreCard.noteSignalPoll(mWifiInfo);
+ }
+ verify(mMemoryStore, never()).read(any(), any()); // Assumes target size >= 3
+
+ for (int i = 0; i < 3; i++) {
+ MacAddress bssid = MacAddress.fromBytes(new byte[]{2, 2, 2, 2, 2, (byte) i});
+ mWifiInfo.setBSSID(bssid.toString());
+ mWifiScoreCard.noteSignalPoll(mWifiInfo);
+ }
+ verify(mMemoryStore, times(3)).read(any(), any()); // Assumes target size < 253
+ }
+
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
index 86de199c3e..2ed9e420f3 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
@@ -52,7 +52,7 @@ import java.io.PrintWriter;
* Unit tests for {@link com.android.server.wifi.WifiScoreReport}.
*/
@SmallTest
-public class WifiScoreReportTest {
+public class WifiScoreReportTest extends WifiBaseTest {
class FakeClock extends Clock {
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 bd8129a380..25e09777f4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -17,9 +17,6 @@
package com.android.server.wifi;
import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_STATIONARY;
-import static android.net.wifi.WifiManager.HOTSPOT_FAILED;
-import static android.net.wifi.WifiManager.HOTSPOT_STARTED;
-import static android.net.wifi.WifiManager.HOTSPOT_STOPPED;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
@@ -32,14 +29,11 @@ import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
import static android.net.wifi.WifiManager.WIFI_FEATURE_INFRA_5G;
import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
-import static com.android.server.wifi.WifiController.CMD_SET_AP;
-import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -47,18 +41,21 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.AdditionalAnswers.returnsSecondArg;
+import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.anyObject;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.ignoreStubs;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.isNull;
import static org.mockito.Mockito.mock;
@@ -66,6 +63,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
@@ -74,8 +72,7 @@ import static org.mockito.Mockito.when;
import android.Manifest;
import android.app.ActivityManager;
import android.app.AppOpsManager;
-import android.app.admin.DeviceAdminInfo;
-import android.app.admin.DevicePolicyManagerInternal;
+import android.app.test.MockAnswerUtil;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -85,13 +82,20 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
+import android.net.MacAddress;
+import android.net.NetworkStack;
import android.net.Uri;
+import android.net.wifi.IActionListener;
import android.net.wifi.IDppCallback;
+import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.IOnWifiUsabilityStatsListener;
+import android.net.wifi.IScanResultsListener;
import android.net.wifi.ISoftApCallback;
import android.net.wifi.ITrafficStateCallback;
+import android.net.wifi.ITxPacketCountListener;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiEnterpriseConfig;
@@ -99,7 +103,9 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
import android.net.wifi.WifiManager.SoftApCallback;
+import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiSsid;
+import android.net.wifi.WifiStackClient;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
@@ -110,9 +116,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IPowerManager;
-import android.os.Looper;
import android.os.Message;
-import android.os.Messenger;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -132,12 +136,14 @@ import com.android.server.wifi.util.WifiAsyncChannel;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.InOrder;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
@@ -154,7 +160,7 @@ import java.util.List;
* Note: this is intended to build up over time and will not immediately cover the entire file.
*/
@SmallTest
-public class WifiServiceImplTest {
+public class WifiServiceImplTest extends WifiBaseTest {
private static final String TAG = "WifiServiceImplTest";
private static final String SCAN_PACKAGE_NAME = "scanPackage";
@@ -174,6 +180,7 @@ public class WifiServiceImplTest {
private static final String WIFI_IFACE_NAME2 = "wlan1";
private static final String TEST_COUNTRY_CODE = "US";
private static final String TEST_FACTORY_MAC = "10:22:34:56:78:92";
+ private static final MacAddress TEST_FACTORY_MAC_ADDR = MacAddress.fromString(TEST_FACTORY_MAC);
private static final String TEST_FQDN = "testfqdn";
private static final List<WifiConfiguration> TEST_WIFI_CONFIGURATION_LIST = Arrays.asList(
WifiConfigurationTestUtil.generateWifiConfig(
@@ -193,17 +200,16 @@ public class WifiServiceImplTest {
private WifiServiceImpl mWifiServiceImpl;
private TestLooper mLooper;
private PowerManager mPowerManager;
- private Handler mHandler;
- private Handler mHandlerSpyForCmiRunWithScissors;
- private Messenger mAppMessenger;
private int mPid;
private int mPid2 = Process.myPid();
private OsuProvider mOsuProvider;
private SoftApCallback mStateMachineSoftApCallback;
+ private SoftApCallback mLohsApCallback;
+ private String mLohsInterfaceName;
private ApplicationInfo mApplicationInfo;
private static final String DPP_URI = "DPP:some_dpp_uri";
- final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
+ private final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
final ArgumentCaptor<IntentFilter> mIntentFilterCaptor =
ArgumentCaptor.forClass(IntentFilter.class);
@@ -217,7 +223,6 @@ public class WifiServiceImplTest {
@Mock WifiInjector mWifiInjector;
@Mock WifiCountryCode mWifiCountryCode;
@Mock Clock mClock;
- @Mock WifiController mWifiController;
@Mock WifiTrafficPoller mWifiTrafficPoller;
@Mock ClientModeImpl mClientModeImpl;
@Mock ActiveModeWarden mActiveModeWarden;
@@ -252,7 +257,6 @@ public class WifiServiceImplTest {
@Mock ITrafficStateCallback mTrafficStateCallback;
@Mock INetworkRequestMatchCallback mNetworkRequestMatchCallback;
@Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
- @Mock DevicePolicyManagerInternal mDevicePolicyManagerInternal;
@Mock TelephonyManager mTelephonyManager;
@Mock IOnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
@Mock WifiConfigManager mWifiConfigManager;
@@ -260,75 +264,15 @@ public class WifiServiceImplTest {
@Mock WifiScoreCard mWifiScoreCard;
@Mock PasspointManager mPasspointManager;
@Mock IDppCallback mDppCallback;
+ @Mock SarManager mSarManager;
+ @Mock ILocalOnlyHotspotCallback mLohsCallback;
+ @Mock IScanResultsListener mClientScanResultsListener;
@Spy FakeWifiLog mLog;
- private class WifiAsyncChannelTester {
- private static final String TAG = "WifiAsyncChannelTester";
- public static final int CHANNEL_STATE_FAILURE = -1;
- public static final int CHANNEL_STATE_DISCONNECTED = 0;
- public static final int CHANNEL_STATE_HALF_CONNECTED = 1;
- public static final int CHANNEL_STATE_FULLY_CONNECTED = 2;
-
- private int mState = CHANNEL_STATE_DISCONNECTED;
- private WifiAsyncChannel mChannel;
- private WifiLog mAsyncTestLog;
-
- WifiAsyncChannelTester(WifiInjector wifiInjector) {
- mAsyncTestLog = wifiInjector.makeLog(TAG);
- }
-
- public int getChannelState() {
- return mState;
- }
-
- public void connect(final Looper looper, final Messenger messenger,
- final Handler incomingMessageHandler) {
- assertEquals("AsyncChannel must be in disconnected state",
- CHANNEL_STATE_DISCONNECTED, mState);
- mChannel = new WifiAsyncChannel(TAG);
- mChannel.setWifiLog(mLog);
- 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) {
- mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
- mState = CHANNEL_STATE_HALF_CONNECTED;
- } else {
- mState = CHANNEL_STATE_FAILURE;
- }
- break;
- case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
- mState = CHANNEL_STATE_FULLY_CONNECTED;
- break;
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- mState = CHANNEL_STATE_DISCONNECTED;
- break;
- default:
- incomingMessageHandler.handleMessage(msg);
- break;
- }
- }
- };
- mChannel.connect(null, handler, messenger);
- }
-
- private Message sendMessageSynchronously(Message request) {
- return mChannel.sendMessageSynchronously(request);
- }
-
- private void sendMessage(Message request) {
- mChannel.sendMessage(request);
- }
- }
-
@Before public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
- mHandler = spy(new Handler(mLooper.getLooper()));
- mAppMessenger = new Messenger(mHandler);
mAsyncChannel = spy(new AsyncChannel());
mApplicationInfo = new ApplicationInfo();
mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
@@ -338,19 +282,20 @@ public class WifiServiceImplTest {
when(mRequestInfo2.getPid()).thenReturn(mPid2);
when(mWifiInjector.getUserManager()).thenReturn(mUserManager);
when(mWifiInjector.getWifiCountryCode()).thenReturn(mWifiCountryCode);
- when(mWifiInjector.getWifiController()).thenReturn(mWifiController);
when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl);
when(mClientModeImpl.syncInitialize(any())).thenReturn(true);
when(mClientModeImpl.getHandler()).thenReturn(new Handler());
when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
- when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(mHandlerThread);
+ when(mWifiInjector.getAsyncChannelHandlerThread()).thenReturn(mHandlerThread);
+ when(mWifiInjector.getWifiHandlerThread()).thenReturn(mHandlerThread);
+ when(mHandlerThread.getThreadHandler()).thenReturn(new Handler(mLooper.getLooper()));
when(mWifiInjector.getPowerProfile()).thenReturn(mPowerProfile);
when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
when(mContext.getResources()).thenReturn(mResources);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
- when(mPackageManager.getApplicationInfoAsUser(any(), anyInt(), anyInt()))
+ when(mPackageManager.getApplicationInfoAsUser(any(), anyInt(), any()))
.thenReturn(mApplicationInfo);
when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore);
doNothing().when(mFrameworkFacade).registerContentObserver(eq(mContext), any(),
@@ -364,8 +309,6 @@ public class WifiServiceImplTest {
WifiAsyncChannel wifiAsyncChannel = new WifiAsyncChannel("WifiServiceImplTest");
wifiAsyncChannel.setWifiLog(mLog);
when(mFrameworkFacade.makeWifiAsyncChannel(anyString())).thenReturn(wifiAsyncChannel);
- when(mWifiPermissionsWrapper.getDevicePolicyManagerInternal())
- .thenReturn(mDevicePolicyManagerInternal);
when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade);
when(mWifiInjector.getWifiLockManager()).thenReturn(mLockManager);
when(mWifiInjector.getWifiMulticastLockManager()).thenReturn(mWifiMulticastLockManager);
@@ -385,10 +328,11 @@ public class WifiServiceImplTest {
when(mWifiInjector.getPasspointManager()).thenReturn(mPasspointManager);
when(mClientModeImpl.getWifiScoreReport()).thenReturn(mWifiScoreReport);
when(mWifiInjector.getWifiScoreCard()).thenReturn(mWifiScoreCard);
+ when(mWifiInjector.getSarManager()).thenReturn(mSarManager);
+ when(mWifiInjector.getWifiThreadRunner())
+ .thenReturn(new WifiThreadRunner(new Handler(mLooper.getLooper())));
when(mClientModeImpl.syncStartSubscriptionProvisioning(anyInt(),
any(OsuProvider.class), any(IProvisioningCallback.class), any())).thenReturn(true);
- when(mPackageManager.hasSystemFeature(
- PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(true);
// Create an OSU provider that can be provisioned via an open OSU AP
mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true);
when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
@@ -400,14 +344,12 @@ public class WifiServiceImplTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_MANAGED_PROVISIONING),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
+ when(mContext.checkPermission(eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(true);
+ when(mLohsCallback.asBinder()).thenReturn(mock(IBinder.class));
- ArgumentCaptor<SoftApCallback> softApCallbackCaptor =
- ArgumentCaptor.forClass(SoftApCallback.class);
- mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
- verify(mActiveModeWarden).registerSoftApCallback(softApCallbackCaptor.capture());
- mStateMachineSoftApCallback = softApCallbackCaptor.getValue();
- mWifiServiceImpl.setWifiHandlerLogForTest(mLog);
+ mWifiServiceImpl = makeWifiServiceImpl();
mDppCallback = new IDppCallback() {
@Override
public void onSuccessConfigReceived(int newNetworkId) throws RemoteException {
@@ -436,36 +378,58 @@ public class WifiServiceImplTest {
};
}
- private WifiAsyncChannelTester verifyAsyncChannelHalfConnected() throws RemoteException {
- WifiAsyncChannelTester channelTester = new WifiAsyncChannelTester(mWifiInjector);
- Handler handler = mock(Handler.class);
- TestLooper looper = new TestLooper();
- channelTester.connect(looper.getLooper(),
- mWifiServiceImpl.getWifiServiceMessenger(TEST_PACKAGE_NAME), handler);
+ /**
+ * Called after each test
+ */
+ @After
+ public void cleanup() {
+ validateMockitoUsage();
+ }
+
+ private WifiServiceImpl makeWifiServiceImpl() {
+ reset(mActiveModeWarden);
+ WifiServiceImpl wifiServiceImpl =
+ new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
+ ArgumentCaptor<SoftApCallback> softApCallbackCaptor =
+ ArgumentCaptor.forClass(SoftApCallback.class);
+ verify(mActiveModeWarden).registerSoftApCallback(softApCallbackCaptor.capture());
+ mStateMachineSoftApCallback = softApCallbackCaptor.getValue();
+ ArgumentCaptor<SoftApCallback> lohsCallbackCaptor =
+ ArgumentCaptor.forClass(SoftApCallback.class);
+ mLohsInterfaceName = WIFI_IFACE_NAME;
+ verify(mActiveModeWarden).registerLohsCallback(lohsCallbackCaptor.capture());
+ mLohsApCallback = lohsCallbackCaptor.getValue();
mLooper.dispatchAll();
- assertEquals("AsyncChannel must be half connected",
- WifiAsyncChannelTester.CHANNEL_STATE_HALF_CONNECTED,
- channelTester.getChannelState());
- return channelTester;
+ return wifiServiceImpl;
}
- /**
- * Verifies that any operations on WifiServiceImpl without setting up the ClientModeImpl
- * channel would fail.
- */
- @Test
- public void testRemoveNetworkUnknown() {
- assertFalse(mWifiServiceImpl.removeNetwork(-1, TEST_PACKAGE_NAME));
- verify(mClientModeImpl, never()).syncRemoveNetwork(any(), anyInt());
+ private WifiServiceImpl makeWifiServiceImplWithMockRunnerWhichTimesOut() {
+ WifiThreadRunner mockRunner = mock(WifiThreadRunner.class);
+ when(mockRunner.call(any(), any())).then(returnsSecondArg());
+ when(mockRunner.call(any(), any(int.class))).then(returnsSecondArg());
+ when(mockRunner.call(any(), any(boolean.class))).then(returnsSecondArg());
+ when(mockRunner.post(any())).thenReturn(false);
+
+ when(mWifiInjector.getWifiThreadRunner()).thenReturn(mockRunner);
+ return makeWifiServiceImpl();
}
/**
- * Tests whether we're able to set up an async channel connection with WifiServiceImpl.
- * This is the path used by some WifiManager public API calls.
+ * Test that REMOVE_NETWORK returns failure to public API when WifiConfigManager returns
+ * failure.
*/
@Test
- public void testAsyncChannelHalfConnected() throws RemoteException {
- verifyAsyncChannelHalfConnected();
+ public void testRemoveNetworkFailureAppBelowQSdk() {
+ doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
+ .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
+ eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
+ when(mWifiConfigManager.removeNetwork(anyInt(), anyInt(), anyString())).thenReturn(false);
+
+ mLooper.startAutoDispatch();
+ boolean succeeded = mWifiServiceImpl.removeNetwork(0, TEST_PACKAGE_NAME);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ assertFalse(succeeded);
}
/**
@@ -487,9 +451,9 @@ public class WifiServiceImplTest {
*/
@Test
public void testDumpNullArgs() {
- setupClientModeImplHandlerForRunWithScissors();
-
+ mLooper.startAutoDispatch();
mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
}
/**
@@ -508,16 +472,13 @@ public class WifiServiceImplTest {
*/
@Test
public void testWifiScoreReportDump() {
- setupClientModeImplHandlerForRunWithScissors();
-
+ mLooper.startAutoDispatch();
mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
- InOrder inOrder = inOrder(mClientModeImpl, mHandlerSpyForCmiRunWithScissors,
- mWifiScoreReport);
+ InOrder inOrder = inOrder(mClientModeImpl, mWifiScoreReport);
inOrder.verify(mClientModeImpl).updateLinkLayerStatsRssiAndScoreReport();
- inOrder.verify(mHandlerSpyForCmiRunWithScissors, atLeastOnce())
- .runWithScissors(any(), anyLong());
inOrder.verify(mWifiScoreReport).dump(any(), any(), any());
}
@@ -542,7 +503,7 @@ public class WifiServiceImplTest {
* Verify that metrics is incremented correctly for normal Apps targeting pre-Q.
*/
@Test
- public void testSetWifiEnabledMetricsNormalAppBelowQSDK() throws Exception {
+ public void testSetWifiEnabledMetricsNormalAppBelowQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
@@ -561,7 +522,7 @@ public class WifiServiceImplTest {
* Verify that metrics is not incremented by apps targeting Q SDK.
*/
@Test
- public void testSetWifiEnabledMetricsNormalAppTargetingQSDKNoIncrement() throws Exception {
+ public void testSetWifiEnabledMetricsNormalAppTargetingQSdkNoIncrement() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
@@ -584,7 +545,7 @@ public class WifiServiceImplTest {
when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
/**
@@ -598,34 +559,33 @@ public class WifiServiceImplTest {
when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
/**
* Verify that wifi can be enabled by the DO apps targeting Q SDK.
*/
@Test
- public void testSetWifiEnabledSuccessForDOAppsTargetingQSDK() throws Exception {
+ public void testSetWifiEnabledSuccessForDOAppsTargetingQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(false);
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(
- Process.myUid(), DeviceAdminInfo.USES_POLICY_DEVICE_OWNER))
+ when(mWifiPermissionsUtil.isDeviceOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
.thenReturn(true);
when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
/**
* Verify that wifi can be enabled by the system apps targeting Q SDK.
*/
@Test
- public void testSetWifiEnabledSuccessForSystemAppsTargetingQSDK() throws Exception {
+ public void testSetWifiEnabledSuccessForSystemAppsTargetingQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
@@ -636,14 +596,14 @@ public class WifiServiceImplTest {
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
/**
* Verify that wifi can be enabled by the apps targeting pre-Q SDK.
*/
@Test
- public void testSetWifiEnabledSuccessForAppsTargetingBelowQSDK() throws Exception {
+ public void testSetWifiEnabledSuccessForAppsTargetingBelowQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
@@ -653,28 +613,14 @@ public class WifiServiceImplTest {
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
- }
-
- /**
- * Verify that wifi is not enabled when wificontroller is not started.
- */
- @Test
- public void testSetWifiEnabledFailureWhenInCryptDebounce() throws Exception {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true);
- when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
- when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
- when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
- assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
- verifyZeroInteractions(mWifiController);
+ verify(mActiveModeWarden).wifiToggled();
}
/**
* Verify that wifi cannot be enabled by the apps targeting Q SDK.
*/
@Test
- public void testSetWifiEnabledFailureForAppsTargetingQSDK() throws Exception {
+ public void testSetWifiEnabledFailureForAppsTargetingQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
@@ -684,7 +630,7 @@ public class WifiServiceImplTest {
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
- verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden, never()).wifiToggled();
}
/**
@@ -703,7 +649,7 @@ public class WifiServiceImplTest {
} catch (SecurityException e) {
}
- verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden, never()).wifiToggled();
}
/**
@@ -719,7 +665,7 @@ public class WifiServiceImplTest {
when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
- verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden, never()).wifiToggled();
}
/**
@@ -735,7 +681,7 @@ public class WifiServiceImplTest {
.thenReturn(PackageManager.PERMISSION_GRANTED);
assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
/**
@@ -755,7 +701,25 @@ public class WifiServiceImplTest {
.thenReturn(PackageManager.PERMISSION_DENIED);
assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
- verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden, never()).wifiToggled();
+ }
+
+ /**
+ * Helper to verify registering for state changes.
+ */
+ private void verifyApRegistration() {
+ assertNotNull(mLohsApCallback);
+ }
+
+ /**
+ * Helper to emulate local-only hotspot state changes.
+ *
+ * Must call verifyApRegistration first.
+ */
+ private void changeLohsState(int apState, int previousState, int error) {
+ // TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
+ // apState, previousState, error, WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ mLohsApCallback.onStateChanged(apState, error);
}
/**
@@ -767,12 +731,8 @@ public class WifiServiceImplTest {
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
-
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_ENABLING, SAP_START_FAILURE_GENERAL,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ verifyApRegistration();
+ mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
when(mContext.checkPermission(
@@ -780,7 +740,7 @@ public class WifiServiceImplTest {
.thenReturn(PackageManager.PERMISSION_GRANTED);
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
/**
@@ -795,12 +755,8 @@ public class WifiServiceImplTest {
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
-
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_ENABLING, SAP_START_FAILURE_GENERAL,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ verifyApRegistration();
+ mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
when(mContext.checkPermission(
eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
@@ -808,7 +764,7 @@ public class WifiServiceImplTest {
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
verify(mSettingsStore, never()).handleWifiToggled(anyBoolean());
- verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden, never()).wifiToggled();
}
@@ -821,7 +777,7 @@ public class WifiServiceImplTest {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
- verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden, never()).wifiToggled();
}
/**
@@ -849,7 +805,7 @@ public class WifiServiceImplTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
/**
@@ -862,34 +818,33 @@ public class WifiServiceImplTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
/**
* Verify that wifi can be disabled by the PO apps targeting Q SDK.
*/
@Test
- public void testSetWifiDisabledSuccessForPOAppsTargetingQSDK() throws Exception {
+ public void testSetWifiDisabledSuccessForPOAppsTargetingQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(false);
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(
- Process.myUid(), DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))
+ when(mWifiPermissionsUtil.isProfileOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
.thenReturn(true);
when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
/**
* Verify that wifi can be disabled by the system apps targeting Q SDK.
*/
@Test
- public void testSetWifiDisabledSuccessForSystemAppsTargetingQSDK() throws Exception {
+ public void testSetWifiDisabledSuccessForSystemAppsTargetingQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
@@ -900,7 +855,7 @@ public class WifiServiceImplTest {
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden).wifiToggled();
}
@@ -908,7 +863,7 @@ public class WifiServiceImplTest {
* Verify that wifi can be disabled by the apps targeting pre-Q SDK.
*/
@Test
- public void testSetWifiDisabledSuccessForAppsTargetingBelowQSDK() throws Exception {
+ public void testSetWifiDisabledSuccessForAppsTargetingBelowQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
@@ -918,28 +873,14 @@ public class WifiServiceImplTest {
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
- verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
- }
-
- /**
- * Verify that wifi is not disabled when wificontroller is not started.
- */
- @Test
- public void testSetWifiDisabledFailureWhenInCryptDebounce() throws Exception {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true);
- when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
- when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(false);
- when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
- assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
- verifyZeroInteractions(mWifiController);
+ verify(mActiveModeWarden).wifiToggled();
}
/**
* Verify that wifi cannot be disabled by the apps targeting Q SDK.
*/
@Test
- public void testSetWifiDisabledFailureForAppsTargetingQSDK() throws Exception {
+ public void testSetWifiDisabledFailureForAppsTargetingQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
@@ -949,7 +890,7 @@ public class WifiServiceImplTest {
when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
- verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden, never()).wifiToggled();
}
/**
@@ -961,7 +902,7 @@ public class WifiServiceImplTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(false);
assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
- verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
+ verify(mActiveModeWarden, never()).wifiToggled();
}
/**
@@ -981,11 +922,9 @@ public class WifiServiceImplTest {
/**
* Ensure unpermitted callers cannot write the SoftApConfiguration.
- *
- * @throws SecurityException
*/
@Test
- public void testSetWifiApConfigurationNotSavedWithoutPermission() {
+ public void testSetWifiApConfigurationNotSavedWithoutPermission() throws Exception {
when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
WifiConfiguration apConfig = new WifiConfiguration();
try {
@@ -998,7 +937,7 @@ public class WifiServiceImplTest {
* Ensure softap config is written when the caller has the correct permission.
*/
@Test
- public void testSetWifiApConfigurationSuccess() {
+ public void testSetWifiApConfigurationSuccess() throws Exception {
when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
WifiConfiguration apConfig = createValidSoftApConfiguration();
@@ -1012,7 +951,7 @@ public class WifiServiceImplTest {
* Ensure that a null config does not overwrite the saved ap config.
*/
@Test
- public void testSetWifiApConfigurationNullConfigNotSaved() {
+ public void testSetWifiApConfigurationNullConfigNotSaved() throws Exception {
when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
assertFalse(mWifiServiceImpl.setWifiApConfiguration(null, TEST_PACKAGE_NAME));
verify(mWifiApConfigStore, never()).setApConfiguration(isNull(WifiConfiguration.class));
@@ -1022,7 +961,7 @@ public class WifiServiceImplTest {
* Ensure that an invalid config does not overwrite the saved ap config.
*/
@Test
- public void testSetWifiApConfigurationWithInvalidConfigNotSaved() {
+ public void testSetWifiApConfigurationWithInvalidConfigNotSaved() throws Exception {
when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
assertFalse(mWifiServiceImpl.setWifiApConfiguration(new WifiConfiguration(),
TEST_PACKAGE_NAME));
@@ -1031,11 +970,9 @@ public class WifiServiceImplTest {
/**
* Ensure unpermitted callers are not able to retrieve the softap config.
- *
- * @throws SecurityException
*/
@Test
- public void testGetWifiApConfigurationNotReturnedWithoutPermission() {
+ public void testGetWifiApConfigurationNotReturnedWithoutPermission() throws Exception {
when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
try {
mWifiServiceImpl.getWifiApConfiguration();
@@ -1048,19 +985,17 @@ public class WifiServiceImplTest {
* Ensure permitted callers are able to retrieve the softap config.
*/
@Test
- public void testGetWifiApConfigurationSuccess() {
- setupClientModeImplHandlerForRunWithScissors();
-
+ public void testGetWifiApConfigurationSuccess() throws Exception {
mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
- mWifiServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
-
when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
WifiConfiguration apConfig = new WifiConfiguration();
when(mWifiApConfigStore.getApConfiguration()).thenReturn(apConfig);
+
+ mLooper.startAutoDispatch();
assertEquals(apConfig, mWifiServiceImpl.getWifiApConfiguration());
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
}
/**
@@ -1068,19 +1003,10 @@ public class WifiServiceImplTest {
* broadcast.
*/
@Test
- public void testGetWifiApEnabled() {
- setupClientModeImplHandlerForRunWithScissors();
-
- // set up WifiServiceImpl with a live thread for testing
- HandlerThread serviceHandlerThread = createAndStartHandlerThreadForRunWithScissors();
- when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(serviceHandlerThread);
- mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
- mWifiServiceImpl.setWifiHandlerLogForTest(mLog);
-
+ public void testGetWifiApEnabled() throws Exception {
// ap should be disabled when wifi hasn't been started
assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState());
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
mLooper.dispatchAll();
@@ -1089,12 +1015,9 @@ public class WifiServiceImplTest {
assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState());
// send an ap state change to verify WifiServiceImpl is updated
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
-
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ verifyApRegistration();
+ mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL);
mLooper.dispatchAll();
assertEquals(WifiManager.WIFI_AP_STATE_FAILED, mWifiServiceImpl.getWifiApEnabledState());
@@ -1117,34 +1040,21 @@ public class WifiServiceImplTest {
}
/**
- * Make sure we do not start wifi if System services have to be restarted to decrypt the device.
- */
- @Test
- public void testWifiControllerDoesNotStartWhenDeviceTriggerResetMainAtBoot() {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true);
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
- mWifiServiceImpl.checkAndStartWifi();
- verify(mWifiController, never()).start();
- }
-
- /**
* Make sure we do start WifiController (wifi disabled) if the device is already decrypted.
*/
@Test
- public void testWifiControllerStartsWhenDeviceIsDecryptedAtBootWithWifiDisabled() {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
+ public void testWifiControllerStartsWhenDeviceBootsWithWifiDisabled() {
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mWifiController).start();
- verify(mWifiController, never()).sendMessage(CMD_WIFI_TOGGLED);
+ verify(mActiveModeWarden).start();
+ verify(mActiveModeWarden, never()).wifiToggled();
}
/**
* Make sure we do start WifiController (wifi enabled) if the device is already decrypted.
*/
@Test
- public void testWifiFullyStartsWhenDeviceIsDecryptedAtBootWithWifiEnabled() {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
+ public void testWifiFullyStartsWhenDeviceBootsWithWifiEnabled() {
when(mSettingsStore.handleWifiToggled(true)).thenReturn(true);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
when(mClientModeImpl.syncGetWifiState()).thenReturn(WIFI_STATE_DISABLED);
@@ -1152,8 +1062,7 @@ public class WifiServiceImplTest {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
mWifiServiceImpl.checkAndStartWifi();
- verify(mWifiController).start();
- verify(mWifiController).sendMessage(CMD_WIFI_TOGGLED);
+ verify(mActiveModeWarden).start();
}
/**
@@ -1163,8 +1072,7 @@ public class WifiServiceImplTest {
public void testStartSoftApWithPermissionsAndNullConfig() {
boolean result = mWifiServiceImpl.startSoftAp(null);
assertTrue(result);
- verify(mWifiController)
- .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), mSoftApModeConfigCaptor.capture());
+ verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture());
assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
}
@@ -1175,7 +1083,7 @@ public class WifiServiceImplTest {
public void testStartSoftApWithPermissionsAndInvalidConfig() {
boolean result = mWifiServiceImpl.startSoftAp(mApConfig);
assertFalse(result);
- verifyZeroInteractions(mWifiController);
+ verifyZeroInteractions(mActiveModeWarden);
}
/**
@@ -1186,57 +1094,48 @@ public class WifiServiceImplTest {
WifiConfiguration config = createValidSoftApConfiguration();
boolean result = mWifiServiceImpl.startSoftAp(config);
assertTrue(result);
- verify(mWifiController)
- .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), mSoftApModeConfigCaptor.capture());
+ verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture());
assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
}
/**
- * Verify does not start softap when wificontroller is not started.
- */
- @Test
- public void testStartSoftApWhenInCryptDebounce() {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true);
-
- WifiConfiguration config = createValidSoftApConfiguration();
- boolean result = mWifiServiceImpl.startSoftAp(config);
- assertFalse(result);
- verifyZeroInteractions(mWifiController);
- }
-
- /**
* Verify a SecurityException is thrown when a caller without the correct permission attempts to
* start softap.
*/
@Test(expected = SecurityException.class)
public void testStartSoftApWithoutPermissionThrowsException() throws Exception {
- doThrow(new SecurityException()).when(mContext)
- .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK),
- eq("WifiService"));
+ when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+ doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+ eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
mWifiServiceImpl.startSoftAp(null);
}
/**
- * Verify caller with proper permission can call stopSoftAp.
+ * Verify that startSoftAP() succeeds if the caller does not have the NETWORK_STACK permission
+ * but does have the MAINLINE_NETWORK_STACK permission.
*/
@Test
- public void testStopSoftApWithPermissions() {
- boolean result = mWifiServiceImpl.stopSoftAp();
+ public void testStartSoftApWithoutNetworkStackWithMainlineNetworkStackSucceeds() {
+ when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+ WifiConfiguration config = createValidSoftApConfiguration();
+ boolean result = mWifiServiceImpl.startSoftAp(config);
assertTrue(result);
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
- eq(WifiManager.IFACE_IP_MODE_TETHERED));
+ verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture());
+ assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
+ verify(mContext).enforceCallingOrSelfPermission(
+ eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
}
/**
- * Verify does not stop softap when wificontroller is not started.
+ * Verify caller with proper permission can call stopSoftAp.
*/
@Test
- public void testStopSoftApWhenInCryptDebounce() {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true);
-
+ public void testStopSoftApWithPermissions() {
boolean result = mWifiServiceImpl.stopSoftAp();
- assertFalse(result);
- verifyZeroInteractions(mWifiController);
+ assertTrue(result);
+ verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_TETHERED);
}
/**
@@ -1245,9 +1144,10 @@ public class WifiServiceImplTest {
*/
@Test(expected = SecurityException.class)
public void testStopSoftApWithoutPermissionThrowsException() throws Exception {
- doThrow(new SecurityException()).when(mContext)
- .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK),
- eq("WifiService"));
+ when(mContext.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+ doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+ eq(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK), any());
mWifiServiceImpl.stopSoftAp();
}
@@ -1256,10 +1156,11 @@ public class WifiServiceImplTest {
*/
@Test
public void testStartScanFailureAppOpsIgnored() {
- setupClientModeImplHandlerForRunWithScissors();
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), SCAN_PACKAGE_NAME);
+ mLooper.startAutoDispatch();
assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
}
@@ -1268,10 +1169,11 @@ public class WifiServiceImplTest {
*/
@Test
public void testStartScanFailureInCanAccessScanResultsPermission() {
- setupClientModeImplHandlerForRunWithScissors();
doThrow(new SecurityException()).when(mWifiPermissionsUtil)
.enforceCanAccessScanResults(SCAN_PACKAGE_NAME, Process.myUid());
+ mLooper.startAutoDispatch();
assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
}
@@ -1280,11 +1182,12 @@ public class WifiServiceImplTest {
*/
@Test
public void testStartScanFailureInRunWithScissors() {
- setupClientModeImplHandlerForRunWithScissors();
- doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
- .runWithScissors(any(), anyLong());
+ mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
+
+ mLooper.startAutoDispatch();
assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
- verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ verify(mScanRequestProxy, never()).startScan(anyInt(), eq(SCAN_PACKAGE_NAME));
}
/**
@@ -1292,10 +1195,12 @@ public class WifiServiceImplTest {
*/
@Test
public void testStartScanFailureFromScanRequestProxy() {
- setupClientModeImplHandlerForRunWithScissors();
when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(false);
+
+ mLooper.startAutoDispatch();
assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
- verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ verify(mScanRequestProxy).startScan(Binder.getCallingUid(), SCAN_PACKAGE_NAME);
}
static final String TEST_SSID = "Sid's Place";
@@ -1369,7 +1274,7 @@ public class WifiServiceImplTest {
*/
@Test
public void testConfiguredNetworkListAreEmptyFromAppWithoutPermission() throws Exception {
- when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt()))
+ when(mWifiConfigManager.getSavedNetworks(anyInt()))
.thenReturn(TEST_WIFI_CONFIGURATION_LIST);
// no permission = target SDK=Q && not a carrier app
@@ -1388,7 +1293,7 @@ public class WifiServiceImplTest {
*/
@Test
public void testConfiguredNetworkListAreEmptyOnSecurityException() throws Exception {
- when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt()))
+ when(mWifiConfigManager.getSavedNetworks(anyInt()))
.thenReturn(TEST_WIFI_CONFIGURATION_LIST);
doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
@@ -1407,7 +1312,7 @@ public class WifiServiceImplTest {
*/
@Test
public void testConfiguredNetworkListAreVisibleFromPermittedApp() throws Exception {
- when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt()))
+ when(mWifiConfigManager.getSavedNetworks(anyInt()))
.thenReturn(TEST_WIFI_CONFIGURATION_LIST);
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
@@ -1415,10 +1320,12 @@ public class WifiServiceImplTest {
mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
+ mLooper.startAutoDispatch();
ParceledListSlice<WifiConfiguration> configs =
mWifiServiceImpl.getConfiguredNetworks(TEST_PACKAGE);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mClientModeImpl).syncGetConfiguredNetworks(anyInt(), any(), eq(Process.WIFI_UID));
+ verify(mWifiConfigManager).getSavedNetworks(eq(Process.WIFI_UID));
WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
TEST_WIFI_CONFIGURATION_LIST, configs.getList());
}
@@ -1429,18 +1336,19 @@ public class WifiServiceImplTest {
* appropriate permissions.
*/
@Test
- public void testPrivilegedConfiguredNetworkListAreEmptyFromAppWithoutPermission()
- throws Exception {
- when(mClientModeImpl.syncGetPrivilegedConfiguredNetwork(any()))
+ public void testPrivilegedConfiguredNetworkListAreEmptyFromAppWithoutPermission() {
+ when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
.thenReturn(TEST_WIFI_CONFIGURATION_LIST);
doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
anyString(), anyInt());
+ mLooper.startAutoDispatch();
ParceledListSlice<WifiConfiguration> configs =
mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
- assertEquals(null, configs);
+ assertNull(configs);
}
/**
@@ -1448,18 +1356,19 @@ public class WifiServiceImplTest {
* appropriate permissions, when enforceCanAccessScanResults raises a SecurityException.
*/
@Test
- public void testPrivilegedConfiguredNetworkListAreEmptyOnSecurityException() throws Exception {
- when(mClientModeImpl.syncGetPrivilegedConfiguredNetwork(any()))
+ public void testPrivilegedConfiguredNetworkListAreEmptyOnSecurityException() {
+ when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
.thenReturn(TEST_WIFI_CONFIGURATION_LIST);
doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
anyString(), anyInt());
+ mLooper.startAutoDispatch();
ParceledListSlice<WifiConfiguration> configs =
mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
- assertEquals(null, configs);
-
+ assertNull(configs);
}
/**
@@ -1467,14 +1376,14 @@ public class WifiServiceImplTest {
* appropriate permissions (simulated by not throwing an exception for READ_WIFI_CREDENTIAL).
*/
@Test
- public void testPrivilegedConfiguredNetworkListAreVisibleFromPermittedApp() throws Exception {
- when(mClientModeImpl.syncGetPrivilegedConfiguredNetwork(any()))
+ public void testPrivilegedConfiguredNetworkListAreVisibleFromPermittedApp() {
+ when(mWifiConfigManager.getConfiguredNetworksWithPasswords())
.thenReturn(TEST_WIFI_CONFIGURATION_LIST);
- mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
-
+ mLooper.startAutoDispatch();
ParceledListSlice<WifiConfiguration> configs =
mWifiServiceImpl.getPrivilegedConfiguredNetworks(TEST_PACKAGE);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
TEST_WIFI_CONFIGURATION_LIST, configs.getList());
@@ -1485,8 +1394,6 @@ public class WifiServiceImplTest {
*/
@Test
public void testGetScanResults() {
- setupClientModeImplHandlerForRunWithScissors();
-
ScanResult[] scanResults =
ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
.getResults();
@@ -1495,7 +1402,9 @@ public class WifiServiceImplTest {
when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
String packageName = "test.com";
+ mLooper.startAutoDispatch();
List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mScanRequestProxy).getScanResults();
ScanTestUtil.assertScanResultsEquals(scanResults,
@@ -1507,9 +1416,7 @@ public class WifiServiceImplTest {
*/
@Test
public void testGetScanResultsFailureInRunWithScissors() {
- setupClientModeImplHandlerForRunWithScissors();
- doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
- .runWithScissors(any(), anyLong());
+ mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
ScanResult[] scanResults =
ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
@@ -1519,7 +1426,9 @@ public class WifiServiceImplTest {
when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
String packageName = "test.com";
+ mLooper.startAutoDispatch();
List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mScanRequestProxy, never()).getScanResults();
assertTrue(retrievedScanResultList.isEmpty());
@@ -1528,11 +1437,10 @@ public class WifiServiceImplTest {
private void registerLOHSRequestFull() {
// allow test to proceed without a permission check failure
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
.thenReturn(false);
- int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
- TEST_PACKAGE_NAME);
+ int result = mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME);
assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result);
verifyCheckChangePermission(TEST_PACKAGE_NAME);
}
@@ -1555,7 +1463,7 @@ public class WifiServiceImplTest {
doThrow(new SecurityException()).when(mContext)
.enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
eq("WifiService"));
- mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME);
}
/**
@@ -1567,7 +1475,7 @@ public class WifiServiceImplTest {
doThrow(new SecurityException())
.when(mWifiPermissionsUtil).enforceLocationPermission(eq(TEST_PACKAGE_NAME),
anyInt());
- mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME);
}
/**
@@ -1577,7 +1485,7 @@ public class WifiServiceImplTest {
@Test(expected = SecurityException.class)
public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationEnabled() {
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
- mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME);
}
/**
@@ -1587,44 +1495,30 @@ public class WifiServiceImplTest {
public void testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp() throws Exception {
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false);
- int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
- TEST_PACKAGE_NAME);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(false);
+ int result = mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME);
assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
}
/**
- * Only start LocalOnlyHotspot if device is in crypt debounce mode.
- */
- @Test
- public void testStartLocalOnlyHotspotFailsIfInCryptDebounce() throws Exception {
- when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true);
- int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
- TEST_PACKAGE_NAME);
- assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
- }
-
- /**
- * Only start LocalOnlyHotspot if we are not tethering.
+ * Only start tethering if we are not tethering.
*/
@Test
public void testTetheringDoesNotStartWhenAlreadyTetheringActive() throws Exception {
- setupClientModeImplHandlerForPost();
-
WifiConfiguration config = createValidSoftApConfiguration();
assertTrue(mWifiServiceImpl.startSoftAp(config));
- verify(mWifiController)
- .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture());
+ verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture());
assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
-
+ mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
+ assertEquals(WIFI_AP_STATE_ENABLED, mWifiServiceImpl.getWifiApEnabledState());
+ reset(mActiveModeWarden);
// Start another session without a stop, that should fail.
assertFalse(mWifiServiceImpl.startSoftAp(createValidSoftApConfiguration()));
- verifyNoMoreInteractions(mWifiController);
+
+ verifyNoMoreInteractions(mActiveModeWarden);
}
/**
@@ -1632,14 +1526,15 @@ public class WifiServiceImplTest {
*/
@Test
public void testHotspotDoesNotStartWhenAlreadyTethering() throws Exception {
- setupClientModeImplHandlerForPost();
+ WifiConfiguration config = createValidSoftApConfiguration();
+ assertTrue(mWifiServiceImpl.startSoftAp(config));
+ mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
+ mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
- mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
mLooper.dispatchAll();
- int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
- mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
+ int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME);
assertEquals(ERROR_INCOMPATIBLE_MODE, returnCode);
}
@@ -1649,11 +1544,10 @@ public class WifiServiceImplTest {
@Test
public void testHotspotDoesNotStartWhenTetheringDisallowed() throws Exception {
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
- when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
+ when(mFrameworkFacade.isAppForeground(any(), anyInt())).thenReturn(true);
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
.thenReturn(true);
- int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
- mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
+ int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME);
assertEquals(ERROR_TETHERING_DISALLOWED, returnCode);
}
@@ -1665,7 +1559,7 @@ public class WifiServiceImplTest {
registerLOHSRequestFull();
// now do the second request that will fail
- mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
+ mWifiServiceImpl.startLocalOnlyHotspot(mLohsCallback, TEST_PACKAGE_NAME);
}
/**
@@ -1673,11 +1567,12 @@ public class WifiServiceImplTest {
* registered callers.
*/
@Test
- public void testStopLocalOnlyHotspotDoesNothingWithoutRegisteredRequests() {
+ public void testStopLocalOnlyHotspotDoesNothingWithoutRegisteredRequests() throws Exception {
// allow test to proceed without a permission check failure
mWifiServiceImpl.stopLocalOnlyHotspot();
+ mLooper.dispatchAll();
// there is nothing registered, so this shouldn't do anything
- verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt());
+ verify(mActiveModeWarden, never()).stopSoftAp(anyInt());
}
/**
@@ -1685,16 +1580,17 @@ public class WifiServiceImplTest {
* but there is still an active request
*/
@Test
- public void testStopLocalOnlyHotspotDoesNothingWithARemainingRegisteredRequest() {
+ public void testStopLocalOnlyHotspotDoesNothingWithRemainingRequest() throws Exception {
// register a request that will remain after the stopLOHS call
mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo);
- registerLOHSRequestFull();
+ setupLocalOnlyHotspot();
// Since we are calling with the same pid, the second register call will be removed
mWifiServiceImpl.stopLocalOnlyHotspot();
+ mLooper.dispatchAll();
// there is still a valid registered request - do not tear down LOHS
- verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt());
+ verify(mActiveModeWarden, never()).stopSoftAp(anyInt());
}
/**
@@ -1702,19 +1598,20 @@ public class WifiServiceImplTest {
* the softAp when there is one registered caller when that caller is removed.
*/
@Test
- public void testStopLocalOnlyHotspotTriggersSoftApStopWithOneRegisteredRequest() {
- registerLOHSRequestFull();
- verify(mWifiController)
- .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), any(SoftApModeConfiguration.class));
+ public void testStopLocalOnlyHotspotTriggersStopWithOneRegisteredRequest() throws Exception {
+ setupLocalOnlyHotspot();
+
+ verify(mActiveModeWarden).startSoftAp(any());
+
+ mWifiServiceImpl.stopLocalOnlyHotspot();
+ mLooper.dispatchAll();
// No permission check required for change_wifi_state.
verify(mContext, never()).enforceCallingOrSelfPermission(
eq("android.Manifest.permission.CHANGE_WIFI_STATE"), anyString());
- mWifiServiceImpl.stopLocalOnlyHotspot();
- // there is was only one request registered, we should tear down softap
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
- eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
+ // there is was only one request registered, we should tear down LOHS
+ verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
}
/**
@@ -1748,8 +1645,7 @@ public class WifiServiceImplTest {
}
private void verifyLohsBand(int expectedBand) {
- verify(mWifiController)
- .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), mSoftApModeConfigCaptor.capture());
+ verify(mActiveModeWarden).startSoftAp(mSoftApModeConfigCaptor.capture());
final WifiConfiguration configuration = mSoftApModeConfigCaptor.getValue().mConfig;
assertNotNull(configuration);
assertEquals(expectedBand, configuration.apBand);
@@ -1765,8 +1661,7 @@ public class WifiServiceImplTest {
mWifiServiceImpl.new LocalOnlyRequestorCallback();
binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo);
- verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0),
- eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
+ verify(mActiveModeWarden, never()).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
}
/**
@@ -1776,7 +1671,7 @@ public class WifiServiceImplTest {
* cleared the requestor that died).
*/
@Test
- public void testServiceImplNotCalledWhenBinderDeathTriggeredWithRegisteredRequests() {
+ public void testServiceImplNotCalledWhenBinderDeathTriggeredWithRequests() throws Exception {
LocalOnlyRequestorCallback binderDeathCallback =
mWifiServiceImpl.new LocalOnlyRequestorCallback();
@@ -1784,18 +1679,18 @@ public class WifiServiceImplTest {
// softap mode
mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo);
- registerLOHSRequestFull();
+ setupLocalOnlyHotspot();
binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo);
- verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt());
+ verify(mActiveModeWarden, never()).stopSoftAp(anyInt());
- reset(mWifiController);
+ reset(mActiveModeWarden);
// now stop as the second request and confirm CMD_SET_AP will be sent to make sure binder
// death requestor was removed
mWifiServiceImpl.stopLocalOnlyHotspot();
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
- eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
+ mLooper.dispatchAll();
+ verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
}
/**
@@ -1853,14 +1748,12 @@ public class WifiServiceImplTest {
*/
@Test
public void registerSoftApCallbackFailureOnLinkToDeath() throws Exception {
- setupClientModeImplHandlerForPost();
-
doThrow(new RemoteException())
.when(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback, 1);
mLooper.dispatchAll();
verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
- verify(mClientSoftApCallback, never()).onNumClientsChanged(0);
+ verify(mClientSoftApCallback, never()).onConnectedClientsChanged(any());
}
@@ -1882,7 +1775,7 @@ public class WifiServiceImplTest {
mWifiServiceImpl.registerSoftApCallback(binder, callback, callbackIdentifier);
mLooper.dispatchAll();
verify(callback).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
- verify(callback).onNumClientsChanged(0);
+ verify(callback).onConnectedClientsChanged(Mockito.<WifiClient>anyList());
}
/**
@@ -1890,8 +1783,6 @@ public class WifiServiceImplTest {
*/
@Test
public void replacesOldCallbackWithNewCallbackWhenRegisteringTwice() throws Exception {
- setupClientModeImplHandlerForPost();
-
final int callbackIdentifier = 1;
registerSoftApCallbackAndVerify(mAppBinder, mClientSoftApCallback, callbackIdentifier);
registerSoftApCallbackAndVerify(
@@ -1902,12 +1793,14 @@ public class WifiServiceImplTest {
verify(mAnotherAppBinder).linkToDeath(any(), anyInt());
verify(mAnotherAppBinder, never()).unlinkToDeath(any(), anyInt());
- final int testNumClients = 4;
- mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
+ final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR);
+ final List<WifiClient> testClients = new ArrayList();
+ testClients.add(testClient);
+ mStateMachineSoftApCallback.onConnectedClientsChanged(testClients);
mLooper.dispatchAll();
// Verify only the second callback is being called
- verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients);
- verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients);
+ verify(mClientSoftApCallback, never()).onConnectedClientsChanged(testClients);
+ verify(mAnotherSoftApCallback).onConnectedClientsChanged(testClients);
}
/**
@@ -1915,18 +1808,18 @@ public class WifiServiceImplTest {
*/
@Test
public void unregisterSoftApCallbackRemovesCallback() throws Exception {
- setupClientModeImplHandlerForPost();
-
final int callbackIdentifier = 1;
registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier);
mLooper.dispatchAll();
- final int testNumClients = 4;
- mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
+ final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR);
+ final List<WifiClient> testClients = new ArrayList();
+ testClients.add(testClient);
+ mStateMachineSoftApCallback.onConnectedClientsChanged(testClients);
mLooper.dispatchAll();
- verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients);
+ verify(mClientSoftApCallback, never()).onConnectedClientsChanged(testClients);
}
/**
@@ -1935,8 +1828,6 @@ public class WifiServiceImplTest {
@Test
public void unregisterSoftApCallbackDoesNotRemoveCallbackIfCallbackIdentifierNotMatching()
throws Exception {
- setupClientModeImplHandlerForPost();
-
final int callbackIdentifier = 1;
registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
@@ -1944,10 +1835,12 @@ public class WifiServiceImplTest {
mWifiServiceImpl.unregisterSoftApCallback(differentCallbackIdentifier);
mLooper.dispatchAll();
- final int testNumClients = 4;
- mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
+ final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR);
+ final List<WifiClient> testClients = new ArrayList();
+ testClients.add(testClient);
+ mStateMachineSoftApCallback.onConnectedClientsChanged(testClients);
mLooper.dispatchAll();
- verify(mClientSoftApCallback).onNumClientsChanged(testNumClients);
+ verify(mClientSoftApCallback).onConnectedClientsChanged(testClients);
}
/**
@@ -1955,23 +1848,21 @@ public class WifiServiceImplTest {
*/
@Test
public void correctCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne() throws Exception {
- setupClientModeImplHandlerForPost();
-
final int callbackIdentifier = 1;
mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback,
callbackIdentifier);
// Change state from default before registering the second callback
- final int testNumClients = 4;
+ final List<WifiClient> testClients = new ArrayList();
mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
- mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
+ mStateMachineSoftApCallback.onConnectedClientsChanged(testClients);
// Register another callback and verify the new state is returned in the immediate callback
final int anotherUid = 2;
mWifiServiceImpl.registerSoftApCallback(mAppBinder, mAnotherSoftApCallback, anotherUid);
mLooper.dispatchAll();
verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
- verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients);
+ verify(mAnotherSoftApCallback).onConnectedClientsChanged(testClients);
// unregister the fisrt callback
mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier);
@@ -1992,8 +1883,6 @@ public class WifiServiceImplTest {
*/
@Test
public void registersForBinderDeathOnRegisterSoftApCallback() throws Exception {
- setupClientModeImplHandlerForPost();
-
final int callbackIdentifier = 1;
registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
@@ -2004,8 +1893,6 @@ public class WifiServiceImplTest {
*/
@Test
public void unregistersSoftApCallbackOnBinderDied() throws Exception {
- setupClientModeImplHandlerForPost();
-
ArgumentCaptor<IBinder.DeathRecipient> drCaptor =
ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
final int callbackIdentifier = 1;
@@ -2017,26 +1904,28 @@ public class WifiServiceImplTest {
verify(mAppBinder).unlinkToDeath(drCaptor.getValue(), 0);
// Verify callback is removed from the list as well
- final int testNumClients = 4;
- mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
+ final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR);
+ final List<WifiClient> testClients = new ArrayList();
+ testClients.add(testClient);
+ mStateMachineSoftApCallback.onConnectedClientsChanged(testClients);
mLooper.dispatchAll();
- verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients);
+ verify(mClientSoftApCallback, never()).onConnectedClientsChanged(testClients);
}
/**
* Verify that soft AP callback is called on NumClientsChanged event
*/
@Test
- public void callsRegisteredCallbacksOnNumClientsChangedEvent() throws Exception {
- setupClientModeImplHandlerForPost();
-
+ public void callsRegisteredCallbacksOnConnectedClientsChangedEvent() throws Exception {
final int callbackIdentifier = 1;
registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
- final int testNumClients = 4;
- mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
+ final WifiClient testClient = new WifiClient(TEST_FACTORY_MAC_ADDR);
+ final List<WifiClient> testClients = new ArrayList();
+ testClients.add(testClient);
+ mStateMachineSoftApCallback.onConnectedClientsChanged(testClients);
mLooper.dispatchAll();
- verify(mClientSoftApCallback).onNumClientsChanged(testNumClients);
+ verify(mClientSoftApCallback).onConnectedClientsChanged(testClients);
}
/**
@@ -2044,8 +1933,6 @@ public class WifiServiceImplTest {
*/
@Test
public void callsRegisteredCallbacksOnSoftApStateChangedEvent() throws Exception {
- setupClientModeImplHandlerForPost();
-
final int callbackIdentifier = 1;
registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
@@ -2059,12 +1946,10 @@ public class WifiServiceImplTest {
* Ap events, even when no callbacks are registered.
*/
@Test
- public void updatesSoftApStateAndNumClientsOnSoftApEvents() throws Exception {
- setupClientModeImplHandlerForPost();
-
- final int testNumClients = 4;
+ public void updatesSoftApStateAndConnectedClientsOnSoftApEvents() throws Exception {
+ final List<WifiClient> testClients = new ArrayList();
mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
- mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
+ mStateMachineSoftApCallback.onConnectedClientsChanged(testClients);
// Register callback after num clients and soft AP are changed.
final int callbackIdentifier = 1;
@@ -2072,7 +1957,7 @@ public class WifiServiceImplTest {
callbackIdentifier);
mLooper.dispatchAll();
verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
- verify(mClientSoftApCallback).onNumClientsChanged(testNumClients);
+ verify(mClientSoftApCallback).onConnectedClientsChanged(testClients);
}
private class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> {
@@ -2083,263 +1968,173 @@ public class WifiServiceImplTest {
}
/**
- * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
- * broadcast is received.
+ * Verify that onFailed is called for registered LOHS callers on SAP_START_FAILURE_GENERAL.
*/
@Test
public void testRegisteredCallbacksTriggeredOnSoftApFailureGeneric() throws Exception {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
+ verifyApRegistration();
registerLOHSRequestFull();
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_FAILED, message.what);
- assertEquals(ERROR_GENERIC, message.arg1);
+
+ verify(mLohsCallback).onHotspotFailed(ERROR_GENERIC);
}
/**
- * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
- * broadcast is received with the SAP_START_FAILURE_NO_CHANNEL error.
+ * Verify that onFailed is called for registered LOHS callers on SAP_START_FAILURE_NO_CHANNEL.
*/
@Test
public void testRegisteredCallbacksTriggeredOnSoftApFailureNoChannel() throws Exception {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
+ verifyApRegistration();
registerLOHSRequestFull();
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_NO_CHANNEL,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_FAILED,
+ WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_NO_CHANNEL);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_FAILED, message.what);
- assertEquals(ERROR_NO_CHANNEL, message.arg1);
+ verify(mLohsCallback).onHotspotFailed(ERROR_NO_CHANNEL);
}
/**
- * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
- * broadcast is received with WIFI_AP_STATE_DISABLING and LOHS was active.
+ * Common setup for starting a LOHS.
*/
- @Test
- public void testRegisteredCallbacksTriggeredOnSoftApDisabling() throws Exception {
- setupClientModeImplHandlerForPost();
-
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
+ private void setupLocalOnlyHotspot() throws Exception {
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
+ verifyApRegistration();
registerLOHSRequestFull();
- mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
+ mWifiServiceImpl.updateInterfaceIpState(mLohsInterfaceName, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STARTED, message.what);
- reset(mHandler);
+ verify(mLohsCallback).onHotspotStarted(any());
+ }
+
+ /**
+ * Verify that onStopped is called for registered LOHS callers when a callback is
+ * received with WIFI_AP_STATE_DISABLING and LOHS was active.
+ */
+ @Test
+ public void testRegisteredCallbacksTriggeredOnSoftApDisabling() throws Exception {
+ setupLocalOnlyHotspot();
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STOPPED, message.what);
+ verify(mLohsCallback).onHotspotStopped();
}
/**
- * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
- * broadcast is received with WIFI_AP_STATE_DISABLED and LOHS was enabled.
+ * Verify that onStopped is called for registered LOHS callers when a callback is
+ * received with WIFI_AP_STATE_DISABLED and LOHS was enabled.
*/
@Test
public void testRegisteredCallbacksTriggeredOnSoftApDisabled() throws Exception {
- setupClientModeImplHandlerForPost();
-
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
- mWifiServiceImpl.checkAndStartWifi();
-
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
-
- registerLOHSRequestFull();
-
- mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
- mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STARTED, message.what);
- reset(mHandler);
+ setupLocalOnlyHotspot();
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STOPPED, message.what);
+ verify(mLohsCallback).onHotspotStopped();
}
/**
- * Verify that no callbacks are called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
- * broadcast is received and the softap started.
+ * Verify that no callbacks are called for registered LOHS callers when a callback is
+ * received and the softap started.
*/
@Test
public void testRegisteredCallbacksNotTriggeredOnSoftApStart() throws Exception {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
+ verifyApRegistration();
registerLOHSRequestFull();
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME,
- IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
mLooper.dispatchAll();
- verify(mHandler, never()).handleMessage(any(Message.class));
+ verifyZeroInteractions(ignoreStubs(mLohsCallback));
}
/**
* Verify that onStopped is called only once for registered LOHS callers when
- * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLING and
+ * callbacks are received with WIFI_AP_STATE_DISABLING and
* WIFI_AP_STATE_DISABLED when LOHS was enabled.
*/
@Test
public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApDisabling() throws Exception {
- setupClientModeImplHandlerForPost();
+ setupLocalOnlyHotspot();
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
- mWifiServiceImpl.checkAndStartWifi();
-
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
-
- registerLOHSRequestFull();
-
- mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
- mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STARTED, message.what);
- reset(mHandler);
-
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
+ changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STOPPED, message.what);
+ verify(mLohsCallback).onHotspotStopped();
}
/**
* Verify that onFailed is called only once for registered LOHS callers when
- * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED twice.
+ * callbacks are received with WIFI_AP_STATE_FAILED twice.
*/
@Test
public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApFailsTwice() throws Exception {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
- when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
- mWifiServiceImpl.checkAndStartWifi();
+ setupLocalOnlyHotspot();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
-
- registerLOHSRequestFull();
-
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
+ changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_FAILED, message.what);
- assertEquals(ERROR_GENERIC, message.arg1);
+ verify(mLohsCallback).onHotspotFailed(ERROR_GENERIC);
}
/**
* Verify that onFailed is called for all registered LOHS callers when
- * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED.
+ * callbacks are received with WIFI_AP_STATE_FAILED.
*/
@Test
public void testAllRegisteredCallbacksTriggeredWhenSoftApFails() throws Exception {
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
+ verifyApRegistration();
// make an additional request for this test
mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
registerLOHSRequestFull();
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
+ changeLohsState(WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC);
verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_FAILED, message.what);
- assertEquals(ERROR_GENERIC, message.arg1);
+ verify(mLohsCallback).onHotspotFailed(ERROR_GENERIC);
}
/**
* Verify that onStopped is called for all registered LOHS callers when
- * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was
+ * callbacks are received with WIFI_AP_STATE_DISABLED when LOHS was
* active.
*/
@Test
public void testAllRegisteredCallbacksTriggeredWhenSoftApStops() throws Exception {
- setupClientModeImplHandlerForPost();
-
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
+ verifyApRegistration();
mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
@@ -2348,50 +2143,36 @@ public class WifiServiceImplTest {
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
verify(mRequestInfo).sendHotspotStartedMessage(any());
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STARTED, message.what);
- reset(mHandler);
-
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ verify(mLohsCallback).onHotspotStarted(any());
+
+ reset(mRequestInfo);
+ clearInvocations(mLohsCallback);
+
+ changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
+ changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
verify(mRequestInfo).sendHotspotStoppedMessage();
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STOPPED, message.what);
+ verify(mLohsCallback).onHotspotStopped();
}
/**
* Verify that onFailed is called for all registered LOHS callers when
- * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was
+ * callbacks are received with WIFI_AP_STATE_DISABLED when LOHS was
* not active.
*/
@Test
public void testAllRegisteredCallbacksTriggeredWhenSoftApStopsLOHSNotActive() throws Exception {
- setupClientModeImplHandlerForPost();
-
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
+ verifyApRegistration();
mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
mWifiServiceImpl.registerLOHSForTest(TEST_PID2, mRequestInfo2);
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
+ changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
verify(mRequestInfo2).sendHotspotFailedMessage(ERROR_GENERIC);
@@ -2405,13 +2186,10 @@ public class WifiServiceImplTest {
*/
@Test
public void testLOHSReadyWithoutRegisteredRequestsStopsSoftApMode() {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
- eq(WifiManager.IFACE_IP_MODE_TETHERED));
+ verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
}
/**
@@ -2421,8 +2199,6 @@ public class WifiServiceImplTest {
@Test
public void testRegisteredLocalOnlyHotspotRequestorsGetOnStartedCallbackWhenReady()
throws Exception {
- setupClientModeImplHandlerForPost();
-
registerLOHSRequestFull();
mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
@@ -2432,10 +2208,7 @@ public class WifiServiceImplTest {
verify(mRequestInfo).sendHotspotStartedMessage(any(WifiConfiguration.class));
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STARTED, message.what);
- assertNotNull((WifiConfiguration) message.obj);
+ verify(mLohsCallback).onHotspotStarted(notNull());
}
/**
@@ -2445,10 +2218,9 @@ public class WifiServiceImplTest {
@Test
public void testRegisterLocalOnlyHotspotRequestAfterAlreadyStartedGetsOnStartedCallback()
throws Exception {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
+ changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
@@ -2456,11 +2228,7 @@ public class WifiServiceImplTest {
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_STARTED, message.what);
- // since the first request was registered out of band, the config will be null
- assertNull((WifiConfiguration) message.obj);
+ verify(mLohsCallback).onHotspotStarted(any());
}
/**
@@ -2470,29 +2238,22 @@ public class WifiServiceImplTest {
*/
@Test
public void testCallOnFailedLocalOnlyHotspotRequestWhenIpConfigFails() throws Exception {
- setupClientModeImplHandlerForPost();
-
- registerLOHSRequestFull();
+ setupLocalOnlyHotspot();
+ reset(mActiveModeWarden);
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_FAILED, message.what);
- assertEquals(ERROR_GENERIC, message.arg1);
+ verify(mLohsCallback).onHotspotFailed(ERROR_GENERIC);
+ verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
- verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0),
- eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
-
- // sendMessage should only happen once since the requestor should be unregistered
- reset(mHandler);
+ clearInvocations(mLohsCallback);
// send HOTSPOT_FAILED message should only happen once since the requestor should be
// unregistered
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
mLooper.dispatchAll();
- verify(mHandler, never()).handleMessage(any(Message.class));
+ verifyZeroInteractions(ignoreStubs(mLohsCallback));
}
/**
@@ -2501,13 +2262,11 @@ public class WifiServiceImplTest {
*/
@Test
public void testStopSoftApWhenIpConfigFails() throws Exception {
- setupClientModeImplHandlerForPost();
-
+ mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
mLooper.dispatchAll();
- verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0),
- eq(WifiManager.IFACE_IP_MODE_TETHERED));
+ verify(mActiveModeWarden).stopSoftAp(IFACE_IP_MODE_TETHERED);
}
/**
@@ -2516,24 +2275,24 @@ public class WifiServiceImplTest {
*/
@Test
public void testCallOnFailedLocalOnlyHotspotRequestWhenTetheringStarts() throws Exception {
- setupClientModeImplHandlerForPost();
-
registerLOHSRequestFull();
+ mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ mLooper.dispatchAll();
+ verify(mLohsCallback).onHotspotStarted(any());
+ clearInvocations(mLohsCallback);
+
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- Message message = mMessageCaptor.getValue();
- assertEquals(HOTSPOT_FAILED, message.what);
- assertEquals(ERROR_INCOMPATIBLE_MODE, message.arg1);
+ verify(mLohsCallback).onHotspotFailed(ERROR_INCOMPATIBLE_MODE);
// sendMessage should only happen once since the requestor should be unregistered
- reset(mHandler);
+ clearInvocations(mLohsCallback);
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
- verify(mHandler, never()).handleMessage(any(Message.class));
+ verifyZeroInteractions(ignoreStubs(mLohsCallback));
}
/**
@@ -2546,7 +2305,7 @@ public class WifiServiceImplTest {
registerLOHSRequestFull();
mLooper.dispatchAll();
- verify(mHandler, never()).handleMessage(any(Message.class));
+ verifyZeroInteractions(ignoreStubs(mLohsCallback));
}
/**
@@ -2556,50 +2315,40 @@ public class WifiServiceImplTest {
@Test
public void testRegisterLocalOnlyHotspotRequestAfterStoppedNoOnStartedCallback()
throws Exception {
- setupClientModeImplHandlerForPost();
-
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
+ verifyApRegistration();
// register a request so we don't drop the LOHS interface ip update
mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
-
+ changeLohsState(WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR);
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
mLooper.dispatchAll();
registerLOHSRequestFull();
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- assertEquals(HOTSPOT_STARTED, mMessageCaptor.getValue().what);
+ verify(mLohsCallback).onHotspotStarted(any());
- reset(mHandler);
+ clearInvocations(mLohsCallback);
// now stop the hotspot
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
- TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
- WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
- WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
+ changeLohsState(WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR);
+ changeLohsState(WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR);
mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- assertEquals(HOTSPOT_STOPPED, mMessageCaptor.getValue().what);
+ verify(mLohsCallback).onHotspotStopped();
- reset(mHandler);
+ clearInvocations(mLohsCallback);
// now register a new caller - they should not get the onStarted callback
- Messenger messenger2 = new Messenger(mHandler);
- IBinder binder2 = mock(IBinder.class);
+ ILocalOnlyHotspotCallback callback2 = mock(ILocalOnlyHotspotCallback.class);
+ when(callback2.asBinder()).thenReturn(mock(IBinder.class));
- int result = mWifiServiceImpl.startLocalOnlyHotspot(messenger2, binder2, TEST_PACKAGE_NAME);
+ int result = mWifiServiceImpl.startLocalOnlyHotspot(callback2, TEST_PACKAGE_NAME);
assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result);
mLooper.dispatchAll();
- verify(mHandler, never()).handleMessage(any(Message.class));
+ verify(mLohsCallback, never()).onHotspotStarted(any());
}
/**
@@ -2615,7 +2364,7 @@ public class WifiServiceImplTest {
doThrow(new SecurityException()).when(mContext)
.enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
eq("WifiService"));
- mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder);
+ mWifiServiceImpl.startWatchLocalOnlyHotspot(mLohsCallback);
}
/**
@@ -2624,7 +2373,7 @@ public class WifiServiceImplTest {
*/
@Test(expected = UnsupportedOperationException.class)
public void testStartWatchLocalOnlyHotspotNotSupported() {
- mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder);
+ mWifiServiceImpl.startWatchLocalOnlyHotspot(mLohsCallback);
}
/**
@@ -2658,27 +2407,31 @@ public class WifiServiceImplTest {
config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
PackageManager pm = mock(PackageManager.class);
- when(pm.hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(true);
when(mContext.getPackageManager()).thenReturn(pm);
- when(pm.getApplicationInfoAsUser(any(), anyInt(), anyInt())).thenReturn(mApplicationInfo);
+ when(pm.getApplicationInfoAsUser(any(), anyInt(), any())).thenReturn(mApplicationInfo);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
- when(mClientModeImpl.syncAddOrUpdatePasspointConfig(any(),
- any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME))).thenReturn(
- true);
+ when(mPasspointManager.addOrUpdateProvider(
+ any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME), eq(false)))
+ .thenReturn(true);
+ mLooper.startAutoDispatch();
assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verifyCheckChangePermission(TEST_PACKAGE_NAME);
- verify(mClientModeImpl).syncAddOrUpdatePasspointConfig(any(),
- any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME));
- reset(mClientModeImpl);
+ verify(mPasspointManager).addOrUpdateProvider(
+ any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME), eq(false));
+ reset(mPasspointManager);
- when(mClientModeImpl.syncAddOrUpdatePasspointConfig(any(),
- any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME))).thenReturn(
- false);
+ when(mPasspointManager.addOrUpdateProvider(
+ any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME), anyBoolean()))
+ .thenReturn(false);
+ mLooper.startAutoDispatch();
assertEquals(-1, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
- verify(mClientModeImpl).syncAddOrUpdatePasspointConfig(any(),
- any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ verifyCheckChangePermission(TEST_PACKAGE_NAME);
+ verify(mPasspointManager).addOrUpdateProvider(
+ any(PasspointConfiguration.class), anyInt(), eq(TEST_PACKAGE_NAME), anyBoolean());
}
/**
@@ -2738,21 +2491,6 @@ public class WifiServiceImplTest {
}
/**
- * Verify that the call to startSubscriptionProvisioning is not directed to the Passpoint
- * specific API startSubscriptionProvisioning when the feature is not supported.
- */
- @Test(expected = UnsupportedOperationException.class)
- public void testStartSubscriptionProvisioniningPasspointUnsupported() throws Exception {
- when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
- when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
- when(mPackageManager.hasSystemFeature(
- PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(false);
- mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback);
- }
-
- /**
* Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
* specific API startSubscriptionProvisioning when the caller provides invalid arguments
*/
@@ -2797,9 +2535,10 @@ public class WifiServiceImplTest {
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false);
+ mLooper.startAutoDispatch();
mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE_NAME);
-
- verify(mClientModeImpl).syncGetPasspointConfigs(any(), eq(false));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ verify(mPasspointManager).getProviderConfigs(Binder.getCallingUid(), false);
}
/**
@@ -2810,9 +2549,40 @@ public class WifiServiceImplTest {
public void testGetPasspointConfigurationsWithPrivilegedPermissions() {
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+ mLooper.startAutoDispatch();
mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE_NAME);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ verify(mPasspointManager).getProviderConfigs(Binder.getCallingUid(), true);
+ }
- verify(mClientModeImpl).syncGetPasspointConfigs(any(), eq(true));
+ /**
+ * Verify that GetPasspointConfigurations will redirect calls to {@link PasspointManager}
+ * and returning the result that's returned from {@link PasspointManager}.
+ */
+ @Test
+ public void testGetPasspointConfigurations() throws Exception {
+ when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+
+ // Setup expected configs.
+ List<PasspointConfiguration> expectedConfigs = new ArrayList<>();
+ PasspointConfiguration config = new PasspointConfiguration();
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn("test.com");
+ config.setHomeSp(homeSp);
+ expectedConfigs.add(config);
+
+ when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
+ .thenReturn(expectedConfigs);
+ mLooper.startAutoDispatch();
+ assertEquals(expectedConfigs, mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ reset(mPasspointManager);
+
+ when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
+ .thenReturn(new ArrayList<PasspointConfiguration>());
+ mLooper.startAutoDispatch();
+ assertTrue(mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE).isEmpty());
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
}
/**
@@ -2825,8 +2595,10 @@ public class WifiServiceImplTest {
when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(anyInt())).thenReturn(
false);
+ mLooper.startAutoDispatch();
mWifiServiceImpl.removePasspointConfiguration(TEST_FQDN, TEST_PACKAGE_NAME);
- verify(mClientModeImpl).syncRemovePasspointConfig(any(), eq(false), eq(TEST_FQDN));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ verify(mPasspointManager).removeProvider(Binder.getCallingUid(), false, TEST_FQDN);
}
/**
@@ -2838,8 +2610,10 @@ public class WifiServiceImplTest {
when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(anyInt())).thenReturn(
true);
+ mLooper.startAutoDispatch();
mWifiServiceImpl.removePasspointConfiguration(TEST_FQDN, TEST_PACKAGE_NAME);
- verify(mClientModeImpl).syncRemovePasspointConfig(any(), eq(true), eq(TEST_FQDN));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ verify(mPasspointManager).removeProvider(Binder.getCallingUid(), true, TEST_FQDN);
}
/**
@@ -2915,143 +2689,70 @@ public class WifiServiceImplTest {
}
/**
- * Helper to test handling of async messages by wifi service when the message comes from an
- * app without {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission.
- */
- private void verifyAsyncChannelMessageHandlingWithoutChangePermisson(
- int requestMsgWhat, int expectedReplyMsgwhat) throws RemoteException {
- WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
-
- int uidWithoutPermission = 5;
- when(mWifiPermissionsUtil.checkChangePermission(eq(uidWithoutPermission)))
- .thenReturn(false);
-
- Message request = Message.obtain();
- request.what = requestMsgWhat;
- request.sendingUid = uidWithoutPermission;
-
- mLooper.startAutoDispatch();
- Message reply = tester.sendMessageSynchronously(request);
- mLooper.stopAutoDispatch();
-
- verify(mClientModeImpl, never()).sendMessage(any(Message.class));
- assertEquals(expectedReplyMsgwhat, reply.what);
- assertEquals(WifiManager.NOT_AUTHORIZED, reply.arg1);
- }
-
- /**
- * Helper to test handling of async messages by wifi service when the message comes from an
- * app without one of the privileged permissions.
- */
- private void verifyAsyncChannelMessageHandlingWithoutPrivilegedPermissons(
- int requestMsgWhat, int expectedReplyMsgwhat) throws RemoteException {
- WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
-
- int uidWithoutPermission = 5;
- when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
- when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
- when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_STACK),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
-
- Message request = Message.obtain();
- request.what = requestMsgWhat;
- request.sendingUid = uidWithoutPermission;
-
- mLooper.startAutoDispatch();
- Message reply = tester.sendMessageSynchronously(request);
- mLooper.stopAutoDispatch();
-
- verify(mClientModeImpl, never()).sendMessage(any(Message.class));
- assertEquals(expectedReplyMsgwhat, reply.what);
- assertEquals(WifiManager.NOT_AUTHORIZED, reply.arg1);
- }
-
- /**
* Verify that the CONNECT_NETWORK message received from an app without
- * one of the privileged permission is rejected with the correct error code.
+ * one of the privileged permission is rejected with a security exception.
*/
@Test
public void testConnectNetworkWithoutPrivilegedPermission() throws Exception {
- verifyAsyncChannelMessageHandlingWithoutPrivilegedPermissons(
- WifiManager.CONNECT_NETWORK, WifiManager.CONNECT_NETWORK_FAILED);
+ try {
+ mWifiServiceImpl.connect(mock(WifiConfiguration.class), TEST_NETWORK_ID,
+ mock(Binder.class),
+ mock(IActionListener.class), 0);
+ fail();
+ } catch (SecurityException e) {
+ verify(mClientModeImpl, never()).connect(any(WifiConfiguration.class), anyInt(),
+ any(Binder.class), any(IActionListener.class), anyInt(), anyInt());
+ }
}
/**
* Verify that the FORGET_NETWORK message received from an app without
- * one of the privileged permission is rejected with the correct error code.
+ * one of the privileged permission is rejected with a security exception.
*/
@Test
public void testForgetNetworkWithoutPrivilegedPermission() throws Exception {
- verifyAsyncChannelMessageHandlingWithoutPrivilegedPermissons(
- WifiManager.SAVE_NETWORK, WifiManager.SAVE_NETWORK_FAILED);
+ try {
+ mWifiServiceImpl.forget(TEST_NETWORK_ID, mock(Binder.class),
+ mock(IActionListener.class), 0);
+ fail();
+ } catch (SecurityException e) {
+ verify(mClientModeImpl, never()).forget(anyInt(), any(Binder.class),
+ any(IActionListener.class), anyInt(), anyInt());
+ }
}
/**
- * Verify that the DISABLE_NETWORK message received from an app without
- * one of the privileged permission is rejected with the correct error code.
+ * Verify that the SAVE_NETWORK message received from an app without
+ * one of the privileged permission is rejected with a security exception.
*/
@Test
- public void testDisableNetworkWithoutPrivilegedPermission() throws Exception {
- verifyAsyncChannelMessageHandlingWithoutPrivilegedPermissons(
- WifiManager.DISABLE_NETWORK, WifiManager.DISABLE_NETWORK_FAILED);
+ public void testSaveNetworkWithoutPrivilegedPermission() throws Exception {
+ try {
+ mWifiServiceImpl.save(mock(WifiConfiguration.class), mock(Binder.class),
+ mock(IActionListener.class), 0);
+ fail();
+ } catch (SecurityException e) {
+ verify(mClientModeImpl, never()).save(any(WifiConfiguration.class),
+ any(Binder.class), any(IActionListener.class), anyInt(), anyInt());
+ }
}
/**
- * Verify that the RSSI_PKTCNT_FETCH message received from an app without
- * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct
- * error code.
+ * Verify that the PKT_CNT_FETCH message received from an app without
+ * CHANGE_WIFI_STATE} permission is rejected with a security exception.
*/
@Test
- public void testRssiPktcntFetchWithoutChangePermission() throws Exception {
- verifyAsyncChannelMessageHandlingWithoutChangePermisson(
- WifiManager.RSSI_PKTCNT_FETCH, WifiManager.RSSI_PKTCNT_FETCH_FAILED);
- }
-
- /**
- * Helper to test handling of async messages by wifi service when the message comes from an
- * app with {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission.
- */
- private void verifyAsyncChannelMessageHandlingWithChangePermisson(
- int requestMsgWhat, Object requestMsgObj) throws RemoteException {
- WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
-
- when(mWifiPermissionsUtil.checkChangePermission(anyInt())).thenReturn(true);
-
- Message request = Message.obtain();
- request.what = requestMsgWhat;
- request.obj = requestMsgObj;
-
- tester.sendMessage(request);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mClientModeImpl).sendMessage(messageArgumentCaptor.capture());
- assertEquals(requestMsgWhat, messageArgumentCaptor.getValue().what);
- }
-
- /**
- * Helper to test handling of async messages by wifi service when the message comes from an
- * app with one of the privileged permissions.
- */
- private void verifyAsyncChannelMessageHandlingWithPrivilegedPermissions(
- int requestMsgWhat, Object requestMsgObj) throws RemoteException {
- WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
-
- when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
- anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
-
- Message request = Message.obtain();
- request.what = requestMsgWhat;
- request.obj = requestMsgObj;
-
- tester.sendMessage(request);
- mLooper.dispatchAll();
-
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mClientModeImpl).sendMessage(messageArgumentCaptor.capture());
- assertEquals(requestMsgWhat, messageArgumentCaptor.getValue().what);
+ public void testTxPacketCountFetchWithoutChangePermission() throws Exception {
+ doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+ android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
+ try {
+ mWifiServiceImpl.getTxPacketCount(TEST_PACKAGE_NAME, mock(Binder.class),
+ mock(ITxPacketCountListener.class), 0);
+ fail();
+ } catch (SecurityException e) {
+ verify(mClientModeImpl, never()).getTxPacketCount(any(Binder.class),
+ any(ITxPacketCountListener.class), anyInt(), anyInt());
+ }
}
/**
@@ -3060,8 +2761,13 @@ public class WifiServiceImplTest {
*/
@Test
public void testConnectNetworkWithPrivilegedPermission() throws Exception {
- verifyAsyncChannelMessageHandlingWithPrivilegedPermissions(
- WifiManager.CONNECT_NETWORK, new WifiConfiguration());
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.connect(mock(WifiConfiguration.class), TEST_NETWORK_ID,
+ mock(Binder.class),
+ mock(IActionListener.class), 0);
+ verify(mClientModeImpl).connect(any(WifiConfiguration.class), anyInt(),
+ any(Binder.class), any(IActionListener.class), anyInt(), anyInt());
}
/**
@@ -3070,18 +2776,26 @@ public class WifiServiceImplTest {
*/
@Test
public void testSaveNetworkWithPrivilegedPermission() throws Exception {
- verifyAsyncChannelMessageHandlingWithPrivilegedPermissions(
- WifiManager.SAVE_NETWORK, new WifiConfiguration());
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.save(mock(WifiConfiguration.class), mock(Binder.class),
+ mock(IActionListener.class), 0);
+ verify(mClientModeImpl).save(any(WifiConfiguration.class),
+ any(Binder.class), any(IActionListener.class), anyInt(), anyInt());
}
/**
- * Verify that the DISABLE_NETWORK message received from an app with
+ * Verify that the FORGET_NETWORK message received from an app with
* one of the privileged permission is forwarded to ClientModeImpl.
*/
@Test
- public void testDisableNetworkWithPrivilegedPermission() throws Exception {
- verifyAsyncChannelMessageHandlingWithPrivilegedPermissions(
- WifiManager.DISABLE_NETWORK, new Object());
+ public void testForgetNetworkWithPrivilegedPermission() throws Exception {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.forget(TEST_NETWORK_ID, mock(Binder.class), mock(IActionListener.class),
+ 0);
+ verify(mClientModeImpl).forget(anyInt(), any(Binder.class),
+ any(IActionListener.class), anyInt(), anyInt());
}
/**
@@ -3090,52 +2804,12 @@ public class WifiServiceImplTest {
*/
@Test
public void testRssiPktcntFetchWithChangePermission() throws Exception {
- verifyAsyncChannelMessageHandlingWithChangePermisson(
- WifiManager.RSSI_PKTCNT_FETCH, new Object());
+ mWifiServiceImpl.getTxPacketCount(TEST_PACKAGE_NAME, mock(Binder.class),
+ mock(ITxPacketCountListener.class), 0);
+ verify(mClientModeImpl).getTxPacketCount(any(Binder.class),
+ any(ITxPacketCountListener.class), anyInt(), anyInt());
}
- /**
- * Verify that setCountryCode() calls WifiCountryCode object on succeess.
- */
- @Test
- public void testSetCountryCode() throws Exception {
- mWifiServiceImpl.setCountryCode(TEST_COUNTRY_CODE);
- verify(mWifiCountryCode).setCountryCode(TEST_COUNTRY_CODE);
- }
-
- /**
- * Verify that setCountryCode() fails and doesn't call WifiCountryCode object
- * if the caller doesn't have CONNECTIVITY_INTERNAL permission.
- */
- @Test(expected = SecurityException.class)
- public void testSetCountryCodeFailsWithoutConnectivityInternalPermission() throws Exception {
- doThrow(new SecurityException()).when(mContext)
- .enforceCallingOrSelfPermission(
- eq(android.Manifest.permission.CONNECTIVITY_INTERNAL),
- eq("ConnectivityService"));
- mWifiServiceImpl.setCountryCode(TEST_COUNTRY_CODE);
- verify(mWifiCountryCode, never()).setCountryCode(TEST_COUNTRY_CODE);
- }
-
- private void setupClientModeImplHandlerForPost() {
- when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler);
- }
-
- /**
- * Set the wifi state machine mock to return a handler created on test thread.
- */
- private void setupClientModeImplHandlerForRunWithScissors() {
- HandlerThread handlerThread = createAndStartHandlerThreadForRunWithScissors();
- mHandlerSpyForCmiRunWithScissors = spy(handlerThread.getThreadHandler());
- when(mWifiInjector.getClientModeImplHandler())
- .thenReturn(mHandlerSpyForCmiRunWithScissors);
- }
-
- private HandlerThread createAndStartHandlerThreadForRunWithScissors() {
- HandlerThread handlerThread = new HandlerThread("ServiceHandlerThreadForTest");
- handlerThread.start();
- return handlerThread;
- }
/**
* Tests the scenario when a scan request arrives while the device is idle. In this case
@@ -3143,8 +2817,6 @@ public class WifiServiceImplTest {
*/
@Test
public void testHandleDelayedScanAfterIdleMode() throws Exception {
- setupClientModeImplHandlerForRunWithScissors();
- when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
mWifiServiceImpl.checkAndStartWifi();
verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
@@ -3162,6 +2834,7 @@ public class WifiServiceImplTest {
// Tell the wifi service that idle mode ended.
when(mPowerManager.isDeviceIdleMode()).thenReturn(false);
TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext);
+ mLooper.dispatchAll();
// Must scan now.
verify(mScanRequestProxy).startScan(Process.myUid(), TEST_PACKAGE_NAME);
@@ -3172,14 +2845,15 @@ public class WifiServiceImplTest {
// Send another scan request. The device is not idle anymore, so it must be executed
// immediately.
+ mLooper.startAutoDispatch();
assertTrue(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
}
/**
* Verify that if the caller has NETWORK_SETTINGS permission, then it doesn't need
* CHANGE_WIFI_STATE permission.
- * @throws Exception
*/
@Test
public void testDisconnectWithNetworkSettingsPerm() throws Exception {
@@ -3196,7 +2870,6 @@ public class WifiServiceImplTest {
/**
* Verify that if the caller doesn't have NETWORK_SETTINGS permission, it could still
* get access with the CHANGE_WIFI_STATE permission.
- * @throws Exception
*/
@Test
public void testDisconnectWithChangeWifiStatePerm() throws Exception {
@@ -3208,7 +2881,6 @@ public class WifiServiceImplTest {
/**
* Verify that the operation fails if the caller has neither NETWORK_SETTINGS or
* CHANGE_WIFI_STATE permissions.
- * @throws Exception
*/
@Test
public void testDisconnectRejected() throws Exception {
@@ -3226,7 +2898,6 @@ public class WifiServiceImplTest {
@Test
public void testPackageRemovedBroadcastHandling() {
- when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler);
mWifiServiceImpl.checkAndStartWifi();
verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
argThat((IntentFilter filter) ->
@@ -3239,10 +2910,14 @@ public class WifiServiceImplTest {
intent.putExtra(Intent.EXTRA_UID, uid);
intent.setData(Uri.fromParts("package", packageName, ""));
mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
+ mLooper.dispatchAll();
- verify(mClientModeImpl).removeAppConfigs(packageName, uid);
+ ArgumentCaptor<ApplicationInfo> aiCaptor = ArgumentCaptor.forClass(ApplicationInfo.class);
+ verify(mWifiConfigManager).removeNetworksForApp(aiCaptor.capture());
+ assertNotNull(aiCaptor.getValue());
+ assertEquals(uid, aiCaptor.getValue().uid);
+ assertEquals(packageName, aiCaptor.getValue().packageName);
- mLooper.dispatchAll();
verify(mScanRequestProxy).clearScanRequestTimestampsForApp(packageName, uid);
verify(mWifiNetworkSuggestionsManager).removeApp(packageName);
verify(mClientModeImpl).removeNetworkRequestUserApprovedAccessPointsForApp(packageName);
@@ -3251,7 +2926,6 @@ public class WifiServiceImplTest {
@Test
public void testPackageRemovedBroadcastHandlingWithNoUid() {
- when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler);
mWifiServiceImpl.checkAndStartWifi();
verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
argThat((IntentFilter filter) ->
@@ -3263,7 +2937,7 @@ public class WifiServiceImplTest {
intent.setData(Uri.fromParts("package", packageName, ""));
mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
- verify(mClientModeImpl, never()).removeAppConfigs(anyString(), anyInt());
+ verify(mWifiConfigManager, never()).removeNetworksForApp(any());
mLooper.dispatchAll();
verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt());
@@ -3275,7 +2949,6 @@ public class WifiServiceImplTest {
@Test
public void testPackageRemovedBroadcastHandlingWithNoPackageName() {
- when(mWifiInjector.getClientModeImplHandler()).thenReturn(mHandler);
mWifiServiceImpl.checkAndStartWifi();
verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
argThat((IntentFilter filter) ->
@@ -3287,7 +2960,7 @@ public class WifiServiceImplTest {
intent.putExtra(Intent.EXTRA_UID, uid);
mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
- verify(mClientModeImpl, never()).removeAppConfigs(anyString(), anyInt());
+ verify(mWifiConfigManager, never()).removeNetworksForApp(any());
mLooper.dispatchAll();
verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt());
@@ -3309,8 +2982,9 @@ public class WifiServiceImplTest {
Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
+ mLooper.dispatchAll();
- verify(mClientModeImpl).removeUserConfigs(userHandle);
+ verify(mWifiConfigManager).removeNetworksForUser(userHandle);
}
@Test
@@ -3326,7 +3000,7 @@ public class WifiServiceImplTest {
intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
- verify(mClientModeImpl, never()).removeUserConfigs(userHandle);
+ verify(mWifiConfigManager, never()).removeNetworksForUser(anyInt());
}
/**
@@ -3527,8 +3201,6 @@ public class WifiServiceImplTest {
*/
@Test
public void registerTrafficStateCallbackAndVerify() throws Exception {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.registerTrafficStateCallback(
mAppBinder, mTrafficStateCallback, TEST_TRAFFIC_STATE_CALLBACK_IDENTIFIER);
mLooper.dispatchAll();
@@ -3541,8 +3213,6 @@ public class WifiServiceImplTest {
*/
@Test
public void unregisterTrafficStateCallbackAndVerify() throws Exception {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.unregisterTrafficStateCallback(0);
mLooper.dispatchAll();
verify(mWifiTrafficPoller).removeCallback(0);
@@ -3604,8 +3274,6 @@ public class WifiServiceImplTest {
*/
@Test
public void registerNetworkRequestMatchCallbackAndVerify() throws Exception {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.registerNetworkRequestMatchCallback(
mAppBinder, mNetworkRequestMatchCallback,
TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER);
@@ -3621,8 +3289,6 @@ public class WifiServiceImplTest {
*/
@Test
public void unregisterNetworkRequestMatchCallbackAndVerify() throws Exception {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.unregisterNetworkRequestMatchCallback(
TEST_NETWORK_REQUEST_MATCH_CALLBACK_IDENTIFIER);
mLooper.dispatchAll();
@@ -3635,8 +3301,6 @@ public class WifiServiceImplTest {
*/
@Test
public void testFactoryReset() throws Exception {
- setupClientModeImplHandlerForPost();
-
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
@@ -3648,44 +3312,26 @@ public class WifiServiceImplTest {
config.setHomeSp(homeSp);
mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
- when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt()))
+ when(mWifiConfigManager.getSavedNetworks(anyInt()))
.thenReturn(Arrays.asList(network));
- when(mClientModeImpl.syncGetPasspointConfigs(any(), anyBoolean()))
+ when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
.thenReturn(Arrays.asList(config));
+ mLooper.startAutoDispatch();
mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME);
- mLooper.dispatchAll();
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mClientModeImpl).syncRemoveNetwork(mAsyncChannel, network.networkId);
- verify(mClientModeImpl).syncRemovePasspointConfig(mAsyncChannel, true, fqdn);
- verify(mWifiConfigManager).clearDeletedEphemeralNetworks();
- verify(mClientModeImpl).clearNetworkRequestUserApprovedAccessPoints();
- verify(mWifiNetworkSuggestionsManager).clear();
- verify(mWifiScoreCard).clear();
- }
-
- /**
- * Verify that Passpoint configuration is not removed in factoryReset if Passpoint feature
- * is not supported.
- */
- @Test
- public void testFactoryResetWithoutPasspointSupport() throws Exception {
- setupClientModeImplHandlerForPost();
-
- mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
- when(mPackageManager.hasSystemFeature(
- PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(false);
-
- mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME);
+ // Let the final post inside the |factoryReset| method run to completion.
mLooper.dispatchAll();
- verify(mClientModeImpl).syncGetConfiguredNetworks(anyInt(), any(), anyInt());
- verify(mClientModeImpl, never()).syncGetPasspointConfigs(any(), anyBoolean());
- verify(mClientModeImpl, never()).syncRemovePasspointConfig(
- any(), anyBoolean(), anyString());
+ verify(mWifiConfigManager).removeNetwork(
+ network.networkId, Binder.getCallingUid(), TEST_PACKAGE_NAME);
+ verify(mPasspointManager).removeProvider(anyInt(), anyBoolean(), eq(fqdn));
verify(mWifiConfigManager).clearDeletedEphemeralNetworks();
verify(mClientModeImpl).clearNetworkRequestUserApprovedAccessPoints();
verify(mWifiNetworkSuggestionsManager).clear();
+ verify(mWifiScoreCard).clear();
+ verify(mPasspointManager).getProviderConfigs(anyInt(), anyBoolean());
}
/**
@@ -3697,32 +3343,32 @@ public class WifiServiceImplTest {
doThrow(new SecurityException()).when(mContext)
.enforceCallingOrSelfPermission(eq(Manifest.permission.CONNECTIVITY_INTERNAL),
eq("ConnectivityService"));
- mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
-
try {
mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME);
fail();
} catch (SecurityException e) {
}
- verify(mClientModeImpl, never()).syncGetConfiguredNetworks(anyInt(), any(), anyInt());
- verify(mClientModeImpl, never()).syncGetPasspointConfigs(any(), eq(false));
+ verify(mWifiConfigManager, never()).getSavedNetworks(anyInt());
+ verify(mPasspointManager, never()).getProviderConfigs(anyInt(), anyBoolean());
}
/**
* Verify that add or update networks is not allowed for apps targeting Q SDK.
*/
@Test
- public void testAddOrUpdateNetworkIsNotAllowedForAppsTargetingQSDK() throws Exception {
- mLooper.dispatchAll();
+ public void testAddOrUpdateNetworkIsNotAllowedForAppsTargetingQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
- when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), any())).thenReturn(
+ new NetworkUpdateResult(0));
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ mLooper.startAutoDispatch();
assertEquals(-1, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verifyCheckChangePermission(TEST_PACKAGE_NAME);
- verify(mClientModeImpl, never()).syncAddOrUpdateNetwork(any(), any());
+ verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt(), any());
verify(mWifiMetrics, never()).incrementNumAddOrUpdateNetworkCalls();
}
@@ -3730,19 +3376,21 @@ public class WifiServiceImplTest {
* Verify that add or update networks is allowed for apps targeting below Q SDK.
*/
@Test
- public void testAddOrUpdateNetworkIsAllowedForAppsTargetingBelowQSDK() throws Exception {
- mLooper.dispatchAll();
+ public void testAddOrUpdateNetworkIsAllowedForAppsTargetingBelowQSdk() throws Exception {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
- when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), any())).thenReturn(
+ new NetworkUpdateResult(0));
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ mLooper.startAutoDispatch();
assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verifyCheckChangePermission(TEST_PACKAGE_NAME);
- verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt(), any());
verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
}
@@ -3751,21 +3399,23 @@ public class WifiServiceImplTest {
*/
@Test
public void testAddOrUpdateNetworkIsAllowedForSettingsApp() throws Exception {
- mLooper.dispatchAll();
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
- when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), any())).thenReturn(
+ new NetworkUpdateResult(0));
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ mLooper.startAutoDispatch();
assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
// Ensure that we don't check for change permission.
verify(mContext, never()).enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
verify(mAppOpsManager, never()).noteOp(
AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
- verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt(), any());
verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
}
@@ -3774,17 +3424,19 @@ public class WifiServiceImplTest {
*/
@Test
public void testAddOrUpdateNetworkIsAllowedForSystemApp() throws Exception {
- mLooper.dispatchAll();
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
- when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), any())).thenReturn(
+ new NetworkUpdateResult(0));
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ mLooper.startAutoDispatch();
assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verifyCheckChangePermission(TEST_PACKAGE_NAME);
- verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt(), any());
verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
}
@@ -3793,20 +3445,22 @@ public class WifiServiceImplTest {
*/
@Test
public void testAddOrUpdateNetworkIsAllowedForAppsWithSystemAlertPermission() throws Exception {
- mLooper.dispatchAll();
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.checkSystemAlertWindowPermission(
Process.myUid(), TEST_PACKAGE_NAME)).thenReturn(true);
- when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), any())).thenReturn(
+ new NetworkUpdateResult(0));
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ mLooper.startAutoDispatch();
assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verifyCheckChangePermission(TEST_PACKAGE_NAME);
verify(mWifiPermissionsUtil).checkSystemAlertWindowPermission(anyInt(), anyString());
- verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt(), any());
verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
}
@@ -3815,19 +3469,20 @@ public class WifiServiceImplTest {
*/
@Test
public void testAddOrUpdateNetworkIsAllowedForDOApp() throws Exception {
- mLooper.dispatchAll();
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(
- Process.myUid(), DeviceAdminInfo.USES_POLICY_DEVICE_OWNER))
+ when(mWifiPermissionsUtil.isDeviceOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
.thenReturn(true);
- when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), any())).thenReturn(
+ new NetworkUpdateResult(0));
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ mLooper.startAutoDispatch();
assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verifyCheckChangePermission(TEST_PACKAGE_NAME);
- verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt(), any());
verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
}
@@ -3836,19 +3491,20 @@ public class WifiServiceImplTest {
*/
@Test
public void testAddOrUpdateNetworkIsAllowedForPOApp() throws Exception {
- mLooper.dispatchAll();
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
- when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(
- Process.myUid(), DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))
+ when(mWifiPermissionsUtil.isProfileOwner(Binder.getCallingUid(), TEST_PACKAGE_NAME))
.thenReturn(true);
- when(mClientModeImpl.syncAddOrUpdateNetwork(any(), any())).thenReturn(0);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), any())).thenReturn(
+ new NetworkUpdateResult(0));
WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ mLooper.startAutoDispatch();
assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verifyCheckChangePermission(TEST_PACKAGE_NAME);
- verify(mClientModeImpl).syncAddOrUpdateNetwork(any(), any());
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt(), any());
verify(mWifiMetrics).incrementNumAddOrUpdateNetworkCalls();
}
@@ -3856,35 +3512,79 @@ public class WifiServiceImplTest {
* Verify that enableNetwork is allowed for privileged Apps
*/
@Test
- public void testEnableNetworkAllowedForPrivilegedApps() throws Exception {
- mLooper.dispatchAll();
+ public void testEnableNetworkWithDisableOthersAllowedForPrivilegedApps() throws Exception {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
- mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public void answer(WifiConfiguration config, int netId, IBinder binder,
+ IActionListener callback, int callbackIdentifier, int callingUid) {
+ try {
+ callback.onSuccess(); // return success
+ } catch (RemoteException e) { }
+ }
+ }).when(mClientModeImpl).connect(
+ isNull(), eq(TEST_NETWORK_ID), any(), any(), anyInt(), anyInt());
+
+ assertTrue(mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME));
- verify(mClientModeImpl).syncEnableNetwork(eq(mAsyncChannel), eq(TEST_NETWORK_ID),
- eq(true));
+ verify(mClientModeImpl).connect(isNull(), eq(TEST_NETWORK_ID), any(), any(), anyInt(),
+ anyInt());
verify(mWifiMetrics).incrementNumEnableNetworkCalls();
}
/**
- * Verify that enableNetwork is allowed for Apps targeting a SDK version less than Q
+ * Verify that enableNetwork (with disableOthers=true) is allowed for Apps targeting a SDK
+ * version less than Q
*/
@Test
- public void testEnabledNetworkAllowedForAppsTargetingLessThanQ() throws Exception {
+ public void testEnabledNetworkWithDisableOthersAllowedForAppsTargetingBelowQSdk()
+ throws Exception {
mLooper.dispatchAll();
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
- mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public void answer(WifiConfiguration config, int netId, IBinder binder,
+ IActionListener callback, int callbackIdentifier, int callingUid) {
+ try {
+ callback.onSuccess(); // return success
+ } catch (RemoteException e) { }
+ }
+ }).when(mClientModeImpl).connect(
+ isNull(), eq(TEST_NETWORK_ID), any(), any(), anyInt(), anyInt());
- verify(mClientModeImpl).syncEnableNetwork(eq(mAsyncChannel), eq(TEST_NETWORK_ID),
- eq(true));
+ assertTrue(mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME));
+
+ verify(mClientModeImpl).connect(isNull(), eq(TEST_NETWORK_ID), any(), any(), anyInt(),
+ anyInt());
+ verify(mWifiMetrics).incrementNumEnableNetworkCalls();
+ }
+
+ /**
+ * Verify that enableNetwork (with disableOthers=false) is allowed for Apps targeting a SDK
+ * version less than Q
+ */
+ @Test
+ public void testEnabledNetworkWithoutDisableOthersAllowedForAppsTargetingBelowQSdk()
+ throws Exception {
+ mLooper.dispatchAll();
+ doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
+ .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
+ eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
+
+ when(mWifiConfigManager.enableNetwork(anyInt(), anyBoolean(), anyInt(), anyString()))
+ .thenReturn(true);
+ mLooper.startAutoDispatch();
+ assertTrue(mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, false, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ verify(mWifiConfigManager).enableNetwork(eq(TEST_NETWORK_ID), eq(false),
+ eq(Binder.getCallingUid()), eq(TEST_PACKAGE_NAME));
verify(mWifiMetrics).incrementNumEnableNetworkCalls();
}
@@ -3893,13 +3593,13 @@ public class WifiServiceImplTest {
*/
@Test
public void testEnableNetworkNotAllowedForAppsTargetingQ() throws Exception {
- mLooper.dispatchAll();
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
mWifiServiceImpl.enableNetwork(TEST_NETWORK_ID, true, TEST_PACKAGE_NAME);
- verify(mClientModeImpl, never()).syncEnableNetwork(anyObject(), anyInt(), anyBoolean());
+ verify(mClientModeImpl, never()).connect(isNull(), anyInt(), any(), any(), anyInt(),
+ anyInt());
verify(mWifiMetrics, never()).incrementNumEnableNetworkCalls();
}
@@ -3909,24 +3609,38 @@ public class WifiServiceImplTest {
*/
@Test
public void testAddNetworkSuggestions() {
- setupClientModeImplHandlerForRunWithScissors();
-
when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString()))
.thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
+ mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString()))
.thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE);
+ mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE,
mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+
+ verify(mWifiNetworkSuggestionsManager, times(2)).add(
+ any(), eq(Binder.getCallingUid()), eq(TEST_PACKAGE_NAME));
+ }
+
+ /**
+ * Ensure that we don't invoke {@link WifiNetworkSuggestionsManager} to add network
+ * suggestions when the looper sync call times out.
+ */
+ @Test
+ public void testAddNetworkSuggestionsFailureInRunWithScissors() {
+ mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
- doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
- .runWithScissors(any(), anyLong());
+ mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mWifiNetworkSuggestionsManager, times(2)).add(
+ verify(mWifiNetworkSuggestionsManager, never()).add(
any(), eq(Binder.getCallingUid()), eq(TEST_PACKAGE_NAME));
}
@@ -3936,28 +3650,72 @@ public class WifiServiceImplTest {
*/
@Test
public void testRemoveNetworkSuggestions() {
- setupClientModeImplHandlerForRunWithScissors();
-
when(mWifiNetworkSuggestionsManager.remove(any(), anyInt(), anyString()))
.thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID);
+ mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
when(mWifiNetworkSuggestionsManager.remove(any(), anyInt(), anyString()))
.thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
+ mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+
+ verify(mWifiNetworkSuggestionsManager, times(2)).remove(any(), anyInt(),
+ eq(TEST_PACKAGE_NAME));
+ }
- doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
- .runWithScissors(any(), anyLong());
+ /**
+ * Ensure that we don't invoke {@link WifiNetworkSuggestionsManager} to remove network
+ * suggestions when the looper sync call times out.
+ */
+ @Test
+ public void testRemoveNetworkSuggestionsFailureInRunWithScissors() {
+ mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
+
+ mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
- verify(mWifiNetworkSuggestionsManager, times(2)).remove(any(), anyInt(),
+ verify(mWifiNetworkSuggestionsManager, never()).remove(any(), anyInt(),
eq(TEST_PACKAGE_NAME));
}
/**
+ * Ensure that we invoke {@link WifiNetworkSuggestionsManager} to get network
+ * suggestions.
+ */
+ @Test
+ public void testGetNetworkSuggestions() {
+ List<WifiNetworkSuggestion> testList = new ArrayList<>();
+ when(mWifiNetworkSuggestionsManager.get(anyString())).thenReturn(testList);
+ mLooper.startAutoDispatch();
+ assertEquals(testList, mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+
+ verify(mWifiNetworkSuggestionsManager).get(eq(TEST_PACKAGE_NAME));
+ }
+
+ /**
+ * Ensure that we don't invoke {@link WifiNetworkSuggestionsManager} to get network
+ * suggestions when the looper sync call times out.
+ */
+ @Test
+ public void testGetNetworkSuggestionsFailureInRunWithScissors() {
+ mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
+
+ mLooper.startAutoDispatch();
+ assertTrue(mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME).isEmpty());
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+
+ verify(mWifiNetworkSuggestionsManager, never()).get(eq(TEST_PACKAGE_NAME));
+ }
+
+ /**
* Verify that if the caller has NETWORK_SETTINGS permission, then it can invoke
* {@link WifiManager#disableEphemeralNetwork(String)}.
*/
@@ -3966,7 +3724,8 @@ public class WifiServiceImplTest {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
- verify(mClientModeImpl).disableEphemeralNetwork(anyString());
+ mLooper.dispatchAll();
+ verify(mWifiConfigManager).disableEphemeralNetwork(anyString());
}
/**
@@ -3978,7 +3737,8 @@ public class WifiServiceImplTest {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
- verify(mClientModeImpl, never()).disableEphemeralNetwork(anyString());
+ mLooper.dispatchAll();
+ verify(mWifiConfigManager, never()).disableEphemeralNetwork(anyString());
}
/**
@@ -3986,10 +3746,11 @@ public class WifiServiceImplTest {
*/
@Test
public void testGetFactoryMacAddresses() throws Exception {
- setupClientModeImplHandlerForRunWithScissors();
when(mClientModeImpl.getFactoryMacAddress()).thenReturn(TEST_FACTORY_MAC);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+ mLooper.startAutoDispatch();
final String[] factoryMacs = mWifiServiceImpl.getFactoryMacAddresses();
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
assertEquals(1, factoryMacs.length);
assertEquals(TEST_FACTORY_MAC, factoryMacs[0]);
verify(mClientModeImpl).getFactoryMacAddress();
@@ -4001,11 +3762,12 @@ public class WifiServiceImplTest {
*/
@Test
public void testGetFactoryMacAddressesPostFail() throws Exception {
- setupClientModeImplHandlerForRunWithScissors();
- doReturn(false).when(mHandlerSpyForCmiRunWithScissors)
- .runWithScissors(any(), anyLong());
+ mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
+
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+ mLooper.startAutoDispatch();
assertNull(mWifiServiceImpl.getFactoryMacAddresses());
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mClientModeImpl, never()).getFactoryMacAddress();
}
@@ -4014,10 +3776,11 @@ public class WifiServiceImplTest {
*/
@Test
public void testGetFactoryMacAddressesFail() throws Exception {
- setupClientModeImplHandlerForRunWithScissors();
when(mClientModeImpl.getFactoryMacAddress()).thenReturn(null);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+ mLooper.startAutoDispatch();
assertNull(mWifiServiceImpl.getFactoryMacAddresses());
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mClientModeImpl).getFactoryMacAddress();
}
@@ -4027,11 +3790,12 @@ public class WifiServiceImplTest {
*/
@Test
public void testGetFactoryMacAddressesFailNoNetworkSettingsPermission() throws Exception {
- setupClientModeImplHandlerForRunWithScissors();
when(mClientModeImpl.getFactoryMacAddress()).thenReturn(TEST_FACTORY_MAC);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false);
try {
+ mLooper.startAutoDispatch();
mWifiServiceImpl.getFactoryMacAddresses();
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
fail();
} catch (SecurityException e) {
assertTrue("Exception message should contain 'factory MAC'",
@@ -4061,8 +3825,6 @@ public class WifiServiceImplTest {
*/
@Test
public void setDeviceMobilityStateRunsOnHandler() {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.setDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
verify(mClientModeImpl, never()).setDeviceMobilityState(anyInt());
mLooper.dispatchAll();
@@ -4124,8 +3886,6 @@ public class WifiServiceImplTest {
*/
@Test
public void testAddOnWifiUsabilityStatsListenerAndVerify() throws Exception {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.addOnWifiUsabilityStatsListener(mAppBinder, mOnWifiUsabilityStatsListener,
TEST_WIFI_USABILITY_STATS_LISTENER_IDENTIFIER);
mLooper.dispatchAll();
@@ -4139,8 +3899,6 @@ public class WifiServiceImplTest {
*/
@Test
public void testRemoveOnWifiUsabilityStatsListenerAndVerify() throws Exception {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.removeOnWifiUsabilityStatsListener(0);
mLooper.dispatchAll();
verify(mWifiMetrics).removeOnWifiUsabilityListener(0);
@@ -4169,8 +3927,6 @@ public class WifiServiceImplTest {
*/
@Test
public void testWifiUsabilityScoreUpdateAfterScoreEvent() {
- setupClientModeImplHandlerForPost();
-
mWifiServiceImpl.updateWifiUsabilityScore(anyInt(), anyInt(), 15);
mLooper.dispatchAll();
verify(mClientModeImpl).updateWifiUsabilityScore(anyInt(), anyInt(), anyInt());
@@ -4182,31 +3938,19 @@ public class WifiServiceImplTest {
.thenReturn(val);
}
- private void startLohsAndTethering(int apCount) {
+ private void startLohsAndTethering(int apCount) throws Exception {
// initialization
- setupClientModeImplHandlerForPost();
setupMaxApInterfaces(apCount);
- mWifiServiceImpl.checkAndStartWifi();
- verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
- (IntentFilter) argThat(new IntentFilterMatcher()));
+ // For these tests, always use distinct interface names for LOHS and tethered.
+ mLohsInterfaceName = WIFI_IFACE_NAME2;
- // start LOHS
- registerLOHSRequestFull();
- String ifaceName = apCount >= 2 ? WIFI_IFACE_NAME2 : WIFI_IFACE_NAME;
- mWifiServiceImpl.updateInterfaceIpState(ifaceName, IFACE_IP_MODE_LOCAL_ONLY);
- mLooper.dispatchAll();
- verify(mWifiController)
- .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), any(SoftApModeConfiguration.class));
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- assertEquals(HOTSPOT_STARTED, mMessageCaptor.getValue().what);
- reset(mWifiController);
- reset(mHandler);
+ setupLocalOnlyHotspot();
+ reset(mActiveModeWarden);
// start tethering
boolean tetheringResult = mWifiServiceImpl.startSoftAp(null);
assertTrue(tetheringResult);
- verify(mWifiController)
- .sendMessage(eq(CMD_SET_AP), eq(1), anyInt(), any(SoftApModeConfiguration.class));
+ verify(mActiveModeWarden).startSoftAp(any());
mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
}
@@ -4216,15 +3960,12 @@ public class WifiServiceImplTest {
* doesn't support dual AP operation.
*/
@Test
- public void testStartLohsAndTethering1AP() {
+ public void testStartLohsAndTethering1AP() throws Exception {
startLohsAndTethering(1);
// verify LOHS got stopped
- mLooper.dispatchAll();
- verify(mHandler).handleMessage(mMessageCaptor.capture());
- assertEquals(HOTSPOT_FAILED, mMessageCaptor.getValue().what);
- verify(mWifiController)
- .sendMessage(eq(CMD_SET_AP), eq(0), eq(WifiManager.IFACE_IP_MODE_LOCAL_ONLY));
+ verify(mLohsCallback).onHotspotFailed(anyInt());
+ verify(mActiveModeWarden).stopSoftAp(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
}
/**
@@ -4232,13 +3973,12 @@ public class WifiServiceImplTest {
* that does support dual AP operation.
*/
@Test
- public void testStartLohsAndTethering2AP() {
+ public void testStartLohsAndTethering2AP() throws Exception {
startLohsAndTethering(2);
// verify LOHS didn't get stopped
- mLooper.dispatchAll();
- verify(mHandler, never()).handleMessage(any(Message.class));
- verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0), anyInt());
+ verifyZeroInteractions(ignoreStubs(mLohsCallback));
+ verify(mActiveModeWarden, never()).stopSoftAp(anyInt());
}
/**
@@ -4271,4 +4011,196 @@ public class WifiServiceImplTest {
} catch (RemoteException e) {
}
}
+
+ /**
+ * Verifies that configs can be removed.
+ */
+ @Test
+ public void testRemoveNetworkIsAllowedForAppsTargetingBelowQSdk() {
+ doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
+ .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
+ when(mWifiConfigManager.removeNetwork(eq(0), anyInt(), anyString())).thenReturn(true);
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
+ eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
+
+ mLooper.startAutoDispatch();
+ boolean result = mWifiServiceImpl.removeNetwork(0, TEST_PACKAGE_NAME);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+
+ assertTrue(result);
+ verify(mWifiConfigManager).removeNetwork(anyInt(), anyInt(), anyString());
+ }
+
+ /**
+ * Verify that addOrUpdatePasspointConfig will redirect calls to {@link PasspointManager}
+ * and returning the result that's returned from {@link PasspointManager}.
+ */
+ @Test
+ public void addOrUpdatePasspointConfig() throws Exception {
+ PasspointConfiguration config = new PasspointConfiguration();
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn("test.com");
+ config.setHomeSp(homeSp);
+
+ when(mPasspointManager.addOrUpdateProvider(
+ config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false))
+ .thenReturn(true);
+ mLooper.startAutoDispatch();
+ assertTrue(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ reset(mPasspointManager);
+
+ when(mPasspointManager.addOrUpdateProvider(
+ config, Binder.getCallingUid(), TEST_PACKAGE_NAME, false))
+ .thenReturn(false);
+ mLooper.startAutoDispatch();
+ assertFalse(mWifiServiceImpl.addOrUpdatePasspointConfiguration(config, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ }
+ /**
+ * Verify that removePasspointConfiguration will redirect calls to {@link PasspointManager}
+ * and returning the result that's returned from {@link PasspointManager}.
+ */
+ @Test
+ public void removePasspointConfig() throws Exception {
+ when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
+
+ String fqdn = "test.com";
+ when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), eq(fqdn))).thenReturn(true);
+ mLooper.startAutoDispatch();
+ assertTrue(mWifiServiceImpl.removePasspointConfiguration(fqdn, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ reset(mPasspointManager);
+
+ when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), eq(fqdn))).thenReturn(false);
+ mLooper.startAutoDispatch();
+ assertFalse(mWifiServiceImpl.removePasspointConfiguration(fqdn, TEST_PACKAGE_NAME));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ }
+
+ /**
+ * Test that DISABLE_NETWORK returns failure to public API when WifiConfigManager returns
+ * failure.
+ */
+ @Test
+ public void testDisableNetworkFailureAppBelowQSdk() throws Exception {
+ doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
+ .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
+ eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
+ when(mWifiConfigManager.disableNetwork(anyInt(), anyInt(), anyString())).thenReturn(false);
+
+ mLooper.startAutoDispatch();
+ boolean succeeded = mWifiServiceImpl.disableNetwork(0, TEST_PACKAGE_NAME);
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+ assertFalse(succeeded);
+ }
+
+ @Test
+ public void testAllowAutojoinFailureNoNetworkSettingsPermission() throws Exception {
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ eq("WifiService"));
+ try {
+ mWifiServiceImpl.allowAutojoin(0, true);
+ fail("Expected SecurityException");
+ } catch (SecurityException e) {
+ // Test succeeded
+ }
+ }
+
+ /**
+ * Test handle boot completed sequence.
+ */
+ @Test
+ public void testHandleBootCompleted() throws Exception {
+ when(mWifiInjector.getPasspointProvisionerHandlerThread())
+ .thenReturn(mock(HandlerThread.class));
+ mWifiServiceImpl.handleBootCompleted();
+ mLooper.dispatchAll();
+
+ verify(mWifiConfigManager).loadFromStore();
+ verify(mPasspointManager).initializeProvisioner(any());
+ verify(mClientModeImpl).handleBootCompleted();
+ }
+
+ /**
+ * Test handle user switch sequence.
+ */
+ @Test
+ public void testHandleUserSwitch() throws Exception {
+ mWifiServiceImpl.handleUserSwitch(5);
+ mLooper.dispatchAll();
+ verify(mWifiConfigManager).handleUserSwitch(5);
+ }
+
+ /**
+ * Test handle user unlock sequence.
+ */
+ @Test
+ public void testHandleUserUnlock() throws Exception {
+ mWifiServiceImpl.handleUserUnlock(5);
+ mLooper.dispatchAll();
+ verify(mWifiConfigManager).handleUserUnlock(5);
+ }
+
+ /**
+ * Test handle user stop sequence.
+ */
+ @Test
+ public void testHandleUserStop() throws Exception {
+ mWifiServiceImpl.handleUserStop(5);
+ mLooper.dispatchAll();
+ verify(mWifiConfigManager).handleUserStop(5);
+ }
+
+ /**
+ * Test register scan result listener without permission.
+ */
+ @Test(expected = SecurityException.class)
+ public void testRegisterScanResultListenerWithMissingPermission() throws Exception {
+ doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.ACCESS_WIFI_STATE), eq("WifiService"));
+ final int listenerIdentifier = 1;
+ mWifiServiceImpl.registerScanResultsListener(mAppBinder,
+ mClientScanResultsListener,
+ listenerIdentifier);
+ }
+
+ /**
+ * Test unregister scan result listener without permission.
+ */
+ @Test(expected = SecurityException.class)
+ public void testUnregisterScanResultListenerWithMissingPermission() throws Exception {
+ doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+ eq(android.Manifest.permission.ACCESS_WIFI_STATE), eq("WifiService"));
+ final int listenerIdentifier = 1;
+ mWifiServiceImpl.unregisterScanResultsListener(listenerIdentifier);
+ }
+
+ /**
+ * Test register scan result listener with illegal argument.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testRegisterScanResultListenerWithIllegalArgument() throws Exception {
+ final int listenerIdentifier = 1;
+ mWifiServiceImpl.registerScanResultsListener(mAppBinder, null, listenerIdentifier);
+ }
+
+ /**
+ * Test register and unregister listener will go to ScanRequestProxy;
+ */
+ @Test
+ public void testRegisterUnregisterScanResultListener() throws Exception {
+ final int listenerIdentifier = 1;
+ mWifiServiceImpl.registerScanResultsListener(mAppBinder,
+ mClientScanResultsListener,
+ listenerIdentifier);
+ mLooper.dispatchAll();
+ verify(mScanRequestProxy).registerScanResultsListener(eq(mAppBinder),
+ eq(mClientScanResultsListener), eq(listenerIdentifier));
+ mWifiServiceImpl.unregisterScanResultsListener(listenerIdentifier);
+ mLooper.dispatchAll();
+ verify(mScanRequestProxy).unregisterScanResultsListener(eq(listenerIdentifier));
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiStateTrackerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiStateTrackerTest.java
index 682ba5b32f..410178888d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiStateTrackerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiStateTrackerTest.java
@@ -34,7 +34,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WifiStateTracker}.
*/
@SmallTest
-public class WifiStateTrackerTest {
+public class WifiStateTrackerTest extends WifiBaseTest {
private static final String TAG = "WifiStateTrackerTest";
@Mock IBatteryStats mBatteryStats;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiThreadRunnerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiThreadRunnerTest.java
new file mode 100644
index 0000000000..59f2ed817b
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiThreadRunnerTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+import java.util.function.Supplier;
+
+@SmallTest
+public class WifiThreadRunnerTest {
+
+ private static final int RESULT = 2;
+ private static final int VALUE_ON_TIMEOUT = -1;
+
+ private WifiThreadRunner mWifiThreadRunner;
+
+ @Mock private Runnable mRunnable;
+
+ private Handler mHandler;
+
+ @Spy private Supplier<Integer> mSupplier = () -> RESULT;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ HandlerThread mHandlerThread = new HandlerThread("WifiThreadRunnerTestHandlerThread");
+ mHandlerThread.start();
+
+ // runWithScissors() is a final method that cannot be mocked, instead wrap it in a spy,
+ // then it can be mocked
+ mHandler = spy(mHandlerThread.getThreadHandler());
+
+ mWifiThreadRunner = new WifiThreadRunner(mHandler);
+ }
+
+ @Test
+ public void callSuccess_returnExpectedValue() {
+ // doAnswer(<lambda>).when(<spy>).method(<args>) syntax is needed for spies instead of
+ // when(<mock>.method(<args>)).thenAnswer(<lambda>) for mocks
+ doAnswer(invocation -> {
+ Object[] args = invocation.getArguments();
+ Runnable runnable = (Runnable) args[0];
+ runnable.run();
+ return true;
+ }).when(mHandler).runWithScissors(any(), anyLong());
+
+ Integer result = mWifiThreadRunner.call(mSupplier, VALUE_ON_TIMEOUT);
+
+ assertThat(result).isEqualTo(RESULT);
+ verify(mSupplier).get();
+ }
+
+ @Test
+ public void callFailure_returnValueOnTimeout() {
+ doReturn(false).when(mHandler).post(any());
+
+ Integer result = mWifiThreadRunner.call(mSupplier, VALUE_ON_TIMEOUT);
+
+ assertThat(result).isEqualTo(VALUE_ON_TIMEOUT);
+ verify(mSupplier, never()).get();
+ }
+
+ @Test
+ public void runSuccess() {
+ doAnswer(invocation -> {
+ Object[] args = invocation.getArguments();
+ Runnable runnable = (Runnable) args[0];
+ runnable.run();
+ return true;
+ }).when(mHandler).runWithScissors(any(), anyLong());
+
+ boolean result = mWifiThreadRunner.run(mRunnable);
+
+ assertThat(result).isTrue();
+ verify(mRunnable).run();
+ }
+
+ @Test
+ public void runFailure() {
+ doReturn(false).when(mHandler).post(any());
+
+ boolean runSuccess = mWifiThreadRunner.run(mRunnable);
+
+ assertThat(runSuccess).isFalse();
+ verify(mRunnable, never()).run();
+ }
+
+ @Test
+ public void postSuccess() {
+ doReturn(true).when(mHandler).post(any());
+
+ boolean postSuccess = mWifiThreadRunner.post(mRunnable);
+
+ assertThat(postSuccess).isTrue();
+ verify(mHandler).post(mRunnable);
+ // assert that the runnable is not run on the calling thread
+ verify(mRunnable, never()).run();
+ }
+
+ @Test
+ public void postFailure() {
+ doReturn(false).when(mHandler).post(any());
+
+ boolean postSuccess = mWifiThreadRunner.post(mRunnable);
+
+ assertThat(postSuccess).isFalse();
+ verify(mHandler).post(mRunnable);
+ verify(mRunnable, never()).run();
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiTrafficPollerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiTrafficPollerTest.java
index ef49d2f4fa..1c7afef546 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiTrafficPollerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiTrafficPollerTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.verify;
import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.WifiManager;
+import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.test.TestLooper;
@@ -40,7 +41,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WifiTrafficPoller}.
*/
@SmallTest
-public class WifiTrafficPollerTest {
+public class WifiTrafficPollerTest extends WifiBaseTest {
public static final String TAG = "WifiTrafficPollerTest";
private TestLooper mLooper;
@@ -63,7 +64,7 @@ public class WifiTrafficPollerTest {
mLooper = new TestLooper();
MockitoAnnotations.initMocks(this);
- mWifiTrafficPoller = new WifiTrafficPoller(mLooper.getLooper());
+ mWifiTrafficPoller = new WifiTrafficPoller(new Handler(mLooper.getLooper()));
// Set the current mTxPkts and mRxPkts to DEFAULT_PACKET_COUNT
mWifiTrafficPoller.notifyOnDataActivity(DEFAULT_PACKET_COUNT, DEFAULT_PACKET_COUNT);
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 aa44023ae9..fc0cdd63b2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -87,7 +87,6 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.os.Handler;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.test.TestLooper;
import android.system.OsConstants;
@@ -119,7 +118,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.WifiVendorHal}.
*/
@SmallTest
-public class WifiVendorHalTest {
+public class WifiVendorHalTest extends WifiBaseTest {
private static final String TEST_IFACE_NAME = "wlan0";
private static final String TEST_IFACE_NAME_1 = "wlan1";
@@ -128,20 +127,22 @@ public class WifiVendorHalTest {
private static final int[] TEST_FREQUENCIES =
{2412, 2417, 2422, 2427, 2432, 2437};
- WifiVendorHal mWifiVendorHal;
+ private WifiVendorHal mWifiVendorHal;
private WifiStatus mWifiStatusSuccess;
private WifiStatus mWifiStatusFailure;
private WifiStatus mWifiStatusBusy;
- WifiLog mWifiLog;
+ private WifiLog mWifiLog;
+ private TestLooper mLooper;
+ private Handler mHandler;
@Mock
private HalDeviceManager mHalDeviceManager;
@Mock
- private TestLooper mLooper;
- @Mock
private WifiVendorHal.HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
@Mock
private IWifiApIface mIWifiApIface;
@Mock
+ private android.hardware.wifi.V1_4.IWifiApIface mIWifiApIfaceV14;
+ @Mock
private IWifiChip mIWifiChip;
@Mock
private android.hardware.wifi.V1_1.IWifiChip mIWifiChipV11;
@@ -168,8 +169,8 @@ public class WifiVendorHalTest {
* device.
*/
private class WifiVendorHalSpyV1_1 extends WifiVendorHal {
- WifiVendorHalSpyV1_1(HalDeviceManager halDeviceManager, Looper looper) {
- super(halDeviceManager, looper);
+ WifiVendorHalSpyV1_1(HalDeviceManager halDeviceManager, Handler handler) {
+ super(halDeviceManager, handler);
}
@Override
@@ -205,8 +206,8 @@ public class WifiVendorHalTest {
* the 1.2 HAL running on the device.
*/
private class WifiVendorHalSpyV1_2 extends WifiVendorHal {
- WifiVendorHalSpyV1_2(HalDeviceManager halDeviceManager, Looper looper) {
- super(halDeviceManager, looper);
+ WifiVendorHalSpyV1_2(HalDeviceManager halDeviceManager, Handler handler) {
+ super(halDeviceManager, handler);
}
@Override
@@ -242,8 +243,8 @@ public class WifiVendorHalTest {
* the 1.3 HAL running on the device.
*/
private class WifiVendorHalSpyV1_3 extends WifiVendorHal {
- WifiVendorHalSpyV1_3(HalDeviceManager halDeviceManager, Looper looper) {
- super(halDeviceManager, looper);
+ WifiVendorHalSpyV1_3(HalDeviceManager halDeviceManager, Handler handler) {
+ super(halDeviceManager, handler);
}
@Override
@@ -289,6 +290,7 @@ public class WifiVendorHalTest {
MockitoAnnotations.initMocks(this);
mWifiLog = new FakeWifiLog();
mLooper = new TestLooper();
+ mHandler = new Handler(mLooper.getLooper());
mWifiStatusSuccess = new WifiStatus();
mWifiStatusSuccess.code = WifiStatusCode.SUCCESS;
mWifiStatusFailure = new WifiStatus();
@@ -364,7 +366,7 @@ public class WifiVendorHalTest {
}).when(mIWifiApIface).getName(any(IWifiIface.getNameCallback.class));
// Create the vendor HAL object under test.
- mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, mHandler);
// Initialize the vendor HAL to capture the registered callback.
mWifiVendorHal.initialize(mVendorHalDeathHandler);
@@ -832,7 +834,7 @@ public class WifiVendorHalTest {
}
}).when(mIWifiStaIfaceV13).getFactoryMacAddress(any(
android.hardware.wifi.V1_3.IWifiStaIface.getFactoryMacAddressCallback.class));
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mHandler);
assertEquals(MacAddress.BROADCAST_ADDRESS.toString(),
mWifiVendorHal.getFactoryMacAddress(TEST_IFACE_NAME).toString());
verify(mIWifiStaIfaceV13).getFactoryMacAddress(any());
@@ -868,7 +870,7 @@ public class WifiVendorHalTest {
*/
@Test
public void testLinkLayerStatsCorrectVersionWithHalV1_3() throws Exception {
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mHandler);
mWifiVendorHal.getWifiLinkLayerStats(TEST_IFACE_NAME);
verify(mIWifiStaIfaceV13).getLinkLayerStats_1_3(any());
}
@@ -1308,7 +1310,7 @@ public class WifiVendorHalTest {
@Test
public void testReadApf() throws Exception {
// Expose the 1.2 IWifiStaIface.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
byte[] program = new byte[] {65, 66, 67};
ArrayList<Byte> expected = new ArrayList<>(3);
@@ -1473,7 +1475,7 @@ public class WifiVendorHalTest {
*/
@Test
public void testFlushRingBufferToFile() throws Exception {
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mHandler);
when(mIWifiChipV13.flushRingBufferToFile()).thenReturn(mWifiStatusSuccess);
assertFalse(mWifiVendorHal.flushRingBufferData());
@@ -2376,7 +2378,7 @@ public class WifiVendorHalTest {
sarInfo.isVoiceCall = true;
// Now expose the 1.1 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mHandler);
when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2402,7 +2404,7 @@ public class WifiVendorHalTest {
sarInfo.isVoiceCall = true;
// Now expose the 1.2 IWifiChip
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2442,7 +2444,7 @@ public class WifiVendorHalTest {
sarInfo.sarSensorSupported = false;
// Now expose the 1.1 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mHandler);
when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2468,7 +2470,7 @@ public class WifiVendorHalTest {
sarInfo.sarSensorSupported = false;
// Now expose the 1.1 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mHandler);
when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2500,7 +2502,7 @@ public class WifiVendorHalTest {
sarInfo.sarSensorSupported = false;
// Now expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2526,7 +2528,7 @@ public class WifiVendorHalTest {
sarInfo.sarSensorSupported = false;
// Now expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2562,7 +2564,7 @@ public class WifiVendorHalTest {
sarInfo.isWifiSapEnabled = true;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
// ON_BODY_CELL_ON
@@ -2591,7 +2593,7 @@ public class WifiVendorHalTest {
sarInfo.isVoiceCall = true;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
// ON_HEAD_CELL_ON
@@ -2620,7 +2622,7 @@ public class WifiVendorHalTest {
sarInfo.isEarPieceActive = true;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
// ON_HEAD_CELL_ON
@@ -2647,7 +2649,7 @@ public class WifiVendorHalTest {
sarInfo.sensorState = SarInfo.SAR_SENSOR_NEAR_HEAD;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
// ON_HEAD_CELL_OFF
@@ -2677,7 +2679,7 @@ public class WifiVendorHalTest {
sarInfo.sensorState = SarInfo.SAR_SENSOR_NEAR_HEAD;
// Now expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2713,7 +2715,7 @@ public class WifiVendorHalTest {
sarInfo.sensorState = SarInfo.SAR_SENSOR_NEAR_HAND;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2748,7 +2750,7 @@ public class WifiVendorHalTest {
sarInfo.sensorState = SarInfo.SAR_SENSOR_NEAR_HEAD;
// Expose the 1.1 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mHandler);
when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess);
when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
@@ -2783,7 +2785,7 @@ public class WifiVendorHalTest {
sarInfo.sensorState = SAR_SENSOR_INVALID_STATE;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
assertTrue(mWifiVendorHal.startVendorHalSta());
assertFalse(mWifiVendorHal.selectTxPowerScenario(sarInfo));
@@ -2813,7 +2815,7 @@ public class WifiVendorHalTest {
sarInfo.isVoiceCall = false;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2845,7 +2847,7 @@ public class WifiVendorHalTest {
sarInfo.isVoiceCall = true;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.selectTxPowerScenario_1_2(anyInt())).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2877,7 +2879,7 @@ public class WifiVendorHalTest {
sarInfo.isVoiceCall = false;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2907,7 +2909,7 @@ public class WifiVendorHalTest {
sarInfo.isVoiceCall = false;
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
when(mIWifiChipV12.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.startVendorHalSta());
@@ -2925,7 +2927,7 @@ public class WifiVendorHalTest {
@Test
public void testSetLowLatencyMode_1_2() throws RemoteException {
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
assertFalse(mWifiVendorHal.setLowLatencyMode(true));
assertFalse(mWifiVendorHal.setLowLatencyMode(false));
}
@@ -2938,7 +2940,7 @@ public class WifiVendorHalTest {
int mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.LOW;
// Expose the 1.3 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mHandler);
when(mIWifiChipV13.setLatencyMode(anyInt())).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.setLowLatencyMode(true));
verify(mIWifiChipV13).setLatencyMode(eq(mode));
@@ -2952,7 +2954,7 @@ public class WifiVendorHalTest {
int mode = android.hardware.wifi.V1_3.IWifiChip.LatencyMode.NORMAL;
// Expose the 1.3 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_3(mHalDeviceManager, mHandler);
when(mIWifiChipV13.setLatencyMode(anyInt())).thenReturn(mWifiStatusSuccess);
assertTrue(mWifiVendorHal.setLowLatencyMode(false));
verify(mIWifiChipV13).setLatencyMode(eq(mode));
@@ -3024,7 +3026,7 @@ public class WifiVendorHalTest {
@Test
public void testAlertCallbackUsing_1_2_EventCallback() throws Exception {
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
assertTrue(mWifiVendorHal.startVendorHalSta());
assertNotNull(mIWifiChipEventCallbackV12);
@@ -3036,9 +3038,9 @@ public class WifiVendorHalTest {
* Verifies setMacAddress() success.
*/
@Test
- public void testSetMacAddressSuccess() throws Exception {
+ public void testSetStaMacAddressSuccess() throws Exception {
// Expose the 1.2 IWifiStaIface.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
when(mIWifiStaIfaceV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusSuccess);
@@ -3050,9 +3052,9 @@ public class WifiVendorHalTest {
* Verifies setMacAddress() can handle failure status.
*/
@Test
- public void testSetMacAddressFailDueToStatusFailure() throws Exception {
+ public void testSetStaMacAddressFailDueToStatusFailure() throws Exception {
// Expose the 1.2 IWifiStaIface.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
when(mIWifiStaIfaceV12.setMacAddress(macByteArray)).thenReturn(mWifiStatusFailure);
@@ -3064,9 +3066,9 @@ public class WifiVendorHalTest {
* Verifies setMacAddress() can handle RemoteException.
*/
@Test
- public void testSetMacAddressFailDueToRemoteException() throws Exception {
+ public void testSetStaMacAddressFailDueToRemoteException() throws Exception {
// Expose the 1.2 IWifiStaIface.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
byte[] macByteArray = TEST_MAC_ADDRESS.toByteArray();
doThrow(new RemoteException()).when(mIWifiStaIfaceV12).setMacAddress(macByteArray);
@@ -3075,6 +3077,51 @@ public class WifiVendorHalTest {
}
/**
+ * 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.setMacAddress(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.setMacAddress(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.setMacAddress(TEST_IFACE_NAME_1, TEST_MAC_ADDRESS));
+ verify(mIWifiApIfaceV14).setMacAddress(macByteArray);
+ }
+
+ /**
* Verifies setMacAddress() does not crash with older HALs.
*/
@Test
@@ -3242,7 +3289,7 @@ public class WifiVendorHalTest {
private void startHalInStaModeAndRegisterRadioModeChangeCallback() {
// Expose the 1.2 IWifiChip.
- mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper());
+ mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mHandler);
mWifiVendorHal.registerRadioModeChangeHandler(mVendorHalRadioModeChangeHandler);
assertTrue(mWifiVendorHal.startVendorHalSta());
assertNotNull(mIWifiChipEventCallbackV12);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiWakeMetricsTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiWakeMetricsTest.java
index de5f380514..a27b141a14 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiWakeMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiWakeMetricsTest.java
@@ -30,7 +30,7 @@ import org.junit.Before;
import org.junit.Test;
@SmallTest
-public class WifiWakeMetricsTest {
+public class WifiWakeMetricsTest extends WifiBaseTest {
private WifiWakeMetrics mWifiWakeMetrics;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java b/service/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java
index ca48f38aea..dadab98d65 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WificondControlTest.java
@@ -39,14 +39,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.app.AlarmManager;
-import android.net.wifi.IApInterface;
-import android.net.wifi.IApInterfaceEventCallback;
-import android.net.wifi.IClientInterface;
-import android.net.wifi.IPnoScanEvent;
-import android.net.wifi.IScanEvent;
-import android.net.wifi.ISendMgmtFrameEvent;
-import android.net.wifi.IWifiScannerImpl;
-import android.net.wifi.IWificond;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
@@ -62,7 +54,16 @@ import com.android.server.wifi.WifiNative.SendMgmtFrameCallback;
import com.android.server.wifi.util.NativeUtil;
import com.android.server.wifi.wificond.ChannelSettings;
import com.android.server.wifi.wificond.HiddenNetwork;
+import com.android.server.wifi.wificond.IApInterface;
+import com.android.server.wifi.wificond.IApInterfaceEventCallback;
+import com.android.server.wifi.wificond.IClientInterface;
+import com.android.server.wifi.wificond.IPnoScanEvent;
+import com.android.server.wifi.wificond.IScanEvent;
+import com.android.server.wifi.wificond.ISendMgmtFrameEvent;
+import com.android.server.wifi.wificond.IWifiScannerImpl;
+import com.android.server.wifi.wificond.IWificond;
import com.android.server.wifi.wificond.NativeScanResult;
+import com.android.server.wifi.wificond.NativeWifiClient;
import com.android.server.wifi.wificond.PnoSettings;
import com.android.server.wifi.wificond.RadioChainInfo;
import com.android.server.wifi.wificond.SingleScanSettings;
@@ -79,7 +80,6 @@ import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.BitSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -88,7 +88,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.WificondControl}.
*/
@SmallTest
-public class WificondControlTest {
+public class WificondControlTest extends WifiBaseTest {
@Mock private WifiInjector mWifiInjector;
@Mock private WifiMonitor mWifiMonitor;
@Mock private WifiMetrics mWifiMetrics;
@@ -138,19 +138,22 @@ public class WificondControlTest {
private static final int TEST_FREQUENCY = 2456;
private static final int TEST_SIGNAL_MBM = -4500;
private static final long TEST_TSF = 34455441;
- private static final BitSet TEST_CAPABILITY = new BitSet(16) {{ set(2); set(5); }};
+ private static final int TEST_CAPABILITY = 0b0000_0000_0010_0100;
private static final boolean TEST_ASSOCIATED = true;
- private static final NativeScanResult MOCK_NATIVE_SCAN_RESULT =
- new NativeScanResult() {{
- ssid = TEST_SSID;
- bssid = TEST_BSSID;
- infoElement = TEST_INFO_ELEMENT_SSID;
- frequency = TEST_FREQUENCY;
- signalMbm = TEST_SIGNAL_MBM;
- capability = TEST_CAPABILITY;
- associated = TEST_ASSOCIATED;
- radioChainInfos = new ArrayList<>();
- }};
+ private static final NativeScanResult MOCK_NATIVE_SCAN_RESULT = createMockNativeScanResult();
+ private static NativeScanResult createMockNativeScanResult() {
+ NativeScanResult result = new NativeScanResult();
+ result.ssid = TEST_SSID;
+ result.bssid = TEST_BSSID;
+ result.infoElement = TEST_INFO_ELEMENT_SSID;
+ result.frequency = TEST_FREQUENCY;
+ result.signalMbm = TEST_SIGNAL_MBM;
+ result.tsf = TEST_TSF;
+ result.capability = TEST_CAPABILITY;
+ result.associated = TEST_ASSOCIATED;
+ result.radioChainInfos = new RadioChainInfo[0];
+ return result;
+ }
private static final RadioChainInfo MOCK_NATIVE_RADIO_CHAIN_INFO_1 =
new RadioChainInfo() {{
chainId = 1;
@@ -221,7 +224,7 @@ public class WificondControlTest {
when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
mLooper = new TestLooper();
mWificondControl = new WificondControl(mWifiInjector, mWifiMonitor, mCarrierNetworkConfig,
- mAlarmManager, mLooper.getLooper(), mClock);
+ mAlarmManager, new Handler(mLooper.getLooper()), mClock);
assertEquals(mClientInterface, mWificondControl.setupInterfaceForClientMode(
TEST_INTERFACE_NAME));
verify(mWifiInjector).makeWificond();
@@ -639,7 +642,7 @@ public class WificondControlTest {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(TEST_INFO_ELEMENT_SSID);
out.write(TEST_INFO_ELEMENT_RSN);
- NativeScanResult nativeScanResult = new NativeScanResult(MOCK_NATIVE_SCAN_RESULT);
+ NativeScanResult nativeScanResult = createMockNativeScanResult();
nativeScanResult.infoElement = out.toByteArray();
when(mWifiScannerImpl.getScanResults()).thenReturn(
new NativeScanResult[] {nativeScanResult});
@@ -687,12 +690,10 @@ public class WificondControlTest {
assertNotNull(mWifiScannerImpl);
// Mock the returned array of NativeScanResult.
- NativeScanResult nativeScanResult = new NativeScanResult(MOCK_NATIVE_SCAN_RESULT);
+ NativeScanResult nativeScanResult = createMockNativeScanResult();
// Add radio chain info
- ArrayList<RadioChainInfo> nativeRadioChainInfos = new ArrayList<RadioChainInfo>() {{
- add(MOCK_NATIVE_RADIO_CHAIN_INFO_1);
- add(MOCK_NATIVE_RADIO_CHAIN_INFO_2);
- }};
+ RadioChainInfo[] nativeRadioChainInfos =
+ { MOCK_NATIVE_RADIO_CHAIN_INFO_1, MOCK_NATIVE_RADIO_CHAIN_INFO_2 };
nativeScanResult.radioChainInfos = nativeRadioChainInfos;
NativeScanResult[] mockScanResults = { nativeScanResult };
@@ -880,12 +881,6 @@ public class WificondControlTest {
pnoScanEvent.OnPnoScanFailed();
verify(mWifiMetrics).incrementPnoScanFailedCount();
-
- pnoScanEvent.OnPnoScanOverOffloadStarted();
- verify(mWifiMetrics).incrementPnoScanStartedOverOffloadCount();
-
- pnoScanEvent.OnPnoScanOverOffloadFailed(0);
- verify(mWifiMetrics).incrementPnoScanFailedOverOffloadCount();
}
/**
@@ -928,9 +923,9 @@ public class WificondControlTest {
TEST_INTERFACE_NAME, mSoftApListener));
verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture());
- int numStations = 5;
- apInterfaceCallbackCaptor.getValue().onNumAssociatedStationsChanged(numStations);
- verify(mSoftApListener).onNumAssociatedStationsChanged(eq(numStations));
+ final NativeWifiClient[] testClients = new NativeWifiClient[]{};
+ apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClients);
+ verify(mSoftApListener).onConnectedClientsChanged(Arrays.asList(testClients));
int channelFrequency = 2437;
int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20;
@@ -1250,13 +1245,16 @@ public class WificondControlTest {
verify(mSendMgmtFrameCallback).onFailure(eq(WifiNative.SEND_MGMT_FRAME_ERROR_TIMEOUT));
}
- private void assertRadioChainInfosEqual(
- List<RadioChainInfo> expected, android.net.wifi.ScanResult.RadioChainInfo[] actual) {
- assertEquals(expected.size(), actual.length);
- for (int i = 0; i < actual.length; i++) {
- RadioChainInfo nativeRadioChainInfo =
- new RadioChainInfo(actual[i].id, actual[i].level);
- assertTrue(expected.contains(nativeRadioChainInfo));
+ private void assertRadioChainInfosEqual(RadioChainInfo[] expected,
+ android.net.wifi.ScanResult.RadioChainInfo[] actual) {
+ assertEquals(expected.length, actual.length);
+ for (int i = 0; i < expected.length; i++) {
+ RadioChainInfo expectedInfo = expected[i];
+ android.net.wifi.ScanResult.RadioChainInfo actualInfo = actual[i];
+ assertEquals(String.format("unexpected chainId at index %d", i),
+ expectedInfo.chainId, actualInfo.id);
+ assertEquals(String.format("unexpected level at index %d", i),
+ expectedInfo.level, actualInfo.level);
}
}
@@ -1277,8 +1275,8 @@ public class WificondControlTest {
if (settings.scanType != mExpectedScanType) {
return false;
}
- ArrayList<ChannelSettings> channelSettings = settings.channelSettings;
- ArrayList<HiddenNetwork> hiddenNetworks = settings.hiddenNetworks;
+ ChannelSettings[] channelSettings = settings.channelSettings;
+ HiddenNetwork[] hiddenNetworks = settings.hiddenNetworks;
if (mExpectedFreqs != null) {
Set<Integer> freqSet = new HashSet<Integer>();
for (ChannelSettings channel : channelSettings) {
@@ -1288,7 +1286,7 @@ public class WificondControlTest {
return false;
}
} else {
- if (channelSettings != null && channelSettings.size() > 0) {
+ if (channelSettings != null && channelSettings.length > 0) {
return false;
}
}
@@ -1304,7 +1302,7 @@ public class WificondControlTest {
}
} else {
- if (hiddenNetworks != null && hiddenNetworks.size() > 0) {
+ if (hiddenNetworks != null && hiddenNetworks.length > 0) {
return false;
}
}
@@ -1338,22 +1336,22 @@ public class WificondControlTest {
if (settings.pnoNetworks == null || mExpectedPnoSettings.networkList == null) {
return false;
}
- if (settings.pnoNetworks.size() != mExpectedPnoSettings.networkList.length) {
+ if (settings.pnoNetworks.length != mExpectedPnoSettings.networkList.length) {
return false;
}
- for (int i = 0; i < settings.pnoNetworks.size(); i++) {
+ for (int i = 0; i < settings.pnoNetworks.length; i++) {
if (!mExpectedPnoSettings.networkList[i].ssid.equals(NativeUtil.encodeSsid(
- NativeUtil.byteArrayToArrayList(settings.pnoNetworks.get(i).ssid)))) {
+ NativeUtil.byteArrayToArrayList(settings.pnoNetworks[i].ssid)))) {
return false;
}
boolean isNetworkHidden = (mExpectedPnoSettings.networkList[i].flags
& WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN) != 0;
- if (isNetworkHidden != settings.pnoNetworks.get(i).isHidden) {
+ if (isNetworkHidden != settings.pnoNetworks[i].isHidden) {
return false;
}
if (!Arrays.equals(mExpectedPnoSettings.networkList[i].frequencies,
- settings.pnoNetworks.get(i).frequencies)) {
+ settings.pnoNetworks[i].frequencies)) {
return false;
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WrongPasswordNotifierTest.java b/service/tests/wifitests/src/com/android/server/wifi/WrongPasswordNotifierTest.java
index 3d011da23f..28fbc9371d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WrongPasswordNotifierTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WrongPasswordNotifierTest.java
@@ -41,7 +41,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WrongPasswordNotifier}.
*/
@SmallTest
-public class WrongPasswordNotifierTest {
+public class WrongPasswordNotifierTest extends WifiBaseTest {
private static final String TEST_SSID = "Test SSID";
@Mock Context mContext;
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 35916d2f6b..b803dd5156 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
@@ -81,6 +81,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.AsyncChannel;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
@@ -107,7 +108,7 @@ import java.util.Set;
* Unit test harness for WifiAwareDataPathStateManager class.
*/
@SmallTest
-public class WifiAwareDataPathStateManagerTest {
+public class WifiAwareDataPathStateManagerTest extends WifiBaseTest {
private static final String sAwareInterfacePrefix = "aware_data";
private TestLooper mMockLooper;
@@ -164,6 +165,7 @@ public class WifiAwareDataPathStateManagerTest {
when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(), anyInt(), anyInt()))
.thenReturn(true);
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ when(mMockNativeManager.isAwareNativeAvailable()).thenReturn(true);
mDut = new WifiAwareStateManager();
mDut.setNative(mMockNativeManager, mMockNative);
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 95ca739af0..47772bd7e9 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
@@ -33,6 +33,7 @@ import android.util.SparseIntArray;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.nano.WifiMetricsProto;
import com.android.server.wifi.util.MetricsUtils;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -53,7 +54,7 @@ import java.util.Map;
* Unit test harness for WifiAwareMetrics
*/
@SmallTest
-public class WifiAwareMetricsTest {
+public class WifiAwareMetricsTest extends WifiBaseTest {
@Mock Clock mClock;
@Mock private Context mMockContext;
@Mock private AppOpsManager mMockAppOpsManager;
@@ -291,6 +292,15 @@ public class WifiAwareMetricsTest {
log.maxConcurrentAttachSessionsInApp, equalTo(2));
collector.checkThat("histogramAttachSessionStatus.length",
log.histogramAttachSessionStatus.length, equalTo(3)); // 3 buckets
+ validateNanStatusProtoHistBucket("Bucket[SUCCESS]",
+ log.histogramAttachSessionStatus[0],
+ WifiMetricsProto.WifiAwareLog.SUCCESS, 5);
+ validateNanStatusProtoHistBucket("Bucket[INTERNAL_FAILURE]",
+ log.histogramAttachSessionStatus[1],
+ WifiMetricsProto.WifiAwareLog.INTERNAL_FAILURE, 2);
+ validateNanStatusProtoHistBucket("Bucket[UNKNOWN_HAL_STATUS]",
+ log.histogramAttachSessionStatus[2],
+ WifiMetricsProto.WifiAwareLog.UNKNOWN_HAL_STATUS, 1);
collector.checkThat("histogramAttachDurationMs.length",
log.histogramAttachDurationMs.length, equalTo(2));
validateProtoHistBucket("Duration[0]", log.histogramAttachDurationMs[0], 5, 6, 1);
@@ -403,8 +413,23 @@ public class WifiAwareMetricsTest {
log.maxConcurrentDiscoverySessionsInSystem, equalTo(8));
collector.checkThat("histogramPublishStatus.length",
log.histogramPublishStatus.length, equalTo(2)); // 2 buckets
+ validateNanStatusProtoHistBucket("Bucket[SUCCESS]",
+ log.histogramPublishStatus[0],
+ WifiMetricsProto.WifiAwareLog.SUCCESS, 3);
+ validateNanStatusProtoHistBucket("Bucket[INTERNAL_FAILURE]",
+ log.histogramPublishStatus[1],
+ WifiMetricsProto.WifiAwareLog.INTERNAL_FAILURE, 1);
collector.checkThat("histogramSubscribeStatus.length",
log.histogramSubscribeStatus.length, equalTo(3)); // 3 buckets
+ validateNanStatusProtoHistBucket("Bucket[SUCCESS]",
+ log.histogramSubscribeStatus[0],
+ WifiMetricsProto.WifiAwareLog.SUCCESS, 5);
+ validateNanStatusProtoHistBucket("Bucket[INTERNAL_FAILURE]",
+ log.histogramSubscribeStatus[1],
+ WifiMetricsProto.WifiAwareLog.INTERNAL_FAILURE, 1);
+ validateNanStatusProtoHistBucket("Bucket[NO_RESOURCES_AVAILABLE]",
+ log.histogramSubscribeStatus[2],
+ WifiMetricsProto.WifiAwareLog.NO_RESOURCES_AVAILABLE, 1);
collector.checkThat("numAppsWithDiscoverySessionFailureOutOfResources",
log.numAppsWithDiscoverySessionFailureOutOfResources, equalTo(1));
validateProtoHistBucket("Publish Duration[0]", log.histogramPublishSessionDurationMs[0], 5,
@@ -510,8 +535,20 @@ public class WifiAwareMetricsTest {
collector.checkThat("maxConcurrentNdpPerNdi", log.maxConcurrentNdpPerNdi, equalTo(3));
collector.checkThat("histogramRequestNdpStatus.length",
log.histogramRequestNdpStatus.length, equalTo(3));
+ validateNanStatusProtoHistBucket("Bucket[SUCCESS]",
+ log.histogramRequestNdpStatus[0],
+ WifiMetricsProto.WifiAwareLog.SUCCESS, 3);
+ validateNanStatusProtoHistBucket("Bucket[INTERNAL_FAILURE]",
+ log.histogramRequestNdpStatus[1],
+ WifiMetricsProto.WifiAwareLog.INTERNAL_FAILURE, 2);
+ validateNanStatusProtoHistBucket("Bucket[UNKNOWN_HAL_STATUS]",
+ log.histogramRequestNdpStatus[2],
+ WifiMetricsProto.WifiAwareLog.NO_RESOURCES_AVAILABLE, 1);
collector.checkThat("histogramRequestNdpOobStatus.length",
log.histogramRequestNdpOobStatus.length, equalTo(1));
+ validateNanStatusProtoHistBucket("Bucket[SUCCESS]",
+ log.histogramRequestNdpOobStatus[0],
+ WifiMetricsProto.WifiAwareLog.SUCCESS, 2);
collector.checkThat("ndpCreationTimeMsMin", log.ndpCreationTimeMsMin, equalTo(1L));
collector.checkThat("ndpCreationTimeMsMax", log.ndpCreationTimeMsMax, equalTo(15L));
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 1be56cc9eb..0a30228cff 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
@@ -48,6 +48,8 @@ import android.util.Pair;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -64,7 +66,7 @@ import java.util.ArrayList;
* Unit test harness for WifiAwareNativeApi
*/
@SmallTest
-public class WifiAwareNativeApiTest {
+public class WifiAwareNativeApiTest extends WifiBaseTest {
@Mock WifiAwareNativeManager mWifiAwareNativeManagerMock;
@Mock IWifiNanIface mIWifiNanIfaceMock;
@Mock android.hardware.wifi.V1_2.IWifiNanIface mIWifiNanIface12Mock;
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 140e7e43c5..d97ae06044 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
@@ -18,6 +18,7 @@ package com.android.server.wifi.aware;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
@@ -34,6 +35,7 @@ import android.os.Handler;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.HalDeviceManager;
+import com.android.server.wifi.WifiBaseTest;
import org.junit.Before;
import org.junit.Rule;
@@ -48,7 +50,7 @@ import org.mockito.MockitoAnnotations;
* Unit test harness for WifiAwareNativeManager.
*/
@SmallTest
-public class WifiAwareNativeManagerTest {
+public class WifiAwareNativeManagerTest extends WifiBaseTest {
private WifiAwareNativeManager mDut;
@Mock private WifiAwareStateManager mWifiAwareStateManagerMock;
@Mock private HalDeviceManager mHalDeviceManager;
@@ -289,5 +291,9 @@ public class WifiAwareNativeManagerTest {
any());
mInOrder.verify(mIWifiNanIface12Mock).registerEventCallback_1_2(any());
assertEquals("Interface mismatch", mIWifiNanIface12Mock, mDut.getWifiNanIface());
+
+ // 3. receive Availability Change, has interface, should ignore
+ mAvailListenerCaptor.getValue().onAvailabilityChanged(false);
+ assertTrue("AwareNativeAvailable mismatch ", mDut.isAwareNativeAvailable());
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java
index 1204c4f815..95b7b0b14f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareServiceImplTest.java
@@ -51,6 +51,7 @@ import android.util.SparseIntArray;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.FrameworkFacade;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
@@ -71,7 +72,7 @@ import java.util.Map;
* Unit test harness for WifiAwareStateManager.
*/
@SmallTest
-public class WifiAwareServiceImplTest {
+public class WifiAwareServiceImplTest extends WifiBaseTest {
private static final int MAX_LENGTH = 255;
private WifiAwareServiceImplSpy mDut;
@@ -553,8 +554,8 @@ public class WifiAwareServiceImplTest {
mDut.sendMessage(clientId, sessionId, peerId, message, messageId, 0);
- verify(mAwareStateManagerMock).sendMessage(clientId, sessionId, peerId, message, messageId,
- 0);
+ verify(mAwareStateManagerMock).sendMessage(anyInt(), eq(clientId), eq(sessionId),
+ eq(peerId), eq(message), eq(messageId), eq(0));
}
/**
@@ -570,8 +571,8 @@ public class WifiAwareServiceImplTest {
mDut.sendMessage(clientId, sessionId, peerId, message, messageId, 0);
- verify(mAwareStateManagerMock).sendMessage(clientId, sessionId, peerId, message, messageId,
- 0);
+ verify(mAwareStateManagerMock).sendMessage(anyInt(), eq(clientId), eq(sessionId),
+ eq(peerId), eq(message), eq(messageId), eq(0));
}
@Test
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 d6b1b38d14..d5948282d5 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
@@ -74,6 +74,7 @@ import android.util.SparseArray;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.server.wifi.util.WifiPermissionsWrapper;
@@ -107,7 +108,7 @@ import java.util.Set;
* Unit test harness for WifiAwareStateManager.
*/
@SmallTest
-public class WifiAwareStateManagerTest {
+public class WifiAwareStateManagerTest extends WifiBaseTest {
private TestLooper mMockLooper;
private Random mRandomNg = new Random(15687);
private WifiAwareStateManager mDut;
@@ -165,6 +166,7 @@ public class WifiAwareStateManagerTest {
when(mMockPowerManager.isDeviceIdleMode()).thenReturn(false);
when(mMockPowerManager.isInteractive()).thenReturn(true);
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ when(mMockNativeManager.isAwareNativeAvailable()).thenReturn(true);
ArgumentCaptor<BroadcastReceiver> bcastRxCaptor = ArgumentCaptor.forClass(
BroadcastReceiver.class);
@@ -1437,8 +1439,8 @@ public class WifiAwareStateManagerTest {
peerMsg.getBytes());
// (4) message Tx successful queuing
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), ssi.getBytes(),
- messageId, 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ ssi.getBytes(), messageId, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
@@ -1447,8 +1449,8 @@ public class WifiAwareStateManagerTest {
mMockLooper.dispatchAll();
// (5) message Tx successful queuing
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), ssi.getBytes(),
- messageId2, 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ ssi.getBytes(), messageId2, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId2));
@@ -1547,7 +1549,7 @@ public class WifiAwareStateManagerTest {
int peerId2 = peerIdCaptor.getValue();
// (4) sending messages back to same peers: one Tx fails, other succeeds
- mDut.sendMessage(clientId, sessionId.getValue(), peerId2, msgToPeer2.getBytes(),
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerId2, msgToPeer2.getBytes(),
msgToPeerId2, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId),
@@ -1556,7 +1558,7 @@ public class WifiAwareStateManagerTest {
mDut.onMessageSendQueuedSuccessResponse(transactionIdVal);
mDut.onMessageSendSuccessNotification(transactionIdVal);
- mDut.sendMessage(clientId, sessionId.getValue(), peerId1, msgToPeer1.getBytes(),
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerId1, msgToPeer1.getBytes(),
msgToPeerId1, 0);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId2);
@@ -1641,8 +1643,8 @@ public class WifiAwareStateManagerTest {
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMessageReceived(peerId.capture(),
eq(msgFromPeer1.getBytes()));
- mDut.sendMessage(clientId, sessionId.getValue(), peerId.getValue(), msgToPeer1.getBytes(),
- msgToPeerId1, 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerId.getValue(),
+ msgToPeer1.getBytes(), msgToPeerId1, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId),
eq(requestorId), eq(peerMacOrig), eq(msgToPeer1.getBytes()),
@@ -1659,8 +1661,8 @@ public class WifiAwareStateManagerTest {
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMessageReceived(peerId.capture(),
eq(msgFromPeer2.getBytes()));
- mDut.sendMessage(clientId, sessionId.getValue(), peerId.getValue(), msgToPeer2.getBytes(),
- msgToPeerId2, 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerId.getValue(),
+ msgToPeer2.getBytes(), msgToPeerId2, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId),
eq(requestorId), eq(peerMacLater), eq(msgToPeer2.getBytes()),
@@ -1732,7 +1734,7 @@ public class WifiAwareStateManagerTest {
eq(peerMatchFilter.getBytes()));
// (3) send message to invalid peer ID
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue() + 5,
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue() + 5,
ssi.getBytes(), messageId, 0);
mMockLooper.dispatchAll();
inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
@@ -1801,8 +1803,8 @@ public class WifiAwareStateManagerTest {
eq(peerMatchFilter.getBytes()));
// (3) send 2 messages and enqueue successfully
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), ssi.getBytes(),
- messageId, 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ ssi.getBytes(), messageId, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
@@ -1810,8 +1812,8 @@ public class WifiAwareStateManagerTest {
mDut.onMessageSendQueuedSuccessResponse(transactionId1);
mMockLooper.dispatchAll();
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), ssi.getBytes(),
- messageId + 1, 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ ssi.getBytes(), messageId + 1, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId + 1));
@@ -1820,8 +1822,8 @@ public class WifiAwareStateManagerTest {
mMockLooper.dispatchAll();
// (4) send a message and get a queueing failure (not queue full)
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), ssi.getBytes(),
- messageId + 2, 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ ssi.getBytes(), messageId + 2, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId + 2));
@@ -1836,8 +1838,8 @@ public class WifiAwareStateManagerTest {
when(mMockNative.sendMessage(anyShort(), anyByte(), anyInt(), any(),
any(), anyInt())).thenReturn(false);
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), ssi.getBytes(),
- messageId + 3, 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ ssi.getBytes(), messageId + 3, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId + 3));
@@ -1927,8 +1929,8 @@ public class WifiAwareStateManagerTest {
eq(peerMatchFilter.getBytes()));
// (3) send message and enqueue successfully
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), ssi.getBytes(),
- messageId, retryCount);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ ssi.getBytes(), messageId, retryCount);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
@@ -2014,8 +2016,8 @@ public class WifiAwareStateManagerTest {
eq(peerMatchFilter.getBytes()));
// (3) send message and enqueue successfully
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), ssi.getBytes(),
- messageId, retryCount);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ ssi.getBytes(), messageId, retryCount);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(messageId));
@@ -2110,7 +2112,7 @@ public class WifiAwareStateManagerTest {
int remainingMessages = numberOfMessages;
for (int i = 0; i < numberOfMessages; ++i) {
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), null,
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(), null,
messageIdBase + i, 0);
mMockLooper.dispatchAll();
// at 1/2 interval have the system simulate transmitting a queued message over-the-air
@@ -2137,6 +2139,153 @@ public class WifiAwareStateManagerTest {
}
/**
+ * Validate that the message queue depth per process function. Tests the case
+ * with two processes both have message num larger than queue depth. And all messages get
+ * into the firmware queue are sent out and are received on first attempt.
+ */
+ @Test
+ public void testSendMessageQueueLimitBlock() throws Exception {
+ final int clientId1 = 1005;
+ final int clientId2 = 1006;
+ final int uid1 = 1000;
+ final int uid2 = 1500;
+ final int pid1 = 2000;
+ final int pid2 = 3000;
+ final String callingPackage1 = "com.google.somePackage1";
+ final String callingPackage2 = "com.google.somePackage2";
+ final String serviceName1 = "some-service-name1";
+ final String serviceName2 = "some-service-name2";
+ final byte subscribeId1 = 15;
+ final byte subscribeId2 = 16;
+ final int requestorId1 = 22;
+ final int requestorId2 = 23;
+ final byte[] peerMac1 = HexEncoding.decode("060708090A0B".toCharArray(), false);
+ final byte[] peerMac2 = HexEncoding.decode("060708090A0C".toCharArray(), false);
+ final int messageIdBase1 = 6948;
+ final int messageIdBase2 = 7948;
+ final int numberOfMessages = 70;
+ final int queueDepth = 6;
+ final int messageQueueDepthPerUid = 50;
+ final int numOfReject = numberOfMessages - messageQueueDepthPerUid;
+
+ ConfigRequest configRequest1 = new ConfigRequest.Builder().build();
+ SubscribeConfig subscribeConfig1 = new SubscribeConfig.Builder()
+ .setServiceName(serviceName1).build();
+ ConfigRequest configRequest2 = new ConfigRequest.Builder().build();
+ SubscribeConfig subscribeConfig2 = new SubscribeConfig.Builder()
+ .setServiceName(serviceName2).build();
+
+ IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
+ IWifiAwareDiscoverySessionCallback mockSessionCallback = mock(
+ IWifiAwareDiscoverySessionCallback.class);
+ ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+ ArgumentCaptor<Integer> sessionId1 = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Integer> sessionId2 = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Integer> messageIdCaptorFail = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Integer> messageIdCaptorSuccess = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Integer> peerIdCaptor1 = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Integer> peerIdCaptor2 = ArgumentCaptor.forClass(Integer.class);
+ InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
+
+ mDut.enableUsage();
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+ mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+ mMockLooper.dispatchAll();
+
+ // (0) connect
+ mDut.connect(clientId1, uid1, pid1, callingPackage1, mockCallback, configRequest1, false);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+ eq(configRequest1), eq(false), eq(true), eq(true), eq(false));
+ mDut.onConfigSuccessResponse(transactionId.getValue());
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockCallback).onConnectSuccess(clientId1);
+
+ mDut.connect(clientId2, uid2, pid2, callingPackage2, mockCallback, configRequest2, false);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockCallback).onConnectSuccess(clientId2);
+
+ // (1) subscribe
+ mDut.subscribe(clientId1, subscribeConfig1, mockSessionCallback);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq((byte) 0),
+ eq(subscribeConfig1));
+ mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId1);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockSessionCallback).onSessionStarted(sessionId1.capture());
+
+ mDut.subscribe(clientId2, subscribeConfig2, mockSessionCallback);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq((byte) 0),
+ eq(subscribeConfig2));
+ mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId2);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockSessionCallback).onSessionStarted(sessionId2.capture());
+
+ // (2) match
+ mDut.onMatchNotification(subscribeId1, requestorId1, peerMac1, null, null, 0, 0);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor1.capture(), isNull(), isNull());
+
+ mDut.onMatchNotification(subscribeId2, requestorId2, peerMac2, null, null, 0, 0);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockSessionCallback).onMatch(peerIdCaptor2.capture(), isNull(), isNull());
+
+ // (3) Enqueue messages
+ SendMessageQueueModelAnswer answerObj = new SendMessageQueueModelAnswer(queueDepth,
+ null, null, null);
+ when(mMockNative.sendMessage(anyShort(), anyByte(), anyInt(), any(),
+ any(), anyInt())).thenAnswer(answerObj);
+
+ for (int i = 0; i < numberOfMessages; ++i) {
+ mDut.sendMessage(uid1, clientId1, sessionId1.getValue(), peerIdCaptor1.getValue(), null,
+ messageIdBase1 + i, 0);
+ }
+ for (int i = 0; i < numberOfMessages; ++i) {
+ mDut.sendMessage(uid2, clientId2, sessionId2.getValue(), peerIdCaptor2.getValue(), null,
+ messageIdBase2 + i, 0);
+ }
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockSessionCallback, times(numOfReject * 2))
+ .onMessageSendFail(messageIdCaptorFail.capture(),
+ eq(NanStatusType.INTERNAL_FAILURE));
+
+ // (4) Transmit messages
+ int successNum = 0;
+ for (int i = 0; i < numberOfMessages * 2; ++i) {
+ if (answerObj.process()) {
+ successNum++;
+ } else {
+ break;
+ }
+ mMockLooper.dispatchAll();
+ }
+ assertEquals("queue empty", 0, answerObj.queueSize());
+ assertEquals("success message num", messageQueueDepthPerUid * 2, successNum);
+ inOrder.verify(mockSessionCallback, times(messageQueueDepthPerUid * 2))
+ .onMessageSendSuccess(messageIdCaptorSuccess.capture());
+
+ for (int i = 0; i < numOfReject; ++i) {
+ assertEquals("message ID: " + i + messageQueueDepthPerUid,
+ messageIdBase1 + i + messageQueueDepthPerUid,
+ (int) messageIdCaptorFail.getAllValues().get(i));
+ assertEquals("message ID: " + i + messageQueueDepthPerUid,
+ messageIdBase2 + i + messageQueueDepthPerUid,
+ (int) messageIdCaptorFail.getAllValues().get(i + numOfReject));
+ }
+
+ for (int i = 0; i < messageQueueDepthPerUid; ++i) {
+ assertEquals("message ID: " + i, messageIdBase1 + i,
+ (int) messageIdCaptorSuccess.getAllValues().get(i));
+ assertEquals("message ID: " + i, messageIdBase2 + i,
+ (int) messageIdCaptorSuccess.getAllValues().get(i + messageQueueDepthPerUid));
+ }
+
+ verifyNoMoreInteractions(mockCallback, mockSessionCallback);
+ }
+
+ /**
* Validate that the host-side message queue functions. A combination of imperfect conditions:
* - Failure to queue: synchronous firmware error
* - Failure to queue: asyncronous firmware error
@@ -2250,7 +2399,7 @@ public class WifiAwareStateManagerTest {
any(), anyInt())).thenAnswer(answerObj);
for (int i = 0; i < numberOfMessages; ++i) {
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), null,
+ mDut.sendMessage(uid + i, clientId, sessionId.getValue(), peerIdCaptor.getValue(), null,
messageIdBase + i, retransmitCount);
mMockLooper.dispatchAll();
}
@@ -2334,8 +2483,8 @@ public class WifiAwareStateManagerTest {
eq(peerMatchFilter.getBytes()));
// (3) message null Tx successful queuing
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), null, messageId,
- 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ null, messageId, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), isNull(byte[].class), eq(messageId));
@@ -2350,7 +2499,7 @@ public class WifiAwareStateManagerTest {
validateInternalSendMessageQueuesCleanedUp(messageId);
// (5) message byte[0] Tx successful queuing
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), new byte[0],
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(), new byte[0],
messageId, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
@@ -2366,8 +2515,8 @@ public class WifiAwareStateManagerTest {
validateInternalSendMessageQueuesCleanedUp(messageId);
// (7) message "" Tx successful queuing
- mDut.sendMessage(clientId, sessionId.getValue(), peerIdCaptor.getValue(), "".getBytes(),
- messageId, 0);
+ mDut.sendMessage(uid, clientId, sessionId.getValue(), peerIdCaptor.getValue(),
+ "".getBytes(), messageId, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
eq(requestorId), eq(peerMac), byteArrayCaptor.capture(), eq(messageId));
@@ -3126,6 +3275,7 @@ public class WifiAwareStateManagerTest {
inOrder.verify(mMockNativeManager).start(any(Handler.class));
mDut.enableUsage();
+ inOrder.verify(mMockNativeManager).isAwareNativeAvailable();
mMockLooper.dispatchAll();
inOrder.verify(mMockNativeManager).tryToGetAware();
inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
@@ -3165,8 +3315,16 @@ public class WifiAwareStateManagerTest {
simulateWifiStateChange(true);
mMockLooper.dispatchAll();
+ // when WifiAware Native is not available, DOZE OFF -> no change
+ when(mMockNativeManager.isAwareNativeAvailable()).thenReturn(false);
+ simulatePowerStateChangeDoze(false);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNativeManager).isAwareNativeAvailable();
+ when(mMockNativeManager.isAwareNativeAvailable()).thenReturn(true);
+
// (5) power state change: DOZE OFF
simulatePowerStateChangeDoze(false);
+ inOrder.verify(mMockNativeManager).isAwareNativeAvailable();
mMockLooper.dispatchAll();
collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
validateCorrectAwareStatusChangeBroadcast(inOrder);
@@ -3192,6 +3350,7 @@ public class WifiAwareStateManagerTest {
inOrder.verify(mMockNativeManager).start(any(Handler.class));
mDut.enableUsage();
+ inOrder.verify(mMockNativeManager).isAwareNativeAvailable();
mMockLooper.dispatchAll();
inOrder.verify(mMockNativeManager).tryToGetAware();
inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
@@ -3227,8 +3386,16 @@ public class WifiAwareStateManagerTest {
simulateWifiStateChange(true);
mMockLooper.dispatchAll();
+ // when WifiAware Native is not available, enable location -> no change
+ when(mMockNativeManager.isAwareNativeAvailable()).thenReturn(false);
+ simulateLocationModeChange(true);
+ inOrder.verify(mMockNativeManager).isAwareNativeAvailable();
+ mMockLooper.dispatchAll();
+ when(mMockNativeManager.isAwareNativeAvailable()).thenReturn(true);
+
// (4) location mode change: enable
simulateLocationModeChange(true);
+ inOrder.verify(mMockNativeManager).isAwareNativeAvailable();
mMockLooper.dispatchAll();
collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
validateCorrectAwareStatusChangeBroadcast(inOrder);
@@ -3254,6 +3421,7 @@ public class WifiAwareStateManagerTest {
inOrder.verify(mMockNativeManager).start(any(Handler.class));
mDut.enableUsage();
+ inOrder.verify(mMockNativeManager).isAwareNativeAvailable();
mMockLooper.dispatchAll();
inOrder.verify(mMockNativeManager).tryToGetAware();
inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
@@ -3289,8 +3457,16 @@ public class WifiAwareStateManagerTest {
simulateLocationModeChange(true);
mMockLooper.dispatchAll();
+ // when WifiAware Native is not available, enable Wifi -> no change
+ when(mMockNativeManager.isAwareNativeAvailable()).thenReturn(false);
+ simulateWifiStateChange(true);
+ inOrder.verify(mMockNativeManager).isAwareNativeAvailable();
+ mMockLooper.dispatchAll();
+ when(mMockNativeManager.isAwareNativeAvailable()).thenReturn(true);
+
// (4) wifi state change: enable
simulateWifiStateChange(true);
+ inOrder.verify(mMockNativeManager).isAwareNativeAvailable();
mMockLooper.dispatchAll();
collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
validateCorrectAwareStatusChangeBroadcast(inOrder);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPDataTest.java
index addb9b5b5b..a467f822f8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPDataTest.java
@@ -24,6 +24,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
import com.android.server.wifi.hotspot2.anqp.Constants;
@@ -40,7 +41,7 @@ import java.util.Map;
* allow easy construction of ANQP elements for testing.
*/
@SmallTest
-public class ANQPDataTest {
+public class ANQPDataTest extends WifiBaseTest {
@Mock Clock mClock;
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java
index 4d4ea44873..5e2f3e1efb 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java
@@ -25,6 +25,7 @@ import android.net.wifi.EAPConstants;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.IMSIParameter;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.anqp.CellularNetwork;
import com.android.server.wifi.hotspot2.anqp.DomainNameElement;
import com.android.server.wifi.hotspot2.anqp.NAIRealmData;
@@ -50,7 +51,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.hotspot2.ANQPMatcher}.
*/
@SmallTest
-public class ANQPMatcherTest {
+public class ANQPMatcherTest extends WifiBaseTest {
private static final String TEST_MCC_MNC = "123456";
private static final String TEST_3GPP_FQDN = String.format("wlan.mnc%s.mcc%s.3gppnetwork.org",
TEST_MCC_MNC.substring(3), TEST_MCC_MNC.substring(0, 3));
@@ -458,4 +459,19 @@ public class ANQPMatcherTest {
assertEquals(-1,
ANQPMatcher.getCarrierEapMethodFromMatchingNAIRealm(TEST_3GPP_FQDN, element));
}
+
+ /**
+ * Verify that domain name match will fail when domain contains invalid values.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyInvalidDomain() throws Exception {
+ IMSIParameter imsiParam = new IMSIParameter("1234", true);
+ List<String> simImsiList = Arrays.asList(new String[] {"123457890", "123498723"});
+ // 3GPP network domain with MCC=123 and MNC=456.
+ String[] domains = new String[] {"wlan.mnc457.mccI23.3gppnetwork.org"};
+ DomainNameElement element = new DomainNameElement(Arrays.asList(domains));
+ assertFalse(ANQPMatcher.matchDomainName(element, null, imsiParam, simImsiList));
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPNetworkKeyTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPNetworkKeyTest.java
index 74a884d7be..fb74940458 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPNetworkKeyTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPNetworkKeyTest.java
@@ -20,13 +20,15 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
/**
* Unit tests for {@link com.android.server.wifi.hotspot2.ANQPNetworkKey}.
*/
@SmallTest
-public class ANQPNetworkKeyTest {
+public class ANQPNetworkKeyTest extends WifiBaseTest {
private static final String SSID = "TestSSID";
private static final long BSSID = 0x123456L;
private static final long HESSID = 0x789012L;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java
index b252f817e0..bc9d02d31f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPRequestManagerTest.java
@@ -30,6 +30,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.anqp.Constants;
import org.junit.Before;
@@ -43,7 +44,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.hotspot2.ANQPRequestManager}.
*/
@SmallTest
-public class ANQPRequestManagerTest {
+public class ANQPRequestManagerTest extends WifiBaseTest {
private static final long TEST_BSSID = 0x123456L;
private static final ANQPNetworkKey TEST_ANQP_KEY =
new ANQPNetworkKey("TestSSID", TEST_BSSID, 0, 0);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/AnqpCacheTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/AnqpCacheTest.java
index 3084e064a2..1e3fdae393 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/AnqpCacheTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/AnqpCacheTest.java
@@ -25,6 +25,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.ANQPData;
import com.android.server.wifi.hotspot2.AnqpCache;
@@ -39,7 +40,7 @@ import org.mockito.Mock;
* allow easy construction of ANQP elements for testing.
*/
@SmallTest
-public class AnqpCacheTest {
+public class AnqpCacheTest extends WifiBaseTest {
private static final ANQPNetworkKey ENTRY_KEY = new ANQPNetworkKey("test", 0L, 0L, 1);
@Mock Clock mClock;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/DomainMatcherTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/DomainMatcherTest.java
index 1671507bf4..d0e41d250d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/DomainMatcherTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/DomainMatcherTest.java
@@ -24,6 +24,8 @@ import android.util.Pair;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.util.Arrays;
@@ -34,7 +36,7 @@ import java.util.Map;
* Unit tests for {@link com.android.server.wifi.hotspot2.DomainMatcher}.
*/
@SmallTest
-public class DomainMatcherTest {
+public class DomainMatcherTest extends WifiBaseTest {
private static final String PRIMARY_DOMAIN = "google.com";
private static final String SECONDARY_DOMAIN1 = "android.com";
private static final String SECONDARY_DOMAIN2 = "testing.test.com";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuNetworkConnectionTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuNetworkConnectionTest.java
index acfb4b47e7..8f3daa2432 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuNetworkConnectionTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuNetworkConnectionTest.java
@@ -39,6 +39,7 @@ import android.net.NetworkRequest;
import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
@@ -48,6 +49,7 @@ import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.TestUtil;
+import com.android.server.wifi.WifiBaseTest;
import org.junit.Before;
import org.junit.Test;
@@ -61,7 +63,7 @@ import java.net.InetAddress;
* Unit tests for {@link OsuNetworkConnection}.
*/
@SmallTest
-public class OsuNetworkConnectionTest {
+public class OsuNetworkConnectionTest extends WifiBaseTest {
private static final String TAG = "OsuNetworkConnectionTest";
private static final int ENABLE_LOGGING = 1;
private static final int DISABLE_LOGGING = 0;
@@ -169,16 +171,6 @@ public class OsuNetworkConnectionTest {
}
/**
- * Verifies that connect() API returns false when OSU AP is a part of an OSEN
- */
- @Test
- public void verifyOSENUnsupported() {
- mNetworkConnection.init(mHandler);
- assertEquals(false,
- mNetworkConnection.connect(TEST_SSID, TEST_NAI_OSEN, TEST_PROVIDER_NAME));
- }
-
- /**
* Verifies that connect() API returns false when WifiManager's addNetwork()
* returns an invalid network ID
*/
@@ -327,4 +319,37 @@ public class OsuNetworkConnectionTest {
assertFalse(networkRequestCaptor.getValue().hasCapability(NET_CAPABILITY_TRUSTED));
}
+
+ /**
+ * Verifies that {@link WifiConfiguration} has been created properly for OSEN OSU network.
+ * It is supposed to create a network as ephemeral network with OSEN protocol and key management
+ * and suppress no internet access notification.
+ */
+ @Test
+ public void verifyWifiConfigurationForOsenOsuNetwork() {
+ mNetworkConnection.init(mHandler);
+
+ assertEquals(true, mNetworkConnection.connect(TEST_SSID, TEST_NAI_OSEN,
+ TEST_PROVIDER_NAME));
+
+ ArgumentCaptor<WifiConfiguration> wifiConfigurationCaptor = ArgumentCaptor.forClass(
+ WifiConfiguration.class);
+ verify(mWifiManager, times(1)).addNetwork(wifiConfigurationCaptor.capture());
+ WifiConfiguration wifiConfiguration = wifiConfigurationCaptor.getValue();
+ assertTrue(wifiConfiguration.isNoInternetAccessExpected());
+ assertTrue(wifiConfiguration.isEphemeral());
+ assertTrue(wifiConfiguration.osu);
+ assertTrue(wifiConfiguration.allowedProtocols.get(WifiConfiguration.Protocol.OSEN));
+ assertTrue(wifiConfiguration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OSEN));
+ assertEquals(wifiConfiguration.enterpriseConfig.getEapMethod(),
+ WifiEnterpriseConfig.Eap.UNAUTH_TLS);
+ assertEquals(wifiConfiguration.enterpriseConfig.getCaPath(),
+ WfaKeyStore.DEFAULT_WFA_CERT_DIR);
+ ArgumentCaptor<NetworkRequest> networkRequestCaptor = ArgumentCaptor.forClass(
+ NetworkRequest.class);
+ verify(mConnectivityManager, times(1)).requestNetwork(networkRequestCaptor.capture(),
+ any(ConnectivityManager.NetworkCallback.class), any(Handler.class), anyInt());
+ assertFalse(networkRequestCaptor.getValue().hasCapability(NET_CAPABILITY_TRUSTED));
+
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuServerConnectionTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuServerConnectionTest.java
index 9fa92c9a30..fbb653bc01 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuServerConnectionTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/OsuServerConnectionTest.java
@@ -37,6 +37,7 @@ import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.org.conscrypt.TrustManagerImpl;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.soap.HttpsServiceConnection;
import com.android.server.wifi.hotspot2.soap.HttpsTransport;
import com.android.server.wifi.hotspot2.soap.SoapParser;
@@ -80,7 +81,7 @@ import javax.net.ssl.X509TrustManager;
* Unit tests for {@link OsuServerConnection}.
*/
@SmallTest
-public class OsuServerConnectionTest {
+public class OsuServerConnectionTest extends WifiBaseTest {
private static final String TEST_VALID_URL = "https://www.google.com";
private static final String TEST_INVALID_URL = "http://www.google.com";
private static final String AUTH_TYPE = "ECDHE_RSA";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java
index c76e2c878c..95251a70d8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java
@@ -24,6 +24,7 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiConfigStore;
import org.junit.Before;
@@ -41,7 +42,7 @@ import java.nio.charset.StandardCharsets;
* Unit tests for {@link com.android.server.wifi.hotspot2.PasspointConfigSharedStoreData}.
*/
@SmallTest
-public class PasspointConfigSharedStoreDataTest {
+public class PasspointConfigSharedStoreDataTest extends WifiBaseTest {
@Mock PasspointConfigSharedStoreData.DataSource mDataSource;
PasspointConfigSharedStoreData mConfigStoreData;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
index 82cdb5a905..54a74978db 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
@@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.wifi.SIMAccessor;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiConfigStore;
import com.android.server.wifi.WifiKeyStore;
@@ -56,7 +57,7 @@ import java.util.Map;
* Unit tests for {@link com.android.server.wifi.hotspot2.PasspointConfigUserStoreData}.
*/
@SmallTest
-public class PasspointConfigUserStoreDataTest {
+public class PasspointConfigUserStoreDataTest extends WifiBaseTest {
private static final String TEST_CA_CERTIFICATE_ALIAS = "CaCert";
private static final String TEST_CA_CERTIFICATE_ALIAS_2 = "CaCert_2";
private static final String TEST_CLIENT_CERTIFICATE_ALIAS = "ClientCert";
@@ -243,11 +244,11 @@ public class PasspointConfigUserStoreDataTest {
List<PasspointProvider> providerList = new ArrayList<>();
providerList.add(new PasspointProvider(createFullPasspointConfiguration(),
mKeyStore, mSimAccessor, TEST_PROVIDER_ID, TEST_CREATOR_UID, TEST_CREATOR_PACKAGE,
- Arrays.asList(TEST_CA_CERTIFICATE_ALIAS), TEST_CLIENT_CERTIFICATE_ALIAS,
+ false, Arrays.asList(TEST_CA_CERTIFICATE_ALIAS), TEST_CLIENT_CERTIFICATE_ALIAS,
TEST_CLIENT_PRIVATE_KEY_ALIAS, null, TEST_HAS_EVER_CONNECTED, TEST_SHARED));
providerList.add(new PasspointProvider(createFullPasspointConfiguration(),
mKeyStore, mSimAccessor, TEST_PROVIDER_ID_2, TEST_CREATOR_UID, TEST_CREATOR_PACKAGE,
- Arrays.asList(TEST_CA_CERTIFICATE_ALIAS, TEST_CA_CERTIFICATE_ALIAS_2),
+ true, Arrays.asList(TEST_CA_CERTIFICATE_ALIAS, TEST_CA_CERTIFICATE_ALIAS_2),
TEST_CLIENT_CERTIFICATE_ALIAS,
TEST_CLIENT_PRIVATE_KEY_ALIAS, TEST_REMEDIATION_CA_CERTIFICATE_ALIAS,
TEST_HAS_EVER_CONNECTED, TEST_SHARED));
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointEventHandlerTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointEventHandlerTest.java
index d958f5a8c8..c21697e696 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointEventHandlerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointEventHandlerTest.java
@@ -26,6 +26,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.hotspot2.anqp.Constants;
@@ -42,7 +43,7 @@ import java.util.List;
* TODO(zqiu): add more test when switch over to use wificond.
*/
@SmallTest
-public class PasspointEventHandlerTest {
+public class PasspointEventHandlerTest extends WifiBaseTest {
private static final String TAG = "PasspointEventHandlerTest";
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 131425af88..41cf336512 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
@@ -48,6 +48,7 @@ import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
@@ -72,6 +73,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.os.test.TestLooper;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Base64;
@@ -86,6 +88,7 @@ import com.android.server.wifi.FakeKeys;
import com.android.server.wifi.IMSIParameter;
import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.ScanDetail;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiConfigManager;
import com.android.server.wifi.WifiConfigStore;
import com.android.server.wifi.WifiConfigurationTestUtil;
@@ -93,6 +96,7 @@ import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiKeyStore;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.WifiNetworkSuggestionsManager;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType;
import com.android.server.wifi.hotspot2.anqp.DomainNameElement;
@@ -117,6 +121,7 @@ import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -128,9 +133,10 @@ import java.util.Set;
* Unit tests for {@link PasspointManager}.
*/
@SmallTest
-public class PasspointManagerTest {
+public class PasspointManagerTest extends WifiBaseTest {
private static final long BSSID = 0x112233445566L;
private static final String TEST_PACKAGE = "com.android.test";
+ private static final String TEST_PACKAGE1 = "com.android.test1";
private static final String ICON_FILENAME = "test";
private static final String TEST_FQDN = "test1.test.com";
private static final String TEST_FQDN2 = "test2.test.com";
@@ -159,6 +165,7 @@ public class PasspointManagerTest {
private static final ANQPNetworkKey TEST_ANQP_KEY2 = ANQPNetworkKey.buildKey(
TEST_SSID, TEST_BSSID, TEST_HESSID, TEST_ANQP_DOMAIN_ID2);
private static final int TEST_CREATOR_UID = 1234;
+ private static final int TEST_CREATOR_UID1 = 1235;
private static final int TEST_UID = 1500;
@Mock Context mContext;
@@ -188,6 +195,7 @@ public class PasspointManagerTest {
@Mock TelephonyManager mTelephonyManager;
@Mock TelephonyManager mDataTelephonyManager;
@Mock SubscriptionManager mSubscriptionManager;
+ @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
Handler mHandler;
TestLooper mLooper;
@@ -214,6 +222,8 @@ public class PasspointManagerTest {
.thenReturn(mPasspointProvisioner);
when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl);
+ when(mWifiInjector.getWifiNetworkSuggestionsManager())
+ .thenReturn(mWifiNetworkSuggestionsManager);
mLooper = new TestLooper();
mHandler = new Handler(mLooper.getLooper());
mManager = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative,
@@ -234,7 +244,8 @@ public class PasspointManagerTest {
mSharedDataSource = sharedDataSource.getValue();
mUserDataSource = userDataSource.getValue();
// SIM is absent
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[0]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Collections.emptyList());
}
/**
@@ -274,16 +285,24 @@ public class PasspointManagerTest {
assertEquals(expectedConfig, installedConfigs.get(0));
}
+ private PasspointProvider createMockProvider(PasspointConfiguration config) {
+ WifiConfiguration wifiConfig = new WifiConfiguration();
+ wifiConfig.FQDN = config.getHomeSp().getFqdn();
+ return createMockProvider(config, wifiConfig);
+ }
+
/**
* Create a mock PasspointProvider with default expectations.
*
* @param config The configuration associated with the provider
* @return {@link com.android.server.wifi.hotspot2.PasspointProvider}
*/
- private PasspointProvider createMockProvider(PasspointConfiguration config) {
+ private PasspointProvider createMockProvider(
+ PasspointConfiguration config, WifiConfiguration wifiConfig) {
PasspointProvider provider = mock(PasspointProvider.class);
when(provider.installCertsAndKeys()).thenReturn(true);
lenient().when(provider.getConfig()).thenReturn(config);
+ lenient().when(provider.getWifiConfig()).thenReturn(wifiConfig);
lenient().when(provider.getCreatorUid()).thenReturn(TEST_CREATOR_UID);
return provider;
}
@@ -340,6 +359,13 @@ public class PasspointManagerTest {
return config;
}
+ private PasspointProvider addTestProvider(String fqdn, String friendlyName,
+ String packageName) {
+ WifiConfiguration wifiConfig = new WifiConfiguration();
+ wifiConfig.FQDN = fqdn;
+ return addTestProvider(fqdn, friendlyName, packageName, wifiConfig);
+ }
+
/**
* Helper function for adding a test provider to the manager. Return the mock
* provider that's added to the manager.
@@ -347,14 +373,14 @@ public class PasspointManagerTest {
* @return {@link PasspointProvider}
*/
private PasspointProvider addTestProvider(String fqdn, String friendlyName,
- String packageName) {
+ String packageName, WifiConfiguration wifiConfig) {
PasspointConfiguration config = createTestConfigWithUserCredential(fqdn, friendlyName);
- PasspointProvider provider = createMockProvider(config);
+ PasspointProvider provider = createMockProvider(config, wifiConfig);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn(
- provider);
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(provider);
when(provider.getPackageName()).thenReturn(packageName);
- assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
return provider;
}
@@ -368,10 +394,10 @@ public class PasspointManagerTest {
PasspointConfiguration config = createTestConfigWithSimCredential(fqdn, imsi, realm);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn(
- provider);
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(provider);
- assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
return provider;
}
@@ -587,7 +613,7 @@ public class PasspointManagerTest {
*/
@Test
public void addProviderWithNullConfig() throws Exception {
- assertFalse(mManager.addOrUpdateProvider(null, TEST_CREATOR_UID, TEST_PACKAGE));
+ assertFalse(mManager.addOrUpdateProvider(null, TEST_CREATOR_UID, TEST_PACKAGE, false));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
}
@@ -600,7 +626,7 @@ public class PasspointManagerTest {
@Test
public void addProviderWithEmptyConfig() throws Exception {
assertFalse(mManager.addOrUpdateProvider(new PasspointConfiguration(), TEST_CREATOR_UID,
- TEST_PACKAGE));
+ TEST_PACKAGE, false));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
}
@@ -617,32 +643,32 @@ public class PasspointManagerTest {
TEST_FRIENDLY_NAME);
// EAP-TLS not allowed for user credential.
config.getCredential().getUserCredential().setEapType(EAPConstants.EAP_TLS);
- assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
}
/**
- * Verify that adding a provider with a valid configuration and user credential will succeed.
+ * Verify that adding a user saved provider with a valid configuration and user credential will
+ * succeed.
*
* @throws Exception
*/
@Test
- public void addRemoveProviderWithValidUserCredential() throws Exception {
+ public void addRemoveSavedProviderWithValidUserCredential() throws Exception {
PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
TEST_FRIENDLY_NAME);
PasspointProvider provider = createMockProvider(config);
when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn(
- provider);
- assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(provider);
+ assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(config);
- verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
- verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE), any(
- AppOpsManager.OnOpChangedListener.class));
+ verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE),
+ any(AppOpsManager.OnOpChangedListener.class));
reset(mWifiMetrics);
reset(mWifiConfigManager);
@@ -656,6 +682,8 @@ public class PasspointManagerTest {
// Remove the provider as the creator app.
assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, TEST_FQDN));
verify(provider).uninstallCertsAndKeys();
+ verify(mWifiConfigManager).removePasspointConfiguredNetwork(
+ provider.getWifiConfig().configKey());
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
@@ -669,19 +697,20 @@ public class PasspointManagerTest {
}
/**
- * Verify that adding a provider with a valid configuration and SIM credential will succeed.
+ * Verify that adding a user saved provider with a valid configuration and SIM credential will
+ * succeed.
*
* @throws Exception
*/
@Test
- public void addRemoveProviderWithValidSimCredential() throws Exception {
+ public void addRemoveSavedProviderWithValidSimCredential() throws Exception {
PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
TEST_REALM);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn(
- provider);
- assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(provider);
+ assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(config);
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
@@ -699,6 +728,8 @@ public class PasspointManagerTest {
// Remove the provider as a privileged non-creator app.
assertTrue(mManager.removeProvider(TEST_UID, true, TEST_FQDN));
verify(provider).uninstallCertsAndKeys();
+ verify(mWifiConfigManager).removePasspointConfiguredNetwork(
+ provider.getWifiConfig().configKey());
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
@@ -711,22 +742,22 @@ public class PasspointManagerTest {
}
/**
- * Verify that adding a provider with the same base domain as the existing provider will
- * succeed, and verify that the existing provider is replaced by the new provider with
+ * Verify that adding a user saved provider with the same base domain as the existing provider
+ * will succeed, and verify that the existing provider is replaced by the new provider with
* the new configuration.
*
* @throws Exception
*/
@Test
- public void addProviderWithExistingConfig() throws Exception {
+ public void addSavedProviderWithExistingConfig() throws Exception {
// Add a provider with the original configuration.
PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
TEST_REALM);
PasspointProvider origProvider = createMockProvider(origConfig);
when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn(
- origProvider);
- assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE));
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(origProvider);
+ assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(origConfig);
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
@@ -746,10 +777,12 @@ public class PasspointManagerTest {
TEST_FRIENDLY_NAME);
PasspointProvider newProvider = createMockProvider(newConfig);
when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn(
- newProvider);
- assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE));
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(newProvider);
+ assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(newConfig);
+ verify(mWifiConfigManager).removePasspointConfiguredNetwork(
+ newProvider.getWifiConfig().configKey());
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
@@ -774,9 +807,9 @@ public class PasspointManagerTest {
PasspointProvider provider = mock(PasspointProvider.class);
when(provider.installCertsAndKeys()).thenReturn(false);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn(
- provider);
- assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), eq(false)))
+ .thenReturn(provider);
+ assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
}
@@ -792,7 +825,7 @@ public class PasspointManagerTest {
TEST_FRIENDLY_NAME);
doThrow(new GeneralSecurityException())
.when(mCertVerifier).verifyCaCert(any(X509Certificate.class));
- assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
}
@@ -810,9 +843,9 @@ public class PasspointManagerTest {
config.setUpdateIdentifier(1);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn(
- provider);
- assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(provider);
+ assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verify(mCertVerifier, never()).verifyCaCert(any(X509Certificate.class));
verifyInstalledConfig(config);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
@@ -963,15 +996,11 @@ public class PasspointManagerTest {
try {
PasspointProvider providerHome = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME,
TEST_PACKAGE);
- WifiConfiguration homeWifiConfiguration = new WifiConfiguration();
- homeWifiConfiguration.FQDN = TEST_FQDN + 0;
- homeWifiConfiguration.isHomeProviderNetwork = true;
+ providerHome.getWifiConfig().isHomeProviderNetwork = true;
PasspointProvider providerRoaming = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME,
TEST_PACKAGE);
- WifiConfiguration roamingWifiConfiguration = new WifiConfiguration();
- roamingWifiConfiguration.FQDN = TEST_FQDN + 1;
PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
- TEST_PACKAGE);
+ TEST_PACKAGE, new WifiConfiguration());
ANQPData entry = new ANQPData(mClock, null);
InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2;
@@ -985,10 +1014,6 @@ public class PasspointManagerTest {
when(providerNone.match(anyMap(), isNull()))
.thenReturn(PasspointMatch.None);
- lenient().when(providerHome.getWifiConfig()).thenReturn(homeWifiConfiguration);
- lenient().when(providerRoaming.getWifiConfig()).thenReturn(roamingWifiConfiguration);
- lenient().when(providerNone.getWifiConfig()).thenReturn(new WifiConfiguration());
-
Map<String, Map<Integer, List<ScanResult>>> configs =
mManager.getAllMatchingFqdnsForScanResults(
createTestScanResults());
@@ -1016,19 +1041,10 @@ public class PasspointManagerTest {
@Test
public void getWifiConfigsForPasspointProfiles() {
PasspointProvider provider1 = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME, TEST_PACKAGE);
- WifiConfiguration wifiConfiguration1 = new WifiConfiguration();
- wifiConfiguration1.FQDN = TEST_FQDN;
PasspointProvider provider2 = addTestProvider(TEST_FQDN + 1, TEST_FRIENDLY_NAME,
TEST_PACKAGE);
- WifiConfiguration wifiConfiguration2 = new WifiConfiguration();
- wifiConfiguration2.FQDN = TEST_FQDN + 1;
PasspointProvider provider3 = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
TEST_PACKAGE);
- WifiConfiguration wifiConfiguration3 = new WifiConfiguration();
- wifiConfiguration3.FQDN = TEST_FQDN + 2;
- lenient().when(provider1.getWifiConfig()).thenReturn(wifiConfiguration1);
- lenient().when(provider2.getWifiConfig()).thenReturn(wifiConfiguration2);
- lenient().when(provider3.getWifiConfig()).thenReturn(wifiConfiguration3);
assertEquals(3, mManager.getWifiConfigsForPasspointProfiles(
Arrays.asList(TEST_FQDN, TEST_FQDN + 1, TEST_FQDN + 2)).size());
@@ -1310,11 +1326,10 @@ public class PasspointManagerTest {
// Verify the provider ID used to create the new provider.
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
eq(mSimAccessor), eq(providerIndex), eq(TEST_CREATOR_UID),
- eq(TEST_PACKAGE))).thenReturn(provider);
+ eq(TEST_PACKAGE), eq(false))).thenReturn(provider);
- assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(config);
- verify(mWifiConfigManager).saveToStore(true);
reset(mWifiConfigManager);
}
@@ -1669,11 +1684,12 @@ public class PasspointManagerTest {
@Test
public void verifyInstallEphemeralPasspointConfigurationWithNonCarrierEapMethod() {
// SIM is present
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(mock(SubscriptionInfo.class)));
PasspointConfiguration config = createTestConfigWithUserCredential("abc.com", "test");
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), anyInt(), isNull())).thenReturn(provider);
+ eq(mSimAccessor), anyLong(), anyInt(), isNull(), eq(false))).thenReturn(provider);
assertFalse(mManager.installEphemeralPasspointConfigForCarrier(config));
}
@@ -1684,12 +1700,13 @@ public class PasspointManagerTest {
@Test
public void verifyInstallEphemeralPasspointConfiguration() {
// SIM is present
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(mock(SubscriptionInfo.class)));
PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
TEST_REALM);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), anyInt(), isNull())).thenReturn(provider);
+ eq(mSimAccessor), anyLong(), anyInt(), isNull(), eq(false))).thenReturn(provider);
assertTrue(mManager.installEphemeralPasspointConfigForCarrier(config));
verify(mAppOpsManager, never()).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE),
@@ -1730,7 +1747,8 @@ public class PasspointManagerTest {
.thenReturn(mDataTelephonyManager);
when(mDataTelephonyManager.getSimOperator()).thenReturn(TEST_MCC_MNC);
// SIM is present
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(mock(SubscriptionInfo.class)));
List<ScanDetail> scanDetails = new ArrayList<>();
scanDetails.add(generateScanDetail(TEST_SSID, TEST_BSSID_STRING, TEST_HESSID,
TEST_ANQP_DOMAIN_ID, true));
@@ -1774,7 +1792,8 @@ public class PasspointManagerTest {
.thenReturn(mDataTelephonyManager);
when(mDataTelephonyManager.getSimOperator()).thenReturn(TEST_MCC_MNC);
// SIM is present
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(mock(SubscriptionInfo.class)));
List<ScanDetail> scanDetails = new ArrayList<>();
scanDetails.add(generateScanDetail(TEST_SSID, TEST_BSSID_STRING, 0, 0, false));
@@ -1830,9 +1849,9 @@ public class PasspointManagerTest {
TEST_REALM);
PasspointProvider provider = createMockProvider(config);
when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
- eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn(
- provider);
- assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE));
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(provider);
+ assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, false));
verifyInstalledConfig(config);
verify(mWifiConfigManager).saveToStore(true);
verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
@@ -1857,4 +1876,440 @@ public class PasspointManagerTest {
// 1 profile available for TEST_CREATOR_UID
assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
}
+
+ /**
+ * Verify that adding a suggestion provider with a valid configuration and user credential will
+ * succeed.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void addRemoveSuggestionProvider() throws Exception {
+ PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN,
+ TEST_FRIENDLY_NAME);
+ PasspointProvider provider = createMockProvider(config);
+ when(provider.getPackageName()).thenReturn(TEST_PACKAGE);
+ when(provider.isFromSuggestion()).thenReturn(true);
+ when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore),
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(true))).thenReturn(provider);
+ assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, true));
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
+ verify(mAppOpsManager, never()).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE),
+ eq(TEST_PACKAGE), any(AppOpsManager.OnOpChangedListener.class));
+ assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty());
+ reset(mWifiMetrics);
+ reset(mWifiConfigManager);
+
+ // Verify content in the data source.
+ List<PasspointProvider> providers = mUserDataSource.getProviders();
+ assertEquals(1, providers.size());
+ assertEquals(config, providers.get(0).getConfig());
+ // Provider index start with 0, should be 1 after adding a provider.
+ assertEquals(1, mSharedDataSource.getProviderIndex());
+
+ // Remove from another Suggestor app, should fail.
+ assertFalse(mManager.removeProvider(TEST_UID, false, TEST_FQDN));
+ verify(provider, never()).uninstallCertsAndKeys();
+ verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
+ provider.getWifiConfig().configKey());
+ verify(mWifiConfigManager, never()).saveToStore(true);
+ verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
+ verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess();
+ verify(mAppOpsManager, never()).stopWatchingMode(
+ any(AppOpsManager.OnOpChangedListener.class));
+ // Verify content in the data source.
+ providers = mUserDataSource.getProviders();
+ assertEquals(1, providers.size());
+ assertEquals(config, providers.get(0).getConfig());
+ // Provider index start with 0, should be 1 after adding a provider.
+ assertEquals(1, mSharedDataSource.getProviderIndex());
+ reset(mWifiMetrics);
+ reset(mWifiConfigManager);
+
+ // Remove the provider from same app.
+ assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, TEST_FQDN));
+ verify(provider).uninstallCertsAndKeys();
+ verify(mWifiConfigManager).removePasspointConfiguredNetwork(
+ provider.getWifiConfig().configKey());
+ verify(mWifiConfigManager).saveToStore(true);
+ verify(mWifiMetrics).incrementNumPasspointProviderUninstallation();
+ verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess();
+ verify(mAppOpsManager, never()).stopWatchingMode(
+ any(AppOpsManager.OnOpChangedListener.class));
+
+ // Verify content in the data source.
+ assertTrue(mUserDataSource.getProviders().isEmpty());
+ // Removing a provider should not change the provider index.
+ assertEquals(1, mSharedDataSource.getProviderIndex());
+ }
+
+ /**
+ * Verify that adding a suggestion provider with the same base domain as the existing
+ * suggestion provider from same app will succeed, and verify that the existing provider is
+ * replaced by the new provider with the new configuration.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void addSuggestionProviderWithExistingConfig() throws Exception {
+ // Add a provider with the original configuration.
+ PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
+ TEST_REALM);
+ PasspointProvider origProvider = createMockProvider(origConfig);
+ when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
+ when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(true))).thenReturn(origProvider);
+ assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, true));
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
+ reset(mWifiMetrics);
+ reset(mWifiConfigManager);
+
+ // Verify data source content.
+ List<PasspointProvider> origProviders = mUserDataSource.getProviders();
+ assertEquals(1, origProviders.size());
+ assertEquals(origConfig, origProviders.get(0).getConfig());
+ assertEquals(1, mSharedDataSource.getProviderIndex());
+
+ // Add same provider as existing suggestion provider
+ // This should be no WifiConfig deletion
+ assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, true));
+ verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
+ origProvider.getWifiConfig().configKey());
+ verify(mWifiConfigManager).saveToStore(true);
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
+ assertEquals(2, mSharedDataSource.getProviderIndex());
+ reset(mWifiMetrics);
+ reset(mWifiConfigManager);
+
+ // Add another provider with the same base domain as the existing saved provider.
+ // This should replace the existing provider with the new configuration.
+ PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
+ TEST_FRIENDLY_NAME);
+ PasspointProvider newProvider = createMockProvider(newConfig);
+ when(newProvider.isFromSuggestion()).thenReturn(true);
+ when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE);
+ when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(true))).thenReturn(newProvider);
+ assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE, true));
+ verify(mWifiConfigManager).removePasspointConfiguredNetwork(
+ newProvider.getWifiConfig().configKey());
+ verify(mWifiConfigManager).saveToStore(true);
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
+
+ // Verify data source content.
+ List<PasspointProvider> newProviders = mUserDataSource.getProviders();
+ assertEquals(1, newProviders.size());
+ assertEquals(newConfig, newProviders.get(0).getConfig());
+ assertEquals(3, mSharedDataSource.getProviderIndex());
+ }
+
+ /**
+ * Verify that adding a saved provider with the same base domain as the existing
+ * suggestion provider will succeed, and verify that the existing provider is
+ * replaced by the new provider with the new configuration.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void addSavedProviderWithExistingSuggestionConfig() throws Exception {
+ // Add a provider with the original configuration.
+ PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
+ TEST_REALM);
+ PasspointProvider origProvider = createMockProvider(origConfig);
+ when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
+ when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(true))).thenReturn(origProvider);
+ assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, true));
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
+ reset(mWifiMetrics);
+ reset(mWifiConfigManager);
+
+ // Verify data source content.
+ List<PasspointProvider> origProviders = mUserDataSource.getProviders();
+ assertEquals(1, origProviders.size());
+ assertEquals(origConfig, origProviders.get(0).getConfig());
+ assertEquals(1, mSharedDataSource.getProviderIndex());
+
+ // Add another provider with the same base domain as the existing saved provider.
+ // This should replace the existing provider with the new configuration.
+ PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
+ TEST_FRIENDLY_NAME);
+ PasspointProvider newProvider = createMockProvider(newConfig);
+ when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(newProvider);
+ assertTrue(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE, false));
+ verify(mWifiConfigManager).removePasspointConfiguredNetwork(
+ newProvider.getWifiConfig().configKey());
+ verify(mWifiConfigManager).saveToStore(true);
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
+
+ // Verify data source content.
+ List<PasspointProvider> newProviders = mUserDataSource.getProviders();
+ assertEquals(1, newProviders.size());
+ assertEquals(newConfig, newProviders.get(0).getConfig());
+ assertEquals(2, mSharedDataSource.getProviderIndex());
+ }
+
+ /**
+ * Verify that adding a suggestion provider with the same base domain as the existing provider
+ * from different apps will fail, and verify that the existing provider is not replaced by the
+ * new provider with the new configuration.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void addSuggestionProviderWithExistingConfigFromDifferentSource() throws Exception {
+ // Add a provider with the original configuration.
+ PasspointConfiguration origConfig = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI,
+ TEST_REALM);
+ PasspointProvider origProvider = createMockProvider(origConfig);
+ when(origProvider.getPackageName()).thenReturn(TEST_PACKAGE);
+ when(mObjectFactory.makePasspointProvider(eq(origConfig), eq(mWifiKeyStore),
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE),
+ eq(false))).thenReturn(origProvider);
+ assertTrue(mManager.addOrUpdateProvider(origConfig, TEST_CREATOR_UID, TEST_PACKAGE, false));
+ verifyInstalledConfig(origConfig);
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess();
+ reset(mWifiMetrics);
+ reset(mWifiConfigManager);
+
+ // Verify data source content.
+ List<PasspointProvider> origProviders = mUserDataSource.getProviders();
+ assertEquals(1, origProviders.size());
+ assertEquals(origConfig, origProviders.get(0).getConfig());
+ assertEquals(1, mSharedDataSource.getProviderIndex());
+
+ // Add another provider with the same base domain as the existing saved provider but from
+ // different app. This should not replace the existing provider with the new configuration.
+ PasspointConfiguration newConfig = createTestConfigWithUserCredential(TEST_FQDN,
+ TEST_FRIENDLY_NAME);
+ PasspointProvider newProvider = createMockProvider(newConfig);
+ when(newProvider.isFromSuggestion()).thenReturn(true);
+ when(newProvider.getPackageName()).thenReturn(TEST_PACKAGE1);
+ when(mObjectFactory.makePasspointProvider(eq(newConfig), eq(mWifiKeyStore),
+ eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE1),
+ eq(true))).thenReturn(newProvider);
+ assertFalse(mManager.addOrUpdateProvider(newConfig, TEST_CREATOR_UID, TEST_PACKAGE1, true));
+ verify(mWifiConfigManager, never()).removePasspointConfiguredNetwork(
+ newProvider.getWifiConfig().configKey());
+ verify(mWifiConfigManager, never()).saveToStore(true);
+ verify(mWifiMetrics).incrementNumPasspointProviderInstallation();
+ verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess();
+
+ // Verify data source content.
+ List<PasspointProvider> newProviders = mUserDataSource.getProviders();
+ assertEquals(1, newProviders.size());
+ assertEquals(origConfig, newProviders.get(0).getConfig());
+ assertEquals(2, mSharedDataSource.getProviderIndex());
+ }
+
+ /**
+ * Verify that an expected map of FQDN and a list of ScanResult will be returned when provided
+ * scanResults are matched to installed Passpoint profiles. If matched Passpoint profiles is
+ * from suggestion, will check if it is approved. If it is not approved, send the user approved
+ * notification, and not to add into the matched list.
+ */
+ @Test
+ public void getAllMatchingFqdnsForScanResultsWithSuggestionProvider() {
+ // static mocking
+ MockitoSession session =
+ com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
+ InformationElementUtil.class).startMocking();
+ try {
+ PasspointProvider providerApproved = addTestProvider(TEST_FQDN + 0, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE);
+ providerApproved.getWifiConfig().isHomeProviderNetwork = true;
+ PasspointProvider providerNeedApprove = addTestProvider(TEST_FQDN + 1,
+ TEST_FRIENDLY_NAME, TEST_PACKAGE1);
+ providerNeedApprove.getWifiConfig().isHomeProviderNetwork = true;
+
+ ANQPData entry = new ANQPData(mClock, null);
+ InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
+ vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID2;
+
+ when(mAnqpCache.getEntry(TEST_ANQP_KEY2)).thenReturn(entry);
+ when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
+ when(providerApproved.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.HomeProvider);
+ when(providerNeedApprove.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.HomeProvider);
+ when(providerApproved.isFromSuggestion()).thenReturn(true);
+ when(providerNeedApprove.isFromSuggestion()).thenReturn(true);
+ when(mWifiNetworkSuggestionsManager
+ .sendUserApprovalNotificationIfNotApproved(eq(TEST_PACKAGE), anyInt()))
+ .thenReturn(false);
+ when(mWifiNetworkSuggestionsManager
+ .sendUserApprovalNotificationIfNotApproved(eq(TEST_PACKAGE1), anyInt()))
+ .thenReturn(true);
+ Map<String, Map<Integer, List<ScanResult>>> configs =
+ mManager.getAllMatchingFqdnsForScanResults(
+ createTestScanResults());
+ verify(mWifiNetworkSuggestionsManager, times(2))
+ .sendUserApprovalNotificationIfNotApproved(eq(TEST_PACKAGE), anyInt());
+ verify(mWifiNetworkSuggestionsManager, times(2))
+ .sendUserApprovalNotificationIfNotApproved(eq(TEST_PACKAGE1), anyInt());
+ // Expects to be matched with home Provider for each AP (two APs).
+ assertEquals(2, configs.get(TEST_FQDN + 0).get(
+ WifiManager.PASSPOINT_HOME_NETWORK).size());
+ assertFalse(
+ configs.get(TEST_FQDN + 0).containsKey(WifiManager.PASSPOINT_ROAMING_NETWORK));
+
+ // Expects there is no matched AP.
+ assertNull(configs.get(TEST_FQDN + 1));
+ } finally {
+ session.finishMocking();
+ }
+ }
+
+ /**
+ * Verify that the HomeProvider provider will be returned when a HomeProvider profile has
+ * not expired and RoamingProvider expiration is unset (still valid).
+ *
+ * @throws Exception
+ */
+ @Test
+ public void matchHomeProviderWhenHomeProviderNotExpired() throws Exception {
+ // static mocking
+ MockitoSession session =
+ com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
+ InformationElementUtil.class).startMocking();
+ try {
+ PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE);
+ providerHome.getConfig().setSubscriptionExpirationTimeInMillis(
+ System.currentTimeMillis() + 100000);
+ providerHome.getWifiConfig().isHomeProviderNetwork = true;
+ PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE);
+ PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE, new WifiConfiguration());
+ ANQPData entry = new ANQPData(mClock, null);
+ InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
+ vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
+
+ when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
+ when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
+ when(providerHome.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.HomeProvider);
+ when(providerRoaming.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.RoamingProvider);
+ when(providerNone.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.None);
+
+ Pair<PasspointProvider, PasspointMatch> result =
+ mManager.matchProvider(createTestScanResult());
+
+ assertEquals(PasspointMatch.HomeProvider, result.second);
+ assertEquals(TEST_FQDN, result.first.getConfig().getHomeSp().getFqdn());
+
+ } finally {
+ session.finishMocking();
+ }
+ }
+
+ /**
+ * Verify that the RoamingProvider provider will be returned when a HomeProvider profile has
+ * expired and RoamingProvider expiration is unset (still valid).
+ *
+ * @throws Exception
+ */
+ @Test
+ public void matchRoamingProviderUnsetWhenHomeProviderExpired() throws Exception {
+ // static mocking
+ MockitoSession session =
+ com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
+ InformationElementUtil.class).startMocking();
+ try {
+ PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE);
+ providerHome.getConfig().setSubscriptionExpirationTimeInMillis(
+ System.currentTimeMillis() - 10000);
+ providerHome.getWifiConfig().isHomeProviderNetwork = true;
+ PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE);
+ PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE, new WifiConfiguration());
+ ANQPData entry = new ANQPData(mClock, null);
+ InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
+ vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
+
+ when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
+ when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
+ when(providerHome.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.HomeProvider);
+ when(providerRoaming.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.RoamingProvider);
+ when(providerNone.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.None);
+
+ Pair<PasspointProvider, PasspointMatch> result =
+ mManager.matchProvider(createTestScanResult());
+
+ assertEquals(PasspointMatch.RoamingProvider, result.second);
+ assertEquals(TEST_FQDN2, result.first.getConfig().getHomeSp().getFqdn());
+
+ } finally {
+ session.finishMocking();
+ }
+ }
+
+ /**
+ * Verify that the RoamingProvider provider will be returned when a HomeProvider profile has
+ * expired and RoamingProvider expiration is still valid.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void matchRoamingProviderNonExpiredWhenHomeProviderExpired() throws Exception {
+ // static mocking
+ MockitoSession session =
+ com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession().mockStatic(
+ InformationElementUtil.class).startMocking();
+ try {
+ PasspointProvider providerHome = addTestProvider(TEST_FQDN, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE);
+ providerHome.getConfig().setSubscriptionExpirationTimeInMillis(
+ System.currentTimeMillis() - 10000);
+ providerHome.getWifiConfig().isHomeProviderNetwork = true;
+ PasspointProvider providerRoaming = addTestProvider(TEST_FQDN2, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE);
+ providerRoaming.getConfig().setSubscriptionExpirationTimeInMillis(
+ System.currentTimeMillis() + 100000);
+ PasspointProvider providerNone = addTestProvider(TEST_FQDN + 2, TEST_FRIENDLY_NAME,
+ TEST_PACKAGE, new WifiConfiguration());
+ ANQPData entry = new ANQPData(mClock, null);
+ InformationElementUtil.Vsa vsa = new InformationElementUtil.Vsa();
+ vsa.anqpDomainID = TEST_ANQP_DOMAIN_ID;
+
+ when(mAnqpCache.getEntry(TEST_ANQP_KEY)).thenReturn(entry);
+ when(InformationElementUtil.getHS2VendorSpecificIE(isNull())).thenReturn(vsa);
+ when(providerHome.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.HomeProvider);
+ when(providerRoaming.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.RoamingProvider);
+ when(providerNone.match(anyMap(), isNull()))
+ .thenReturn(PasspointMatch.None);
+
+ Pair<PasspointProvider, PasspointMatch> result =
+ mManager.matchProvider(createTestScanResult());
+
+ assertEquals(PasspointMatch.RoamingProvider, result.second);
+ assertEquals(TEST_FQDN2, result.first.getConfig().getHomeSp().getFqdn());
+
+ } finally {
+ session.finishMocking();
+ }
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java
index c7ce3f1278..5ceb2b76b5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java
@@ -37,6 +37,7 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.HomeSp;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.LocalLog;
@@ -68,6 +69,7 @@ import java.util.List;
*/
@SmallTest
public class PasspointNetworkEvaluatorTest {
+ // TODO(b/140763176): should extend WifiBaseTest, but if it does then it fails with NPE
private static final int TEST_NETWORK_ID = 1;
private static final String TEST_SSID1 = "ssid1";
private static final String TEST_SSID2 = "ssid2";
@@ -156,7 +158,8 @@ public class PasspointNetworkEvaluatorTest {
when(mWifiInjector.makeTelephonyManager()).thenReturn(mTelephonyManager);
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager);
// SIM is present
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(mock(SubscriptionInfo.class)));
when(mDataTelephonyManager.getSimOperator()).thenReturn("123456");
when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
}
@@ -234,7 +237,8 @@ public class PasspointNetworkEvaluatorTest {
assertNotNull(addedConfig.getValue().enterpriseConfig);
assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
assertTrue(addedConfig.getValue().isHomeProviderNetwork);
- verify(mWifiConfigManager).enableNetwork(eq(TEST_NETWORK_ID), eq(false), anyInt());
+ verify(mWifiConfigManager).enableNetwork(
+ eq(TEST_NETWORK_ID), eq(false), anyInt(), any());
verify(mWifiConfigManager).setNetworkCandidateScanResult(
eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt());
verify(mWifiConfigManager).updateScanDetailForNetwork(
@@ -277,7 +281,8 @@ public class PasspointNetworkEvaluatorTest {
assertNotNull(addedConfig.getValue().enterpriseConfig);
assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
assertFalse(addedConfig.getValue().isHomeProviderNetwork);
- verify(mWifiConfigManager).enableNetwork(eq(TEST_NETWORK_ID), eq(false), anyInt());
+ verify(mWifiConfigManager).enableNetwork(
+ eq(TEST_NETWORK_ID), eq(false), anyInt(), any());
verify(mWifiConfigManager).setNetworkCandidateScanResult(
eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt());
verify(mWifiConfigManager).updateScanDetailForNetwork(
@@ -322,7 +327,8 @@ public class PasspointNetworkEvaluatorTest {
assertNotNull(addedConfig.getValue().enterpriseConfig);
assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
assertTrue(addedConfig.getValue().isHomeProviderNetwork);
- verify(mWifiConfigManager).enableNetwork(eq(TEST_NETWORK_ID), eq(false), anyInt());
+ verify(mWifiConfigManager).enableNetwork(
+ eq(TEST_NETWORK_ID), eq(false), anyInt(), any());
verify(mWifiConfigManager).setNetworkCandidateScanResult(
eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt());
verify(mWifiConfigManager).updateScanDetailForNetwork(
@@ -387,7 +393,8 @@ public class PasspointNetworkEvaluatorTest {
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
when(testProvider.isSimCredential()).thenReturn(true);
// SIM is absent
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[0]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Collections.emptyList());
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
@@ -416,7 +423,8 @@ public class PasspointNetworkEvaluatorTest {
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
when(testProvider.isSimCredential()).thenReturn(true);
// SIM is present
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[1]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(mock(SubscriptionInfo.class)));
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
.thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
@@ -456,7 +464,8 @@ public class PasspointNetworkEvaluatorTest {
List<ScanDetail> scanDetails = Collections.singletonList(
generateScanDetail(TEST_SSID1, TEST_BSSID1));
// SIM is absent
- when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[0]);
+ when(mSubscriptionManager.getActiveSubscriptionInfoList())
+ .thenReturn(Arrays.asList(mock(SubscriptionInfo.class)));
when(mPasspointManager.hasCarrierProvider(anyString())).thenReturn(false);
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkScoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkScoreTest.java
index 1bea1a2797..ff04874981 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkScoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkScoreTest.java
@@ -25,6 +25,7 @@ import android.net.wifi.ScanResult;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.ScanDetail;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
import com.android.server.wifi.hotspot2.anqp.Constants;
import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType;
@@ -42,7 +43,7 @@ import java.util.Map;
* Unit tests for {@link com.android.server.wifi.hotspot2.PasspointNetworkScore}.
*/
@SmallTest
-public class PasspointNetworkScoreTest {
+public class PasspointNetworkScoreTest extends WifiBaseTest {
private static class TestData {
public final boolean isHomeProvider;
public final boolean isActiveNetwork;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java
index 31229c5628..ec05332141 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java
@@ -18,7 +18,6 @@ package com.android.server.wifi.hotspot2;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -36,9 +35,11 @@ import android.util.Base64;
import androidx.test.filters.SmallTest;
+import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.FakeKeys;
import com.android.server.wifi.IMSIParameter;
import com.android.server.wifi.SIMAccessor;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiKeyStore;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
import com.android.server.wifi.hotspot2.anqp.CellularNetwork;
@@ -75,7 +76,7 @@ import java.util.Set;
*/
@SmallTest
@RunWith(Parameterized.class)
-public class PasspointProviderTest {
+public class PasspointProviderTest extends WifiBaseTest {
private static final long PROVIDER_ID = 12L;
private static final int CREATOR_UID = 1234;
private static final String CREATOR_PACKAGE = "com.android.test";
@@ -89,6 +90,33 @@ public class PasspointProviderTest {
private static final String CLIENT_CERTIFICATE_ALIAS = "HS2_12";
private static final String CLIENT_PRIVATE_KEY_ALIAS = "HS2_12";
private static final String REMEDIATION_CA_CERTIFICATE_ALIAS = "HS2_REMEDIATION_12";
+ private static final String SYSTEM_CA_STORE_PATH = "/system/etc/security/cacerts";
+
+ private static final int TEST_UPDATE_IDENTIFIER = 1234;
+ private static final int TEST_USAGE_LIMIT_DATA_LIMIT = 100;
+ private static final String TEST_FQDN = "test.com";
+ private static final String TEST_FQDN2 = "test2.com";
+ private static final String TEST_FRIENDLY_NAME = "Friendly Name";
+ private static final long[] TEST_RC_OIS = new long[] {0x1234L, 0x2345L};
+ private static final long[] TEST_IE_RC_OIS = new long[] {0x1234L, 0x2133L};
+ private static final long[] TEST_IE_NO_MATCHED_RC_OIS = new long[] {0x2255L, 0x2133L};
+ private static final Long[] TEST_ANQP_RC_OIS = new Long[] {0x1234L, 0x2133L};
+ private static final String TEST_REALM = "realm.com";
+ private static final String[] TEST_TRUSTED_NAME =
+ new String[] {"trusted.fqdn.com", "another.fqdn.com"};
+ // User credential data
+ private static final String TEST_USERNAME = "username";
+ private static final String TEST_PASSWORD = "password";
+ // SIM credential data
+ private static final int TEST_EAP_TYPE = WifiEnterpriseConfig.Eap.SIM;
+ private static final int TEST_SIM_CREDENTIAL_TYPE = EAPConstants.EAP_SIM;
+ private static final String TEST_IMSI = "1234567890";
+
+ private enum CredentialType {
+ USER,
+ CERT,
+ SIM
+ }
@Mock WifiKeyStore mKeyStore;
@Mock SIMAccessor mSimAccessor;
@@ -126,7 +154,7 @@ public class PasspointProviderTest {
*/
private PasspointProvider createProvider(PasspointConfiguration config) {
return new PasspointProvider(config, mKeyStore, mSimAccessor, PROVIDER_ID, CREATOR_UID,
- CREATOR_PACKAGE);
+ CREATOR_PACKAGE, false);
}
/**
@@ -199,27 +227,222 @@ public class PasspointProviderTest {
}
/**
- * Verify that modification to the configuration used for creating PasspointProvider
- * will not change the configuration stored inside the PasspointProvider.
+ * Helper function for generating test passpoint configuration for test cases
*
+ * @param credentialType which type credential is generated.
+ * @param isLegacy if true, omit some passpoint fields to avoid breaking comparison
+ * between passpoint configuration converted from wifi configuration
+ * and generated passpoint configuration.
+ * @return a valid passpoint configuration
* @throws Exception
*/
- @Test
- public void verifyModifyOriginalConfig() throws Exception {
- // Create a dummy PasspointConfiguration.
+ private PasspointConfiguration generateTestPasspointConfiguration(
+ CredentialType credentialType, boolean isLegacy) throws Exception {
PasspointConfiguration config = new PasspointConfiguration();
+ if (!isLegacy) {
+ config.setUpdateIdentifier(TEST_UPDATE_IDENTIFIER);
+ config.setUsageLimitDataLimit(TEST_USAGE_LIMIT_DATA_LIMIT);
+ }
HomeSp homeSp = new HomeSp();
- homeSp.setFqdn("test1");
+ homeSp.setFqdn(TEST_FQDN);
+ homeSp.setFriendlyName(TEST_FRIENDLY_NAME);
+ homeSp.setRoamingConsortiumOis(TEST_RC_OIS);
config.setHomeSp(homeSp);
Credential credential = new Credential();
- credential.setUserCredential(new Credential.UserCredential());
+ credential.setRealm(TEST_REALM);
+
+ if (credentialType == CredentialType.USER) {
+ byte[] base64EncodedPw =
+ Base64.encode(TEST_PASSWORD.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
+ String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
+ Credential.UserCredential userCredential = new Credential.UserCredential();
+ userCredential.setEapType(EAPConstants.EAP_TTLS);
+ userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
+ userCredential.setUsername(TEST_USERNAME);
+ userCredential.setPassword(encodedPasswordStr);
+ if (!isLegacy) {
+ credential.setCaCertificates(new X509Certificate[] {FakeKeys.CA_CERT0});
+ }
+ credential.setUserCredential(userCredential);
+ } else if (credentialType == CredentialType.CERT) {
+ Credential.CertificateCredential certCredential =
+ new Credential.CertificateCredential();
+ if (!isLegacy) {
+ certCredential.setCertSha256Fingerprint(
+ MessageDigest.getInstance("SHA-256")
+ .digest(FakeKeys.CLIENT_CERT.getEncoded()));
+ credential.setCaCertificates(new X509Certificate[] {FakeKeys.CA_CERT0});
+ credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
+ credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT});
+ } else {
+ certCredential.setCertType(Credential.CertificateCredential.CERT_TYPE_X509V3);
+ }
+ credential.setCertCredential(certCredential);
+ } else if (credentialType == CredentialType.SIM) {
+ Credential.SimCredential simCredential = new Credential.SimCredential();
+ simCredential.setImsi(TEST_IMSI);
+ simCredential.setEapType(EAPConstants.EAP_SIM);
+ credential.setSimCredential(simCredential);
+ }
config.setCredential(credential);
+
+ return config;
+ }
+
+ /**
+ * Helper function for verifying wifi configuration based on passpoing configuration
+ *
+ * @param passpointConfig the source of wifi configuration.
+ * @param wifiConfig wifi configuration be verified.
+ *
+ * @throws Exception
+ */
+ private void verifyWifiConfigWithTestData(
+ PasspointConfiguration passpointConfig, WifiConfiguration wifiConfig) {
+ BitSet allowedProtocols = new BitSet();
+ allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+
+ HomeSp homeSp = passpointConfig.getHomeSp();
+ Credential credential = passpointConfig.getCredential();
+
+ // Need to verify field by field since WifiConfiguration doesn't
+ // override equals() function.
+ WifiEnterpriseConfig wifiEnterpriseConfig = wifiConfig.enterpriseConfig;
+ assertEquals(homeSp.getFqdn(), wifiConfig.FQDN);
+ assertEquals(homeSp.getFriendlyName(), wifiConfig.providerFriendlyName);
+ assertTrue(Arrays.equals(homeSp.getRoamingConsortiumOis(),
+ wifiConfig.roamingConsortiumIds));
+
+ assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
+ assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
+ assertEquals(wifiConfig.updateIdentifier,
+ Integer.toString(passpointConfig.getUpdateIdentifier()));
+ assertEquals(allowedProtocols, wifiConfig.allowedProtocols);
+ assertEquals(Integer.toString(passpointConfig.getUpdateIdentifier()),
+ wifiConfig.updateIdentifier);
+ assertFalse(wifiConfig.shared);
+ assertEquals(credential.getRealm(), wifiEnterpriseConfig.getRealm());
+
+ if (credential.getUserCredential() != null) {
+ Credential.UserCredential userCredential = credential.getUserCredential();
+ byte[] pwOctets = Base64.decode(userCredential.getPassword(), Base64.DEFAULT);
+ String decodedPassword = new String(pwOctets, StandardCharsets.UTF_8);
+
+ assertEquals("anonymous@" + credential.getRealm(),
+ wifiEnterpriseConfig.getAnonymousIdentity());
+ assertEquals(WifiEnterpriseConfig.Eap.TTLS, wifiEnterpriseConfig.getEapMethod());
+ switch (userCredential.getNonEapInnerMethod()) {
+ case Credential.UserCredential.AUTH_METHOD_PAP:
+ assertEquals(WifiEnterpriseConfig.Phase2.PAP,
+ wifiEnterpriseConfig.getPhase2Method());
+ break;
+ case Credential.UserCredential.AUTH_METHOD_MSCHAP:
+ assertEquals(WifiEnterpriseConfig.Phase2.MSCHAP,
+ wifiEnterpriseConfig.getPhase2Method());
+ break;
+ case Credential.UserCredential.AUTH_METHOD_MSCHAPV2:
+ assertEquals(WifiEnterpriseConfig.Phase2.MSCHAPV2,
+ wifiEnterpriseConfig.getPhase2Method());
+ break;
+ }
+ assertEquals(userCredential.getUsername(), wifiEnterpriseConfig.getIdentity());
+ assertEquals(decodedPassword, wifiEnterpriseConfig.getPassword());
+ assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED, wifiConfig.meteredOverride);
+
+ if (!ArrayUtils.isEmpty(passpointConfig.getAaaServerTrustedNames())) {
+ assertEquals(String.join(";", passpointConfig.getAaaServerTrustedNames()),
+ wifiEnterpriseConfig.getDomainSuffixMatch());
+ } else {
+ assertEquals(homeSp.getFqdn(), wifiEnterpriseConfig.getDomainSuffixMatch());
+ }
+
+ if (!ArrayUtils.isEmpty(passpointConfig.getAaaServerTrustedNames())) {
+ assertTrue(Arrays.equals(new String[] {SYSTEM_CA_STORE_PATH},
+ wifiEnterpriseConfig.getCaCertificateAliases()));
+ } else if (ArrayUtils.isEmpty(credential.getCaCertificates())) {
+ assertTrue(Arrays.equals(new String[] {SYSTEM_CA_STORE_PATH},
+ wifiEnterpriseConfig.getCaCertificateAliases()));
+ } else {
+ assertEquals(CA_CERTIFICATE_ALIAS, wifiEnterpriseConfig.getCaCertificateAlias());
+ }
+ if (passpointConfig.getCredential().getCheckAaaServerCertStatus()) {
+ assertEquals(wifiEnterpriseConfig.getOcsp(),
+ WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
+ } else {
+ assertEquals(wifiEnterpriseConfig.getOcsp(),
+ WifiEnterpriseConfig.OCSP_NONE);
+ }
+ } else if (credential.getCertCredential() != null) {
+ Credential.CertificateCredential certCredential = credential.getCertCredential();
+ assertEquals("anonymous@" + credential.getRealm(),
+ wifiEnterpriseConfig.getAnonymousIdentity());
+ assertEquals(WifiEnterpriseConfig.Eap.TLS, wifiEnterpriseConfig.getEapMethod());
+ assertEquals(CLIENT_CERTIFICATE_ALIAS,
+ wifiEnterpriseConfig.getClientCertificateAlias());
+ assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED, wifiConfig.meteredOverride);
+ // Domain suffix match
+ if (ArrayUtils.isEmpty(passpointConfig.getAaaServerTrustedNames())) {
+ assertEquals(homeSp.getFqdn(), wifiEnterpriseConfig.getDomainSuffixMatch());
+ } else {
+ assertEquals(String.join(";", passpointConfig.getAaaServerTrustedNames()),
+ wifiEnterpriseConfig.getDomainSuffixMatch());
+ assertTrue(Arrays.equals(new String[] {SYSTEM_CA_STORE_PATH},
+ wifiEnterpriseConfig.getCaCertificateAliases()));
+ }
+ // CA certificate
+ if (!ArrayUtils.isEmpty(passpointConfig.getAaaServerTrustedNames())) {
+ assertTrue(Arrays.equals(new String[] {SYSTEM_CA_STORE_PATH},
+ wifiEnterpriseConfig.getCaCertificateAliases()));
+ } else if (!ArrayUtils.isEmpty(credential.getCaCertificates())) {
+ assertEquals(CA_CERTIFICATE_ALIAS, wifiEnterpriseConfig.getCaCertificateAlias());
+ } else {
+ assertTrue(Arrays.equals(new String[] {SYSTEM_CA_STORE_PATH},
+ wifiEnterpriseConfig.getCaCertificateAliases()));
+ }
+ if (passpointConfig.getCredential().getCheckAaaServerCertStatus()) {
+ assertEquals(wifiEnterpriseConfig.getOcsp(),
+ WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
+ } else {
+ assertEquals(wifiEnterpriseConfig.getOcsp(),
+ WifiEnterpriseConfig.OCSP_NONE);
+ }
+ } else if (credential.getSimCredential() != null) {
+ Credential.SimCredential simCredential = credential.getSimCredential();
+ switch (simCredential.getEapType()) {
+ case EAPConstants.EAP_SIM:
+ assertEquals(WifiEnterpriseConfig.Eap.SIM,
+ wifiEnterpriseConfig.getEapMethod());
+ break;
+ case EAPConstants.EAP_AKA:
+ assertEquals(WifiEnterpriseConfig.Eap.AKA,
+ wifiEnterpriseConfig.getEapMethod());
+ break;
+ case EAPConstants.EAP_AKA_PRIME:
+ assertEquals(WifiEnterpriseConfig.Eap.AKA_PRIME,
+ wifiEnterpriseConfig.getEapMethod());
+ break;
+ }
+ assertEquals(simCredential.getImsi(), wifiEnterpriseConfig.getPlmn());
+ }
+ }
+
+ /**
+ * Verify that modification to the configuration used for creating PasspointProvider
+ * will not change the configuration stored inside the PasspointProvider.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyModifyOriginalConfig() throws Exception {
+ // Create a dummy PasspointConfiguration.
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
verifyInstalledConfig(config, true);
// Modify the original configuration, the configuration maintained by the provider
// should be unchanged.
- config.getHomeSp().setFqdn("test2");
+ config.getHomeSp().setFqdn(TEST_FQDN2);
verifyInstalledConfig(config, false);
}
@@ -232,20 +455,15 @@ public class PasspointProviderTest {
@Test
public void verifyModifyRetrievedConfig() throws Exception {
// Create a dummy PasspointConfiguration.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn("test1");
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setUserCredential(new Credential.UserCredential());
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
verifyInstalledConfig(config, true);
// Modify the retrieved configuration, verify the configuration maintained by the
// provider should be unchanged.
PasspointConfiguration retrievedConfig = mProvider.getConfig();
- retrievedConfig.getHomeSp().setFqdn("test2");
+ retrievedConfig.getHomeSp().setFqdn(TEST_FQDN2);
verifyInstalledConfig(retrievedConfig, false);
}
@@ -257,16 +475,11 @@ public class PasspointProviderTest {
@Test
public void installCertsAndKeysSuccess() throws Exception {
// Create a dummy configuration with certificate credential.
- PasspointConfiguration config = new PasspointConfiguration();
- Credential credential = new Credential();
- Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
- certCredential.setCertSha256Fingerprint(
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
- credential.setCertCredential(certCredential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.CERT, false);
+ Credential credential = config.getCredential();
+ Credential.CertificateCredential certCredential = credential.getCertCredential();
credential.setCaCertificates(new X509Certificate[]{FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
- credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
- credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT});
- config.setCredential(credential);
if (mRemediationCaCertificate != null) {
UpdateParameter updateParameter = new UpdateParameter();
updateParameter.setCaCertificate(mRemediationCaCertificate);
@@ -309,15 +522,11 @@ public class PasspointProviderTest {
@Test
public void installCertsAndKeysFailure() throws Exception {
// Create a dummy configuration with certificate credential.
- PasspointConfiguration config = new PasspointConfiguration();
- Credential credential = new Credential();
- Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
- certCredential.setCertSha256Fingerprint(
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
- credential.setCertCredential(certCredential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.CERT, false);
+ Credential credential = config.getCredential();
+ Credential.CertificateCredential certCredential = credential.getCertCredential();
credential.setCaCertificates(new X509Certificate[]{FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
- credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
- credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT});
config.setCredential(credential);
UpdateParameter updateParameter = new UpdateParameter();
@@ -359,15 +568,11 @@ public class PasspointProviderTest {
@Test
public void uninstallCertsAndKeys() throws Exception {
// Create a dummy configuration with certificate credential.
- PasspointConfiguration config = new PasspointConfiguration();
- Credential credential = new Credential();
- Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
- certCredential.setCertSha256Fingerprint(
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
- credential.setCertCredential(certCredential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.CERT, false);
+ Credential credential = config.getCredential();
+ Credential.CertificateCredential certCredential = credential.getCertCredential();
credential.setCaCertificates(new X509Certificate[]{FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
- credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
- credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT});
config.setCredential(credential);
if (mRemediationCaCertificate != null) {
UpdateParameter updateParameter = new UpdateParameter();
@@ -418,24 +623,15 @@ public class PasspointProviderTest {
*/
@Test
public void matchFQDNWithoutNAIRealm() throws Exception {
- String testDomain = "test.com";
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(testDomain);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup ANQP elements.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPDomName,
- createDomainNameElement(new String[] {testDomain}));
+ createDomainNameElement(new String[] {TEST_FQDN}));
assertEquals(PasspointMatch.HomeProvider,
mProvider.match(anqpElementMap, mRoamingConsortium));
@@ -449,28 +645,17 @@ public class PasspointProviderTest {
*/
@Test
public void matchFQDNWithNAIRealmMatch() throws Exception {
- String testDomain = "test.com";
- String testRealm = "realm.com";
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(testDomain);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(testRealm);
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup Domain Name ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPDomName,
- createDomainNameElement(new String[] {testDomain}));
+ createDomainNameElement(new String[] {TEST_FQDN}));
anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
- createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS,
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
assertEquals(PasspointMatch.HomeProvider,
@@ -486,28 +671,17 @@ public class PasspointProviderTest {
*/
@Test
public void matchFQDNWithNAIRealmMismatch() throws Exception {
- String testDomain = "test.com";
- String testRealm = "realm.com";
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(testDomain);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(testRealm);
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup Domain Name ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPDomName,
- createDomainNameElement(new String[] {testDomain}));
+ createDomainNameElement(new String[] {TEST_FQDN}));
anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
- createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null));
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TLS, null));
assertEquals(PasspointMatch.None, mProvider.match(anqpElementMap, mRoamingConsortium));
}
@@ -520,18 +694,11 @@ public class PasspointProviderTest {
*/
@Test
public void matchFQDNWith3GPPNetworkDomainName() throws Exception {
- String testImsi = "1234567890";
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- config.setHomeSp(new HomeSp());
- Credential credential = new Credential();
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setImsi(testImsi);
- credential.setSimCredential(simCredential);
- config.setCredential(credential);
- when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false)))
- .thenReturn(Arrays.asList(new String[] {testImsi}));
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.SIM, false);
+ when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI, false)))
+ .thenReturn(Arrays.asList(new String[] {TEST_IMSI}));
mProvider = createProvider(config);
// Setup Domain Name ANQP element.
@@ -552,33 +719,19 @@ public class PasspointProviderTest {
*/
@Test
public void matchFQDNOverRoamingProvider() throws Exception {
- // Setup test data.
- String testDomain = "test.com";
- String testImsi = "1234567890";
- long[] providerRCOIs = new long[] {0x1234L, 0x2345L};
- Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L};
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(testDomain);
- homeSp.setRoamingConsortiumOis(providerRCOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setImsi(testImsi);
- credential.setSimCredential(simCredential);
- config.setCredential(credential);
- when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false)))
- .thenReturn(Arrays.asList(new String[] {testImsi}));
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.SIM, false);
+ when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI, false)))
+ .thenReturn(Arrays.asList(new String[] {TEST_IMSI}));
mProvider = createProvider(config);
// Setup ANQP elements.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPDomName,
- createDomainNameElement(new String[] {testDomain}));
+ createDomainNameElement(new String[] {TEST_FQDN}));
anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
- createRoamingConsortiumElement(anqpRCOIs));
+ createRoamingConsortiumElement(TEST_ANQP_RC_OIS));
anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork,
createThreeGPPNetworkElement(new String[] {"123456"}));
@@ -594,25 +747,15 @@ public class PasspointProviderTest {
*/
@Test
public void matchRoamingConsortiumWithoutNAIRealm() throws Exception {
- long[] providerRCOIs = new long[] {0x1234L, 0x2345L};
- Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L};
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setRoamingConsortiumOis(providerRCOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.SIM, false);
mProvider = createProvider(config);
// Setup Roaming Consortium ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
- createRoamingConsortiumElement(anqpRCOIs));
+ createRoamingConsortiumElement(TEST_ANQP_RC_OIS));
assertEquals(PasspointMatch.RoamingProvider,
mProvider.match(anqpElementMap, mRoamingConsortium));
@@ -627,29 +770,18 @@ public class PasspointProviderTest {
*/
@Test
public void matchRoamingConsortiumWithNAIRealmMatch() throws Exception {
- long[] providerRCOIs = new long[] {0x1234L, 0x2345L};
- Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L};
- String testRealm = "realm.com";
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setRoamingConsortiumOis(providerRCOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(testRealm);
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup Roaming Consortium ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
- createRoamingConsortiumElement(anqpRCOIs));
+ createRoamingConsortiumElement(TEST_ANQP_RC_OIS));
anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
- createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS,
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
assertEquals(PasspointMatch.RoamingProvider,
@@ -664,30 +796,18 @@ public class PasspointProviderTest {
*/
@Test
public void matchRoamingConsortiumWithNAIRealmMisMatch() throws Exception {
- long[] providerRCOIs = new long[] {0x1234L, 0x2345L};
- Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L};
- String testRealm = "realm.com";
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setRoamingConsortiumOis(providerRCOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(testRealm);
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup Roaming Consortium ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
- createRoamingConsortiumElement(anqpRCOIs));
+ createRoamingConsortiumElement(TEST_ANQP_RC_OIS));
// Set up NAI with different EAP method
anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
- createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null));
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TLS, null));
assertEquals(PasspointMatch.None,
mProvider.match(anqpElementMap, mRoamingConsortium));
@@ -701,26 +821,16 @@ public class PasspointProviderTest {
*/
@Test
public void matchRoamingConsortiumIeWithoutNAIRealm() throws Exception {
- long[] providerRCOIs = new long[] {0x1234L, 0x2345L};
- long[] ieRCOIs = new long[] {0x1234L, 0x2133L};
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setRoamingConsortiumOis(providerRCOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup Roaming Consortium ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
// Setup Roaming Consortium Information element.
- when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(ieRCOIs);
+ when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(TEST_IE_RC_OIS);
assertEquals(PasspointMatch.RoamingProvider,
mProvider.match(anqpElementMap, mRoamingConsortium));
@@ -735,30 +845,18 @@ public class PasspointProviderTest {
*/
@Test
public void matchRoamingConsortiumIeWithNAIRealmMatch() throws Exception {
- long[] providerRCOIs = new long[] {0x1234L, 0x2345L};
- long[] ieRCOIs = new long[] {0x1234L, 0x2133L};
- String testRealm = "realm.com";
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setRoamingConsortiumOis(providerRCOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(testRealm);
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup Roaming Consortium ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
// Setup Roaming Consortium Information element.
- when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(ieRCOIs);
+ when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(TEST_IE_RC_OIS);
anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
- createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS,
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
assertEquals(PasspointMatch.RoamingProvider,
@@ -773,31 +871,19 @@ public class PasspointProviderTest {
*/
@Test
public void matchRoamingConsortiumIeWithNAIRealmMismatch() throws Exception {
- long[] providerRCOIs = new long[] {0x1234L, 0x2345L};
- long[] ieRCOIs = new long[] {0x1234L, 0x2133L};
- String testRealm = "realm.com";
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setRoamingConsortiumOis(providerRCOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(testRealm);
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup Roaming Consortium ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
// Setup Roaming Consortium Information element.
- when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(ieRCOIs);
+ when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(TEST_IE_RC_OIS);
// Set up NAI with different EAP method
anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
- createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null));
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TLS, null));
assertEquals(PasspointMatch.None,
mProvider.match(anqpElementMap, mRoamingConsortium));
@@ -812,26 +898,16 @@ public class PasspointProviderTest {
*/
@Test
public void misMatchForRoamingConsortiumIeAndNAIRealm() throws Exception {
- long[] providerRCOIs = new long[] {0x1234L, 0x2345L};
- long[] ieRCOIs = new long[] {0x2255L, 0x2133L};
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setRoamingConsortiumOis(providerRCOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup Roaming Consortium ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
// Setup Roaming Consortium Information element.
- when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(ieRCOIs);
+ when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(TEST_IE_NO_MATCHED_RC_OIS);
assertEquals(PasspointMatch.None,
mProvider.match(anqpElementMap, mRoamingConsortium));
@@ -846,18 +922,11 @@ public class PasspointProviderTest {
*/
@Test
public void matchThreeGPPNetworkWithNAIRealmMismatch() throws Exception {
- String testImsi = "1234567890";
- String testRealm = "realm.com";
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- config.setHomeSp(new HomeSp());
- Credential credential = new Credential();
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setImsi(testImsi);
- credential.setSimCredential(simCredential);
- config.setCredential(credential);
- when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false)))
- .thenReturn(Arrays.asList(new String[] {testImsi}));
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.SIM, false);
+ when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI, false)))
+ .thenReturn(Arrays.asList(new String[] {TEST_IMSI}));
mProvider = createProvider(config);
// Setup 3GPP Network ANQP element.
@@ -867,7 +936,7 @@ public class PasspointProviderTest {
// Setup NAI Realm ANQP element with different realm.
anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
- createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS,
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
assertEquals(PasspointMatch.RoamingProvider,
@@ -883,19 +952,11 @@ public class PasspointProviderTest {
*/
@Test
public void matchThreeGPPNetworkWithNAIRealmMatch() throws Exception {
- String testImsi = "1234567890";
- String testRealm = "realm.com";
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- config.setHomeSp(new HomeSp());
- Credential credential = new Credential();
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setImsi(testImsi);
- credential.setSimCredential(simCredential);
- config.setCredential(credential);
- credential.setRealm(testRealm);
- when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false)))
- .thenReturn(Arrays.asList(new String[] {testImsi}));
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.SIM, false);
+ when(mSimAccessor.getMatchingImsis(new IMSIParameter(TEST_IMSI, false)))
+ .thenReturn(Arrays.asList(new String[] {TEST_IMSI}));
mProvider = createProvider(config);
// Setup 3GPP Network ANQP element.
@@ -905,7 +966,7 @@ public class PasspointProviderTest {
// Setup NAI Realm ANQP element with same realm.
anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
- createNAIRealmElement(testRealm, EAPConstants.EAP_AKA, null));
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_AKA, null));
assertEquals(PasspointMatch.RoamingProvider,
mProvider.match(anqpElementMap, mRoamingConsortium));
@@ -919,69 +980,65 @@ public class PasspointProviderTest {
*/
@Test
public void matchOnlyNAIRealmWithOtherInformationMismatch() throws Exception {
- String testRealm = "realm.com";
-
// Setup test provider.
- PasspointConfiguration config = new PasspointConfiguration();
- config.setHomeSp(new HomeSp());
- Credential credential = new Credential();
- credential.setRealm(testRealm);
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
// Setup NAI Realm ANQP element.
Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
- createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS,
+ createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
assertEquals(PasspointMatch.RoamingProvider,
mProvider.match(anqpElementMap, mRoamingConsortium));
}
-
/**
* Verify that an expected WifiConfiguration will be returned for a Passpoint provider
- * with an user credential.
+ * with a user credential.
*
* @throws Exception
*/
@Test
public void getWifiConfigWithUserCredential() throws Exception {
- // Test data.
- String fqdn = "test.com";
- String friendlyName = "Friendly Name";
- long[] rcOIs = new long[] {0x1234L, 0x2345L};
- String realm = "realm.com";
- String username = "username";
- String password = "password";
- byte[] base64EncodedPw =
- Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
- String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
- BitSet allowedProtocols = new BitSet();
- allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ // Create provider for R2.
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
+ mProvider = createProvider(config);
+ // Install certificate.
+ when(mKeyStore.putCertInKeyStore(CA_CERTIFICATE_NAME, FakeKeys.CA_CERT0))
+ .thenReturn(true);
+ assertTrue(mProvider.installCertsAndKeys());
+
+ // Retrieve the WifiConfiguration associated with the provider, and verify the content of
+ // the configuration.
+ verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
+
+ // Verify that AAA server trusted names are provisioned.
+ config.setAaaServerTrustedNames(TEST_TRUSTED_NAME);
+ mProvider = createProvider(config);
+ verifyWifiConfigWithTestData(config,
+ createProvider(config).getWifiConfig());
+ }
+
+ /**
+ * Verify that an expected WifiConfiguration will be returned for a Passpoint provider
+ * with a user credential which has AAA server trusted names provisioned.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void getWifiConfigWithUserCredentialHasAaaServerTrustedNames() throws Exception {
// Create provider for R2.
- PasspointConfiguration config = new PasspointConfiguration();
- config.setUpdateIdentifier(1234);
- config.setUsageLimitDataLimit(100);
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(fqdn);
- homeSp.setFriendlyName(friendlyName);
- homeSp.setRoamingConsortiumOis(rcOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(realm);
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setUsername(username);
- userCredential.setPassword(encodedPasswordStr);
- userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
- credential.setUserCredential(userCredential);
- credential.setCaCertificates(new X509Certificate[] {FakeKeys.CA_CERT0});
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
+ config.setAaaServerTrustedNames(TEST_TRUSTED_NAME);
+ Credential credential = config.getCredential();
+ // OCSP (Online Certificate Status Protocol) is required.
+ credential.setCheckAaaServerCertStatus(true);
mProvider = createProvider(config);
// Install certificate.
@@ -990,28 +1047,33 @@ public class PasspointProviderTest {
assertTrue(mProvider.installCertsAndKeys());
// Retrieve the WifiConfiguration associated with the provider, and verify the content of
- // the configuration. Need to verify field by field since WifiConfiguration doesn't
- // override equals() function.
- WifiConfiguration wifiConfig = mProvider.getWifiConfig();
- WifiEnterpriseConfig wifiEnterpriseConfig = wifiConfig.enterpriseConfig;
- assertEquals(fqdn, wifiConfig.FQDN);
- assertEquals(friendlyName, wifiConfig.providerFriendlyName);
- assertTrue(Arrays.equals(rcOIs, wifiConfig.roamingConsortiumIds));
- assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
- assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
- assertEquals(wifiConfig.updateIdentifier, Integer.toString(config.getUpdateIdentifier()));
- assertEquals(allowedProtocols, wifiConfig.allowedProtocols);
- assertEquals("1234", wifiConfig.updateIdentifier);
- assertFalse(wifiConfig.shared);
- assertEquals(realm, wifiEnterpriseConfig.getRealm());
- assertEquals(fqdn, wifiEnterpriseConfig.getDomainSuffixMatch());
- assertEquals("anonymous@" + realm, wifiEnterpriseConfig.getAnonymousIdentity());
- assertEquals(WifiEnterpriseConfig.Eap.TTLS, wifiEnterpriseConfig.getEapMethod());
- assertEquals(WifiEnterpriseConfig.Phase2.MSCHAPV2, wifiEnterpriseConfig.getPhase2Method());
- assertEquals(username, wifiEnterpriseConfig.getIdentity());
- assertEquals(password, wifiEnterpriseConfig.getPassword());
- assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED, wifiConfig.meteredOverride);
- assertEquals(CA_CERTIFICATE_ALIAS, wifiEnterpriseConfig.getCaCertificateAlias());
+ // the configuration.
+ verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
+
+ // Verify that AAA server trusted names are provisioned.
+ config.setAaaServerTrustedNames(TEST_TRUSTED_NAME);
+ mProvider = createProvider(config);
+ verifyWifiConfigWithTestData(config,
+ createProvider(config).getWifiConfig());
+ }
+
+ /**
+ * Verify that an expected WifiConfiguration will be returned for a Passpoint provider
+ * with a user credential which has no CA cert.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void getWifiConfigWithUserCredentialNoCaCert() throws Exception {
+ // Create provider for R2.
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
+ config.getCredential().setCaCertificates(null);
+ mProvider = createProvider(config);
+
+ // Retrieve the WifiConfiguration associated with the provider, and verify the content of
+ // the configuration.
+ verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
}
/**
@@ -1022,33 +1084,37 @@ public class PasspointProviderTest {
*/
@Test
public void getWifiConfigWithCertCredential() throws Exception {
- // Test data.
- String fqdn = "test.com";
- String friendlyName = "Friendly Name";
- long[] rcOIs = new long[] {0x1234L, 0x2345L};
- String realm = "realm.com";
- BitSet allowedProtocols = new BitSet();
- allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ // Create provider.
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.CERT, false);
+ mProvider = createProvider(config);
+ // Install certificate.
+ when(mKeyStore.putCertInKeyStore(CA_CERTIFICATE_NAME, FakeKeys.CA_CERT0))
+ .thenReturn(true);
+ when(mKeyStore.putKeyInKeyStore(CLIENT_PRIVATE_KEY_NAME, FakeKeys.RSA_KEY1))
+ .thenReturn(true);
+ when(mKeyStore.putCertInKeyStore(CLIENT_CERTIFICATE_NAME, FakeKeys.CLIENT_CERT))
+ .thenReturn(true);
+ assertTrue(mProvider.installCertsAndKeys());
+
+ // Retrieve the WifiConfiguration associated with the provider, and verify the content of
+ // the configuration.
+ verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
+ }
+
+ /**
+ * Verify that an expected WifiConfiguration will be returned for a Passpoint provider
+ * with a certificate credential which has AAA server trusted names provisioned.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void getWifiConfigWithCertCredentialHasAaaServerTrustedNames() throws Exception {
// Create provider.
- PasspointConfiguration config = new PasspointConfiguration();
- config.setUpdateIdentifier(1234);
- config.setUsageLimitTimeLimitInMinutes(100);
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(fqdn);
- homeSp.setFriendlyName(friendlyName);
- homeSp.setRoamingConsortiumOis(rcOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(realm);
- Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
- certCredential.setCertSha256Fingerprint(
- MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
- credential.setCertCredential(certCredential);
- credential.setCaCertificates(new X509Certificate[] {FakeKeys.CA_CERT0});
- credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
- credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT});
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.CERT, false);
+ config.setAaaServerTrustedNames(TEST_TRUSTED_NAME);
mProvider = createProvider(config);
// Install certificate.
@@ -1061,25 +1127,34 @@ public class PasspointProviderTest {
assertTrue(mProvider.installCertsAndKeys());
// Retrieve the WifiConfiguration associated with the provider, and verify the content of
- // the configuration. Need to verify field by field since WifiConfiguration doesn't
- // override equals() function.
- WifiConfiguration wifiConfig = mProvider.getWifiConfig();
- WifiEnterpriseConfig wifiEnterpriseConfig = wifiConfig.enterpriseConfig;
- assertEquals(fqdn, wifiConfig.FQDN);
- assertEquals(friendlyName, wifiConfig.providerFriendlyName);
- assertTrue(Arrays.equals(rcOIs, wifiConfig.roamingConsortiumIds));
- assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
- assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
- assertEquals(allowedProtocols, wifiConfig.allowedProtocols);
- assertEquals("1234", wifiConfig.updateIdentifier);
- assertFalse(wifiConfig.shared);
- assertEquals(realm, wifiEnterpriseConfig.getRealm());
- assertEquals(fqdn, wifiEnterpriseConfig.getDomainSuffixMatch());
- assertEquals("anonymous@" + realm, wifiEnterpriseConfig.getAnonymousIdentity());
- assertEquals(WifiEnterpriseConfig.Eap.TLS, wifiEnterpriseConfig.getEapMethod());
- assertEquals(CLIENT_CERTIFICATE_ALIAS, wifiEnterpriseConfig.getClientCertificateAlias());
- assertEquals(CA_CERTIFICATE_ALIAS, wifiEnterpriseConfig.getCaCertificateAlias());
- assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED, wifiConfig.meteredOverride);
+ // the configuration.
+ verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
+ }
+
+ /**
+ * Verify that an expected WifiConfiguration will be returned for a Passpoint provider
+ * with a certificate credential which has no CA cert.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void getWifiConfigWithCertCredentialNoCaCert() throws Exception {
+ // Create provider.
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.CERT, false);
+ config.getCredential().setCaCertificates(null);
+ mProvider = createProvider(config);
+
+ // Install certificate.
+ when(mKeyStore.putKeyInKeyStore(CLIENT_PRIVATE_KEY_NAME, FakeKeys.RSA_KEY1))
+ .thenReturn(true);
+ when(mKeyStore.putCertInKeyStore(CLIENT_CERTIFICATE_NAME, FakeKeys.CLIENT_CERT))
+ .thenReturn(true);
+ assertTrue(mProvider.installCertsAndKeys());
+
+ // Retrieve the WifiConfiguration associated with the provider, and verify the content of
+ // the configuration.
+ verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
}
/**
@@ -1090,97 +1165,41 @@ public class PasspointProviderTest {
*/
@Test
public void getWifiConfigWithSimCredential() throws Exception {
- // Test data.
- String fqdn = "test.com";
- String friendlyName = "Friendly Name";
- long[] rcOIs = new long[] {0x1234L, 0x2345L};
- String realm = "realm.com";
- String imsi = "1234*";
- BitSet allowedProtocols = new BitSet();
- allowedProtocols.set(WifiConfiguration.Protocol.RSN);
-
// Create provider.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(fqdn);
- homeSp.setFriendlyName(friendlyName);
- homeSp.setRoamingConsortiumOis(rcOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(realm);
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setImsi(imsi);
- simCredential.setEapType(EAPConstants.EAP_SIM);
- credential.setSimCredential(simCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.SIM, false);
mProvider = createProvider(config);
// Retrieve the WifiConfiguration associated with the provider, and verify the content of
- // the configuration. Need to verify field by field since WifiConfiguration doesn't
- // override equals() function.
- WifiConfiguration wifiConfig = mProvider.getWifiConfig();
- WifiEnterpriseConfig wifiEnterpriseConfig = wifiConfig.enterpriseConfig;
- assertEquals(fqdn, wifiConfig.FQDN);
- assertEquals(friendlyName, wifiConfig.providerFriendlyName);
- assertTrue(Arrays.equals(rcOIs, wifiConfig.roamingConsortiumIds));
- assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
- assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
- assertEquals(allowedProtocols, wifiConfig.allowedProtocols);
- assertNull(wifiConfig.updateIdentifier);
- assertFalse(wifiConfig.shared);
- assertEquals(realm, wifiEnterpriseConfig.getRealm());
- assertEquals(fqdn, wifiEnterpriseConfig.getDomainSuffixMatch());
- assertEquals(WifiEnterpriseConfig.Eap.SIM, wifiEnterpriseConfig.getEapMethod());
- assertEquals(imsi, wifiEnterpriseConfig.getPlmn());
- assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, wifiConfig.meteredOverride);
+ // the configuration.
+ verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
}
/**
* Verify that an expected {@link PasspointConfiguration} will be returned when converting
- * from a {@link WifiConfiguration} containing an user credential.
+ * from a {@link WifiConfiguration} containing a user credential.
*
* @throws Exception
*/
@Test
public void convertFromWifiConfigWithUserCredential() throws Exception {
- // Test data.
- String fqdn = "test.com";
- String friendlyName = "Friendly Name";
- long[] rcOIs = new long[] {0x1234L, 0x2345L};
- String realm = "realm.com";
- String username = "username";
- String password = "password";
- byte[] base64EncodedPw =
- Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
- String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
-
// Setup WifiConfiguration for legacy Passpoint configuraiton.
WifiConfiguration wifiConfig = new WifiConfiguration();
- wifiConfig.FQDN = fqdn;
- wifiConfig.providerFriendlyName = friendlyName;
- wifiConfig.roamingConsortiumIds = rcOIs;
- wifiConfig.enterpriseConfig.setIdentity(username);
- wifiConfig.enterpriseConfig.setPassword(password);
- wifiConfig.enterpriseConfig.setRealm(realm);
+ wifiConfig.FQDN = TEST_FQDN;
+ wifiConfig.providerFriendlyName = TEST_FRIENDLY_NAME;
+ wifiConfig.roamingConsortiumIds = TEST_RC_OIS;
+ wifiConfig.enterpriseConfig.setIdentity(TEST_USERNAME);
+ wifiConfig.enterpriseConfig.setPassword(TEST_PASSWORD);
+ wifiConfig.enterpriseConfig.setRealm(TEST_REALM);
wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
// Setup expected {@link PasspointConfiguration}
- PasspointConfiguration passpointConfig = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(fqdn);
- homeSp.setFriendlyName(friendlyName);
- homeSp.setRoamingConsortiumOis(rcOIs);
- passpointConfig.setHomeSp(homeSp);
- Credential credential = new Credential();
- Credential.UserCredential userCredential = new Credential.UserCredential();
- userCredential.setUsername(username);
- userCredential.setPassword(encodedPasswordStr);
- userCredential.setEapType(EAPConstants.EAP_TTLS);
- userCredential.setNonEapInnerMethod("PAP");
- credential.setUserCredential(userCredential);
- credential.setRealm(realm);
- passpointConfig.setCredential(credential);
+ PasspointConfiguration passpointConfig = generateTestPasspointConfiguration(
+ CredentialType.USER, true);
+ Credential.UserCredential userCredential =
+ passpointConfig.getCredential().getUserCredential();
+ userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_PAP);
assertEquals(passpointConfig, PasspointProvider.convertFromWifiConfig(wifiConfig));
}
@@ -1193,36 +1212,18 @@ public class PasspointProviderTest {
*/
@Test
public void convertFromWifiConfigWithSimCredential() throws Exception {
- // Test data.
- String fqdn = "test.com";
- String friendlyName = "Friendly Name";
- long[] rcOIs = new long[] {0x1234L, 0x2345L};
- String realm = "realm.com";
- String imsi = "1234";
-
// Setup WifiConfiguration for legacy Passpoint configuraiton.
WifiConfiguration wifiConfig = new WifiConfiguration();
- wifiConfig.FQDN = fqdn;
- wifiConfig.providerFriendlyName = friendlyName;
- wifiConfig.roamingConsortiumIds = rcOIs;
- wifiConfig.enterpriseConfig.setRealm(realm);
+ wifiConfig.FQDN = TEST_FQDN;
+ wifiConfig.providerFriendlyName = TEST_FRIENDLY_NAME;
+ wifiConfig.roamingConsortiumIds = TEST_RC_OIS;
+ wifiConfig.enterpriseConfig.setRealm(TEST_REALM);
wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
- wifiConfig.enterpriseConfig.setPlmn(imsi);
+ wifiConfig.enterpriseConfig.setPlmn(TEST_IMSI);
// Setup expected {@link PasspointConfiguration}
- PasspointConfiguration passpointConfig = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(fqdn);
- homeSp.setFriendlyName(friendlyName);
- homeSp.setRoamingConsortiumOis(rcOIs);
- passpointConfig.setHomeSp(homeSp);
- Credential credential = new Credential();
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setEapType(EAPConstants.EAP_SIM);
- simCredential.setImsi(imsi);
- credential.setSimCredential(simCredential);
- credential.setRealm(realm);
- passpointConfig.setCredential(credential);
+ PasspointConfiguration passpointConfig = generateTestPasspointConfiguration(
+ CredentialType.SIM, true);
assertEquals(passpointConfig, PasspointProvider.convertFromWifiConfig(wifiConfig));
}
@@ -1235,33 +1236,17 @@ public class PasspointProviderTest {
*/
@Test
public void convertFromWifiConfigWithCertCredential() throws Exception {
- // Test data.
- String fqdn = "test.com";
- String friendlyName = "Friendly Name";
- long[] rcOIs = new long[] {0x1234L, 0x2345L};
- String realm = "realm.com";
-
// Setup WifiConfiguration for legacy Passpoint configuraiton.
WifiConfiguration wifiConfig = new WifiConfiguration();
- wifiConfig.FQDN = fqdn;
- wifiConfig.providerFriendlyName = friendlyName;
- wifiConfig.roamingConsortiumIds = rcOIs;
- wifiConfig.enterpriseConfig.setRealm(realm);
+ wifiConfig.FQDN = TEST_FQDN;
+ wifiConfig.providerFriendlyName = TEST_FRIENDLY_NAME;
+ wifiConfig.roamingConsortiumIds = TEST_RC_OIS;
+ wifiConfig.enterpriseConfig.setRealm(TEST_REALM);
wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
// Setup expected {@link PasspointConfiguration}
- PasspointConfiguration passpointConfig = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(fqdn);
- homeSp.setFriendlyName(friendlyName);
- homeSp.setRoamingConsortiumOis(rcOIs);
- passpointConfig.setHomeSp(homeSp);
- Credential credential = new Credential();
- Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
- certCredential.setCertType(Credential.CertificateCredential.CERT_TYPE_X509V3);
- credential.setCertCredential(certCredential);
- credential.setRealm(realm);
- passpointConfig.setCredential(credential);
+ PasspointConfiguration passpointConfig = generateTestPasspointConfiguration(
+ CredentialType.CERT, true);
assertEquals(passpointConfig, PasspointProvider.convertFromWifiConfig(wifiConfig));
}
@@ -1274,27 +1259,8 @@ public class PasspointProviderTest {
*/
@Test
public void providerBackedBySimCredential() throws Exception {
- // Test data.
- String fqdn = "test.com";
- String friendlyName = "Friendly Name";
- long[] rcOIs = new long[] {0x1234L, 0x2345L};
- String realm = "realm.com";
- String imsi = "1234*";
-
- // Create provider with SIM credential.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(fqdn);
- homeSp.setFriendlyName(friendlyName);
- homeSp.setRoamingConsortiumOis(rcOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setRealm(realm);
- Credential.SimCredential simCredential = new Credential.SimCredential();
- simCredential.setImsi(imsi);
- simCredential.setEapType(EAPConstants.EAP_SIM);
- credential.setSimCredential(simCredential);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.SIM, false);
mProvider = createProvider(config);
assertTrue(mProvider.isSimCredential());
@@ -1308,25 +1274,8 @@ public class PasspointProviderTest {
*/
@Test
public void providerNotBackedBySimCredential() throws Exception {
- // Test data.
- String fqdn = "test.com";
- String friendlyName = "Friendly Name";
- long[] rcOIs = new long[] {0x1234L, 0x2345L};
- String realm = "realm.com";
-
- // Create provider with certificate credential.
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn(fqdn);
- homeSp.setFriendlyName(friendlyName);
- homeSp.setRoamingConsortiumOis(rcOIs);
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
- certCredential.setCertType(Credential.CertificateCredential.CERT_TYPE_X509V3);
- credential.setCertCredential(certCredential);
- credential.setRealm(realm);
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.CERT, false);
mProvider = createProvider(config);
assertFalse(mProvider.isSimCredential());
@@ -1340,13 +1289,8 @@ public class PasspointProviderTest {
*/
@Test
public void setHasEverConnected() throws Exception {
- PasspointConfiguration config = new PasspointConfiguration();
- HomeSp homeSp = new HomeSp();
- homeSp.setFqdn("test1");
- config.setHomeSp(homeSp);
- Credential credential = new Credential();
- credential.setUserCredential(new Credential.UserCredential());
- config.setCredential(credential);
+ PasspointConfiguration config = generateTestPasspointConfiguration(
+ CredentialType.USER, false);
mProvider = createProvider(config);
verifyInstalledConfig(config, true);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java
index 64a7f9e2d1..e101aa9b0a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java
@@ -63,6 +63,7 @@ import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.org.conscrypt.TrustManagerImpl;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
@@ -105,7 +106,7 @@ import javax.net.ssl.SSLContext;
* Unit tests for {@link PasspointProvisioner}.
*/
@SmallTest
-public class PasspointProvisionerTest {
+public class PasspointProvisionerTest extends WifiBaseTest {
private static final int TEST_UID = 1500;
private static final int STEP_INIT = 0;
private static final int STEP_AP_CONNECT = 1;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointXmlUtilsTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointXmlUtilsTest.java
index 928a491684..233a740f96 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointXmlUtilsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointXmlUtilsTest.java
@@ -29,6 +29,7 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.WifiBaseTest;
import org.junit.Test;
import org.xmlpull.v1.XmlPullParser;
@@ -50,7 +51,7 @@ import java.util.Map;
* Unit tests for {@link com.android.server.wifi.hotspot2.PasspointXmlUtilsTest}.
*/
@SmallTest
-public class PasspointXmlUtilsTest {
+public class PasspointXmlUtilsTest extends WifiBaseTest {
/**
* Helper function for generating a {@link PasspointConfiguration} for testing the XML
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ServiceProviderVerifierTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ServiceProviderVerifierTest.java
index e6ecb330ec..fc4611af39 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ServiceProviderVerifierTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/ServiceProviderVerifierTest.java
@@ -32,14 +32,15 @@ import android.util.Pair;
import androidx.test.filters.SmallTest;
-import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
-import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import com.android.org.bouncycastle.asn1.DEROctetString;
-import com.android.org.bouncycastle.asn1.DERSequence;
-import com.android.org.bouncycastle.asn1.DERTaggedObject;
-import com.android.org.bouncycastle.asn1.DERUTF8String;
-import com.android.org.bouncycastle.asn1.x509.GeneralName;
-
+import com.android.server.wifi.WifiBaseTest;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.DERUTF8String;
+import org.bouncycastle.asn1.x509.GeneralName;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -55,7 +56,7 @@ import java.util.Locale;
* Unit tests for {@link ServiceProviderVerifier}.
*/
@SmallTest
-public class ServiceProviderVerifierTest {
+public class ServiceProviderVerifierTest extends WifiBaseTest {
private List<List<?>> mNewNames;
private static final String LOCAL_HOST_NAME = "localhost";
private static final byte[] LOCAL_HOST_ADDRESS = {127, 0, 0, 1};
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/SystemInfoTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/SystemInfoTest.java
index 62d7b503f8..6acc8872c0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/SystemInfoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/SystemInfoTest.java
@@ -27,6 +27,7 @@ import android.telephony.TelephonyManager;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiNative;
import org.junit.Before;
@@ -37,7 +38,7 @@ import org.mockito.Mock;
* Unit tests for {@link SystemInfo}.
*/
@SmallTest
-public class SystemInfoTest {
+public class SystemInfoTest extends WifiBaseTest {
@Mock Context mContext;
@Mock TelephonyManager mTelephonyManager;
@Mock TelephonyManager mDataTelephonyManager;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/UtilsTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/UtilsTest.java
index 6ddeb263eb..b3e17c6176 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/UtilsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/UtilsTest.java
@@ -18,6 +18,8 @@ package com.android.server.wifi.hotspot2;
import static org.junit.Assert.*;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.util.ArrayList;
@@ -25,7 +27,7 @@ import java.util.ArrayList;
/**
* Unit tests for {@link com.android.server.wifi.hotspot2.Utils}.
*/
-public class UtilsTest {
+public class UtilsTest extends WifiBaseTest {
@Test
public void testRoamingConsortiumsToStringLong() {
assertEquals("null", Utils.roamingConsortiumsToString((long[]) null));
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ANQPParserTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ANQPParserTest.java
index 016e322614..2aabcaa7a5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ANQPParserTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ANQPParserTest.java
@@ -22,6 +22,8 @@ import android.net.wifi.WifiSsid;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -39,7 +41,7 @@ import java.util.Locale;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.ANQPParser}.
*/
@SmallTest
-public class ANQPParserTest {
+public class ANQPParserTest extends WifiBaseTest {
/**
* Helper function for generating payload for a Venue Name ANQP element.
*
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/CellularNetworkTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/CellularNetworkTest.java
index 3b47ab4f04..1cfc85db18 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/CellularNetworkTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/CellularNetworkTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertNull;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -33,7 +35,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.CellularNetwork}.
*/
@SmallTest
-public class CellularNetworkTest {
+public class CellularNetworkTest extends WifiBaseTest {
private static final byte[] TEST_PLMN_BYTES_1 = new byte[] {0x12, 0x34, 0x56};
private static final String TEST_PLMN_STRING_1 = "214653";
private static final byte[] TEST_PLMN_BYTES_2 = new byte[] {0x13, (byte) 0xF9, 0x32};
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/DomainNameElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/DomainNameElementTest.java
index e293a4a9f3..1b81749d89 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/DomainNameElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/DomainNameElementTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -35,7 +37,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.DomainNameElement}.
*/
@SmallTest
-public class DomainNameElementTest {
+public class DomainNameElementTest extends WifiBaseTest {
private static final String TEST_DOMAIN_NAME1 = "test1.com";
private static final String TEST_DOMAIN_NAME2 = "test2.com";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSConnectionCapabilityElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSConnectionCapabilityElementTest.java
index 62a2b7f7cf..8c68c13f37 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSConnectionCapabilityElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSConnectionCapabilityElementTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.nio.BufferUnderflowException;
@@ -33,7 +35,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.HSConnectionCapabilityElement}.
*/
@SmallTest
-public class HSConnectionCapabilityElementTest {
+public class HSConnectionCapabilityElementTest extends WifiBaseTest {
private static final ProtocolPortTuple TEST_TUPLE1 =
new ProtocolPortTuple(1, 2, ProtocolPortTuple.PROTO_STATUS_CLOSED);
private static final ProtocolPortTuple TEST_TUPLE2 =
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSFriendlyNameElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSFriendlyNameElementTest.java
index dffb5a563d..256df82734 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSFriendlyNameElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSFriendlyNameElementTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -38,7 +40,7 @@ import java.util.Locale;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.HSFriendlyNameElement}.
*/
@SmallTest
-public class HSFriendlyNameElementTest {
+public class HSFriendlyNameElementTest extends WifiBaseTest {
private static final String TEST_LANGUAGE = "en";
private static final Locale TEST_LOCALE = Locale.forLanguageTag(TEST_LANGUAGE);
private static final String TEST_OPERATOR_NAME1 = "Operator1";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSIconFileElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSIconFileElementTest.java
index a1a9aba4a8..2b77613aef 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSIconFileElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSIconFileElementTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -32,7 +34,7 @@ import java.nio.charset.StandardCharsets;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.HSIconFileElement}.
*/
@SmallTest
-public class HSIconFileElementTest {
+public class HSIconFileElementTest extends WifiBaseTest {
private static final String TEST_ICON_TYPE = "png";
private static final byte[] TEST_ICON_DATA = new byte[8];
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSOsuProvidersElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSOsuProvidersElementTest.java
index de89ff9800..dfb5abec24 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSOsuProvidersElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSOsuProvidersElementTest.java
@@ -22,6 +22,8 @@ import android.net.wifi.WifiSsid;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -37,7 +39,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement}.
*/
@SmallTest
-public class HSOsuProvidersElementTest {
+public class HSOsuProvidersElementTest extends WifiBaseTest {
private static final byte[] TEST_OSU_SSID_BYTES = "Test SSID".getBytes(StandardCharsets.UTF_8);
private static final WifiSsid TEST_OSU_SSID =
WifiSsid.createFromByteArray(TEST_OSU_SSID_BYTES);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSWanMetricsElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSWanMetricsElementTest.java
index bebfc5adfb..e4b65f359d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSWanMetricsElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/HSWanMetricsElementTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -30,7 +32,7 @@ import java.nio.ByteOrder;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.HSWanMetricsElement}.
*/
@SmallTest
-public class HSWanMetricsElementTest {
+public class HSWanMetricsElementTest extends WifiBaseTest {
private static final int TEST_LINK_STATUS = HSWanMetricsElement.LINK_STATUS_UP;
private static final boolean TEST_SYMMETRIC_LINK = true;
private static final boolean TEST_AT_CAPACITY = true;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/I18NameTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/I18NameTest.java
index e495b8417f..bf9e230451 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/I18NameTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/I18NameTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -34,7 +36,7 @@ import java.util.Locale;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.I18Name}.
*/
@SmallTest
-public class I18NameTest {
+public class I18NameTest extends WifiBaseTest {
private static final String TEST_LANGUAGE = "en";
private static final Locale TEST_LOCALE = Locale.forLanguageTag(TEST_LANGUAGE);
private static final String TEST_TEXT = "Hello World";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IPAddressTypeAvailabilityElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IPAddressTypeAvailabilityElementTest.java
index 9c2862708f..2250871be0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IPAddressTypeAvailabilityElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IPAddressTypeAvailabilityElementTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -29,7 +31,7 @@ import java.nio.ByteBuffer;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.IPAddressTypeAvailabilityElement}.
*/
@SmallTest
-public class IPAddressTypeAvailabilityElementTest {
+public class IPAddressTypeAvailabilityElementTest extends WifiBaseTest {
private static final int TEST_IPV4_AVAILABILITY =
IPAddressTypeAvailabilityElement.IPV4_PUBLIC;
private static final int TEST_IPV6_AVAILABILITY =
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IconInfoTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IconInfoTest.java
index c44ad0bf02..3580a745ce 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IconInfoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/IconInfoTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertNotEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.nio.BufferUnderflowException;
@@ -30,7 +32,7 @@ import java.nio.ByteBuffer;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.IconInfo}.
*/
@SmallTest
-public class IconInfoTest {
+public class IconInfoTest extends WifiBaseTest {
private static final int TEST_WIDTH = 1111;
private static final int TEST_HEIGHT = 2222;
private static final String TEST_LANGUAGE = "language";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmDataTest.java
index aa342d4af7..4839b3d63b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmDataTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -30,7 +32,7 @@ import java.nio.ByteBuffer;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.NAIRealmData}.
*/
@SmallTest
-public class NAIRealmDataTest {
+public class NAIRealmDataTest extends WifiBaseTest {
/**
* Verify that BufferUnderflowException will be thrown when parsing from an empty buffer.
*
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmElementTest.java
index 553f0ee833..6e0c87a3cd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/NAIRealmElementTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.nio.ByteBuffer;
@@ -32,7 +34,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.NAIRealmElement}.
*/
@SmallTest
-public class NAIRealmElementTest {
+public class NAIRealmElementTest extends WifiBaseTest {
/**
* Helper function for returning a ByteBuffer containing raw bytes for NAI Realm Element
* with specified number of NAI Realm Data.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/OsuProviderInfoTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/OsuProviderInfoTest.java
index 2855db9d77..7dea30be04 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/OsuProviderInfoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/OsuProviderInfoTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertNotNull;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -34,7 +36,7 @@ import java.util.Locale;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.OsuProviderInfo}.
*/
@SmallTest
-public class OsuProviderInfoTest {
+public class OsuProviderInfoTest extends WifiBaseTest {
/**
* Verify that BufferUnderflowException will be thrown when parsing an empty buffer.
* @throws Exception
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ProtocolPortTupleTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ProtocolPortTupleTest.java
index fc0942a7e3..ba6a79f7ef 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ProtocolPortTupleTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ProtocolPortTupleTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.nio.BufferUnderflowException;
@@ -30,7 +32,7 @@ import java.nio.ByteOrder;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.ProtocolPortTuple}.
*/
@SmallTest
-public class ProtocolPortTupleTest {
+public class ProtocolPortTupleTest extends WifiBaseTest {
private static final int TEST_PROTOCOL = 1;
private static final int TEST_PORT = 2;
private static final int TEST_STATUS = ProtocolPortTuple.PROTO_STATUS_CLOSED;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RawByteElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RawByteElementTest.java
index 3032210eb7..dd78f33339 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RawByteElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RawByteElementTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.nio.ByteBuffer;
@@ -28,7 +30,7 @@ import java.nio.ByteBuffer;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.RawByteElement}.
*/
@SmallTest
-public class RawByteElementTest {
+public class RawByteElementTest extends WifiBaseTest {
private static final Constants.ANQPElementType TEST_ELEMENT_ID =
Constants.ANQPElementType.HSOSUProviders;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RoamingConsortiumElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RoamingConsortiumElementTest.java
index dad7c2bc4d..2df578a409 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RoamingConsortiumElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/RoamingConsortiumElementTest.java
@@ -23,6 +23,8 @@ import android.util.Pair;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -37,7 +39,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.RoamingConsortiumElement}.
*/
@SmallTest
-public class RoamingConsortiumElementTest {
+public class RoamingConsortiumElementTest extends WifiBaseTest {
// Default test data. Each test data contained a pair indicating the number of bytes for the
// OI and the value of the OI.
private static final Pair<Integer, Long> TEST_OI1 = new Pair<Integer, Long>(1, 0x12L);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ThreeGPPNetworkElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ThreeGPPNetworkElementTest.java
index 4add837699..8a036e0680 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ThreeGPPNetworkElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/ThreeGPPNetworkElementTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -34,7 +36,7 @@ import java.util.List;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.ThreeGPPNetworkElement}.
*/
@SmallTest
-public class ThreeGPPNetworkElementTest {
+public class ThreeGPPNetworkElementTest extends WifiBaseTest {
private static final byte[][] TEST_NETWORK1_PLMN_BYTES =
new byte[][] { new byte[] {0x21, 0x63, 0x54},
new byte[] {0x43, (byte) 0x85, 0x76} };
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/VenueNameElementTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/VenueNameElementTest.java
index 006ebac36e..3bfcd69ff0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/VenueNameElementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/VenueNameElementTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -38,7 +40,7 @@ import java.util.Locale;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.VenueNameElement}.
*/
@SmallTest
-public class VenueNameElementTest {
+public class VenueNameElementTest extends WifiBaseTest {
private static final String TEST_LANGUAGE = "en";
private static final Locale TEST_LOCALE = Locale.forLanguageTag(TEST_LANGUAGE);
private static final String TEST_VENUE_NAME1 = "Venue1";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/CredentialTypeTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/CredentialTypeTest.java
index 160029b639..d130571b76 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/CredentialTypeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/CredentialTypeTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -30,7 +32,7 @@ import java.nio.ByteBuffer;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.eap.CredentialType}.
*/
@SmallTest
-public class CredentialTypeTest {
+public class CredentialTypeTest extends WifiBaseTest {
private static final int TEST_TYPE = CredentialType.CREDENTIAL_TYPE_USIM;
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/EAPMethodTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/EAPMethodTest.java
index 8ddd9a8f17..69c20d5d5a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/EAPMethodTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/EAPMethodTest.java
@@ -22,6 +22,8 @@ import android.net.wifi.EAPConstants;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -36,7 +38,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.eap.EAPMethod}.
*/
@SmallTest
-public class EAPMethodTest {
+public class EAPMethodTest extends WifiBaseTest {
/**
* Setup basic test data - contained multiple parameters of the same type.
*/
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/ExpandedEAPMethodTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/ExpandedEAPMethodTest.java
index 1c112dfaa3..a2c92fd9a9 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/ExpandedEAPMethodTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/ExpandedEAPMethodTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -30,7 +32,7 @@ import java.nio.ByteBuffer;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.eap.ExpandedEAPMethod}.
*/
@SmallTest
-public class ExpandedEAPMethodTest {
+public class ExpandedEAPMethodTest extends WifiBaseTest {
private static final int TEST_VENDOR_ID = 0x123456;
private static final long TEST_VENDOR_TYPE = 0x23456523;
private static final byte[] TEST_DATA_BYTES =
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/InnerAuthEAPTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/InnerAuthEAPTest.java
index d7087d94da..6a2bc79a30 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/InnerAuthEAPTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/InnerAuthEAPTest.java
@@ -22,6 +22,8 @@ import android.net.wifi.EAPConstants;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -32,7 +34,7 @@ import java.nio.ByteBuffer;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.eap.InnerAuthEAP}.
*/
@SmallTest
-public class InnerAuthEAPTest {
+public class InnerAuthEAPTest extends WifiBaseTest {
private static final int TEST_EAP_METHOD_ID = EAPConstants.EAP_TTLS;
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/NonEAPInnerAuthTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/NonEAPInnerAuthTest.java
index 3a4b6ed3a4..c3101f7e43 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/NonEAPInnerAuthTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/NonEAPInnerAuthTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.net.ProtocolException;
@@ -30,7 +32,7 @@ import java.nio.ByteBuffer;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.eap.NonEAPInnerAuth}.
*/
@SmallTest
-public class NonEAPInnerAuthTest {
+public class NonEAPInnerAuthTest extends WifiBaseTest {
private static final int TEST_AUTH_TYPE = NonEAPInnerAuth.AUTH_TYPE_MSCHAP;
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/VendorSpecificAuthTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/VendorSpecificAuthTest.java
index 491077e3b6..3e167f8474 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/VendorSpecificAuthTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/anqp/eap/VendorSpecificAuthTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.nio.BufferUnderflowException;
@@ -29,7 +31,7 @@ import java.nio.ByteBuffer;
* Unit tests for {@link com.android.server.wifi.hotspot2.anqp.eap.VendorSpecificAuth}.
*/
@SmallTest
-public class VendorSpecificAuthTest {
+public class VendorSpecificAuthTest extends WifiBaseTest {
private static final byte[] TEST_DATA = new byte[] {0x12, 0x34, 0x45, 0x56};
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevDetailMoTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevDetailMoTest.java
index f54e360d0c..af3fa0219a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevDetailMoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevDetailMoTest.java
@@ -30,6 +30,7 @@ import android.telephony.TelephonyManager;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.SystemInfo;
import org.junit.Before;
@@ -41,7 +42,7 @@ import org.mockito.Mock;
* TODO(b/80300806): change the test to verify the XML in terms of the structure of XML.
*/
@SmallTest
-public class DevDetailMoTest {
+public class DevDetailMoTest extends WifiBaseTest {
private static final String TEST_DEV_ID = "12312341";
private static final String TEST_MANUFACTURER = Build.MANUFACTURER;
private static final String TEST_HW_VERSION = "Test HW 1.0";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevInfoMoTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevInfoMoTest.java
index d0a538ed57..aaa4e39d4b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevInfoMoTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/DevInfoMoTest.java
@@ -24,6 +24,7 @@ import android.os.Build;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.SystemInfo;
import org.junit.Test;
@@ -33,7 +34,7 @@ import org.junit.Test;
* TODO(b/80300806): change the test to verify the XML in terms of the structure of XML.
*/
@SmallTest
-public class DevInfoMoTest {
+public class DevInfoMoTest extends WifiBaseTest {
private static final String TEST_DEV_ID = "12312341";
private static final String TEST_MANUFACTURER = Build.MANUFACTURER;
private static final String TEST_MODEL = Build.MODEL;
@@ -61,4 +62,4 @@ public class DevInfoMoTest {
TEST_MODEL, MoSerializer.DM_VERSION, TEST_LANGUAGE);
assertEquals(expected, DevInfoMo.serializeToXml(systemInfo));
}
-} \ No newline at end of file
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/MoSerializerTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/MoSerializerTest.java
index 2c28ed22ce..213dd74c7d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/MoSerializerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/omadm/MoSerializerTest.java
@@ -22,6 +22,8 @@ import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
@@ -35,7 +37,7 @@ import java.util.List;
* Unit tests for {@link MoSerializer}.
*/
@SmallTest
-public class MoSerializerTest {
+public class MoSerializerTest extends WifiBaseTest {
MoSerializer mMoSerializer;
Document mDocument;
static final String TEST_NODE = "test_node";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessageTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessageTest.java
index 933a20602b..4b2739be8d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessageTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessageTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertNull;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import org.ksoap2.serialization.SoapObject;
@@ -28,7 +30,7 @@ import org.ksoap2.serialization.SoapObject;
* Unit tests for {@link ExchangeCompleteMessage}.
*/
@SmallTest
-public class ExchangeCompleteMessageTest {
+public class ExchangeCompleteMessageTest extends WifiBaseTest {
private static final String TEST_STATUS = "OK";
private static final String TEST_SESSION_ID = "D215D696517BA138F1D28442DF0F4E07";
private static final String TEST_VERSION = "1.0";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsServiceConnectionTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsServiceConnectionTest.java
index 3d5dae847f..ee813a6b63 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsServiceConnectionTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsServiceConnectionTest.java
@@ -27,6 +27,8 @@ import android.net.Network;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.ksoap2.HeaderProperty;
@@ -48,7 +50,7 @@ import javax.net.ssl.HttpsURLConnection;
* Unit tests for {@link HttpsServiceConnection}.
*/
@SmallTest
-public class HttpsServiceConnectionTest {
+public class HttpsServiceConnectionTest extends WifiBaseTest {
private static final String TEST_URL = "https://127.0.0.1:12345/index.htm";
private HttpsServiceConnection mHttpsServiceConnection;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsTransportTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsTransportTest.java
index 6975765d82..d0aff449ba 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsTransportTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/HttpsTransportTest.java
@@ -25,6 +25,8 @@ import android.net.Network;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -38,7 +40,7 @@ import javax.net.ssl.HttpsURLConnection;
* Unit tests for {@link HttpsTransport}.
*/
@SmallTest
-public class HttpsTransportTest {
+public class HttpsTransportTest extends WifiBaseTest {
private static final String TEST_URL = "https://127.0.0.1:12345/index.htm";
private URL mUrl;
private HttpsTransport mHttpsTransport;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataMessageTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataMessageTest.java
index 7fe03e124e..841dcd6f2b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataMessageTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataMessageTest.java
@@ -31,6 +31,7 @@ import android.telephony.TelephonyManager;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.SystemInfo;
import com.android.server.wifi.hotspot2.omadm.DevDetailMo;
import com.android.server.wifi.hotspot2.omadm.DevInfoMo;
@@ -49,7 +50,7 @@ import org.mockito.Mock;
* Unit tests for {@link PostDevDataMessage}.
*/
@SmallTest
-public class PostDevDataMessageTest {
+public class PostDevDataMessageTest extends WifiBaseTest {
private static final String TEST_DEV_ID = "12312341";
private static final String TEST_MANUFACTURER = Build.MANUFACTURER;
private static final String TEST_MODEL = Build.MODEL;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataResponseTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataResponseTest.java
index 0b48a73ef3..9e1fb2983c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataResponseTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/PostDevDataResponseTest.java
@@ -22,6 +22,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.soap.command.SppCommand;
import org.junit.Before;
@@ -33,7 +34,7 @@ import org.ksoap2.serialization.SoapObject;
* Unit tests for {@link PostDevDataResponse}.
*/
@SmallTest
-public class PostDevDataResponseTest {
+public class PostDevDataResponseTest extends WifiBaseTest {
private static final String EXEC = "exec";
private static final String BROWSER_COMMAND = "launchBrowserToURI";
private static final String TEST_URL = "https://127.0.0.1:12345/index.htm";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/RedirectListenerTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/RedirectListenerTest.java
index d61a59d6f9..aa4e188730 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/RedirectListenerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/RedirectListenerTest.java
@@ -29,6 +29,8 @@ import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -42,7 +44,7 @@ import fi.iki.elonen.NanoHTTPD;
* Unit tests for {@link RedirectListener}.
*/
@SmallTest
-public class RedirectListenerTest {
+public class RedirectListenerTest extends WifiBaseTest {
private static final int TEST_PORT = 1010;
private RedirectListenerSpy mRedirectListener;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SoapParserTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SoapParserTest.java
index 2445caba5c..c52a84abd4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SoapParserTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SoapParserTest.java
@@ -22,6 +22,8 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.ksoap2.serialization.PropertyInfo;
@@ -31,7 +33,7 @@ import org.ksoap2.serialization.SoapObject;
* Unit tests for {@link SoapParser}.
*/
@SmallTest
-public class SoapParserTest {
+public class SoapParserTest extends WifiBaseTest {
private static final String EXEC = "exec";
private static final String BROWSER_COMMAND = "launchBrowserToURI";
private static final String TEST_URL = "https://127.0.0.1:12345/index.htm";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SppResponseMessageTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SppResponseMessageTest.java
index 4169868f1d..823cc9d602 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SppResponseMessageTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/SppResponseMessageTest.java
@@ -22,6 +22,8 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.ksoap2.serialization.SoapObject;
@@ -33,7 +35,7 @@ import java.util.Map;
* Unit tests for {@link SppResponseMessage}.
*/
@SmallTest
-public class SppResponseMessageTest {
+public class SppResponseMessageTest extends WifiBaseTest {
private static final String TEST_STATUS = "OK";
private static final String TEST_ERROR_STATUS = "Error occurred";
private static final String TEST_SESSION_ID = "D215D696517BA138F1D28442DF0F4E07";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/UpdateResponseMessageTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/UpdateResponseMessageTest.java
index 9098c2297b..881ed9c943 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/UpdateResponseMessageTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/UpdateResponseMessageTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertNotNull;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
@@ -30,7 +32,7 @@ import org.ksoap2.serialization.SoapSerializationEnvelope;
* Unit tests for {@link UpdateResponseMessage}.
*/
@SmallTest
-public class UpdateResponseMessageTest {
+public class UpdateResponseMessageTest extends WifiBaseTest {
private static final String TEST_SESSION_ID = "123456";
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/BrowserUriTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/BrowserUriTest.java
index 2fe5e752f0..e5691e7d88 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/BrowserUriTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/BrowserUriTest.java
@@ -22,6 +22,8 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.ksoap2.serialization.PropertyInfo;
@@ -30,7 +32,7 @@ import org.ksoap2.serialization.PropertyInfo;
* Unit tests for {@link BrowserUri}.
*/
@SmallTest
-public class BrowserUriTest {
+public class BrowserUriTest extends WifiBaseTest {
private static final String BROWSER_COMMAND = "launchBrowserToURI";
private static final String TEST_URL = "https://127.0.0.1:12345/index.htm";
private BrowserUri mBrowserUri;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/PpsMoDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/PpsMoDataTest.java
index cc56b06ef2..28642661ef 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/PpsMoDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/PpsMoDataTest.java
@@ -26,6 +26,8 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.ksoap2.serialization.PropertyInfo;
@@ -35,7 +37,7 @@ import org.ksoap2.serialization.SoapPrimitive;
* Unit tests for {@link PpsMoData}.
*/
@SmallTest
-public class PpsMoDataTest {
+public class PpsMoDataTest extends WifiBaseTest {
private static final String TEST_PPS_MO_XML = "<MgmtTree>test</MgmtTree>";
private static final String TEST_TREE_URI = "testTreeURI";
private static final String TEST_MO_URN = "testMoURN";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/SppCommandTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/SppCommandTest.java
index 52d4615ad1..1f00e2c520 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/SppCommandTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/command/SppCommandTest.java
@@ -22,6 +22,8 @@ import static org.mockito.MockitoAnnotations.initMocks;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.ksoap2.serialization.PropertyInfo;
@@ -31,7 +33,7 @@ import org.ksoap2.serialization.SoapObject;
* Unit tests for {@link SppCommand}.
*/
@SmallTest
-public class SppCommandTest {
+public class SppCommandTest extends WifiBaseTest {
private static final String EXEC = "exec";
private static final String BROWSER_COMMAND = "launchBrowserToURI";
private static final String GET_CERT_COMMAND = "getCertificate";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackTest.java
index 807352cf42..fafb632227 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceCallbackTest.java
@@ -36,6 +36,7 @@ import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.p2p.WifiP2pServiceImpl.P2pStatus;
import com.android.server.wifi.util.NativeUtil;
@@ -53,7 +54,7 @@ import java.util.List;
* Unit tests for SupplicantP2pIfaceCallback
*/
@SmallTest
-public class SupplicantP2pIfaceCallbackTest {
+public class SupplicantP2pIfaceCallbackTest extends WifiBaseTest {
private static final String TAG = "SupplicantP2pIfaceCallbackTest";
private String mIface = "test_p2p0";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java
index 8c3328eff0..c642daf0cb 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/SupplicantP2pIfaceHalTest.java
@@ -51,6 +51,7 @@ import android.text.TextUtils;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.util.NativeUtil;
import org.junit.Assert.*;
@@ -71,7 +72,7 @@ import java.util.Map;
* Unit tests for SupplicantP2pIfaceHal
*/
@SmallTest
-public class SupplicantP2pIfaceHalTest {
+public class SupplicantP2pIfaceHalTest extends WifiBaseTest {
private static final String TAG = "SupplicantP2pIfaceHalTest";
private SupplicantP2pIfaceHal mDut;
private @Mock IServiceManager mServiceManagerMock;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMetricsTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMetricsTest.java
index 7d4796d212..bc69ec68a2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMetricsTest.java
@@ -24,6 +24,7 @@ import android.net.wifi.p2p.WifiP2pGroupList;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.nano.WifiMetricsProto.GroupEvent;
import com.android.server.wifi.nano.WifiMetricsProto.P2pConnectionEvent;
import com.android.server.wifi.nano.WifiMetricsProto.WifiP2pStats;
@@ -37,7 +38,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WifiP2pMetrics}.
*/
@SmallTest
-public class WifiP2pMetricsTest {
+public class WifiP2pMetricsTest extends WifiBaseTest {
@Mock Clock mClock;
WifiP2pMetrics mWifiP2pMetrics;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMonitorTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMonitorTest.java
index 68aceb37e1..bced05d007 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMonitorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pMonitorTest.java
@@ -27,6 +27,7 @@ import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiInjector;
import org.junit.Before;
@@ -37,7 +38,7 @@ import org.mockito.ArgumentCaptor;
* Unit tests for {@link com.android.server.wifi.WifiP2pMonitor}.
*/
@SmallTest
-public class WifiP2pMonitorTest {
+public class WifiP2pMonitorTest extends WifiBaseTest {
private static final String P2P_IFACE_NAME = "p2p0";
private static final String SECOND_P2P_IFACE_NAME = "p2p1";
private WifiP2pMonitor mWifiP2pMonitor;
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 962acd01e7..eb48b71c75 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
@@ -41,6 +41,7 @@ import com.android.server.wifi.HalDeviceManager.InterfaceAvailableForRequestList
import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
import com.android.server.wifi.HalDeviceManager.ManagerStatusListener;
import com.android.server.wifi.PropertyService;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiVendorHal;
import org.junit.Before;
@@ -54,7 +55,7 @@ import org.mockito.MockitoAnnotations;
* {@link com.android.server.wifi.WifiP2pNative}.
*/
@SmallTest
-public class WifiP2pNativeInterfaceManagementTest {
+public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest {
private static final String P2P_IFACE_NAME = "p2p0";
private static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface";
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 4fda65e38e..045b1752f3 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
@@ -43,6 +43,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.PropertyService;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiVendorHal;
import org.junit.Before;
@@ -55,7 +56,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.WifiP2pMonitor}.
*/
@SmallTest
-public class WifiP2pNativeTest {
+public class WifiP2pNativeTest extends WifiBaseTest {
private static final String TEST_DEVICE_NAME = "Android_HelloWorld";
private static final String TEST_IFACE = "p2p-p2p0-1";
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 15d9ef9157..8127ffe478 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
@@ -78,6 +78,7 @@ import com.android.internal.R;
import com.android.server.wifi.FakeWifiLog;
import com.android.server.wifi.FrameworkFacade;
import com.android.server.wifi.HalDeviceManager;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.nano.WifiMetricsProto.P2pConnectionEvent;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -97,7 +98,7 @@ import java.util.List;
* Unit test harness for WifiP2pServiceImpl.
*/
@SmallTest
-public class WifiP2pServiceImplTest {
+public class WifiP2pServiceImplTest extends WifiBaseTest {
private static final String TAG = "WifiP2pServiceImplTest";
private static final String IFACE_NAME_P2P = "mockP2p0";
private static final long STATE_CHANGE_WAITING_TIME = 1000;
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 a319539c53..891fb40030 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 android.util.Log;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.nano.WifiMetricsProto;
import org.junit.Before;
@@ -48,7 +49,7 @@ import java.util.List;
* Unit test harness for RttMetrics
*/
@SmallTest
-public class RttMetricsTest {
+public class RttMetricsTest extends WifiBaseTest {
private RttMetrics mDut;
@Mock
diff --git a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttNativeTest.java b/service/tests/wifitests/src/com/android/server/wifi/rtt/RttNativeTest.java
index d2f22da6a9..f6562fae77 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttNativeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/rtt/RttNativeTest.java
@@ -46,6 +46,7 @@ import android.net.wifi.rtt.RangingRequest;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.HalDeviceManager;
+import com.android.server.wifi.WifiBaseTest;
import org.hamcrest.core.IsNull;
import org.junit.Before;
@@ -63,7 +64,7 @@ import java.util.List;
* Unit test harness for the RttNative class.
*/
@SmallTest
-public class RttNativeTest {
+public class RttNativeTest extends WifiBaseTest {
private RttNative mDut;
private WifiStatus mStatusSuccess;
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 cd61aac08c..1156aa863b 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
@@ -75,6 +75,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
import com.android.server.wifi.FrameworkFacade;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.nano.WifiMetricsProto;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -98,7 +99,7 @@ import java.util.Set;
* Unit test harness for the RttServiceImpl class.
*/
@SmallTest
-public class RttServiceImplTest {
+public class RttServiceImplTest extends WifiBaseTest {
private static final long BACKGROUND_PROCESS_EXEC_GAP_MS = 10 * 60 * 1000; // 10 minutes.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/BackgroundScanSchedulerTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/BackgroundScanSchedulerTest.java
index f5e777e202..39ecb6f6eb 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/BackgroundScanSchedulerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/BackgroundScanSchedulerTest.java
@@ -32,6 +32,7 @@ import android.util.ArraySet;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WifiNative.BucketSettings;
import com.android.server.wifi.scanner.KnownBandsChannelHelper.KnownBandsChannelCollection;
@@ -50,7 +51,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.scanner.BackgroundScanScheduler}.
*/
@SmallTest
-public class BackgroundScanSchedulerTest {
+public class BackgroundScanSchedulerTest extends WifiBaseTest {
private static final int DEFAULT_MAX_BUCKETS = 9;
private static final int DEFAULT_MAX_CHANNELS_PER_BUCKET = 23;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
index 7e02507395..9b24b14a4f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
@@ -39,6 +39,7 @@ import com.android.server.wifi.MockResources;
import com.android.server.wifi.MockWifiMonitor;
import com.android.server.wifi.ScanDetail;
import com.android.server.wifi.ScanResults;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiMonitor;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection;
@@ -60,7 +61,7 @@ import java.util.Set;
* {@link com.android.server.wifi.scanner.WifiScannerImpl}.
*/
@SmallTest
-public abstract class BaseWifiScannerImplTest {
+public abstract class BaseWifiScannerImplTest extends WifiBaseTest {
protected static final String IFACE_NAME = "a_test_interface_name";
@Mock Context mContext;
TestAlarmManager mAlarmManager;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/ChannelHelperTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/ChannelHelperTest.java
index 74674b966b..5ad6c32f5e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/ChannelHelperTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/ChannelHelperTest.java
@@ -30,6 +30,7 @@ import android.net.wifi.WifiScanner;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiNative;
import org.junit.Before;
@@ -41,14 +42,14 @@ import org.junit.runner.RunWith;
* Unit tests for {@link com.android.server.wifi.scanner.ChannelHelper}.
*/
@RunWith(Enclosed.class) // WARNING: tests cannot be declared in the outer class
-public class ChannelHelperTest {
+public class ChannelHelperTest extends WifiBaseTest {
/**
* Unit tests for
* {@link com.android.server.wifi.scanner.ChannelHelper#toString}.
*/
@SmallTest
- public static class ToStringTest {
+ public static class ToStringTest extends WifiBaseTest {
/**
* Compute a string representing the channels in a ScanSettings with a band set.
*/
@@ -117,7 +118,7 @@ public class ChannelHelperTest {
* {@link com.android.server.wifi.scanner.ChannelHelper.ChannelCollection}.
*/
@SmallTest
- public static class ChannelCollectionTest {
+ public static class ChannelCollectionTest extends WifiBaseTest {
ChannelHelper.ChannelCollection mChannelCollection;
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/KnownBandsChannelHelperTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/KnownBandsChannelHelperTest.java
index bc70f65b85..2fadf0355e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/KnownBandsChannelHelperTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/KnownBandsChannelHelperTest.java
@@ -31,6 +31,7 @@ import android.net.wifi.WifiScanner;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiNative;
import org.junit.Before;
@@ -51,13 +52,14 @@ public class KnownBandsChannelHelperTest {
private static final int[] CHANNELS_24_GHZ = new int[]{2400, 2450};
private static final int[] CHANNELS_5_GHZ = new int[]{5150, 5175};
private static final int[] CHANNELS_DFS = new int[]{5600, 5650, 5660};
+ private static final int[] CHANNELS_DFS_OTHER = new int[]{5600, 5650, 5660, 5680};
/**
* Unit tests for
* {@link com.android.server.wifi.scanner.KnownBandsChannelHelper.estimateScanDuration}.
*/
@SmallTest
- public static class EstimateScanDurationTest {
+ public static class EstimateScanDurationTest extends WifiBaseTest {
KnownBandsChannelHelper mChannelHelper;
/**
@@ -102,7 +104,7 @@ public class KnownBandsChannelHelperTest {
* {@link com.android.server.wifi.scanner.KnownBandsChannelHelper.getAvailableScanChannels}.
*/
@SmallTest
- public static class GetAvailableScanChannelsTest {
+ public static class GetAvailableScanChannelsTest extends WifiBaseTest {
KnownBandsChannelHelper mChannelHelper;
/**
@@ -185,7 +187,7 @@ public class KnownBandsChannelHelperTest {
* {@link com.android.server.wifi.scanner.KnownBandsChannelHelper.settingsContainChannel}.
*/
@SmallTest
- public static class SettingsContainChannelTest {
+ public static class SettingsContainChannelTest extends WifiBaseTest {
KnownBandsChannelHelper mChannelHelper;
/**
@@ -257,10 +259,49 @@ public class KnownBandsChannelHelperTest {
/**
* Unit tests for
+ * {@link com.android.server.wifi.scanner.KnownBandsChannelHelper#equals(ChannelHelper)}.
+ */
+ @SmallTest
+ public static class EqualsTest extends WifiBaseTest {
+ /**
+ * Creates 2 channel helper instances which are equal.
+ */
+ @Test
+ public void channelHelpersAreSatisfiedBySame() {
+ KnownBandsChannelHelper channelHelper0 = new PresetKnownBandsChannelHelper(
+ CHANNELS_24_GHZ,
+ CHANNELS_5_GHZ,
+ CHANNELS_DFS);
+ KnownBandsChannelHelper channelHelper1 = new PresetKnownBandsChannelHelper(
+ CHANNELS_24_GHZ,
+ CHANNELS_5_GHZ,
+ CHANNELS_DFS);
+ assertTrue(channelHelper0.satisfies(channelHelper1));
+ }
+
+ /**
+ * Creates 2 channel helper instances which are equal.
+ */
+ @Test
+ public void channelHelpersAreNotSatisfiedByDifferent() {
+ KnownBandsChannelHelper channelHelper0 = new PresetKnownBandsChannelHelper(
+ CHANNELS_24_GHZ,
+ CHANNELS_5_GHZ,
+ CHANNELS_DFS);
+ KnownBandsChannelHelper channelHelper1 = new PresetKnownBandsChannelHelper(
+ CHANNELS_24_GHZ,
+ CHANNELS_5_GHZ,
+ CHANNELS_DFS_OTHER);
+ assertFalse(channelHelper0.satisfies(channelHelper1));
+ }
+ }
+
+ /**
+ * Unit tests for
* {@link com.android.server.wifi.scanner.KnownBandsChannelHelper.KnownBandsChannelCollection}.
*/
@SmallTest
- public static class KnownBandsChannelCollectionTest {
+ public static class KnownBandsChannelCollectionTest extends WifiBaseTest {
ChannelHelper.ChannelCollection mChannelCollection;
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/ScanScheduleUtilFilterTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/ScanScheduleUtilFilterTest.java
index e08829f8f1..4bf2766ed3 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/ScanScheduleUtilFilterTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/ScanScheduleUtilFilterTest.java
@@ -33,6 +33,8 @@ import android.net.wifi.WifiScanner.ScanSettings;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
@@ -41,7 +43,7 @@ import org.junit.Test;
* {@link com.android.server.wifi.scanner.ScanScheduleUtil}.
*/
@SmallTest
-public class ScanScheduleUtilFilterTest {
+public class ScanScheduleUtilFilterTest extends WifiBaseTest {
private ChannelHelper mChannelHelper;
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 c2c974499d..ea1fb51d50 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
@@ -17,6 +17,8 @@
package com.android.server.wifi.scanner;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.wifi.WifiScanner.GET_AVAILABLE_CHANNELS_EXTRA;
import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder;
import static com.android.server.wifi.ScanTestUtil.assertNativePnoSettingsEquals;
@@ -51,13 +53,15 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.app.test.TestAlarmManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiScanner;
+import android.net.wifi.WifiStackClient;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -65,6 +69,7 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.WorkSource;
import android.os.test.TestLooper;
+import android.util.ArraySet;
import android.util.Pair;
import androidx.test.filters.SmallTest;
@@ -73,12 +78,12 @@ import com.android.internal.app.IBatteryStats;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.internal.util.test.BidirectionalAsyncChannel;
-import com.android.server.wifi.CellularLinkLayerStatsCollector;
import com.android.server.wifi.Clock;
import com.android.server.wifi.DppMetrics;
import com.android.server.wifi.FakeWifiLog;
import com.android.server.wifi.FrameworkFacade;
import com.android.server.wifi.ScanResults;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
@@ -112,15 +117,20 @@ import java.util.regex.Pattern;
* Unit tests for {@link com.android.server.wifi.scanner.WifiScanningServiceImpl}.
*/
@SmallTest
-public class WifiScanningServiceTest {
+public class WifiScanningServiceTest extends WifiBaseTest {
public static final String TAG = "WifiScanningServiceTest";
private static final int TEST_MAX_SCAN_BUCKETS_IN_CAPABILITIES = 8;
private static final String TEST_PACKAGE_NAME = "com.test.123";
+ private static final String TEST_IFACE_NAME_0 = "wlan0";
+ private static final String TEST_IFACE_NAME_1 = "wlan1";
+ private static final WifiScanner.ScanData DUMMY_SCAN_DATA =
+ new WifiScanner.ScanData(0, 0, new ScanResult[0]);
@Mock Context mContext;
TestAlarmManager mAlarmManager;
- @Mock WifiScannerImpl mWifiScannerImpl;
+ @Mock WifiScannerImpl mWifiScannerImpl0;
+ @Mock WifiScannerImpl mWifiScannerImpl1;
@Mock WifiScannerImpl.WifiScannerImplFactory mWifiScannerImplFactory;
@Mock IBatteryStats mBatteryStats;
@Mock WifiInjector mWifiInjector;
@@ -129,11 +139,13 @@ public class WifiScanningServiceTest {
@Spy FakeWifiLog mLog;
@Mock WifiPermissionsUtil mWifiPermissionsUtil;
@Mock DppMetrics mDppMetrics;
+ @Mock WifiNative mWifiNative;
+ ChannelHelper mChannelHelper0;
+ ChannelHelper mChannelHelper1;
WifiMetrics mWifiMetrics;
TestLooper mLooper;
WifiScanningServiceImpl mWifiScanningServiceImpl;
@Mock WifiP2pMetrics mWifiP2pMetrics;
- @Mock CellularLinkLayerStatsCollector mCellularLinkLayerStatsCollector;
@Before
public void setUp() throws Exception {
@@ -145,19 +157,28 @@ public class WifiScanningServiceTest {
when(mWifiInjector.getWifiPermissionsUtil())
.thenReturn(mWifiPermissionsUtil);
- ChannelHelper channelHelper = new PresetKnownBandsChannelHelper(
+ mChannelHelper0 = new PresetKnownBandsChannelHelper(
new int[]{2400, 2450},
new int[]{5150, 5175},
new int[]{5600, 5650, 5660});
+ mChannelHelper1 = new PresetKnownBandsChannelHelper(
+ new int[]{2400, 2450},
+ new int[]{5150, 5175},
+ new int[]{5600, 5660, 5680}); // 5650 is missing from channelHelper0
mLooper = new TestLooper();
mWifiMetrics = new WifiMetrics(mContext, mFrameworkFacade, mClock, mLooper.getLooper(),
- new WifiAwareMetrics(mClock), new RttMetrics(mClock), new WifiPowerMetrics(),
- mWifiP2pMetrics, mDppMetrics, mCellularLinkLayerStatsCollector);
+ new WifiAwareMetrics(mClock), new RttMetrics(mClock),
+ new WifiPowerMetrics(mBatteryStats),
+ mWifiP2pMetrics, mDppMetrics);
when(mWifiScannerImplFactory
- .create(any(), any(), any()))
- .thenReturn(mWifiScannerImpl);
- when(mWifiScannerImpl.getChannelHelper()).thenReturn(channelHelper);
+ .create(any(), any(), any(), eq(TEST_IFACE_NAME_0)))
+ .thenReturn(mWifiScannerImpl0);
+ when(mWifiScannerImpl0.getChannelHelper()).thenReturn(mChannelHelper0);
+ when(mWifiScannerImplFactory
+ .create(any(), any(), any(), eq(TEST_IFACE_NAME_1)))
+ .thenReturn(mWifiScannerImpl1);
+ when(mWifiScannerImpl1.getChannelHelper()).thenReturn(mChannelHelper1);
when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
when(mWifiInjector.makeLog(anyString())).thenReturn(mLog);
WifiAsyncChannel mWifiAsyncChannel = new WifiAsyncChannel("ScanningServiceTest");
@@ -165,6 +186,12 @@ public class WifiScanningServiceTest {
when(mFrameworkFacade.makeWifiAsyncChannel(anyString())).thenReturn(mWifiAsyncChannel);
when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade);
when(mWifiInjector.getClock()).thenReturn(mClock);
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0)));
+ when(mWifiInjector.getWifiNative()).thenReturn(mWifiNative);
+ when(mContext.checkPermission(eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK),
+ anyInt(), eq(Binder.getCallingUid())))
+ .thenReturn(PERMISSION_GRANTED);
mWifiScanningServiceImpl = new WifiScanningServiceImpl(mContext, mLooper.getLooper(),
mWifiScannerImplFactory, mBatteryStats, mWifiInjector);
}
@@ -381,11 +408,16 @@ public class WifiScanningServiceTest {
private WifiNative.ScanEventHandler verifyStartSingleScan(InOrder order,
WifiNative.ScanSettings expected) {
+ return verifyStartSingleScanForImpl(mWifiScannerImpl0, order, expected);
+ }
+
+ private WifiNative.ScanEventHandler verifyStartSingleScanForImpl(
+ WifiScannerImpl wifiScannerImpl, InOrder order, WifiNative.ScanSettings expected) {
ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor =
ArgumentCaptor.forClass(WifiNative.ScanSettings.class);
ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor =
ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class);
- order.verify(mWifiScannerImpl).startSingleScan(scanSettingsCaptor.capture(),
+ order.verify(wifiScannerImpl).startSingleScan(scanSettingsCaptor.capture(),
scanEventHandlerCaptor.capture());
assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue());
return scanEventHandlerCaptor.getValue();
@@ -397,7 +429,7 @@ public class WifiScanningServiceTest {
ArgumentCaptor.forClass(WifiNative.ScanSettings.class);
ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor =
ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class);
- order.verify(mWifiScannerImpl).startBatchedScan(scanSettingsCaptor.capture(),
+ order.verify(mWifiScannerImpl0).startBatchedScan(scanSettingsCaptor.capture(),
scanEventHandlerCaptor.capture());
assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue());
return scanEventHandlerCaptor.getValue();
@@ -411,7 +443,7 @@ public class WifiScanningServiceTest {
}
private void setupAndLoadDriver(int max_scan_buckets) {
- when(mWifiScannerImpl.getScanCapabilities(any(WifiNative.ScanCapabilities.class)))
+ when(mWifiScannerImpl0.getScanCapabilities(any(WifiNative.ScanCapabilities.class)))
.thenAnswer(new AnswerWithArguments() {
public boolean answer(WifiNative.ScanCapabilities capabilities) {
capabilities.max_scan_cache_size = Integer.MAX_VALUE;
@@ -457,7 +489,7 @@ public class WifiScanningServiceTest {
@Test
public void construct() throws Exception {
- verifyNoMoreInteractions(mWifiScannerImpl, mWifiScannerImpl,
+ verifyNoMoreInteractions(mWifiScannerImpl0, mWifiScannerImpl0,
mWifiScannerImplFactory, mBatteryStats);
dumpService(); // make sure this succeeds
}
@@ -492,12 +524,12 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
verify(mWifiScannerImplFactory, times(1))
- .create(any(), any(), any());
+ .create(any(), any(), any(), eq(TEST_IFACE_NAME_0));
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
InOrder order = inOrder(handler);
- when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startBatchedScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendBackgroundScanRequest(controlChannel, 192, generateValidScanSettings(), null);
mLooper.dispatchAll();
@@ -519,7 +551,7 @@ public class WifiScanningServiceTest {
// Ensure we didn't create scanner instance twice.
verify(mWifiScannerImplFactory, times(1))
- .create(any(), any(), any());
+ .create(any(), any(), any(), any());
}
@Test
@@ -553,7 +585,7 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
controlChannel.sendMessage(Message.obtain(null, Protocol.BASE_WIFI_MANAGER));
mLooper.dispatchAll();
verifyFailedResponse(order, handler, 0, WifiScanner.REASON_INVALID_REQUEST,
@@ -578,7 +610,7 @@ public class WifiScanningServiceTest {
@Test
public void rejectBackgroundScanRequestWhenScannerImplCreateFails() throws Exception {
// Fail scanner impl creation.
- when(mWifiScannerImplFactory.create(any(), any(), any())).thenReturn(null);
+ when(mWifiScannerImplFactory.create(any(), any(), any(), any())).thenReturn(null);
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
@@ -592,7 +624,14 @@ public class WifiScanningServiceTest {
}
private void doSuccessfulSingleScan(WifiScanner.ScanSettings requestSettings,
- WifiNative.ScanSettings nativeSettings, ScanResults results) throws RemoteException {
+ WifiNative.ScanSettings nativeSettings, @NonNull ScanResults resultsForImpl0)
+ throws RemoteException {
+ doSuccessfulSingleScanOnImpls(requestSettings, nativeSettings, resultsForImpl0, null);
+ }
+
+ private void doSuccessfulSingleScanOnImpls(WifiScanner.ScanSettings requestSettings,
+ WifiNative.ScanSettings nativeSettings, @NonNull ScanResults resultsForImpl0,
+ @Nullable ScanResults resultsForImpl1) throws RemoteException {
int requestId = 12;
WorkSource workSource = new WorkSource(2292);
startServiceAndLoadDriver();
@@ -600,30 +639,50 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+ if (resultsForImpl1 != null) {
+ when(mWifiScannerImpl1.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+ }
sendSingleScanRequest(controlChannel, requestId, requestSettings, workSource);
mLooper.dispatchAll();
- WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings);
+ WifiNative.ScanEventHandler eventHandler0 =
+ verifyStartSingleScanForImpl(mWifiScannerImpl0, order, nativeSettings);
+ WifiNative.ScanEventHandler eventHandler1 = null;
+ if (resultsForImpl1 != null) {
+ eventHandler1 = verifyStartSingleScanForImpl(mWifiScannerImpl1, order, nativeSettings);
+ }
verifySuccessfulResponse(order, handler, requestId);
verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource));
- when(mWifiScannerImpl.getLatestSingleScanResults())
- .thenReturn(results.getRawScanData());
- eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
+ .thenReturn(resultsForImpl0.getScanData());
+ eventHandler0.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+ if (resultsForImpl1 != null) {
+ when(mWifiScannerImpl1.getLatestSingleScanResults())
+ .thenReturn(resultsForImpl1.getScanData());
+ eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+ }
mLooper.dispatchAll();
- verifyScanResultsReceived(order, handler, requestId, results.getScanData());
+ ScanResults expectedResults = resultsForImpl0;
+ if (resultsForImpl1 != null) {
+ expectedResults = ScanResults.merge(
+ resultsForImpl0.getScanData().getBandScanned(),
+ resultsForImpl0, resultsForImpl1);
+ }
+ verifyScanResultsReceived(order, handler, requestId, expectedResults.getScanData());
verifySingleScanCompletedReceived(order, handler, requestId);
verifyNoMoreInteractions(handler);
verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource));
assertDumpContainsRequestLog("addSingleScanRequest", requestId);
assertDumpContainsCallbackLog("singleScanResults", requestId,
- "results=" + results.getScanData().getResults().length);
+ "results=" + expectedResults.getScanData().getResults().length);
}
/**
@@ -700,8 +759,8 @@ public class WifiScanningServiceTest {
requestSettings.type = WifiScanner.TYPE_HIGH_ACCURACY;
WorkSource workSource = new WorkSource(Binder.getCallingUid()); // don't explicitly set
- when(mContext.checkPermission(
- Manifest.permission.NETWORK_STACK, -1, Binder.getCallingUid()))
+ when(mContext.checkPermission(eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK),
+ anyInt(), eq(Binder.getCallingUid())))
.thenReturn(PERMISSION_DENIED);
startServiceAndLoadDriver();
@@ -709,10 +768,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
// successful start
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
@@ -732,7 +791,7 @@ public class WifiScanningServiceTest {
// Ensure that no scan was triggered to the lower layers.
verify(mBatteryStats, never()).noteWifiScanStoppedFromSource(eq(workSource));
- verify(mWifiScannerImpl, never()).startSingleScan(any(WifiNative.ScanSettings.class),
+ verify(mWifiScannerImpl0, never()).startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class));
}
@@ -752,8 +811,8 @@ public class WifiScanningServiceTest {
};
WorkSource workSource = new WorkSource(Binder.getCallingUid()); // don't explicitly set
- when(mContext.checkPermission(
- Manifest.permission.NETWORK_STACK, -1, Binder.getCallingUid()))
+ when(mContext.checkPermission(eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK),
+ anyInt(), eq(Binder.getCallingUid())))
.thenReturn(PERMISSION_DENIED);
startServiceAndLoadDriver();
@@ -761,10 +820,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
// successful start
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
@@ -784,7 +843,7 @@ public class WifiScanningServiceTest {
// Ensure that no scan was triggered to the lower layers.
verify(mBatteryStats, never()).noteWifiScanStoppedFromSource(eq(workSource));
- verify(mWifiScannerImpl, never()).startSingleScan(any(WifiNative.ScanSettings.class),
+ verify(mWifiScannerImpl0, never()).startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class));
}
@@ -806,10 +865,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
// successful start
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
@@ -829,7 +888,7 @@ public class WifiScanningServiceTest {
// Ensure that no scan was triggered to the lower layers.
verify(mBatteryStats, never()).noteWifiScanStoppedFromSource(eq(workSource));
- verify(mWifiScannerImpl, never()).startSingleScan(any(WifiNative.ScanSettings.class),
+ verify(mWifiScannerImpl0, never()).startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class));
}
@@ -839,8 +898,8 @@ public class WifiScanningServiceTest {
@Test
public void sendSingleScanRequestWithNoPrivilegedParamsSetFromNonPrivilegedApp()
throws Exception {
- when(mContext.checkPermission(
- Manifest.permission.NETWORK_STACK, -1, Binder.getCallingUid()))
+ when(mContext.checkPermission(eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK),
+ anyInt(), eq(Binder.getCallingUid())))
.thenReturn(PERMISSION_DENIED);
WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400, 5150, 5175),
0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
@@ -863,10 +922,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
// scan fails
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(false);
sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
@@ -901,10 +960,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
// successful start
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
@@ -945,10 +1004,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
// successful start
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
@@ -978,10 +1037,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
// successful start
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
@@ -1005,12 +1064,12 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
// Run scan 1
sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
@@ -1028,6 +1087,46 @@ public class WifiScanningServiceTest {
}
/**
+ * Send a single scan request and then disable Wi-Fi before it completes
+ */
+ @Test
+ public void sendSingleScanRequestThenDisableWifiAfterScanCompleteButBeforeReportingResults() {
+ WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ ScanResults results = ScanResults.create(0, WifiScanner.WIFI_BAND_UNSPECIFIED, 2400);
+ int requestId = 2293;
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
+
+ // Run scan 1
+ sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order,
+ computeSingleScanNativeSettings(requestSettings));
+ verifySuccessfulResponse(order, handler, requestId);
+
+ // disable wifi
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_DISABLE));
+ // scan results complete event
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
+ .thenReturn(results.getScanData());
+ eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyFailedResponse(order, handler, requestId, WifiScanner.REASON_UNSPECIFIED,
+ "Scan was interrupted");
+ verifyNoMoreInteractions(handler);
+ }
+
+ /**
* Send a single scan request, schedule a second pending scan and disable Wi-Fi before the first
* scan completes.
*/
@@ -1046,12 +1145,12 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
// Request scan 1
sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
@@ -1103,12 +1202,12 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl, mContext);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mContext);
// Run scan 1
sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
@@ -1119,7 +1218,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(order, handler, requestId1);
// dispatch scan 1 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results1.getScanData());
eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1142,7 +1241,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(order, handler, requestId2);
// dispatch scan 2 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results2.getScanData());
eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1171,13 +1270,13 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
InOrder handlerOrder = inOrder(handler);
- InOrder nativeOrder = inOrder(mWifiScannerImpl);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl0);
// Run scan 1
sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
@@ -1193,7 +1292,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(handlerOrder, handler, requestId2);
// dispatch scan 1 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results1.getScanData());
eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1206,7 +1305,7 @@ public class WifiScanningServiceTest {
computeSingleScanNativeSettings(requestSettings2));
// dispatch scan 2 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results2.getScanData());
eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1241,13 +1340,13 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
InOrder handlerOrder = inOrder(handler);
- InOrder nativeOrder = inOrder(mWifiScannerImpl);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl0);
// Run scan 1
sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
@@ -1263,7 +1362,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(handlerOrder, handler, requestId2);
// dispatch scan 1 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results1.getScanData());
eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1276,7 +1375,7 @@ public class WifiScanningServiceTest {
computeSingleScanNativeSettings(requestSettings2));
// dispatch scan 2 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results2.getScanData());
eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1334,13 +1433,13 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
InOrder handlerOrder = inOrder(handler);
- InOrder nativeOrder = inOrder(mWifiScannerImpl);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl0);
// Run scan 1
sendSingleScanRequest(controlChannel, requestId1, requestSettings1, workSource1);
@@ -1364,7 +1463,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(handlerOrder, handler, requestId3);
// dispatch scan 1 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results1.getScanData());
eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1379,7 +1478,7 @@ public class WifiScanningServiceTest {
nativeSettings2and3);
// dispatch scan 2 and 3 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results2and3.getScanData());
eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1435,13 +1534,13 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
InOrder handlerOrder = inOrder(handler);
- InOrder nativeOrder = inOrder(mWifiScannerImpl);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl0);
// Run scan 1
sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
@@ -1457,7 +1556,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(handlerOrder, handler, requestId2);
// dispatch scan 1 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(resultsBoth.getScanData());
eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1510,13 +1609,13 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
InOrder handlerOrder = inOrder(handler);
- InOrder nativeOrder = inOrder(mWifiScannerImpl);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl0);
// Run scan 1
sendSingleScanRequest(controlChannel, requestId1, requestSettings1, workSource1);
@@ -1540,7 +1639,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(handlerOrder, handler, requestId3);
// dispatch scan 1 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results1and3.getScanData());
eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1556,7 +1655,7 @@ public class WifiScanningServiceTest {
computeSingleScanNativeSettings(requestSettings2));
// dispatch scan 2 and 3 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results2.getScanData());
eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1595,7 +1694,7 @@ public class WifiScanningServiceTest {
expectedResults);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
controlChannel.sendMessage(
Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
@@ -1625,7 +1724,7 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
controlChannel.sendMessage(
Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
@@ -1647,7 +1746,7 @@ public class WifiScanningServiceTest {
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
controlChannel.sendMessage(
Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
@@ -1674,7 +1773,7 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
controlChannel.sendMessage(
Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
@@ -1696,7 +1795,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(order, handler, secondScanRequestId);
// dispatch scan 2 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(expectedSingleResult.getScanData());
eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1731,7 +1830,7 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
controlChannel.sendMessage(
Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
@@ -1756,7 +1855,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(order, handler, secondScanRequestId);
// dispatch scan 2 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(expectedPartialResults.getScanData());
eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1805,7 +1904,7 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
controlChannel.sendMessage(
Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
@@ -1833,7 +1932,7 @@ public class WifiScanningServiceTest {
expectedResults);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
controlChannel.sendMessage(
Message.obtain(null, WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS, 0));
@@ -1874,9 +1973,9 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
registerScanListener(controlChannel, listenerRequestId);
@@ -1889,7 +1988,7 @@ public class WifiScanningServiceTest {
WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings);
verifySuccessfulResponse(order, handler, requestId);
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results.getRawScanData());
eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1922,9 +2021,9 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
registerScanListener(controlChannel, listenerRequestId);
@@ -1940,7 +2039,7 @@ public class WifiScanningServiceTest {
deregisterScanListener(controlChannel, listenerRequestId);
mLooper.dispatchAll();
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results.getRawScanData());
eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -1987,13 +2086,13 @@ public class WifiScanningServiceTest {
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
InOrder handlerOrder = inOrder(handler);
- InOrder nativeOrder = inOrder(mWifiScannerImpl);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl0);
// Run scan 1
sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
@@ -2020,7 +2119,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(handlerOrder, handler, listenerRequestId);
// dispatch scan 1 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results1.getScanData());
eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -2034,7 +2133,7 @@ public class WifiScanningServiceTest {
nativeSettings2and3);
// dispatch scan 2 and 3 results
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results2and3.getScanData());
eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -2051,9 +2150,25 @@ public class WifiScanningServiceTest {
}
@Test
+ public void rejectSingleScanRequestWhenScannerGetIfaceNameFails() throws Exception {
+ // Failed to get client interface name.
+ when(mWifiNative.getClientInterfaceNames()).thenReturn(new ArraySet<>());
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler);
+ sendSingleScanRequest(controlChannel, 122, generateValidScanSettings(), null);
+ mLooper.dispatchAll();
+ verifyFailedResponse(order, handler, 122, WifiScanner.REASON_UNSPECIFIED, "not available");
+ }
+
+ @Test
public void rejectSingleScanRequestWhenScannerImplCreateFails() throws Exception {
// Fail scanner impl creation.
- when(mWifiScannerImplFactory.create(any(), any(), any())).thenReturn(null);
+ when(mWifiScannerImplFactory.create(any(), any(), any(), any())).thenReturn(null);
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
@@ -2066,7 +2181,6 @@ public class WifiScanningServiceTest {
verifyFailedResponse(order, handler, 122, WifiScanner.REASON_UNSPECIFIED, "not available");
}
-
private void doSuccessfulBackgroundScan(WifiScanner.ScanSettings requestSettings,
WifiNative.ScanSettings nativeSettings) {
startServiceAndLoadDriver();
@@ -2074,9 +2188,9 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
- when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startBatchedScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendBackgroundScanRequest(controlChannel, 12, requestSettings, null);
@@ -2173,13 +2287,13 @@ public class WifiScanningServiceTest {
return ScanResults.create(0, 2400, 5150, 5175);
}
- private WifiNative.PnoEventHandler verifyHwPno(InOrder order,
+ private WifiNative.PnoEventHandler verifyHwPnoForImpl(WifiScannerImpl impl, InOrder order,
WifiNative.PnoSettings expected) {
ArgumentCaptor<WifiNative.PnoSettings> pnoSettingsCaptor =
ArgumentCaptor.forClass(WifiNative.PnoSettings.class);
ArgumentCaptor<WifiNative.PnoEventHandler> pnoEventHandlerCaptor =
ArgumentCaptor.forClass(WifiNative.PnoEventHandler.class);
- order.verify(mWifiScannerImpl).setHwPnoList(pnoSettingsCaptor.capture(),
+ order.verify(impl).setHwPnoList(pnoSettingsCaptor.capture(),
pnoEventHandlerCaptor.capture());
assertNativePnoSettingsEquals(expected, pnoSettingsCaptor.getValue());
return pnoEventHandlerCaptor.getValue();
@@ -2213,7 +2327,7 @@ public class WifiScanningServiceTest {
private void expectSuccessfulBackgroundScan(InOrder order,
WifiNative.ScanSettings nativeSettings, ScanResults results) {
- when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startBatchedScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
mLooper.dispatchAll();
WifiNative.ScanEventHandler eventHandler = verifyStartBackgroundScan(order, nativeSettings);
@@ -2222,27 +2336,52 @@ public class WifiScanningServiceTest {
for (ScanResult fullScanResult : results.getRawScanResults()) {
eventHandler.onFullScanResult(fullScanResult, 0);
}
- when(mWifiScannerImpl.getLatestBatchedScanResults(anyBoolean())).thenReturn(scanDatas);
+ when(mWifiScannerImpl0.getLatestBatchedScanResults(anyBoolean())).thenReturn(scanDatas);
eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
mLooper.dispatchAll();
}
private void expectHwPnoScan(InOrder order, Handler handler, int requestId,
WifiNative.PnoSettings nativeSettings, ScanResults results) {
- when(mWifiScannerImpl.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ when(mWifiScannerImpl0.isHwPnoSupported(anyBoolean())).thenReturn(true);
- when(mWifiScannerImpl.setHwPnoList(any(WifiNative.PnoSettings.class),
+ when(mWifiScannerImpl0.setHwPnoList(any(WifiNative.PnoSettings.class),
any(WifiNative.PnoEventHandler.class))).thenReturn(true);
mLooper.dispatchAll();
- WifiNative.PnoEventHandler eventHandler = verifyHwPno(order, nativeSettings);
+ WifiNative.PnoEventHandler eventHandler =
+ verifyHwPnoForImpl(mWifiScannerImpl0, order, nativeSettings);
verifySuccessfulResponse(order, handler, requestId);
eventHandler.onPnoNetworkFound(results.getRawScanResults());
mLooper.dispatchAll();
}
+ private void expectHwPnoScanOnImpls(InOrder order, Handler handler,
+ int requestId, WifiNative.PnoSettings nativeSettings,
+ @Nullable ScanResults resultsForImpl0, @Nullable ScanResults resultsForImpl1) {
+ when(mWifiScannerImpl0.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ when(mWifiScannerImpl1.isHwPnoSupported(anyBoolean())).thenReturn(true);
+
+ when(mWifiScannerImpl0.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(true);
+ when(mWifiScannerImpl1.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(true);
+ mLooper.dispatchAll();
+ WifiNative.PnoEventHandler eventHandler0 =
+ verifyHwPnoForImpl(mWifiScannerImpl0, order, nativeSettings);
+ WifiNative.PnoEventHandler eventHandler1 =
+ verifyHwPnoForImpl(mWifiScannerImpl1, order, nativeSettings);
+ verifySuccessfulResponse(order, handler, requestId);
+ if (resultsForImpl0 != null) {
+ eventHandler0.onPnoNetworkFound(resultsForImpl0.getRawScanResults());
+ } else if (resultsForImpl1 != null) {
+ eventHandler1.onPnoNetworkFound(resultsForImpl1.getRawScanResults());
+ }
+ mLooper.dispatchAll();
+ }
+
/**
- * Tests wificond PNO scan when the PNO scan results contain IE info. This ensures that the
- * PNO scan results are plumbed back to the client as a PNO network found event.
+ * Tests wificond PNO scan. This ensures that the PNO scan results are plumbed back to the
+ * client as a PNO network found event.
*/
@Test
public void testSuccessfulHwPnoScanWithNoBackgroundScan() throws Exception {
@@ -2250,7 +2389,7 @@ public class WifiScanningServiceTest {
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
int requestId = 12;
ScanResults scanResults = createScanResultsForPno();
@@ -2267,14 +2406,14 @@ public class WifiScanningServiceTest {
@Test
public void rejectHwPnoScanRequestWhenScannerImplCreateFails() throws Exception {
// Fail scanner impl creation.
- when(mWifiScannerImplFactory.create(any(), any(), any())).thenReturn(null);
+ when(mWifiScannerImplFactory.create(any(), any(), any(), any())).thenReturn(null);
startServiceAndLoadDriver();
mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
ScanResults scanResults = createScanResultsForPno();
Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
@@ -2338,13 +2477,13 @@ public class WifiScanningServiceTest {
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
mLooper.dispatchAll();
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
ScanResults results = ScanResults.create(0, WifiScanner.WIFI_BAND_BOTH, 2400);
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results.getRawScanData());
- InOrder order = inOrder(mWifiScannerImpl, handler);
+ InOrder order = inOrder(mWifiScannerImpl0, handler);
sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
mLooper.dispatchAll();
@@ -2390,10 +2529,10 @@ public class WifiScanningServiceTest {
// Ensure we didn't create scanner instance twice.
verify(mWifiScannerImplFactory, times(1))
- .create(any(), any(), any());
+ .create(any(), any(), any(), any());
InOrder order = inOrder(handler);
- when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startBatchedScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendBackgroundScanRequest(controlChannel, 192, generateValidScanSettings(), null);
mLooper.dispatchAll();
@@ -2416,9 +2555,9 @@ public class WifiScanningServiceTest {
// Ensure we didn't create scanner instance twice.
verify(mWifiScannerImplFactory, times(1))
- .create(any(), any(), any());
+ .create(any(), any(), any(), any());
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
int requestId = 12;
WorkSource workSource = new WorkSource(2292);
@@ -2427,7 +2566,7 @@ public class WifiScanningServiceTest {
ScanResults results =
ScanResults.create(0, WifiScanner.WIFI_BAND_UNSPECIFIED, 2400, 5150, 5175);
- when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
any(WifiNative.ScanEventHandler.class))).thenReturn(true);
sendSingleScanRequest(controlChannel, requestId, requestSettings, workSource);
@@ -2438,7 +2577,7 @@ public class WifiScanningServiceTest {
verifySuccessfulResponse(order, handler, requestId);
verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource));
- when(mWifiScannerImpl.getLatestSingleScanResults())
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
.thenReturn(results.getRawScanData());
eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
@@ -2467,9 +2606,9 @@ public class WifiScanningServiceTest {
// Ensure we didn't create scanner instance twice.
verify(mWifiScannerImplFactory, times(1))
- .create(any(), any(), any());
+ .create(any(), any(), any(), any());
- InOrder order = inOrder(handler, mWifiScannerImpl);
+ InOrder order = inOrder(handler, mWifiScannerImpl0);
int requestId = 12;
ScanResults scanResults = createScanResultsForPno();
@@ -2484,7 +2623,7 @@ public class WifiScanningServiceTest {
}
/**
- * Verifies that only clients with NETWORK_STACK permission can issues restricted messages
+ * Verifies that only clients with PERMISSION_MAINLINE_WIFI_STACK permission can issues restricted messages
* (from API's).
*/
@Test
@@ -2494,9 +2633,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- // Client doesn't have NETWORK_STACK permission.
+ // Client doesn't have PERMISSION_MAINLINE_WIFI_STACK permission.
doThrow(new SecurityException()).when(mContext).enforcePermission(
- eq(Manifest.permission.NETWORK_STACK), anyInt(), eq(Binder.getCallingUid()), any());
+ eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK), anyInt(),
+ eq(Binder.getCallingUid()), any());
controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_ENABLE));
mLooper.dispatchAll();
@@ -2529,18 +2669,25 @@ public class WifiScanningServiceTest {
"Not authorized", messageCaptor.getAllValues().get(4));
// Ensure we didn't create scanner instance.
- verify(mWifiScannerImplFactory, never()).create(any(), any(), any());
+ verify(mWifiScannerImplFactory, never()).create(any(), any(), any(), any());
}
/**
- * Verifies that clients without NETWORK_STACK permission cannot issue any messages when they
+ * Verifies that clients without PERMISSION_MAINLINE_WIFI_STACK permission cannot issue any messages when they
* don't have the necessary location permissions & location is enabled.
*/
@Test
public void rejectAllMessagesFromNonPrivilegedAppsWithoutLocationPermission() throws Exception {
// Start service & initialize it.
startServiceAndLoadDriver();
+ doThrow(new SecurityException()).when(mContext).enforcePermission(
+ eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK), anyInt(),
+ eq(Binder.getCallingUid()), any());
+ when(mContext.checkPermission(eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK),
+ anyInt(), eq(Binder.getCallingUid())))
+ .thenReturn(PERMISSION_DENIED);
+
// Location permission or mode check fail.
doThrow(new SecurityException()).when(mWifiPermissionsUtil)
.enforceCanAccessScanResultsForWifiScanner(any(), eq(Binder.getCallingUid()),
@@ -2549,9 +2696,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- // Client doesn't have NETWORK_STACK permission.
- doThrow(new SecurityException()).when(mContext).enforcePermission(
- eq(Manifest.permission.NETWORK_STACK), anyInt(), eq(Binder.getCallingUid()), any());
+ // Client doesn't have PERMISSION_MAINLINE_WIFI_STACK permission.
+ when(mContext.checkPermission(eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK),
+ anyInt(), eq(Binder.getCallingUid())))
+ .thenReturn(PERMISSION_DENIED);
controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_SINGLE_SCAN));
mLooper.dispatchAll();
@@ -2574,11 +2722,11 @@ public class WifiScanningServiceTest {
"Not authorized", messageCaptor.getAllValues().get(2));
// Validate the initialization sequence.
- verify(mWifiScannerImpl).getChannelHelper();
- verify(mWifiScannerImpl).getScanCapabilities(any());
+ verify(mWifiScannerImpl0).getChannelHelper();
+ verify(mWifiScannerImpl0).getScanCapabilities(any());
// Ensure we didn't start any scans after.
- verifyNoMoreInteractions(mWifiScannerImpl);
+ verifyNoMoreInteractions(mWifiScannerImpl0);
}
/**
@@ -2593,9 +2741,13 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- // Client doesn't have NETWORK_STACK permission.
+ // Client doesn't have PERMISSION_MAINLINE_WIFI_STACK permission.
doThrow(new SecurityException()).when(mContext).enforcePermission(
- eq(Manifest.permission.NETWORK_STACK), anyInt(), eq(Binder.getCallingUid()), any());
+ eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK), anyInt(),
+ eq(Binder.getCallingUid()), any());
+ when(mContext.checkPermission(eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK),
+ anyInt(), eq(Binder.getCallingUid())))
+ .thenReturn(PERMISSION_DENIED);
Bundle bundle = new Bundle();
bundle.putString(WifiScanner.REQUEST_PACKAGE_NAME_KEY, TEST_PACKAGE_NAME);
@@ -2653,9 +2805,13 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- // Client doesn't have NETWORK_STACK permission.
+ // Client doesn't have PERMISSION_MAINLINE_WIFI_STACK permission.
doThrow(new SecurityException()).when(mContext).enforcePermission(
- eq(Manifest.permission.NETWORK_STACK), anyInt(), eq(Binder.getCallingUid()), any());
+ eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK), anyInt(),
+ eq(Binder.getCallingUid()), any());
+ when(mContext.checkPermission(eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK),
+ anyInt(), eq(Binder.getCallingUid())))
+ .thenReturn(PERMISSION_DENIED);
Bundle bundle = new Bundle();
bundle.putString(WifiScanner.REQUEST_PACKAGE_NAME_KEY, TEST_PACKAGE_NAME);
@@ -2715,9 +2871,10 @@ public class WifiScanningServiceTest {
Handler handler = mock(Handler.class);
BidirectionalAsyncChannel controlChannel = connectChannel(handler);
- // Client does have NETWORK_STACK permission.
+ // Client does have WIFI_STACK permission.
doNothing().when(mContext).enforcePermission(
- eq(Manifest.permission.NETWORK_STACK), anyInt(), eq(Binder.getCallingUid()), any());
+ eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK), anyInt(),
+ eq(Binder.getCallingUid()), any());
Bundle bundle = new Bundle();
bundle.putString(WifiScanner.REQUEST_PACKAGE_NAME_KEY, TEST_PACKAGE_NAME);
@@ -2737,4 +2894,648 @@ public class WifiScanningServiceTest {
verify(mWifiPermissionsUtil, never()).enforceCanAccessScanResultsForWifiScanner(
eq(TEST_PACKAGE_NAME), eq(Binder.getCallingUid()), anyBoolean(), anyBoolean());
}
+
+ /**
+ * Setup/teardown a second scanner impl dynamically.
+ */
+ @Test
+ public void setupAndTeardownSecondImpl() throws Exception {
+ // start up service with a single impl.
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+ verify(mWifiScannerImplFactory, times(1))
+ .create(any(), any(), any(), eq(TEST_IFACE_NAME_0));
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler);
+
+ // Now setup an impl for second iface.
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_ENABLE));
+ mLooper.dispatchAll();
+
+ verify(mWifiScannerImplFactory, times(1))
+ .create(any(), any(), any(), eq(TEST_IFACE_NAME_1));
+
+ // Now teardown the impl for second iface.
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0)));
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_ENABLE));
+ mLooper.dispatchAll();
+
+ verify(mWifiScannerImpl1).cleanup();
+
+ // Now teardown everything.
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_DISABLE));
+ mLooper.dispatchAll();
+
+ verify(mWifiScannerImpl0).cleanup();
+ }
+
+ /**
+ * Setup/teardown a second scanner impl dynamically which satisfies the same set of channels
+ * as the existing one.
+ */
+ @Test
+ public void setupAndTeardownSecondImplWhichSatisfiesExistingImpl() throws Exception {
+ // start up service with a single impl.
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+ verify(mWifiScannerImplFactory, times(1))
+ .create(any(), any(), any(), eq(TEST_IFACE_NAME_0));
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler);
+
+ // Now setup an impl for second iface.
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+ // Setup the second impl to contain the same set of channels as the first one.
+ when(mWifiScannerImpl1.getChannelHelper()).thenReturn(mChannelHelper0);
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_ENABLE));
+ mLooper.dispatchAll();
+
+ // Verify that we created the new impl and immediately tore it down because it was
+ // satisfied by an existing impl.
+ verify(mWifiScannerImplFactory, times(1))
+ .create(any(), any(), any(), eq(TEST_IFACE_NAME_1));
+ verify(mWifiScannerImpl1, times(1)).getChannelHelper();
+ verify(mWifiScannerImpl1, times(1)).cleanup();
+
+ // Now teardown the second iface.
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0)));
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_ENABLE));
+ mLooper.dispatchAll();
+
+ // do nothing, since impl1 was never added to the active impl list.
+ verifyNoMoreInteractions(mWifiScannerImpl1);
+
+ // Now teardown everything.
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_DISABLE));
+ mLooper.dispatchAll();
+
+ verify(mWifiScannerImpl0).cleanup();
+ }
+
+ /**
+ * Setup a second scanner impl and tearddown a existing scanning impl dynamically which
+ * satisfies the same set of channels as the existing one.
+ */
+ @Test
+ public void setupSecondImplAndTeardownFirstImplWhichSatisfiesExistingImpl() throws Exception {
+ // start up service with a single impl.
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+ verify(mWifiScannerImplFactory, times(1))
+ .create(any(), any(), any(), eq(TEST_IFACE_NAME_0));
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler);
+
+
+ // Now setup an impl for second iface and teardown the first one.
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_1)));
+ // Setup the second impl to contain the same set of channels as the first one.
+ when(mWifiScannerImpl1.getChannelHelper()).thenReturn(mChannelHelper0);
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_ENABLE));
+ mLooper.dispatchAll();
+
+ // tear down the first one because corresponding iface was brought down.
+ verify(mWifiScannerImpl0).cleanup();
+
+ // Verify that we created the new impl.
+ verify(mWifiScannerImplFactory, times(1))
+ .create(any(), any(), any(), eq(TEST_IFACE_NAME_1));
+ verify(mWifiScannerImpl1, never()).getChannelHelper();
+
+ // Now teardown everything.
+ controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_DISABLE));
+ mLooper.dispatchAll();
+
+ verify(mWifiScannerImpl1).cleanup();
+ }
+
+ /**
+ * Do a single scan for a band and verify that it is successful across multiple impls.
+ */
+ @Test
+ public void sendSingleScanBandRequestOnMultipleImpls() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+ WifiScanner.ScanSettings requestSettings = createRequest(
+ WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 0, 0, 20,
+ WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ doSuccessfulSingleScanOnImpls(requestSettings,
+ computeSingleScanNativeSettings(requestSettings),
+ ScanResults.create(0, WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 2400),
+ ScanResults.create(0, WifiScanner.WIFI_BAND_BOTH_WITH_DFS, 5150));
+ }
+
+ /**
+ * Do a single scan for a list of channels and verify that it is successful across multiple
+ * impls.
+ */
+ @Test
+ public void sendSingleScanChannelsRequestOnMultipleImpls() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+ WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400, 5150, 5175),
+ 0, 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ doSuccessfulSingleScanOnImpls(requestSettings,
+ computeSingleScanNativeSettings(requestSettings),
+ ScanResults.create(0, WifiScanner.WIFI_BAND_UNSPECIFIED, 2400),
+ ScanResults.create(0, WifiScanner.WIFI_BAND_UNSPECIFIED, 5175));
+ }
+
+ /**
+ * Do a single scan with no results and verify that it is successful across multiple
+ * impls.
+ */
+ @Test
+ public void sendSingleScanRequestWithNoResultsOnMultipleImpls() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ doSuccessfulSingleScanOnImpls(requestSettings,
+ computeSingleScanNativeSettings(requestSettings),
+ ScanResults.create(0, WifiScanner.WIFI_BAND_BOTH, new int[0]),
+ ScanResults.create(0, WifiScanner.WIFI_BAND_BOTH, new int[0]));
+ }
+
+ /**
+ * Do a single scan, which the hardware fails to start across multiple impls, and verify that a
+ * failure response is delivered.
+ */
+ @Test
+ public void sendSingleScanRequestWhichFailsToStartOnMultipleImpls() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId = 33;
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
+
+ // scan fails
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(false);
+ when(mWifiScannerImpl1.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(false);
+
+ sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
+
+ mLooper.dispatchAll();
+ // Scan is successfully queue, but then fails to execute
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ order.verify(handler, times(2)).handleMessage(messageCaptor.capture());
+ assertSuccessfulResponse(requestId, messageCaptor.getAllValues().get(0));
+ assertFailedResponse(requestId, WifiScanner.REASON_UNSPECIFIED,
+ "Failed to start single scan", messageCaptor.getAllValues().get(1));
+ verifyNoMoreInteractions(mBatteryStats);
+
+ assertEquals(mWifiMetrics.getOneshotScanCount(), 1);
+ assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1);
+ assertDumpContainsRequestLog("addSingleScanRequest", requestId);
+ }
+
+ /**
+ * Do a single scan, which the hardware fails to start on one of the impl, and verify that a
+ * successful response is delivered when other impls succeed.
+ */
+ @Test
+ public void sendSingleScanRequestWhichFailsToStartOnOneImpl() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ WifiNative.ScanSettings nativeSettings = computeSingleScanNativeSettings(requestSettings);
+ ScanResults results =
+ ScanResults.create(0, WifiScanner.WIFI_BAND_UNSPECIFIED, 2400, 5150, 5175);
+ int requestId = 33;
+ WorkSource workSource = new WorkSource(2292);
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
+
+ // scan fails on impl0
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(false);
+ // scan succeeds on impl1
+ when(mWifiScannerImpl1.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ sendSingleScanRequest(controlChannel, requestId, requestSettings, workSource);
+
+ mLooper.dispatchAll();
+
+ WifiNative.ScanEventHandler eventHandler0 =
+ verifyStartSingleScanForImpl(mWifiScannerImpl0, order, nativeSettings);
+ WifiNative.ScanEventHandler eventHandler1 =
+ verifyStartSingleScanForImpl(mWifiScannerImpl1, order, nativeSettings);
+ verifySuccessfulResponse(order, handler, requestId);
+ verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource));
+
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
+ .thenReturn(new WifiScanner.ScanData(DUMMY_SCAN_DATA));
+ // Send scan success on impl1
+ when(mWifiScannerImpl1.getLatestSingleScanResults())
+ .thenReturn(results.getRawScanData());
+ eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyScanResultsReceived(order, handler, requestId, results.getScanData());
+ verifySingleScanCompletedReceived(order, handler, requestId);
+ verifyNoMoreInteractions(handler);
+ verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource));
+ assertDumpContainsRequestLog("addSingleScanRequest", requestId);
+ assertDumpContainsCallbackLog("singleScanResults", requestId,
+ "results=" + results.getScanData().getResults().length);
+ }
+
+ /**
+ * Do a single scan, which successfully starts, but fails across multiple impls partway through
+ * and verify that a failure response is delivered.
+ */
+ @Test
+ public void sendSingleScanRequestWhichFailsAfterStartOnMultipleImpls() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId = 33;
+ WorkSource workSource = new WorkSource(Binder.getCallingUid()); // don't explicitly set
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
+
+ // successful start
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+ when(mWifiScannerImpl1.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
+
+ // Scan is successfully queue
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler0 =
+ verifyStartSingleScanForImpl(mWifiScannerImpl0, order,
+ computeSingleScanNativeSettings(requestSettings));
+ WifiNative.ScanEventHandler eventHandler1 =
+ verifyStartSingleScanForImpl(mWifiScannerImpl1, order,
+ computeSingleScanNativeSettings(requestSettings));
+ verifySuccessfulResponse(order, handler, requestId);
+ verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource));
+
+ // but then fails to execute
+ eventHandler0.onScanStatus(WifiNative.WIFI_SCAN_FAILED);
+ eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_FAILED);
+ mLooper.dispatchAll();
+ verifyFailedResponse(order, handler, requestId,
+ WifiScanner.REASON_UNSPECIFIED, "Scan failed");
+ assertDumpContainsCallbackLog("singleScanFailed", requestId,
+ "reason=" + WifiScanner.REASON_UNSPECIFIED + ", Scan failed");
+ assertEquals(mWifiMetrics.getOneshotScanCount(), 1);
+ assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN), 1);
+ verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource));
+ }
+
+ /**
+ * Do a single scan, which successfully starts, but fails partway through on one of the impls
+ * and verify that a successful response is delivered.
+ */
+ @Test
+ public void sendSingleScanRequestWhichFailsAfterStartOnOneImpl() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+
+ WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ WifiNative.ScanSettings nativeSettings = computeSingleScanNativeSettings(requestSettings);
+ ScanResults results =
+ ScanResults.create(0, WifiScanner.WIFI_BAND_UNSPECIFIED, 2400, 5150, 5175);
+ int requestId = 33;
+ WorkSource workSource = new WorkSource(Binder.getCallingUid()); // don't explicitly set
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
+
+ // successful start
+ when(mWifiScannerImpl0.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+ when(mWifiScannerImpl1.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ sendSingleScanRequest(controlChannel, requestId, requestSettings, null);
+
+ // Scan is successfully queued
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler0 =
+ verifyStartSingleScanForImpl(mWifiScannerImpl0, order, nativeSettings);
+ WifiNative.ScanEventHandler eventHandler1 =
+ verifyStartSingleScanForImpl(mWifiScannerImpl1, order, nativeSettings);
+ verifySuccessfulResponse(order, handler, requestId);
+ verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource));
+
+ // then fails to execute on impl0
+ when(mWifiScannerImpl0.getLatestSingleScanResults())
+ .thenReturn(new WifiScanner.ScanData(DUMMY_SCAN_DATA));
+ eventHandler0.onScanStatus(WifiNative.WIFI_SCAN_FAILED);
+ // but succeeds on impl1
+ when(mWifiScannerImpl1.getLatestSingleScanResults())
+ .thenReturn(results.getRawScanData());
+ eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyScanResultsReceived(order, handler, requestId, results.getScanData());
+ verifySingleScanCompletedReceived(order, handler, requestId);
+ verifyNoMoreInteractions(handler);
+ verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource));
+ assertDumpContainsRequestLog("addSingleScanRequest", requestId);
+ assertDumpContainsCallbackLog("singleScanResults", requestId,
+ "results=" + results.getScanData().getResults().length);
+ }
+
+ /**
+ * Tests wificond PNO scan across multiple impls. This ensures that the
+ * PNO scan results are plumbed back to the client as a PNO network found event.
+ */
+ @Test
+ public void testSuccessfulHwPnoScanOnMultipleImpls() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
+ int requestId = 12;
+
+ ScanResults scanResults = createScanResultsForPno();
+ Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
+ createScanSettingsForHwPno();
+ Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
+ createPnoSettings(scanResults);
+
+ // Results received on impl 0
+ sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
+ expectHwPnoScanOnImpls(order, handler, requestId, pnoSettings.second, scanResults, null);
+ verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults());
+ }
+
+ /**
+ * Tests wificond PNO scan that fails to start on all impls.
+ */
+ @Test
+ public void testFailedHwPnoScanWhichFailsToStartOnMultipleImpls() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
+ int requestId = 12;
+
+ ScanResults scanResults = createScanResultsForPno();
+ Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
+ createScanSettingsForHwPno();
+ Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
+ createPnoSettings(scanResults);
+
+ when(mWifiScannerImpl0.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ when(mWifiScannerImpl1.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ // pno scan fails on both impls
+ when(mWifiScannerImpl0.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(false);
+ when(mWifiScannerImpl1.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(false);
+
+ sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
+ mLooper.dispatchAll();
+
+ verifyFailedResponse(order, handler, requestId, WifiScanner.REASON_INVALID_REQUEST,
+ "bad request");
+ }
+
+ /**
+ * Tests wificond PNO scan that fails to start on one of the impls.
+ */
+ @Test
+ public void testSuccessfulHwPnoScanWhichFailsToStartOnOneImpl() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
+ int requestId = 12;
+
+ ScanResults scanResults = createScanResultsForPno();
+ Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
+ createScanSettingsForHwPno();
+ Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
+ createPnoSettings(scanResults);
+
+ when(mWifiScannerImpl0.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ when(mWifiScannerImpl1.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ // pno scan fails on impl0
+ when(mWifiScannerImpl0.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(false);
+ // pno scan succeeds on impl1
+ when(mWifiScannerImpl1.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(true);
+
+ sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
+ mLooper.dispatchAll();
+
+ WifiNative.PnoEventHandler eventHandler0 =
+ verifyHwPnoForImpl(mWifiScannerImpl0, order, pnoSettings.second);
+ WifiNative.PnoEventHandler eventHandler1 =
+ verifyHwPnoForImpl(mWifiScannerImpl1, order, pnoSettings.second);
+
+ verifySuccessfulResponse(order, handler, requestId);
+
+ eventHandler1.onPnoNetworkFound(scanResults.getRawScanResults());
+ mLooper.dispatchAll();
+
+ verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults());
+ }
+
+ /**
+ * Tests wificond PNO scan that fails after start on all impls.
+ */
+ @Test
+ public void testFailedHwPnoScanWhichFailsAfterStartOnMultipleImpls() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
+ int requestId = 12;
+
+ ScanResults scanResults = createScanResultsForPno();
+ Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
+ createScanSettingsForHwPno();
+ Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
+ createPnoSettings(scanResults);
+
+ when(mWifiScannerImpl0.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ when(mWifiScannerImpl1.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ // pno scan succeeds
+ when(mWifiScannerImpl0.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(true);
+ when(mWifiScannerImpl1.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(true);
+
+ sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
+ mLooper.dispatchAll();
+
+ WifiNative.PnoEventHandler eventHandler0 =
+ verifyHwPnoForImpl(mWifiScannerImpl0, order, pnoSettings.second);
+ WifiNative.PnoEventHandler eventHandler1 =
+ verifyHwPnoForImpl(mWifiScannerImpl1, order, pnoSettings.second);
+
+ verifySuccessfulResponse(order, handler, requestId);
+
+ // fails afterwards.
+ eventHandler0.onPnoScanFailed();
+ eventHandler1.onPnoScanFailed();
+ mLooper.dispatchAll();
+
+ // Scan is successfully queue, but then fails to execute
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ order.verify(handler).handleMessage(messageCaptor.capture());
+ assertFailedResponse(requestId, WifiScanner.REASON_UNSPECIFIED,
+ "pno scan failed", messageCaptor.getValue());
+ }
+
+ /**
+ * Tests wificond PNO scan that fails after start on one impls.
+ */
+ @Test
+ public void testSuccessfulHwPnoScanWhichFailsAfterStartOnOneImpl() throws Exception {
+ when(mWifiNative.getClientInterfaceNames())
+ .thenReturn(new ArraySet<>(Arrays.asList(TEST_IFACE_NAME_0, TEST_IFACE_NAME_1)));
+
+ startServiceAndLoadDriver();
+ mWifiScanningServiceImpl.setWifiHandlerLogForTest(mLog);
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder order = inOrder(handler, mWifiScannerImpl0, mWifiScannerImpl1);
+ int requestId = 12;
+
+ ScanResults scanResults = createScanResultsForPno();
+ Pair<WifiScanner.ScanSettings, WifiNative.ScanSettings> scanSettings =
+ createScanSettingsForHwPno();
+ Pair<WifiScanner.PnoSettings, WifiNative.PnoSettings> pnoSettings =
+ createPnoSettings(scanResults);
+
+ when(mWifiScannerImpl0.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ when(mWifiScannerImpl1.isHwPnoSupported(anyBoolean())).thenReturn(true);
+ // pno scan succeeds
+ when(mWifiScannerImpl0.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(true);
+ when(mWifiScannerImpl1.setHwPnoList(any(WifiNative.PnoSettings.class),
+ any(WifiNative.PnoEventHandler.class))).thenReturn(true);
+
+ sendPnoScanRequest(controlChannel, requestId, scanSettings.first, pnoSettings.first);
+ mLooper.dispatchAll();
+
+ WifiNative.PnoEventHandler eventHandler0 =
+ verifyHwPnoForImpl(mWifiScannerImpl0, order, pnoSettings.second);
+ WifiNative.PnoEventHandler eventHandler1 =
+ verifyHwPnoForImpl(mWifiScannerImpl1, order, pnoSettings.second);
+
+ verifySuccessfulResponse(order, handler, requestId);
+
+ // fails afterwards on impl0.
+ eventHandler0.onPnoScanFailed();
+ // pno match on impl1.
+ eventHandler1.onPnoNetworkFound(scanResults.getRawScanResults());
+ mLooper.dispatchAll();
+
+ verifyPnoNetworkFoundReceived(order, handler, requestId, scanResults.getRawScanResults());
+ }
+
+ /**
+ * Tests that {@link WifiScanningServiceImpl#getAvailableChannels(int, String)} throws a
+ * {@link SecurityException} if the caller doesn't hold the required permissions.
+ */
+ @Test(expected = SecurityException.class)
+ public void getAvailableChannels_noPermission_throwsException() throws Exception {
+ startServiceAndLoadDriver();
+
+ // no MAINLINE_WIFI_STACK permission
+ doThrow(new SecurityException()).when(mContext).enforcePermission(
+ eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK), anyInt(),
+ eq(Binder.getCallingUid()), any());
+
+ // Location permission or mode check fail.
+ doThrow(new SecurityException())
+ .when(mWifiPermissionsUtil).enforceCanAccessScanResultsForWifiScanner(
+ TEST_PACKAGE_NAME, Binder.getCallingUid(), false, false);
+
+ mWifiScanningServiceImpl.getAvailableChannels(WifiScanner.WIFI_BAND_24_GHZ,
+ TEST_PACKAGE_NAME);
+ }
+
+ /**
+ * Tests that {@link WifiScanningServiceImpl#getAvailableChannels(int, String)} returns
+ * the expected result if the caller does hold the required permissions.
+ */
+ @Test
+ public void getAvailableChannels_hasPermission_returnsSuccessfully() throws Exception {
+ startServiceAndLoadDriver();
+
+ // has MAINLINE_WIFI_STACK permission
+ doNothing().when(mContext).enforcePermission(
+ eq(WifiStackClient.PERMISSION_MAINLINE_WIFI_STACK), anyInt(),
+ eq(Binder.getCallingUid()), any());
+
+ // has access scan results permission
+ doNothing().when(mWifiPermissionsUtil).enforceCanAccessScanResultsForWifiScanner(
+ TEST_PACKAGE_NAME, Binder.getCallingUid(), false, false);
+
+ Bundle bundle = mWifiScanningServiceImpl.getAvailableChannels(
+ WifiScanner.WIFI_BAND_24_GHZ, TEST_PACKAGE_NAME);
+ List<Integer> actual = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
+
+ List<Integer> expected = Arrays.asList(2400, 2450);
+ assertEquals(expected, actual);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondPnoScannerTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondPnoScannerTest.java
index 8dcc177198..e4b6ec5784 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondPnoScannerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondPnoScannerTest.java
@@ -35,6 +35,7 @@ import com.android.server.wifi.Clock;
import com.android.server.wifi.MockResources;
import com.android.server.wifi.MockWifiMonitor;
import com.android.server.wifi.ScanResults;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiMonitor;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection;
@@ -52,7 +53,7 @@ import java.util.Set;
* Unit tests for {@link com.android.server.wifi.scanner.WificondScannerImpl.setPnoList}.
*/
@SmallTest
-public class WificondPnoScannerTest {
+public class WificondPnoScannerTest extends WifiBaseTest {
private static final String IFACE_NAME = "a_test_interface_name";
@Mock Context mContext;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java
index 4f2492042d..c2a09fe27e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java
@@ -28,6 +28,7 @@ import android.net.wifi.WifiScanner;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.ScanDetail;
import com.android.server.wifi.ScanResults;
import com.android.server.wifi.WifiMonitor;
import com.android.server.wifi.WifiNative;
@@ -35,12 +36,16 @@ import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.InOrder;
+
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;
import java.util.regex.Pattern;
/**
@@ -48,6 +53,10 @@ import java.util.regex.Pattern;
*/
@SmallTest
public class WificondScannerTest extends BaseWifiScannerImplTest {
+ private static final String NATIVE_SCAN_TITLE = "Latest native scan results:";
+ private static final String NATIVE_PNO_SCAN_TITLE = "Latest native pno scan results:";
+ private static final String NATIVE_SCAN_IE_TITLE = "Latest native scan results IEs:";
+
WifiMonitor mWifiMonitorSpy;
@Before
public void setup() throws Exception {
@@ -163,11 +172,97 @@ public class WificondScannerTest extends BaseWifiScannerImplTest {
}
/**
- * Test that dump() of WificondScannerImpl dumps native scan results.
+ * Test that dump() of WificondScannerImpl dumps native scan results with correct format when
+ * scan result is empty.
*/
@Test
- public void dumpContainsNativeScanResults() {
- assertDumpContainsRequestLog("Latest native scan results:");
+ public void testDumpWithCorrectFormatWithEmptyScanResult() {
+ // The format of scan dump when zero Ap in scan result.
+ // ---------------------------------------------
+ // "Latest native scan results:\n" : Key word can't modify.
+ // "Latest native pno scan results:\n": Key word can't modify.
+ // " ... \n": Any String and any line. No limited.
+ // "Latest native scan results IEs:\n": Key word can't modify.
+ // "\n" : Should be stop with "\n"
+ //---------------------------------------------
+ Pattern zeroScanResultRegex = Pattern.compile(
+ "" + NATIVE_SCAN_TITLE + "\n"
+ + "" + NATIVE_PNO_SCAN_TITLE + "\n"
+ + "(.*\n)*"
+ + "" + NATIVE_SCAN_IE_TITLE + "\n"
+ + "\n");
+
+ String dump = dumpObject();
+
+ assertLogContainsRequestPattern(zeroScanResultRegex, dump);
+
+ }
+
+ /**
+ * Test that dump() of WificondScannerImpl dumps native scan results with correct format when
+ * the number of AP in the scan result is not zero.
+ */
+ @Test
+ public void testDumpWithCorrectFormatWithScanResult() {
+ // Prepare the setting to trigger a scan.
+ WifiNative.ScanSettings settings = new NativeScanSettingsBuilder()
+ .withBasePeriod(10000)
+ .withMaxApPerScan(2)
+ .addBucketWithBand(10000,
+ WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN
+ | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT,
+ WifiScanner.WIFI_BAND_24_GHZ)
+ .build();
+ long approxScanStartUs = mClock.getElapsedSinceBootMillis() * 1000;
+ ArrayList<ScanDetail> rawScanResults = new ArrayList<>(Arrays.asList(
+ ScanResults.generateNativeResults(0, 5150, 5171)));
+ WifiNative.ScanEventHandler eventHandler = mock(WifiNative.ScanEventHandler.class);
+ InOrder order = inOrder(eventHandler, mWifiNative);
+ // scan succeeds
+ when(mWifiNative.scan(eq(IFACE_NAME), anyInt(), any(), any(List.class))).thenReturn(true);
+ when(mWifiNative.getScanResults(eq(IFACE_NAME))).thenReturn(rawScanResults);
+
+ int ap_count = rawScanResults.size();
+ // The format of scan dump when the number of AP in the scan result is not zero.
+ // ---------------------------------------------
+ // "Latest native scan results:\n" : Key word can't modify.
+ // " BSSID ... \n" : Must start with 4 spaces but only show when
+ // the number of AP in the scan result is not zero.
+ // " The APs information \n" : Must start with 2 spaces and show bssid first.
+ // " ... \n" : Continues to print AP information and
+ // total AP information line should be
+ // same as the number of AP in the scan result.
+ // "Latest native pno scan results:\n": Key word can't modify.
+ // " ... \n": Any String and any line. No limited.
+ // "Latest native scan results IEs:\n": Key word can't modify.
+ // ie raw data : loop to start print ie raw data, finish with "\n"
+ // ... : Continues to print ie raw data and
+ // total ie raw data line should be same as
+ // the number of AP in the scan result.
+ // "\n" : Should be stop with "\n"
+ //---------------------------------------------
+ Pattern scanResultRegex = Pattern.compile(
+ "" + NATIVE_SCAN_TITLE + "\n"
+ + " .*\n"
+ + "( .{2}:.{2}:.{2}:.{2}:.{2}:.{2}.*\n){" + ap_count + "}"
+ + "" + NATIVE_PNO_SCAN_TITLE + "\n"
+ + "(.*\n)*"
+ + "" + NATIVE_SCAN_IE_TITLE + "\n"
+ + "(.*\n){" + ap_count + "}"
+ + "\n");
+
+ // Trigger a scan to update mNativeScanResults in WificondScannerImpl.
+ assertTrue(mScanner.startSingleScan(settings, eventHandler));
+ Set<Integer> expectedScan = expectedBandScanFreqs(WifiScanner.WIFI_BAND_24_GHZ);
+ order.verify(mWifiNative).scan(eq(IFACE_NAME), anyInt(), eq(expectedScan), any(List.class));
+
+ // Notify scan has finished
+ mWifiMonitor.sendMessage(eq(IFACE_NAME), WifiMonitor.SCAN_RESULTS_EVENT);
+ mLooper.dispatchAll();
+ // Get the dump string.
+ String dump = dumpObject();
+
+ assertLogContainsRequestPattern(scanResultRegex, dump);
}
@Test
@@ -181,11 +276,9 @@ public class WificondScannerTest extends BaseWifiScannerImplTest {
eq(WifiMonitor.SCAN_RESULTS_EVENT), any());
}
- private void assertDumpContainsRequestLog(String log) {
- String objectDump = dumpObject();
- Pattern logLineRegex = Pattern.compile(".*" + log + ".*");
- assertTrue("dump did not contain log = " + log + "\n " + objectDump + "\n",
- logLineRegex.matcher(objectDump).find());
+ private void assertLogContainsRequestPattern(Pattern logLineRegex, String log) {
+ assertTrue("dump did not contain log = " + logLineRegex.toString() + "\n" + log + "\n",
+ logLineRegex.matcher(log).find());
}
private String dumpObject() {
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 ee43c001a4..d02a790c45 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
@@ -26,6 +26,7 @@ import android.net.wifi.WifiScanner;
import androidx.test.filters.SmallTest;
import com.android.internal.util.ArrayUtils;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiNative;
import org.junit.Before;
@@ -40,7 +41,7 @@ import java.util.Arrays;
* Unit tests for {@link com.android.server.wifi.util.ApConfigUtil}.
*/
@SmallTest
-public class ApConfigUtilTest {
+public class ApConfigUtilTest extends WifiBaseTest {
private static final String TEST_COUNTRY_CODE = "TestCountry";
@@ -98,7 +99,9 @@ public class ApConfigUtilTest {
5765, 153,
5785, 157,
5805, 161,
- 5825, 165
+ 5825, 165,
+ 5845, 169,
+ 5865, 173
};
private static final Integer[] ALLOWED_2G_CHANNELS = {1, 2, 3, 4};
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/BitMaskTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/BitMaskTest.java
index c905f27fde..83144de957 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/BitMaskTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/BitMaskTest.java
@@ -18,6 +18,8 @@ package com.android.server.wifi.util;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Assert;
import org.junit.Test;
@@ -25,7 +27,7 @@ import org.junit.Test;
* Unit tests for {@link com.android.server.wifi.util.BitMask}.
*/
@SmallTest
-public class BitMaskTest {
+public class BitMaskTest extends WifiBaseTest {
/**
* Test that checkoff.testAndClear works as advertised
*/
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/ByteArrayRingBufferTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/ByteArrayRingBufferTest.java
index 5c397c70c9..d403213777 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/ByteArrayRingBufferTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/ByteArrayRingBufferTest.java
@@ -23,13 +23,15 @@ import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
/**
* Unit tests for {@link com.android.server.wifi.util.ByteArrayRingBuffer}.
*/
@SmallTest
-public class ByteArrayRingBufferTest {
+public class ByteArrayRingBufferTest extends WifiBaseTest {
private static final int MAX_BYTES = 10;
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java
index c281b6440d..69958917a4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java
@@ -18,6 +18,8 @@ package com.android.server.wifi.util;
import static org.junit.Assert.*;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Ignore;
import org.junit.Test;
@@ -26,7 +28,7 @@ import java.io.File;
/**
* Unit tests for {@link com.android.server.wifi.util.DataIntegrityChecker}.
*/
-public class DataIntegrityCheckerTest {
+public class DataIntegrityCheckerTest extends WifiBaseTest {
private static byte[] sGoodData = {1, 2, 3, 4};
private static byte[] sBadData = {5, 6, 7, 8};
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/ExternalCallbackTrackerTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/ExternalCallbackTrackerTest.java
index 94c1aee38b..4eee45233a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/ExternalCallbackTrackerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/ExternalCallbackTrackerTest.java
@@ -29,6 +29,8 @@ import android.os.RemoteException;
import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -39,7 +41,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for {@link com.android.server.wifi.util.ExternalCallbackTracker}.
*/
@SmallTest
-public class ExternalCallbackTrackerTest {
+public class ExternalCallbackTrackerTest extends WifiBaseTest {
private static final int TEST_CALLBACK_IDENTIFIER = 56;
@Mock Handler mHandler;
@Mock ISoftApCallback mCallback;
@@ -85,7 +87,7 @@ public class ExternalCallbackTrackerTest {
public void testRemoveCallback() throws Exception {
testAddCallback();
- assertTrue(mExternalCallbackTracker.remove(TEST_CALLBACK_IDENTIFIER));
+ assertNotNull(mExternalCallbackTracker.remove(TEST_CALLBACK_IDENTIFIER));
assertEquals(0, mExternalCallbackTracker.getNumCallbacks());
assertTrue(mExternalCallbackTracker.getCallbacks().isEmpty());
verify(mBinder).unlinkToDeath(any(), anyInt());
@@ -99,7 +101,7 @@ public class ExternalCallbackTrackerTest {
public void testRemoveCallbackFailureOnWrongIdentifier() throws Exception {
testAddCallback();
- assertFalse(mExternalCallbackTracker.remove(TEST_CALLBACK_IDENTIFIER + 5));
+ assertNull(mExternalCallbackTracker.remove(TEST_CALLBACK_IDENTIFIER + 5));
assertEquals(1, mExternalCallbackTracker.getNumCallbacks());
assertEquals(mCallback, mExternalCallbackTracker.getCallbacks().get(0));
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/FrameParserTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/FrameParserTest.java
index 9fc23034ab..42d44c1a2b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/FrameParserTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/FrameParserTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiLoggerHal;
import org.junit.Test;
@@ -28,7 +29,7 @@ import org.junit.Test;
* Unit tests for {@link com.android.server.wifi.util.FrameParser}.
*/
@SmallTest
-public class FrameParserTest {
+public class FrameParserTest extends WifiBaseTest {
private static final byte[] TEST_EAPOL_1_OF_4_FRAME_BYTES = new byte[] {
(byte) 0x7C, (byte) 0x7D, (byte) 0x3D, (byte) 0x51, (byte) 0x10, (byte) 0xDC,
@@ -340,4 +341,4 @@ public class FrameParserTest {
assertEquals("Action No Ack", parser.mTypeString);
assertEquals("N/A", parser.mResultString);
}
-} \ No newline at end of file
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java
index dd567053c0..c11b300e54 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,11 +21,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import android.net.wifi.ScanResult;
import android.net.wifi.ScanResult.InformationElement;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.hotspot2.NetworkDetail;
+import com.android.server.wifi.util.InformationElementUtil.HtOperation;
+import com.android.server.wifi.util.InformationElementUtil.VhtOperation;
import org.junit.Test;
@@ -38,7 +42,7 @@ import java.util.BitSet;
* Unit tests for {@link com.android.server.wifi.util.InformationElementUtil}.
*/
@SmallTest
-public class InformationElementUtilTest {
+public class InformationElementUtilTest extends WifiBaseTest {
// SSID Information Element tags
private static final byte[] TEST_SSID_BYTES_TAG = new byte[] { (byte) 0x00, (byte) 0x0B };
@@ -775,6 +779,24 @@ public class InformationElementUtilTest {
}
/**
+ * Test Capabilities.generateCapabilitiesString() with the IBSS capability bit set.
+ *
+ * Expect the function to return a string with [IBSS] there.
+ */
+ @Test
+ public void buildCapabilities_IbssCapabilitySet() {
+ BitSet beaconCap = new BitSet(16);
+ beaconCap.set(1);
+
+ InformationElementUtil.Capabilities capabilities =
+ new InformationElementUtil.Capabilities();
+ capabilities.from(new InformationElement[0], beaconCap, false);
+ String result = capabilities.generateCapabilitiesString();
+
+ assertEquals("[IBSS]", result);
+ }
+
+ /**
* Verify the expectations when building an ExtendedCapabilites IE from data with no bits set.
* Both ExtendedCapabilities#isStrictUtf8() and ExtendedCapabilites#is80211McRTTResponder()
* should return false.
@@ -990,5 +1012,163 @@ public class InformationElementUtilTest {
assertEquals(0x112233445566L, interworking.hessid);
}
+ /**
+ * Verify that the expected HT Operation information element is parsed and retrieved from the
+ * list of IEs.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void getHtOperationElement() throws Exception {
+ final int primaryFreq = 2467;
+ InformationElement ie = new InformationElement();
+ ie.id = InformationElement.EID_HT_OPERATION;
+ /**
+ * HT Operation Format:
+ * | Primary Channel | HT Operation Info | Basic HT-MCS Set |
+ * 1 5 16
+ *
+ * HT Operation Info Format (relevant parts only):
+ *
+ * B0 B1 B2 -----
+ * | Secondary Channel Offset | STA Channel Width | Other |
+ */
+ ie.bytes = new byte[22];
+ ie.bytes[0] = (byte) 11;
+ ie.bytes[1] = (byte) 0x83; //Setting Secondary channel offset = 3
+ // Remaining bytes are not relevant
+
+ HtOperation htOperation = new HtOperation();
+ htOperation.from(ie);
+
+ assertTrue(htOperation.isPresent());
+ assertEquals(ScanResult.CHANNEL_WIDTH_40MHZ, htOperation.getChannelWidth());
+ assertEquals(primaryFreq - 10, htOperation.getCenterFreq0(primaryFreq));
+ }
+
+ /**
+ * Verify that the expected VHT Operation information element is parsed and retrieved from the
+ * list of IEs.
+ * In this test case Channel BW is set to be 20/40 MHz
+ *
+ * @throws Exception
+ */
+ @Test
+ public void getVhtOperationElement20_40Mhz() throws Exception {
+ InformationElement ie = new InformationElement();
+ ie.id = InformationElement.EID_VHT_OPERATION;
+ /**
+ * VHT Operation Format:
+ * | VHT Operation Info | Basic HT-MCS Set |
+ * 3 2
+ *
+ * VHT Operation Info Format:
+ * | Channel Width | Channel Center Freq Seg 0 | Channel Center Freq Seg 1 |
+ * 1 1 1
+ */
+ ie.bytes = new byte[]{(byte) 0x00, (byte) 0xF0, (byte) 0xF1, (byte) 0x00, (byte) 0x00};
+
+ VhtOperation vhtOperation = new VhtOperation();
+ vhtOperation.from(ie);
+
+ assertTrue(vhtOperation.isPresent());
+ assertEquals(ScanResult.UNSPECIFIED, vhtOperation.getChannelWidth());
+ assertEquals(0, vhtOperation.getCenterFreq0());
+ assertEquals(0, vhtOperation.getCenterFreq1());
+ }
+
+ /**
+ * Verify that the expected VHT Operation information element is parsed and retrieved from the
+ * list of IEs.
+ * In this test case Channel BW is set to be 80 MHz
+ *
+ * @throws Exception
+ */
+ @Test
+ public void getVhtOperationElement80Mhz() throws Exception {
+ InformationElement ie = new InformationElement();
+ ie.id = InformationElement.EID_VHT_OPERATION;
+ /**
+ * VHT Operation Format:
+ * | VHT Operation Info | Basic HT-MCS Set |
+ * 3 2
+ *
+ * VHT Operation Info Format:
+ * | Channel Width | Channel Center Freq Seg 0 | Channel Center Freq Seg 1 |
+ * 1 1 1
+ */
+ ie.bytes = new byte[]{(byte) 0x01, (byte) 36, (byte) 0x00, (byte) 0x00, (byte) 0x00};
+
+ VhtOperation vhtOperation = new VhtOperation();
+ vhtOperation.from(ie);
+
+ assertTrue(vhtOperation.isPresent());
+ assertEquals(ScanResult.CHANNEL_WIDTH_80MHZ, vhtOperation.getChannelWidth());
+ assertEquals(5180, vhtOperation.getCenterFreq0());
+ assertEquals(0, vhtOperation.getCenterFreq1());
+ }
+
+ /**
+ * Verify that the expected VHT Operation information element is parsed and retrieved from the
+ * list of IEs.
+ * In this test case Channel BW is set to be 160 MHz
+ *
+ * @throws Exception
+ */
+ @Test
+ public void getVhtOperationElement160Mhz() throws Exception {
+ InformationElement ie = new InformationElement();
+ ie.id = InformationElement.EID_VHT_OPERATION;
+ /**
+ * VHT Operation Format:
+ * | VHT Operation Info | Basic HT-MCS Set |
+ * 3 2
+ *
+ * VHT Operation Info Format:
+ * | Channel Width | Channel Center Freq Seg 0 | Channel Center Freq Seg 1 |
+ * 1 1 1
+ */
+ ie.bytes = new byte[]{(byte) 0x01, (byte) 44, (byte) 36, (byte) 0x00, (byte) 0x00};
+
+ VhtOperation vhtOperation = new VhtOperation();
+ vhtOperation.from(ie);
+
+ assertTrue(vhtOperation.isPresent());
+ assertEquals(ScanResult.CHANNEL_WIDTH_160MHZ, vhtOperation.getChannelWidth());
+ assertEquals(5220, vhtOperation.getCenterFreq0());
+ assertEquals(5180, vhtOperation.getCenterFreq1());
+ }
+
+ /**
+ * Verify that the expected VHT Operation information element is parsed and retrieved from the
+ * list of IEs.
+ * In this test case Channel BW is set to be 80+80 MHz
+ *
+ * @throws Exception
+ */
+ @Test
+ public void getVhtOperationElement80PlusMhz() throws Exception {
+ InformationElement ie = new InformationElement();
+ ie.id = InformationElement.EID_VHT_OPERATION;
+ /**
+ * VHT Operation Format:
+ * | VHT Operation Info | Basic HT-MCS Set |
+ * 3 2
+ *
+ * VHT Operation Info Format:
+ * | Channel Width | Channel Center Freq Seg 0 | Channel Center Freq Seg 1 |
+ * 1 1 1
+ */
+ ie.bytes = new byte[]{(byte) 0x01, (byte) 54, (byte) 36, (byte) 0x00, (byte) 0x00};
+
+ VhtOperation vhtOperation = new VhtOperation();
+ vhtOperation.from(ie);
+
+ assertTrue(vhtOperation.isPresent());
+ assertEquals(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, vhtOperation.getChannelWidth());
+ assertEquals(5270, vhtOperation.getCenterFreq0());
+ assertEquals(5180, vhtOperation.getCenterFreq1());
+ }
+
// TODO: SAE, OWN, SUITE_B
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/IntCounterTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/IntCounterTest.java
index 794f562665..d82f07334a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/IntCounterTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/IntCounterTest.java
@@ -21,6 +21,7 @@ import static com.android.server.wifi.WifiMetricsTestUtil.buildInt32Count;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.nano.WifiMetricsProto.Int32Count;
import org.junit.Test;
@@ -30,7 +31,7 @@ import org.junit.Test;
* Unit tests for IntCounter.
*/
@SmallTest
-public class IntCounterTest {
+public class IntCounterTest extends WifiBaseTest {
private static final int[] TEST_KEYS = {
100, 20, 34, 5656, 3535, 6456, -1231, -4235, 20, 3535, -5, 100, 6456, 34, -4235, -4235
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/IntHistogramTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/IntHistogramTest.java
index fc09036af8..888b5f2ac9 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/IntHistogramTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/IntHistogramTest.java
@@ -23,6 +23,7 @@ import static org.hamcrest.core.IsEqual.equalTo;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.nano.WifiMetricsProto.HistogramBucketInt32;
import org.junit.Before;
@@ -36,7 +37,7 @@ import org.mockito.MockitoAnnotations;
* Unit tests for IntHistogram.
*/
@SmallTest
-public class IntHistogramTest {
+public class IntHistogramTest extends WifiBaseTest {
@Rule
public ErrorCollector collector = new ErrorCollector();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/KalmanFilterTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/KalmanFilterTest.java
index 54d6e0c3e4..c5ac0452b7 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/KalmanFilterTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/KalmanFilterTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.util.Random;
@@ -29,7 +31,7 @@ import java.util.Random;
* Unit tests for {@link com.android.server.wifi.util.KalmanFilter}.
*/
@SmallTest
-public class KalmanFilterTest {
+public class KalmanFilterTest extends WifiBaseTest {
/**
* Test that constructor works
*/
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/MatrixTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/MatrixTest.java
index 3d971ab663..5fa95be9f2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/MatrixTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/MatrixTest.java
@@ -22,6 +22,8 @@ import static org.junit.Assert.fail;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.util.ArrayList;
@@ -32,7 +34,7 @@ import java.util.Random;
* Unit tests for {@link com.android.server.wifi.util.Matrix}.
*/
@SmallTest
-public class MatrixTest {
+public class MatrixTest extends WifiBaseTest {
/**
* Test that both forms of constructor work
*/
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/MetricsUtilsTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/MetricsUtilsTest.java
index 58d4b9e39a..e2f4d3d379 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/MetricsUtilsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/MetricsUtilsTest.java
@@ -22,6 +22,8 @@ import android.util.SparseIntArray;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -32,7 +34,7 @@ import org.mockito.MockitoAnnotations;
* Unit test harness for MetricsUtils.
*/
@SmallTest
-public class MetricsUtilsTest {
+public class MetricsUtilsTest extends WifiBaseTest {
@Rule
public ErrorCollector collector = new ErrorCollector();
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 d4bcb479e5..566a94b45c 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
@@ -20,6 +20,8 @@ import static org.junit.Assert.*;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
import java.util.ArrayList;
@@ -29,7 +31,7 @@ import java.util.Arrays;
* Unit tests for {@link com.android.server.wifi.util.NativeUtil}.
*/
@SmallTest
-public class NativeUtilTest {
+public class NativeUtilTest extends WifiBaseTest {
/**
* Test that parsing a typical colon-delimited MAC address works.
*/
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/ObjectCounterTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/ObjectCounterTest.java
index 20a2803532..b468a9a2b7 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/ObjectCounterTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/ObjectCounterTest.java
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertThat;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.util.ObjectCounter.ProtobufConverter;
import org.hamcrest.collection.IsIterableContainingInAnyOrder;
@@ -34,7 +35,7 @@ import java.util.Objects;
* Unit test for ObjectCounter
*/
@SmallTest
-public class ObjectCounterTest {
+public class ObjectCounterTest extends WifiBaseTest {
/**
* Test Key type: composite key with 3 fields
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
index 45adffd1dd..30d84de32e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
@@ -26,6 +26,7 @@ import android.net.wifi.WifiSsid;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.ScanDetail;
+import com.android.server.wifi.WifiBaseTest;
import org.junit.Test;
@@ -36,7 +37,7 @@ import java.util.Arrays;
* Unit tests for {@link com.android.server.wifi.util.ScanResultUtil}.
*/
@SmallTest
-public class ScanResultUtilTest {
+public class ScanResultUtilTest extends WifiBaseTest {
@Test
public void convertScanResult() {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/StringUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/StringUtilTest.java
index 7308f12272..db61686991 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/StringUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/StringUtilTest.java
@@ -21,13 +21,15 @@ import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
+import com.android.server.wifi.WifiBaseTest;
+
import org.junit.Test;
/**
* Unit tests for {@link com.android.server.wifi.util.StringUtil}.
*/
@SmallTest
-public class StringUtilTest {
+public class StringUtilTest extends WifiBaseTest {
static final byte ASCII_UNIT_SEPARATOR = 31;
static final byte ASCII_DEL = 127;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
index 531673f0ed..483855a16b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
@@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.server.wifi.CarrierNetworkConfig;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiConfigurationTestUtil;
import com.android.server.wifi.util.TelephonyUtil.SimAuthRequestData;
import com.android.server.wifi.util.TelephonyUtil.SimAuthResponseData;
@@ -49,7 +50,7 @@ import javax.crypto.Cipher;
* Unit tests for {@link com.android.server.wifi.util.TelephonyUtil}.
*/
@SmallTest
-public class TelephonyUtilTest {
+public class TelephonyUtilTest extends WifiBaseTest {
private TelephonyUtil mTelephonyUtil;
@Mock
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/TimedQuotaManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/TimedQuotaManagerTest.java
index 3dcad7cd70..4884ac9278 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/TimedQuotaManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/TimedQuotaManagerTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.when;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.Clock;
+import com.android.server.wifi.WifiBaseTest;
import org.junit.Before;
import org.junit.Test;
@@ -35,7 +36,7 @@ import java.time.Duration;
* Unit tests for {@link TimedQuotaManager}.
*/
@SmallTest
-public class TimedQuotaManagerTest {
+public class TimedQuotaManagerTest extends WifiBaseTest {
private static final long DAY_MILLIS = Duration.ofDays(1).toMillis();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/WifiHandlerTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/WifiHandlerTest.java
index fbf147180c..edbe39df32 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/WifiHandlerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/WifiHandlerTest.java
@@ -25,6 +25,7 @@ import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.FakeWifiLog;
+import com.android.server.wifi.WifiBaseTest;
import org.junit.Before;
import org.junit.Test;
@@ -36,7 +37,7 @@ import org.mockito.Spy;
/** Unit tests for {@link WifiHandler}. */
@RunWith(JUnit4.class)
@SmallTest
-public class WifiHandlerTest {
+public class WifiHandlerTest extends WifiBaseTest {
private static final String TAG = "WifiHandlerTest";
private WifiHandler mCodeUnderTest;
@Spy FakeWifiLog mWifiLog;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
index 0c9ed26b7b..8e3c1bb713 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
@@ -31,15 +31,15 @@ import static org.mockito.Mockito.when;
import android.Manifest;
import android.app.AppOpsManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.location.LocationManager;
import android.net.NetworkStack;
import android.os.Build;
-import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -47,6 +47,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.wifi.BinderUtil;
import com.android.server.wifi.FakeWifiLog;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiInjector;
import org.junit.Before;
@@ -59,13 +60,12 @@ import org.mockito.Spy;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import java.util.Arrays;
import java.util.HashMap;
/** Unit tests for {@link WifiPermissionsUtil}. */
@RunWith(JUnit4.class)
@SmallTest
-public class WifiPermissionsUtilTest {
+public class WifiPermissionsUtilTest extends WifiBaseTest {
public static final String TAG = "WifiPermissionsUtilTest";
// Mock objects for testing
@@ -74,13 +74,14 @@ public class WifiPermissionsUtilTest {
@Mock private PackageManager mMockPkgMgr;
@Mock private ApplicationInfo mMockApplInfo;
@Mock private AppOpsManager mMockAppOps;
- @Mock private UserInfo mMockUserInfo;
@Mock private UserManager mMockUserManager;
@Mock private ContentResolver mMockContentResolver;
@Mock private WifiInjector mWifiInjector;
@Mock private LocationManager mLocationManager;
+ @Mock private DevicePolicyManager mDevicePolicyManager;
@Spy private FakeWifiLog mWifiLog;
+ private static final String TEST_WIFI_STACK_APK_NAME = "com.android.wifi";
private static final String TEST_PACKAGE_NAME = "com.google.somePackage";
private static final String INVALID_PACKAGE = "BAD_PACKAGE";
private static final int MANAGED_PROFILE_UID = 1100000;
@@ -90,7 +91,6 @@ public class WifiPermissionsUtilTest {
private static final boolean DONT_HIDE_FROM_APP_OPS = false;
private static final boolean HIDE_FROM_APP_OPS = true;
- private final int mCallingUser = UserHandle.USER_CURRENT_OR_SELF;
private final String mMacAddressPermission = "android.permission.PEERS_MAC_ADDRESS";
private final String mInteractAcrossUsersFullPermission =
"android.permission.INTERACT_ACROSS_USERS_FULL";
@@ -109,7 +109,6 @@ public class WifiPermissionsUtilTest {
private int mFineLocationPermission;
private int mAllowFineLocationApps;
private int mHardwareLocationPermission;
- private String mPkgNameOfTopActivity;
private int mCurrentUser;
private boolean mIsLocationEnabled;
private boolean mThrowSecurityException;
@@ -159,20 +158,6 @@ public class WifiPermissionsUtilTest {
}
/**
- * Verify we return false when the override config permission check throws a RemoteException.
- */
- @Test
- public void testCheckConfigOverridePermissionWithException() throws Exception {
- mUid = OTHER_USER_UID; // do not really care about this value
- setupTestCase();
- WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
- mMockContext, mMockUserManager, mWifiInjector);
- doThrow(new RemoteException("Failed to check permissions for " + mUid))
- .when(mMockPermissionsWrapper).getOverrideWifiConfigPermission(mUid);
- assertFalse(codeUnderTest.checkConfigOverridePermission(mUid));
- }
-
- /**
* Test case setting: Package is valid
* Location mode is enabled
* Caller can read peers mac address
@@ -187,7 +172,7 @@ public class WifiPermissionsUtilTest {
mUid = MANAGED_PROFILE_UID;
mPermissionsList.put(mMacAddressPermission, mUid);
mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
- mCurrentUser = UserHandle.USER_CURRENT_OR_SELF;
+ mCurrentUser = UserHandle.USER_SYSTEM;
mIsLocationEnabled = true;
setupTestCase();
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
@@ -210,7 +195,6 @@ public class WifiPermissionsUtilTest {
mUid = MANAGED_PROFILE_UID;
mPermissionsList.put(mMacAddressPermission, mUid);
mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
- mMockUserInfo.id = mCallingUser;
mIsLocationEnabled = true;
setupTestCase();
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
@@ -297,10 +281,9 @@ public class WifiPermissionsUtilTest {
public void testLegacyForegroundAppWithOtherPermissionsDenied() throws Exception {
mThrowSecurityException = false;
mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.GINGERBREAD;
- mPkgNameOfTopActivity = TEST_PACKAGE_NAME;
mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
mUid = MANAGED_PROFILE_UID;
- mCurrentUser = UserHandle.USER_CURRENT_OR_SELF;
+ mCurrentUser = UserHandle.USER_SYSTEM;
setupTestCase();
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
mMockContext, mMockUserManager, mWifiInjector);
@@ -328,7 +311,6 @@ public class WifiPermissionsUtilTest {
mAllowCoarseLocationApps = AppOpsManager.MODE_ALLOWED;
mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
mUid = MANAGED_PROFILE_UID;
- mMockUserInfo.id = mCallingUser;
setupTestCase();
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
mMockContext, mMockUserManager, mWifiInjector);
@@ -377,8 +359,6 @@ public class WifiPermissionsUtilTest {
mIsLocationEnabled = false;
setupTestCase();
- when(mMockPermissionsWrapper.getChangeWifiConfigPermission(mUid))
- .thenReturn(PackageManager.PERMISSION_DENIED);
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
mMockContext, mMockUserManager, mWifiInjector);
@@ -411,8 +391,6 @@ public class WifiPermissionsUtilTest {
mIsLocationEnabled = false;
setupTestCase();
- when(mMockPermissionsWrapper.getChangeWifiConfigPermission(mUid))
- .thenReturn(PackageManager.PERMISSION_GRANTED);
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
mMockContext, mMockUserManager, mWifiInjector);
@@ -446,8 +424,6 @@ public class WifiPermissionsUtilTest {
mIsLocationEnabled = false;
setupTestCase();
- when(mMockPermissionsWrapper.getAccessWifiStatePermission(mUid))
- .thenReturn(PackageManager.PERMISSION_GRANTED);
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
mMockContext, mMockUserManager, mWifiInjector);
@@ -719,14 +695,14 @@ public class WifiPermissionsUtilTest {
mAllowCoarseLocationApps = AppOpsManager.MODE_ALLOWED;
mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
mUid = MANAGED_PROFILE_UID;
- mMockUserInfo.id = mCallingUser;
setupTestCase();
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
mMockContext, mMockUserManager, mWifiInjector);
codeUnderTest.enforceLocationPermission(TEST_PACKAGE_NAME, mUid);
// verify that checking FINE for legacy apps!
- verify(mMockAppOps).noteOp(eq(AppOpsManager.OP_FINE_LOCATION), anyInt(), anyString());
+ verify(mMockAppOps).noteOp(eq(AppOpsManager.OPSTR_FINE_LOCATION), anyInt(), anyString(),
+ any(), any());
}
/**
@@ -742,12 +718,12 @@ public class WifiPermissionsUtilTest {
mAllowFineLocationApps = AppOpsManager.MODE_ALLOWED;
mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
mUid = MANAGED_PROFILE_UID;
- mMockUserInfo.id = mCallingUser;
setupTestCase();
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
mMockContext, mMockUserManager, mWifiInjector);
codeUnderTest.enforceLocationPermission(TEST_PACKAGE_NAME, mUid);
- verify(mMockAppOps).noteOp(eq(AppOpsManager.OP_FINE_LOCATION), anyInt(), anyString());
+ verify(mMockAppOps)
+ .noteOp(eq(AppOpsManager.OPSTR_FINE_LOCATION), anyInt(), anyString(), any(), any());
}
/**
@@ -765,7 +741,6 @@ public class WifiPermissionsUtilTest {
mAllowFineLocationApps = AppOpsManager.MODE_ERRORED;
mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
mUid = MANAGED_PROFILE_UID;
- mMockUserInfo.id = mCallingUser;
setupTestCase();
WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
mMockContext, mMockUserManager, mWifiInjector);
@@ -829,8 +804,8 @@ public class WifiPermissionsUtilTest {
WifiPermissionsUtil wifiPermissionsUtil = new WifiPermissionsUtil(mMockPermissionsWrapper,
mMockContext, mMockUserManager, mWifiInjector);
- when(mMockAppOps.noteOp(
- AppOpsManager.OP_SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID, TEST_PACKAGE_NAME))
+ when(mMockAppOps.noteOp(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID,
+ TEST_PACKAGE_NAME, null, null))
.thenReturn(AppOpsManager.MODE_DEFAULT);
when(mMockPermissionsWrapper.getUidPermission(
Manifest.permission.SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID))
@@ -838,8 +813,8 @@ public class WifiPermissionsUtilTest {
assertFalse(wifiPermissionsUtil.checkSystemAlertWindowPermission(
MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
- when(mMockAppOps.noteOp(
- AppOpsManager.OP_SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID, TEST_PACKAGE_NAME))
+ when(mMockAppOps.noteOp(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID,
+ TEST_PACKAGE_NAME, null, null))
.thenReturn(AppOpsManager.MODE_DEFAULT);
when(mMockPermissionsWrapper.getUidPermission(
Manifest.permission.SYSTEM_ALERT_WINDOW, MANAGED_PROFILE_UID))
@@ -865,6 +840,95 @@ public class WifiPermissionsUtilTest {
}
/**
+ * Verifies the helper method exposed for checking if the app is a DeviceOwner.
+ */
+ @Test
+ public void testIsDeviceOwnerApp() throws Exception {
+ setupMocks();
+ WifiPermissionsUtil wifiPermissionsUtil = new WifiPermissionsUtil(mMockPermissionsWrapper,
+ mMockContext, mMockUserManager, mWifiInjector);
+
+ when(mMockContext.getSystemService(DevicePolicyManager.class))
+ .thenReturn(mDevicePolicyManager);
+
+ when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser())
+ .thenReturn(new ComponentName(TEST_PACKAGE_NAME, new String()));
+ when(mDevicePolicyManager.getDeviceOwnerUser())
+ .thenReturn(UserHandle.getUserHandleForUid(MANAGED_PROFILE_UID));
+ assertTrue(wifiPermissionsUtil.isDeviceOwner(
+ MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
+
+
+ // userId does not match
+ when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser())
+ .thenReturn(new ComponentName(TEST_PACKAGE_NAME, new String()));
+ when(mDevicePolicyManager.getDeviceOwnerUser())
+ .thenReturn(UserHandle.getUserHandleForUid(OTHER_USER_UID));
+ assertFalse(wifiPermissionsUtil.isDeviceOwner(
+ MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
+
+ // Package Name does not match
+ when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser())
+ .thenReturn(new ComponentName(INVALID_PACKAGE, new String()));
+ when(mDevicePolicyManager.getDeviceOwnerUser())
+ .thenReturn(UserHandle.getUserHandleForUid(MANAGED_PROFILE_UID));
+ assertFalse(wifiPermissionsUtil.isDeviceOwner(
+ MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
+
+ // No device owner.
+ when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser())
+ .thenReturn(null);
+ assertFalse(wifiPermissionsUtil.isDeviceOwner(
+ MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
+
+ // DevicePolicyManager does not exist.
+ when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
+ .thenReturn(null);
+ assertFalse(wifiPermissionsUtil.isDeviceOwner(
+ MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
+ }
+
+ /**
+ * Verifies the helper method exposed for checking if the app is a ProfileOwner.
+ */
+ @Test
+ public void testIsProfileOwnerApp() throws Exception {
+ setupMocks();
+ WifiPermissionsUtil wifiPermissionsUtil = new WifiPermissionsUtil(mMockPermissionsWrapper,
+ mMockContext, mMockUserManager, mWifiInjector);
+
+ when(mMockContext.createPackageContextAsUser(
+ TEST_WIFI_STACK_APK_NAME, 0, UserHandle.getUserHandleForUid(MANAGED_PROFILE_UID)))
+ .thenReturn(mMockContext);
+ when(mMockContext.getSystemService(DevicePolicyManager.class))
+ .thenReturn(mDevicePolicyManager);
+
+ when(mDevicePolicyManager.isProfileOwnerApp(TEST_PACKAGE_NAME))
+ .thenReturn(true);
+ assertTrue(wifiPermissionsUtil.isProfileOwner(
+ MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
+
+ when(mDevicePolicyManager.isProfileOwnerApp(TEST_PACKAGE_NAME))
+ .thenReturn(false);
+ assertFalse(wifiPermissionsUtil.isProfileOwner(
+ MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
+
+ // DevicePolicyManager does not exist.
+ when(mMockContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
+ .thenReturn(null);
+ assertFalse(wifiPermissionsUtil.isProfileOwner(
+ MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
+
+ // Invalid package name.
+ doThrow(new PackageManager.NameNotFoundException())
+ .when(mMockContext).createPackageContextAsUser(
+ TEST_WIFI_STACK_APK_NAME, 0,
+ UserHandle.getUserHandleForUid(MANAGED_PROFILE_UID));
+ assertFalse(wifiPermissionsUtil.isProfileOwner(
+ MANAGED_PROFILE_UID, TEST_PACKAGE_NAME));
+ }
+
+ /**
* Test case setting: caller does not have Location permission.
* Expect a SecurityException
*/
@@ -899,9 +963,10 @@ public class WifiPermissionsUtilTest {
codeUnderTest.enforceCanAccessScanResultsForWifiScanner(TEST_PACKAGE_NAME, mUid,
CHECK_LOCATION_SETTINGS, DONT_HIDE_FROM_APP_OPS);
- verify(mMockAppOps, never()).checkOp(
- AppOpsManager.OP_FINE_LOCATION, mUid, TEST_PACKAGE_NAME);
- verify(mMockAppOps).noteOp(AppOpsManager.OP_FINE_LOCATION, mUid, TEST_PACKAGE_NAME);
+ verify(mMockAppOps, never())
+ .unsafeCheckOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME);
+ verify(mMockAppOps)
+ .noteOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME, null, null);
}
/**
@@ -928,9 +993,10 @@ public class WifiPermissionsUtilTest {
codeUnderTest.enforceCanAccessScanResultsForWifiScanner(TEST_PACKAGE_NAME, mUid,
IGNORE_LOCATION_SETTINGS, HIDE_FROM_APP_OPS);
- verify(mMockAppOps).checkOp(AppOpsManager.OP_FINE_LOCATION, mUid, TEST_PACKAGE_NAME);
+ verify(mMockAppOps).unsafeCheckOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid,
+ TEST_PACKAGE_NAME);
verify(mMockAppOps, never()).noteOp(
- AppOpsManager.OP_FINE_LOCATION, mUid, TEST_PACKAGE_NAME);
+ AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME, null, null);
}
@@ -1148,16 +1214,16 @@ public class WifiPermissionsUtilTest {
}
private void setupMocks() throws Exception {
- when(mMockPkgMgr.getApplicationInfoAsUser(eq(TEST_PACKAGE_NAME), eq(0), anyInt()))
+ when(mMockPkgMgr.getApplicationInfoAsUser(eq(TEST_PACKAGE_NAME), eq(0), any()))
.thenReturn(mMockApplInfo);
when(mMockContext.getPackageManager()).thenReturn(mMockPkgMgr);
- when(mMockAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, mUid, TEST_PACKAGE_NAME))
- .thenReturn(mWifiScanAllowApps);
- when(mMockAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, mUid, TEST_PACKAGE_NAME))
- .thenReturn(mAllowCoarseLocationApps);
- when(mMockAppOps.noteOp(AppOpsManager.OP_FINE_LOCATION, mUid, TEST_PACKAGE_NAME))
- .thenReturn(mAllowFineLocationApps);
- when(mMockAppOps.checkOp(AppOpsManager.OP_FINE_LOCATION, mUid, TEST_PACKAGE_NAME))
+ when(mMockAppOps.noteOp(AppOpsManager.OPSTR_WIFI_SCAN, mUid, TEST_PACKAGE_NAME, null, null))
+ .thenReturn(mWifiScanAllowApps);
+ when(mMockAppOps.noteOp(AppOpsManager.OPSTR_COARSE_LOCATION, mUid, TEST_PACKAGE_NAME, null,
+ null)).thenReturn(mAllowCoarseLocationApps);
+ when(mMockAppOps.noteOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME, null,
+ null)).thenReturn(mAllowFineLocationApps);
+ when(mMockAppOps.unsafeCheckOp(AppOpsManager.OPSTR_FINE_LOCATION, mUid, TEST_PACKAGE_NAME))
.thenReturn(mAllowFineLocationApps);
if (mThrowSecurityException) {
doThrow(new SecurityException("Package " + TEST_PACKAGE_NAME + " doesn't belong"
@@ -1166,13 +1232,12 @@ public class WifiPermissionsUtilTest {
}
when(mMockContext.getSystemService(Context.APP_OPS_SERVICE))
.thenReturn(mMockAppOps);
- when(mMockUserManager.getProfiles(mCurrentUser))
- .thenReturn(Arrays.asList(mMockUserInfo));
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
when(mMockContext.getSystemService(Context.USER_SERVICE))
.thenReturn(mMockUserManager);
when(mWifiInjector.makeLog(anyString())).thenReturn(mWifiLog);
when(mMockContext.getSystemService(Context.LOCATION_SERVICE)).thenReturn(mLocationManager);
+ when(mMockContext.getPackageName()).thenReturn(TEST_WIFI_STACK_APK_NAME);
}
private void initTestVars() {
@@ -1181,9 +1246,7 @@ public class WifiPermissionsUtilTest {
mWifiScanAllowApps = AppOpsManager.MODE_ERRORED;
mUid = OTHER_USER_UID;
mThrowSecurityException = true;
- mMockUserInfo.id = UserHandle.USER_NULL;
mMockApplInfo.targetSdkVersion = Build.VERSION_CODES.M;
- mPkgNameOfTopActivity = INVALID_PACKAGE;
mIsLocationEnabled = false;
mCurrentUser = UserHandle.USER_SYSTEM;
mCoarseLocationPermission = PackageManager.PERMISSION_DENIED;
@@ -1198,7 +1261,9 @@ public class WifiPermissionsUtilTest {
anyString(), anyInt());
doAnswer(mReturnPermission).when(mMockPermissionsWrapper).getUidPermission(
anyString(), anyInt());
- when(mMockPermissionsWrapper.getCallingUserId(mUid)).thenReturn(mCallingUser);
+ when(mMockUserManager.isSameProfileGroup(UserHandle.SYSTEM,
+ UserHandle.getUserHandleForUid(MANAGED_PROFILE_UID)))
+ .thenReturn(true);
when(mMockPermissionsWrapper.getCurrentUser()).thenReturn(mCurrentUser);
when(mMockPermissionsWrapper.getUidPermission(mManifestStringCoarse, mUid))
.thenReturn(mCoarseLocationPermission);
@@ -1207,6 +1272,5 @@ public class WifiPermissionsUtilTest {
when(mMockPermissionsWrapper.getUidPermission(mManifestStringHardware, mUid))
.thenReturn(mHardwareLocationPermission);
when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(mIsLocationEnabled);
- when(mMockPermissionsWrapper.getTopPkgName()).thenReturn(mPkgNameOfTopActivity);
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
index 85b4a93700..e2a3411872 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import android.net.IpConfiguration;
+import android.net.MacAddress;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import android.net.wifi.WifiEnterpriseConfig;
@@ -29,6 +30,7 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiConfigurationTestUtil;
import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
import com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil;
@@ -50,7 +52,7 @@ import java.util.HashMap;
* Unit tests for {@link com.android.server.wifi.util.XmlUtil}.
*/
@SmallTest
-public class XmlUtilTest {
+public class XmlUtilTest extends WifiBaseTest {
public static final String XML_STRING_EAP_METHOD_REPLACE_FORMAT =
"<int name=\"EapMethod\" value=\"%d\" />";
@@ -208,7 +210,7 @@ public class XmlUtilTest {
configuration.lastUpdateUid = configuration.lastConnectUid = configuration.creatorUid;
configuration.creatorName = configuration.lastUpdateName = TEST_PACKAGE_NAME;
configuration.creationTime = "04-04-2016";
- configuration.getOrCreateRandomizedMacAddress();
+ configuration.setRandomizedMacAddress(MacAddress.createRandomUnicastAddress());
configuration.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
serializeDeserializeWifiConfigurationForConfigStore(configuration);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/wificond/NativeScanResultTest.java b/service/tests/wifitests/src/com/android/server/wifi/wificond/NativeScanResultTest.java
deleted file mode 100644
index 11be8315f9..0000000000
--- a/service/tests/wifitests/src/com/android/server/wifi/wificond/NativeScanResultTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2017 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.wificond;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-
-/**
- * Unit tests for {@link com.android.server.wifi.wificond.NativeScanResult}.
- */
-@SmallTest
-public class NativeScanResultTest {
-
- private static final byte[] TEST_SSID =
- new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
- private static final byte[] TEST_BSSID =
- new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1,
- (byte) 0x2c, (byte) 0x97, (byte) 0x8b};
- private static final byte[] TEST_INFO_ELEMENT =
- new byte[] {(byte) 0x01, (byte) 0x03, (byte) 0x12, (byte) 0xbe, (byte) 0xff};
- private static final int TEST_FREQUENCY = 2456;
- private static final int TEST_SIGNAL_MBM = -45;
- private static final long TEST_TSF = 34455441;
- private static final BitSet TEST_CAPABILITY = new BitSet(16) {{ set(2); set(5); }};
- private static final boolean TEST_ASSOCIATED = true;
- private static final int[] RADIO_CHAIN_IDS = { 0, 1 };
- private static final int[] RADIO_CHAIN_LEVELS = { -56, -65 };
-
- /**
- * NativeScanResult object can be serialized and deserialized, while keeping the
- * values unchanged.
- */
- @Test
- public void canSerializeAndDeserialize() {
- NativeScanResult scanResult = new NativeScanResult();
- scanResult.ssid = TEST_SSID;
- scanResult.bssid = TEST_BSSID;
- scanResult.infoElement = TEST_INFO_ELEMENT;
- scanResult.frequency = TEST_FREQUENCY;
- scanResult.signalMbm = TEST_SIGNAL_MBM;
- scanResult.tsf = TEST_TSF;
- scanResult.capability = TEST_CAPABILITY;
- scanResult.associated = TEST_ASSOCIATED;
- scanResult.radioChainInfos = new ArrayList<>(Arrays.asList(
- new RadioChainInfo(RADIO_CHAIN_IDS[0], RADIO_CHAIN_LEVELS[0]),
- new RadioChainInfo(RADIO_CHAIN_IDS[1], RADIO_CHAIN_LEVELS[1])));
- Parcel parcel = Parcel.obtain();
- scanResult.writeToParcel(parcel, 0);
- // Rewind the pointer to the head of the parcel.
- parcel.setDataPosition(0);
- NativeScanResult scanResultDeserialized = NativeScanResult.CREATOR.createFromParcel(parcel);
-
- assertArrayEquals(scanResult.ssid, scanResultDeserialized.ssid);
- assertArrayEquals(scanResult.bssid, scanResultDeserialized.bssid);
- assertArrayEquals(scanResult.infoElement, scanResultDeserialized.infoElement);
- assertEquals(scanResult.frequency, scanResultDeserialized.frequency);
- assertEquals(scanResult.signalMbm, scanResultDeserialized.signalMbm);
- assertEquals(scanResult.tsf, scanResultDeserialized.tsf);
- assertEquals(scanResult.capability, scanResultDeserialized.capability);
- assertEquals(scanResult.associated, scanResultDeserialized.associated);
- assertTrue(scanResult.radioChainInfos.containsAll(scanResultDeserialized.radioChainInfos));
- }
-}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/wificond/PnoSettingsTest.java b/service/tests/wifitests/src/com/android/server/wifi/wificond/PnoSettingsTest.java
deleted file mode 100644
index b484665c39..0000000000
--- a/service/tests/wifitests/src/com/android/server/wifi/wificond/PnoSettingsTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2017 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.wificond;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-
-/**
- * Unit tests for {@link com.android.server.wifi.wificond.PnoSettingsResult}.
- */
-@SmallTest
-public class PnoSettingsTest {
-
- private static final byte[] TEST_SSID_1 =
- new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
- private static final byte[] TEST_SSID_2 =
- new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'};
- private static final int[] TEST_FREQUENCIES_1 = {};
- private static final int[] TEST_FREQUENCIES_2 = {2500, 5124};
- private static final int TEST_INTERVAL_MS = 30000;
- private static final int TEST_MIN_2G_RSSI = -60;
- private static final int TEST_MIN_5G_RSSI = -65;
- private static final int TEST_VALUE = 42;
-
- private PnoNetwork mPnoNetwork1;
- private PnoNetwork mPnoNetwork2;
-
- @Before
- public void setUp() {
- mPnoNetwork1 = new PnoNetwork();
- mPnoNetwork1.ssid = TEST_SSID_1;
- mPnoNetwork1.isHidden = true;
- mPnoNetwork1.frequencies = TEST_FREQUENCIES_1;
-
- mPnoNetwork2 = new PnoNetwork();
- mPnoNetwork2.ssid = TEST_SSID_2;
- mPnoNetwork2.isHidden = false;
- mPnoNetwork2.frequencies = TEST_FREQUENCIES_2;
- }
-
- /**
- * PnoSettings object can be serialized and deserialized, while keeping the
- * values unchanged.
- */
- @Test
- public void canSerializeAndDeserialize() {
- PnoSettings pnoSettings = new PnoSettings();
- pnoSettings.intervalMs = TEST_INTERVAL_MS;
- pnoSettings.min2gRssi = TEST_MIN_2G_RSSI;
- pnoSettings.min5gRssi = TEST_MIN_5G_RSSI;
- pnoSettings.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2));
-
- Parcel parcel = Parcel.obtain();
- pnoSettings.writeToParcel(parcel, 0);
- // Rewind the pointer to the head of the parcel.
- parcel.setDataPosition(0);
- PnoSettings pnoSettingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel);
-
- assertEquals(pnoSettings, pnoSettingsDeserialized);
- assertEquals(pnoSettings.hashCode(), pnoSettingsDeserialized.hashCode());
- }
-
- /**
- * Tests usage of {@link PnoSettings} as a HashMap key type.
- */
- @Test
- public void testAsHashMapKey() {
- PnoSettings pnoSettings1 = new PnoSettings();
- pnoSettings1.intervalMs = TEST_INTERVAL_MS;
- pnoSettings1.min2gRssi = TEST_MIN_2G_RSSI;
- pnoSettings1.min5gRssi = TEST_MIN_5G_RSSI;
- pnoSettings1.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2));
-
- PnoSettings pnoSettings2 = new PnoSettings();
- pnoSettings2.intervalMs = TEST_INTERVAL_MS;
- pnoSettings2.min2gRssi = TEST_MIN_2G_RSSI;
- pnoSettings2.min5gRssi = TEST_MIN_5G_RSSI;
- pnoSettings2.pnoNetworks = new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2));
-
- assertEquals(pnoSettings1, pnoSettings2);
- assertEquals(pnoSettings1.hashCode(), pnoSettings2.hashCode());
-
- HashMap<PnoSettings, Integer> map = new HashMap<>();
- map.put(pnoSettings1, TEST_VALUE);
-
- assertEquals(TEST_VALUE, map.get(pnoSettings2).intValue());
- }
-}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/wificond/SingleScanSettingsTest.java b/service/tests/wifitests/src/com/android/server/wifi/wificond/SingleScanSettingsTest.java
deleted file mode 100644
index 5b424b7682..0000000000
--- a/service/tests/wifitests/src/com/android/server/wifi/wificond/SingleScanSettingsTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017 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.wificond;
-
-import static org.junit.Assert.assertEquals;
-
-import android.net.wifi.IWifiScannerImpl;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-
-/**
- * Unit tests for {@link com.android.server.wifi.wificond.SingleScanSettingsResult}.
- */
-@SmallTest
-public class SingleScanSettingsTest {
-
- private static final byte[] TEST_SSID_1 =
- new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
- private static final byte[] TEST_SSID_2 =
- new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'};
- private static final int TEST_FREQUENCY_1 = 2456;
- private static final int TEST_FREQUENCY_2 = 5215;
- private static final int TEST_VALUE = 42;
-
- private ChannelSettings mChannelSettings1;
- private ChannelSettings mChannelSettings2;
- private HiddenNetwork mHiddenNetwork1;
- private HiddenNetwork mHiddenNetwork2;
-
- @Before
- public void setUp() {
- mChannelSettings1 = new ChannelSettings();
- mChannelSettings1.frequency = TEST_FREQUENCY_1;
- mChannelSettings2 = new ChannelSettings();
- mChannelSettings2.frequency = TEST_FREQUENCY_2;
-
- mHiddenNetwork1 = new HiddenNetwork();
- mHiddenNetwork1.ssid = TEST_SSID_1;
- mHiddenNetwork2 = new HiddenNetwork();
- mHiddenNetwork2.ssid = TEST_SSID_2;
- }
-
- /**
- * SingleScanSettings object can be serialized and deserialized, while keeping the
- * values unchanged.
- */
- @Test
- public void canSerializeAndDeserialize() {
- SingleScanSettings scanSettings = new SingleScanSettings();
- scanSettings.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY;
-
- scanSettings.channelSettings =
- new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2));
- scanSettings.hiddenNetworks =
- new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2));
-
- Parcel parcel = Parcel.obtain();
- scanSettings.writeToParcel(parcel, 0);
- // Rewind the pointer to the head of the parcel.
- parcel.setDataPosition(0);
- SingleScanSettings scanSettingsDeserialized =
- SingleScanSettings.CREATOR.createFromParcel(parcel);
-
- assertEquals(scanSettings, scanSettingsDeserialized);
- assertEquals(scanSettings.hashCode(), scanSettingsDeserialized.hashCode());
- }
-
- /**
- * Tests usage of {@link SingleScanSettings} as a HashMap key type.
- */
- @Test
- public void testAsHashMapKey() {
- SingleScanSettings scanSettings1 = new SingleScanSettings();
- scanSettings1.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY;
- scanSettings1.channelSettings =
- new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2));
- scanSettings1.hiddenNetworks =
- new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2));
-
- SingleScanSettings scanSettings2 = new SingleScanSettings();
- scanSettings2.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY;
- scanSettings2.channelSettings =
- new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2));
- scanSettings2.hiddenNetworks =
- new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2));
-
- assertEquals(scanSettings1, scanSettings2);
- assertEquals(scanSettings1.hashCode(), scanSettings2.hashCode());
-
- HashMap<SingleScanSettings, Integer> map = new HashMap<>();
- map.put(scanSettings1, TEST_VALUE);
-
- assertEquals(TEST_VALUE, map.get(scanSettings2).intValue());
- }
-}
diff --git a/service/wifi.rc b/service/wifi.rc
new file mode 100644
index 0000000000..9a04252dc5
--- /dev/null
+++ b/service/wifi.rc
@@ -0,0 +1,84 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# These are needed for migration of data from "system" user to "network_stack" user
+# since wifi is no longer running in "system_server".
+on post-fs-data
+ chown network_stack network_stack /data/misc/wifi
+ chown network_stack network_stack /data/misc/wifi/WifiConfigStore.xml
+ chown network_stack network_stack /data/misc/wifi/softap.conf
+
+on property:sys.user.0.ce_available=true
+ mkdir /data/misc_ce/0/wifi 0770 network_stack network_stack
+ # For devices upgrading, we need to change permission.
+ chown network_stack network_stack /data/misc_ce/0/wifi
+ chown network_stack network_stack /data/misc_ce/0/wifi/WifiConfigStore.xml
+ chown network_stack network_stack /data/misc_ce/0/wifi/WifiConfigStoreNetworkSuggestions.xml
+
+ # Load the new sepolicy file context labels (these files were relabeled in R).
+ restorecon /data/misc_ce/0/wifi
+ restorecon /data/misc_ce/0/wifi/WifiConfigStore.xml
+ restorecon /data/misc_ce/0/wifi/WifiConfigStoreNetworkSuggestions.xml
+
+# Below are for kernel tracing related stuff.
+on fs
+ setprop sys.wifitracing.started 0
+
+on property:sys.boot_completed=1 && property:sys.wifitracing.started=0
+ # Create trace buffer, and set basic configuration.
+ mkdir /sys/kernel/debug/tracing/instances/wifi 711
+ restorecon_recursive /sys/kernel/debug/tracing/instances/wifi
+ write /sys/kernel/debug/tracing/instances/wifi/tracing_on 0
+ write /sys/kernel/debug/tracing/instances/wifi/buffer_size_kb 1
+ write /sys/kernel/debug/tracing/instances/wifi/trace_options disable_on_free
+
+ # Enable cfg80211 events for connection and key management events.
+ # - Events are not actually logged until WifiService writes "1" to
+ # /sys/kernel/debug/tracing/instances/wifi/tracing_on.
+ # - WifiService is responsible for turning tracing off and on.
+ write /sys/kernel/debug/tracing/instances/wifi/events/cfg80211/cfg80211_gtk_rekey_notify/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/cfg80211/rdev_add_key/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/cfg80211/rdev_assoc/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/cfg80211/rdev_auth/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/cfg80211/rdev_connect/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/cfg80211/rdev_set_default_key/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/cfg80211/rdev_set_default_mgmt_key/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/cfg80211/rdev_set_rekey_data/enable 1
+
+ # Enable datapath events for Wifi.
+ # - Events are not actually logged until WifiService writes "1" to
+ # /sys/kernel/debug/tracing/instances/wifi/tracing_on.
+ # - WifiService will ensure that tracing is turned back off,
+ # when a connection attempt ends (whether in success or failure)
+ write /sys/kernel/debug/tracing/instances/wifi/events/net/filter name==${wifi.interface:-wlan0}
+ write /sys/kernel/debug/tracing/instances/wifi/events/net/net_dev_queue/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/net/net_dev_xmit/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/net/netif_rx/enable 1
+ write /sys/kernel/debug/tracing/instances/wifi/events/net/netif_receive_skb/enable 1
+
+ # Set DAC to allow network_stack to enable/disable, and read wifi trace
+ # events.
+ chown network_stack network_stack /sys/kernel/debug/tracing/instances/wifi/tracing_on
+ chown network_stack network_stack /sys/kernel/debug/tracing/instances/wifi/free_buffer
+ chown network_stack network_stack /sys/kernel/debug/tracing/instances/wifi/trace
+ chmod 200 /sys/kernel/debug/tracing/instances/wifi/tracing_on
+ chmod 400 /sys/kernel/debug/tracing/instances/wifi/free_buffer
+ chmod 600 /sys/kernel/debug/tracing/instances/wifi/trace
+ setprop sys.wifitracing.started 1
+
+on property:sys.boot_completed=1 && property:wifi.interface=* && property:sys.wifitracing.started=1
+ # Override default value.
+ write /sys/kernel/debug/tracing/instances/wifi/events/net/filter name==${wifi.interface}
diff --git a/service/wifi-events.rc b/service/wifi_inprocess.rc
index f332226658..286d18063d 100644
--- a/service/wifi-events.rc
+++ b/service/wifi_inprocess.rc
@@ -14,6 +14,26 @@
# limitations under the License.
#
+# These are needed for migration of data from "network_stack" user to "system" user
+# if wifi is no longer running in "system_server".
+on post-fs-data
+ chown system system /data/misc/wifi
+ chown system system /data/misc/wifi/WifiConfigStore.xml
+ chown system system /data/misc/wifi/softap.conf
+
+on property:sys.user.0.ce_available=true
+ mkdir /data/misc_ce/0/wifi 0770 system system
+ # For devices upgrading, we need to change permission.
+ chown system system /data/misc_ce/0/wifi
+ chown system system /data/misc_ce/0/wifi/WifiConfigStore.xml
+ chown system system /data/misc_ce/0/wifi/WifiConfigStoreNetworkSuggestions.xml
+
+ # Load the new sepolicy file context labels (these files were relabeled in R).
+ restorecon /data/misc_ce/0/wifi
+ restorecon /data/misc_ce/0/wifi/WifiConfigStore.xml
+ restorecon /data/misc_ce/0/wifi/WifiConfigStoreNetworkSuggestions.xml
+
+# Below are for kernel tracing related stuff.
on fs
setprop sys.wifitracing.started 0
@@ -49,7 +69,7 @@ on property:sys.boot_completed=1 && property:sys.wifitracing.started=0
write /sys/kernel/debug/tracing/instances/wifi/events/net/netif_rx/enable 1
write /sys/kernel/debug/tracing/instances/wifi/events/net/netif_receive_skb/enable 1
- # Set DAC to allow system_server to enable/disable, and read wifi trace
+ # Set DAC to allow system to enable/disable, and read wifi trace
# events.
chown system /sys/kernel/debug/tracing/instances/wifi/tracing_on
chown system /sys/kernel/debug/tracing/instances/wifi/free_buffer