fix: 首次提交

This commit is contained in:
2024-12-09 11:25:23 +08:00
parent d0c01071e9
commit 2c2109a5f3
4741 changed files with 290641 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
// 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 {
default_team: "trendy_team_fwk_wifi_hal",
default_applicable_licenses: ["Android-Apache-2.0"],
}
java_defaults {
name: "WifiTrackerLibTestDefaults",
srcs: ["src/**/*.java"],
static_libs: [
"androidx.test.rules",
"frameworks-base-testutils",
"flag-junit",
"mockito-target-extended-minus-junit4",
"truth",
"Robolectric_all-target_upstream",
],
libs: [
"android.test.mock",
],
jni_libs: [
"libdexmakerjvmtiagent",
"libstaticjvmtiagent",
],
platform_apis: true,
test_suites: ["general-tests"],
}
android_test {
name: "WifiTrackerLibTests",
defaults: ["WifiTrackerLibTestDefaults"],
static_libs: [
"WifiTrackerLib",
],
}
android_test {
name: "SdkWifiTrackerLibTests",
defaults: ["WifiTrackerLibTestDefaults"],
exclude_srcs: ["src/**/NonSdkApiWrapperTest.java"],
static_libs: [
"SdkWifiTrackerLib",
],
}

View File

@@ -0,0 +1,37 @@
<?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.wifitrackerlib.test" >
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<activity android:label="WifiTrackerTestsDummyLabel"
android:name="WifiTrackerTestsDummyName"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.wifitrackerlib.test"
android:label="WifiTrackerLib Tests">
</instrumentation>
</manifest>

View File

@@ -0,0 +1,890 @@
#!/usr/bin/python3
#
# Copyright 2021, 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.
#
# This script simulates different combinations of scans and config to allow a tester to manually
# verify behavior in the Wi-Fi picker without setting up an actual test environment with real APs.
# This is especially useful for verifying interactions between scans and configs of multiple
# security types from the same security family, along with suggestions for the same networks.
#
# INSTRUCTIONS:
# 1) Connect an adb debuggable test device.
# 2) Open the test device and navigate to the Wi-Fi picker.
# 3) In main(), uncomment any test cases that you want to test.
# 4) If testing suggestions INSTEAD of configs, only set ADD_SUGGESTION_INSTEAD_OF_CONFIG to True.
# 5) If testing suggestions AND configs, only set ADD_IDENTICAL_SUGGESTION to True.
# 6) Run this script 'py simulate_wifi.py'
# 7) Follow the prompts from the script. The prompts will ask you to verify the behavior of the
# Wi-Fi picker through user interaction and visual confirmation.
#
# NOTE: Suggestions may take several seconds to appear. This is expected since it may be some scans
# cycles until WifiManager#getWifiConfigForMatchedNetworkSuggestionsSharedWithUser() returns
# the matching suggestion.
import subprocess
import sys
import time
OPEN_SSID = "fakeOpen"
OWE_SSID = "fakeOwe"
OPEN_OWE_SSID = "fakeOpenOwe"
WPA2_SSID = "fakeWpa2"
WPA3_SSID = "fakeWpa3"
WPA2_WPA3_SSID = "fakeWpa2Wpa3"
# only one of these should be True (possibly none for just adding base configuration)
ADD_SUGGESTION_INSTEAD_OF_CONFIG = False
ADD_IDENTICAL_SUGGESTION = False
def main() -> None:
root()
time.sleep(5)
# Single Open scan
# testOpenScanNoConfigs()
# testOpenScanOpenConfig()
# testOpenScanOweConfig()
# testOpenScanOpenOweConfig()
# Single OWE scan
# testOweScanNoConfigs()
# testOweScanOpenConfig()
# testOweScanOweConfig()
# testOweScanOpenOweConfig()
# Single Open/OWE scan
# testOpenOweScanNoConfigs()
# testOpenOweScanOpenConfig()
# testOpenOweScanOweConfig()
# testOpenOweScanOpenOweConfig()
# Open scan and OWE scan
# testOpenScanOweScanNoConfigs()
# testOpenScanOweScanOpenConfig()
# testOpenScanOweScanOweConfig()
# testOpenScanOweScanOpenOweConfig()
# Open scan and Open/OWE scan
# testOpenScanOpenOweScanNoConfigs()
# testOpenScanOpenOweScanOpenConfig()
# testOpenScanOpenOweScanOweConfig()
# testOpenScanOpenOweScanOpenOweConfig()
# Open/OWE scan and OWE scan
# testOpenOweScanOweScanNoConfigs()
# testOpenOweScanOweScanOpenConfig()
# testOpenOweScanOweScanOweConfig()
# testOpenOweScanOweScanOpenOweConfig()
# Open, Open/OWE, and OWE scans
# testOpenScanOpenOweScanOweScanNoConfigs()
# testOpenScanOpenOweScanOweScanOpenConfig()
# testOpenScanOpenOweScanOweScanOweConfig()
# testOpenScanOpenOweScanOweScanOpenOweConfig()
# Single WPA2 scan
# testWpa2ScanNoConfigs()
# testWpa2ScanWpa2Config()
# testWpa2ScanWpa3Config()
# testWpa2ScanWpa2Wpa3Config()
# Single WPA3 scan
# testWpa3ScanNoConfigs()
# testWpa3ScanWpa2Config()
# testWpa3ScanWpa3Config()
# testWpa3ScanWpa2Wpa3Config()
# Single WP2/WPA3 scan
# testWpa2Wpa3ScanNoConfigs()
# testWpa2Wpa3ScanWpa2Config()
# testWpa2Wpa3ScanWpa3Config()
# testWpa2Wpa3ScanWpa2Wpa3Config()
# WPA2 scan and WPA3 scan
# testWpa2ScanWpa3ScanNoConfigs()
# testWpa2ScanWpa3ScanWpa2Config()
# testWpa2ScanWpa3ScanWpa3Config()
# testWpa2ScanWpa3ScanWpa2Wpa3Config()
# WPA2 scan and WPA2/WPA3 scan
# testWpa2ScanWpa2Wpa3ScanNoConfigs()
# testWpa2ScanWpa2Wpa3ScanWpa2Config()
# testWpa2ScanWpa2Wpa3ScanWpa3Config()
# testWpa2ScanWpa2Wpa3ScanWpa2Wpa3Config()
# WPA2/WPA3 scan and WPA3 scan
# testWpa2Wpa3ScanWpa3ScanNoConfigs()
# testWpa2Wpa3ScanWpa3ScanWpa2Config()
# testWpa2Wpa3ScanWpa3ScanWpa3Config()
# testWpa2Wpa3ScanWpa3ScanWpa2Wpa3Config()
# WPA2, WPA2/WPA3, and WPA3 scans
# testWpa2ScanWpa2Wpa3ScanWpa3ScanNoConfigs()
# testWpa2ScanWpa2Wpa3ScanWpa3ScanWpa2Config()
# testWpa2ScanWpa2Wpa3ScanWpa3ScanWpa3Config()
# testWpa2ScanWpa2Wpa3ScanWpa3ScanWpa2Wpa3Config()
return 0
def testTemplate(method_name, fake_scans, fake_configs, pre_instructions, post_instructions) -> None:
print("")
print("")
print("****** Test: " + method_name)
print("** Resetting all scans/configs")
settings_reset()
print("** Starting to fake scans")
fake_scans()
startFakingScans()
startScan()
time.sleep(5)
print("** Fake scan results:")
for scan in getScanResults():
print(scan.decode())
print("** Inserting fake configurations (and optionally suggestions)")
fake_configs()
print("** Pre action saved networks:")
for config in getSavedConfigs():
print(config.decode())
if ADD_IDENTICAL_SUGGESTION or ADD_SUGGESTION_INSTEAD_OF_CONFIG:
print("** Pre action suggestions:")
for sugg in getSuggestions():
print(sugg.decode())
print("---> " + pre_instructions)
input("** Then press Enter to continue ...")
print("** Post action saved networks:")
for config in getSavedConfigs():
print(config.decode())
print("---> " + post_instructions)
input("** Press Enter to continue ...")
#
# Single WPA2 scan: different WPA2/WPA3 configurations
#
def testWpa2ScanNoConfigs() -> None:
testTemplate(
testWpa2ScanNoConfigs.__name__,
lambda : addFakeWpa2Scan(WPA2_SSID, "80:01:02:03:04:05"),
lambda : print("no configs added"),
"Open picker: select " + WPA2_SSID,
"Should ask for passphrase, then be WPA2 (+ WPA3^ if device supports auto-upgrade)"
)
def testWpa2ScanWpa2Config() -> None:
testTemplate(
testWpa2ScanWpa2Config.__name__,
lambda : addFakeWpa2Scan(WPA2_SSID, "80:01:02:03:04:05"),
lambda : addWpa2Config(WPA2_SSID),
"Open picker: select " + WPA2_SSID,
"Should not ask for passphrase, then be WPA2 only if device does not support auto-upgrade (otherwise + WPA3^)"
)
def testWpa2ScanWpa3Config() -> None:
testTemplate(
testWpa2ScanWpa3Config.__name__,
lambda : addFakeWpa2Scan(WPA2_SSID, "80:01:02:03:04:05"),
lambda : addWpa3Config(WPA2_SSID),
"Open picker: select " + WPA2_SSID,
"Should ask for passphrase, then be WPA2+WPA3"
)
def testWpa2ScanWpa2Wpa3Config() -> None:
testTemplate(
testWpa2ScanWpa2Wpa3Config.__name__,
lambda : addFakeWpa2Scan(WPA2_SSID, "80:01:02:03:04:05"),
lambda : (addWpa2Config(WPA2_SSID),
addWpa3Config(WPA2_SSID)),
"Open picker: select " + WPA2_SSID,
"Should not ask for passphrase, then be WPA2+WPA3"
)
#
# Single WPA3 scan: different WPA2/WPA3 configurations
#
def testWpa3ScanNoConfigs() -> None:
testTemplate(
testWpa3ScanNoConfigs.__name__,
lambda : addFakeWpa3Scan(WPA3_SSID, "80:01:02:03:04:05"),
lambda : print("no configs added"),
"Open picker: select " + WPA3_SSID,
"Should ask for passphrase, then be WPA3"
)
def testWpa3ScanWpa2Config() -> None:
testTemplate(
testWpa3ScanWpa2Config.__name__,
lambda : addFakeWpa3Scan(WPA3_SSID, "80:01:02:03:04:05"),
lambda : addWpa2Config(WPA3_SSID),
"Open picker: select " + WPA3_SSID,
"If no auto-upgrade: Should ask for passphrase, then be WPA2 + WPA3, otherwise should not ask for passphrase and be WPA2+WPA3^"
)
def testWpa3ScanWpa3Config() -> None:
testTemplate(
testWpa3ScanWpa3Config.__name__,
lambda : addFakeWpa3Scan(WPA3_SSID, "80:01:02:03:04:05"),
lambda : addWpa3Config(WPA3_SSID),
"Open picker: select " + WPA3_SSID,
"Should not ask for passphrase, then be WPA3"
)
def testWpa3ScanWpa2Wpa3Config() -> None:
testTemplate(
testWpa3ScanWpa2Wpa3Config.__name__,
lambda : addFakeWpa3Scan(WPA3_SSID, "80:01:02:03:04:05"),
lambda : (addWpa2Config(WPA3_SSID),
addWpa3Config(WPA3_SSID)),
"Open picker: select " + WPA3_SSID,
"Should not ask for passphrase, then be WPA2+WPA3"
)
#
# Single WPA2/WPA3 scan: different WPA2/WPA3 configurations
#
def testWpa2Wpa3ScanNoConfigs() -> None:
testTemplate(
testWpa2Wpa3ScanNoConfigs.__name__,
lambda : addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
lambda : print("no configs added"),
"Open picker: select " + WPA2_WPA3_SSID,
"Should ask for passphrase, then be WPA2 if no auto-upgrade, WPA2+WPA3^ if auto-upgrade"
)
def testWpa2Wpa3ScanWpa2Config() -> None:
testTemplate(
testWpa2Wpa3ScanWpa2Config.__name__,
lambda : addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
lambda : addWpa2Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2 if no auto-upgrade (otherwise WPA2+WPA3^)"
)
def testWpa2Wpa3ScanWpa3Config() -> None:
testTemplate(
testWpa2Wpa3ScanWpa3Config.__name__,
lambda : addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
lambda : addWpa3Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA3"
)
def testWpa2Wpa3ScanWpa2Wpa3Config() -> None:
testTemplate(
testWpa2Wpa3ScanWpa2Wpa3Config.__name__,
lambda : addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
lambda : (addWpa2Config(WPA2_WPA3_SSID),
addWpa3Config(WPA2_WPA3_SSID)),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2+WPA3"
)
#
# Single WPA2 scan and single WPA3 scan: different WPA2/WPA3 configurations
#
def testWpa2ScanWpa3ScanNoConfigs() -> None:
testTemplate(
testWpa2ScanWpa3ScanNoConfigs.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa3Scan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : print("no configs added"),
"Open picker: select " + WPA2_WPA3_SSID,
"Should ask for passphrase, then be WPA2 if no auto-upgrade, WPA2+WPA3^ if auto-upgrade"
)
def testWpa2ScanWpa3ScanWpa2Config() -> None:
testTemplate(
testWpa2ScanWpa3ScanWpa2Config.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa3Scan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : addWpa2Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2 if no auto-upgrade (otherwise WPA2+WPA3^)"
)
def testWpa2ScanWpa3ScanWpa3Config() -> None:
testTemplate(
testWpa2ScanWpa3ScanWpa3Config.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa3Scan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : addWpa3Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA3"
)
def testWpa2ScanWpa3ScanWpa2Wpa3Config() -> None:
testTemplate(
testWpa2ScanWpa3ScanWpa2Wpa3Config.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa3Scan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : (addWpa2Config(WPA2_WPA3_SSID),
addWpa3Config(WPA2_WPA3_SSID)),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2+WPA3"
)
#
# Single WPA2 scan and single WPA2+WPA3 transition scan: different WPA2/WPA3 configurations
#
def testWpa2ScanWpa2Wpa3ScanNoConfigs() -> None:
testTemplate(
testWpa2ScanWpa2Wpa3ScanNoConfigs.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : print("no configs added"),
"Open picker: select " + WPA2_WPA3_SSID,
"Should ask for passphrase, then be WPA2 if no auto-upgrade, WPA2+WPA3^ if auto-upgrade"
)
def testWpa2ScanWpa2Wpa3ScanWpa2Config() -> None:
testTemplate(
testWpa2ScanWpa2Wpa3ScanWpa2Config.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : addWpa2Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2 if no auto-upgrade (otherwise WPA2+WPA3^)"
)
def testWpa2ScanWpa2Wpa3ScanWpa3Config() -> None:
testTemplate(
testWpa2ScanWpa2Wpa3ScanWpa3Config.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : addWpa3Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA3"
)
def testWpa2ScanWpa2Wpa3ScanWpa2Wpa3Config() -> None:
testTemplate(
testWpa2ScanWpa2Wpa3ScanWpa2Wpa3Config.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : (addWpa2Config(WPA2_WPA3_SSID),
addWpa3Config(WPA2_WPA3_SSID)),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2+WPA3"
)
#
# Single WPA2+WPA3 transition scan and single WPA3 scan: different WPA2/WPA3 configurations
#
def testWpa2Wpa3ScanWpa3ScanNoConfigs() -> None:
testTemplate(
testWpa2Wpa3ScanWpa3ScanNoConfigs.__name__,
lambda : (addFakeWpa3Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : print("no configs added"),
"Open picker: select " + WPA2_WPA3_SSID,
"Should ask for passphrase, then be WPA2 if no auto-upgrade, WPA2+WPA3^ if auto-upgrade"
)
def testWpa2Wpa3ScanWpa3ScanWpa2Config() -> None:
testTemplate(
testWpa2Wpa3ScanWpa3ScanWpa2Config.__name__,
lambda : (addFakeWpa3Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : addWpa2Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2 if no auto-upgrade (otherwise WPA2+WPA3^)"
)
def testWpa2Wpa3ScanWpa3ScanWpa3Config() -> None:
testTemplate(
testWpa2Wpa3ScanWpa3ScanWpa3Config.__name__,
lambda : (addFakeWpa3Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : addWpa3Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA3"
)
def testWpa2Wpa3ScanWpa3ScanWpa2Wpa3Config() -> None:
testTemplate(
testWpa2Wpa3ScanWpa3ScanWpa2Wpa3Config.__name__,
lambda : (addFakeWpa3Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:02:02:03:04:06")),
lambda : (addWpa2Config(WPA2_WPA3_SSID),
addWpa3Config(WPA2_WPA3_SSID)),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2+WPA3"
)
#
# Single WPA2 scan, single WPA2+WPA3 transition scan, and single WPA3 scan: different WPA2/WPA3 configurations
#
def testWpa2ScanWpa2Wpa3ScanWpa3ScanNoConfigs() -> None:
testTemplate(
testWpa2ScanWpa2Wpa3ScanWpa3ScanNoConfigs.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa3Scan(WPA2_WPA3_SSID, "80:02:02:03:04:06"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:03:02:03:04:07")),
lambda : print("no configs added"),
"Open picker: select " + WPA2_WPA3_SSID,
"Should ask for passphrase, then be WPA2 if no auto-upgrade, WPA2+WPA3^ if auto-upgrade"
)
def testWpa2ScanWpa2Wpa3ScanWpa3ScanWpa2Config() -> None:
testTemplate(
testWpa2ScanWpa2Wpa3ScanWpa3ScanWpa2Config.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa3Scan(WPA2_WPA3_SSID, "80:02:02:03:04:06"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:03:02:03:04:07")),
lambda : addWpa2Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2 if no auto-upgrade (otherwise WPA2+WPA3^)"
)
def testWpa2ScanWpa2Wpa3ScanWpa3ScanWpa3Config() -> None:
testTemplate(
testWpa2ScanWpa2Wpa3ScanWpa3ScanWpa3Config.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa3Scan(WPA2_WPA3_SSID, "80:02:02:03:04:06"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:03:02:03:04:07")),
lambda : addWpa3Config(WPA2_WPA3_SSID),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA3"
)
def testWpa2ScanWpa2Wpa3ScanWpa3ScanWpa2Wpa3Config() -> None:
testTemplate(
testWpa2ScanWpa2Wpa3ScanWpa3ScanWpa2Wpa3Config.__name__,
lambda : (addFakeWpa2Scan(WPA2_WPA3_SSID, "80:01:02:03:04:05"),
addFakeWpa3Scan(WPA2_WPA3_SSID, "80:02:02:03:04:06"),
addFakeWpa2Wpa3TransitionScan(WPA2_WPA3_SSID, "80:03:02:03:04:07")),
lambda : (addWpa2Config(WPA2_WPA3_SSID),
addWpa3Config(WPA2_WPA3_SSID)),
"Open picker: select " + WPA2_WPA3_SSID,
"Should not ask for passphrase, then be WPA2+WPA3"
)
#
# Single open scan: different open/OWE configurations
#
def testOpenScanNoConfigs() -> None:
testTemplate(
testOpenScanNoConfigs.__name__,
lambda : addFakeOpenScan(OPEN_SSID, "80:01:02:03:04:05"),
lambda : print("no configs added"),
"Open picker: select " + OPEN_SSID,
"Should be Open + OWE^ if device supports auto-upgrade"
)
def testOpenScanOpenConfig() -> None:
testTemplate(
testOpenScanOpenConfig.__name__,
lambda : addFakeOpenScan(OPEN_SSID, "80:01:02:03:04:05"),
lambda : addOpenConfig(OPEN_SSID),
"Open picker: select " + OPEN_SSID,
"Should be Open only if device does not support auto-upgrade (otherwise + OWE^)"
)
def testOpenScanOweConfig() -> None:
testTemplate(
testOpenScanOweConfig.__name__,
lambda : addFakeOpenScan(OPEN_SSID, "80:01:02:03:04:05"),
lambda : addOweConfig(OPEN_SSID),
"Open picker: select " + OPEN_SSID,
"Should be Open + OWE"
)
def testOpenScanOpenOweConfig() -> None:
testTemplate(
testOpenScanOpenOweConfig.__name__,
lambda : addFakeOpenScan(OPEN_SSID, "80:01:02:03:04:05"),
lambda : (addOpenConfig(OPEN_SSID),
addOweConfig(OPEN_SSID)),
"Open picker: select " + OPEN_SSID,
"Should be Open + OWE"
)
#
# Single OWE scan: different open/OWE configurations
#
def testOweScanNoConfigs() -> None:
testTemplate(
testOweScanNoConfigs.__name__,
lambda : addFakeOweScan(OWE_SSID, "80:01:02:03:04:05"),
lambda : print("no configs added"),
"Open picker: select " + OWE_SSID,
"Should be OWE"
)
def testOweScanOpenConfig() -> None:
testTemplate(
testOweScanOpenConfig.__name__,
lambda : addFakeOweScan(OWE_SSID, "80:01:02:03:04:05"),
lambda : addOpenConfig(OWE_SSID),
"Open picker: select " + OWE_SSID,
"Should be Open+OWE^"
)
def testOweScanOweConfig() -> None:
testTemplate(
testOweScanOweConfig.__name__,
lambda : addFakeOweScan(OWE_SSID, "80:01:02:03:04:05"),
lambda : addOweConfig(OWE_SSID),
"Open picker: select " + OWE_SSID,
"Should be OWE"
)
def testOweScanOpenOweConfig() -> None:
testTemplate(
testOweScanOpenOweConfig.__name__,
lambda : addFakeOweScan(OWE_SSID, "80:01:02:03:04:05"),
lambda : (addOpenConfig(OWE_SSID),
addOweConfig(OWE_SSID)),
"Open picker: select " + OWE_SSID,
"Should be Open + OWE"
)
#
# Single Open/OWE transition mode scan: different open/OWE configurations
#
def testOpenOweScanNoConfigs() -> None:
testTemplate(
testOpenOweScanNoConfigs.__name__,
lambda : addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
lambda : print("no configs added"),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE"
)
def testOpenOweScanOpenConfig() -> None:
testTemplate(
testOpenOweScanOpenConfig.__name__,
lambda : addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
lambda : addOpenConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE^"
)
def testOpenOweScanOweConfig() -> None:
testTemplate(
testOpenOweScanOweConfig.__name__,
lambda : addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
lambda : addOweConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be OWE"
)
def testOpenOweScanOpenOweConfig() -> None:
testTemplate(
testOpenOweScanOpenOweConfig.__name__,
lambda : addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
lambda : (addOpenConfig(OPEN_OWE_SSID),
addOweConfig(OPEN_OWE_SSID)),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open + OWE"
)
#
# Single Open scan and single OWE scan: different Open/OWE configurations
#
def testOpenScanOweScanNoConfigs() -> None:
testTemplate(
testOpenScanOweScanNoConfigs.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOweScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : print("no configs added"),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE"
)
def testOpenScanOweScanOpenConfig() -> None:
testTemplate(
testOpenScanOweScanOpenConfig.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOweScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : addOpenConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open if no auto-upgrade (otherwise Open+OWE^)"
)
def testOpenScanOweScanOweConfig() -> None:
testTemplate(
testOpenScanOweScanOweConfig.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOweScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : addOweConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be OWE"
)
def testOpenScanOweScanOpenOweConfig() -> None:
testTemplate(
testOpenScanOweScanOpenOweConfig.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOweScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : (addOpenConfig(OPEN_OWE_SSID),
addOweConfig(OPEN_OWE_SSID)),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE"
)
#
# Single Open scan and single Open+OWE transition scan: different Open/OWE configurations
#
def testOpenScanOpenOweScanNoConfigs() -> None:
testTemplate(
testOpenScanOpenOweScanNoConfigs.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : print("no configs added"),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE"
)
def testOpenScanOpenOweScanOpenConfig() -> None:
testTemplate(
testOpenScanOpenOweScanOpenConfig.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : addOpenConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open if no auto-upgrade (otherwise Open+OWE^)"
)
def testOpenScanOpenOweScanOweConfig() -> None:
testTemplate(
testOpenScanOpenOweScanOweConfig.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : addOweConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be OWE"
)
def testOpenScanOpenOweScanOpenOweConfig() -> None:
testTemplate(
testOpenScanOpenOweScanOpenOweConfig.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : (addOpenConfig(OPEN_OWE_SSID),
addOweConfig(OPEN_OWE_SSID)),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE"
)
#
# Single Open+OWE transition scan and single OWE scan: different Open/OWE configurations
#
def testOpenOweScanOweScanNoConfigs() -> None:
testTemplate(
testOpenOweScanOweScanNoConfigs.__name__,
lambda : (addFakeOweScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : print("no configs added"),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE"
)
def testOpenOweScanOweScanOpenConfig() -> None:
testTemplate(
testOpenOweScanOweScanOpenConfig.__name__,
lambda : (addFakeOweScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : addOpenConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open if no auto-upgrade (otherwise Open+OWE^)"
)
def testOpenOweScanOweScanOweConfig() -> None:
testTemplate(
testOpenOweScanOweScanOweConfig.__name__,
lambda : (addFakeOweScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : addOweConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be OWE"
)
def testOpenOweScanOweScanOpenOweConfig() -> None:
testTemplate(
testOpenOweScanOweScanOpenOweConfig.__name__,
lambda : (addFakeOweScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:02:02:03:04:06")),
lambda : (addOpenConfig(OPEN_OWE_SSID),
addOweConfig(OPEN_OWE_SSID)),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE"
)
#
# Single Open scan, single Open+OWE transition scan, and single OWE scan: different Open/OWE configurations
#
def testOpenScanOpenOweScanOweScanNoConfigs() -> None:
testTemplate(
testOpenScanOpenOweScanOweScanNoConfigs.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOweScan(OPEN_OWE_SSID, "80:02:02:03:04:06"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:03:02:03:04:07")),
lambda : print("no configs added"),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE"
)
def testOpenScanOpenOweScanOweScanOpenConfig() -> None:
testTemplate(
testOpenScanOpenOweScanOweScanOpenConfig.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOweScan(OPEN_OWE_SSID, "80:02:02:03:04:06"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:03:02:03:04:07")),
lambda : addOpenConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open if no auto-upgrade (otherwise Open+OWE^)"
)
def testOpenScanOpenOweScanOweScanOweConfig() -> None:
testTemplate(
testOpenScanOpenOweScanOweScanOweConfig.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOweScan(OPEN_OWE_SSID, "80:02:02:03:04:06"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:03:02:03:04:07")),
lambda : addOweConfig(OPEN_OWE_SSID),
"Open picker: select " + OPEN_OWE_SSID,
"Should be OWE"
)
def testOpenScanOpenOweScanOweScanOpenOweConfig() -> None:
testTemplate(
testOpenScanOpenOweScanOweScanOpenOweConfig.__name__,
lambda : (addFakeOpenScan(OPEN_OWE_SSID, "80:01:02:03:04:05"),
addFakeOweScan(OPEN_OWE_SSID, "80:02:02:03:04:06"),
addFakeOpenOweTransitionScan(OPEN_OWE_SSID, "80:03:02:03:04:07")),
lambda : (addOpenConfig(OPEN_OWE_SSID),
addOweConfig(OPEN_OWE_SSID)),
"Open picker: select " + OPEN_OWE_SSID,
"Should be Open+OWE"
)
def root() -> None:
subprocess.run(["adb", "root"])
def settings_reset() -> None:
subprocess.run(["adb", "shell", "cmd", "wifi", "settings-reset"])
def getSavedConfigs() -> str:
return subprocess.check_output(["adb", "shell", "cmd", "wifi", "list-networks"]).splitlines()
def getSuggestions() -> str:
return subprocess.check_output(["adb", "shell", "cmd", "wifi", "list-suggestions"]).splitlines()
def getScanResults() -> str:
return subprocess.check_output(["adb", "shell", "cmd", "wifi", "list-scan-results"]).splitlines()
def startScan() -> None:
subprocess.run(["adb", "shell", "cmd", "wifi", "start-scan"])
def startFakingScans() -> None:
subprocess.run(["adb", "shell", "cmd", "wifi", "start-faking-scans"])
def resetFakeScans() -> None:
subprocess.run(["adb", "shell", "cmd", "wifi", "reset-fake-scans"])
#
# Add fake scans
#
def addFakeScan(ssid: str, bssid: str, cap: str, freq: int = 2412, dbm: int = -55) -> None:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-fake-scan", ssid, bssid, cap, str(freq), str(dbm)])
def addFakeOpenScan(ssid: str, bssid: str, freq: int = 2412, dbm: int = -55) -> None:
addFakeScan(ssid, bssid, "[ESS]", freq, dbm)
def addFakeWpa2Scan(ssid: str, bssid: str, freq: int = 2412, dbm: int = -55) -> None:
addFakeScan(ssid, bssid, "[WPA2-PSK-CCMP][RSN-PSK-CCMP][ESS]", freq, dbm)
def addFakeWpa3Scan(ssid: str, bssid: str, freq: int = 2412, dbm: int = -55) -> None:
addFakeScan(ssid, bssid, "[RSN-SAE+FT/SAE-CCMP][ESS]", freq, dbm)
def addFakeOweScan(ssid: str, bssid: str, freq: int = 2412, dbm: int = -55) -> None:
addFakeScan(ssid, bssid, "[RSN-OWE-CCMP]", freq, dbm)
def addFakeWpa2Wpa3TransitionScan(ssid: str, bssid: str, freq: int = 2412, dbm: int = -55) -> None:
addFakeScan(ssid, bssid, "[WPA2-PSK-CCMP][RSN-PSK+SAE-CCMP][ESS][MFPC]", freq, dbm)
def addFakeOpenOweTransitionScan(ssid: str, bssid: str, freq: int = 2412, dbm: int = -55) -> None:
addFakeScan(ssid, bssid, "[RSN-OWE_TRANSITION-CCMP][ESS]", freq, dbm)
def addFakePasspointScan(ssid: str, bssid: str, freq: int = 2412, dbm: int = -55) -> None:
addFakeScan(ssid, bssid, "[WPA2-EAP/SHA1-CCMP][RSN-EAP/SHA1-CCMP][ESS][MFPR][MFPC][PASSPOINT]", freq, dbm)
#
# Add configs
#
def addOpenConfig(ssid: str) -> None:
if not ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-network", ssid, "open"])
if ADD_IDENTICAL_SUGGESTION or ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-suggestion", ssid, "open"])
def addOweConfig(ssid: str) -> None:
if not ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-network", ssid, "owe"])
if ADD_IDENTICAL_SUGGESTION or ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-suggestion", ssid, "owe"])
def addOpenOweConfig(ssid: str) -> None:
if not ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-network", ssid, "open"])
subprocess.run(["adb", "shell", "cmd", "wifi", "add-network", ssid, "owe"])
if ADD_IDENTICAL_SUGGESTION or ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-suggestion", ssid, "open"])
subprocess.run(["adb", "shell", "cmd", "wifi", "add-suggestion", ssid, "owe"])
def addWpa2Config(ssid: str) -> None:
if not ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-network", ssid, "wpa2", "SomePassphrase"])
if ADD_IDENTICAL_SUGGESTION or ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-suggestion", ssid, "wpa2", "SomePassphrase", "-s"])
def addWpa3Config(ssid: str) -> None:
if not ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-network", ssid, "wpa3", "SomePassphrase"])
if ADD_IDENTICAL_SUGGESTION or ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-suggestion", ssid, "wpa3", "SomePassphrase", "-s"])
def addWpa2Wpa3Config(ssid: str) -> None:
if not ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-network", ssid, "wpa2", "SomePassphrase"])
subprocess.run(["adb", "shell", "cmd", "wifi", "add-network", ssid, "wpa3", "SomePassphrase"])
if ADD_IDENTICAL_SUGGESTION or ADD_SUGGESTION_INSTEAD_OF_CONFIG:
subprocess.run(["adb", "shell", "cmd", "wifi", "add-suggestion", ssid, "wpa2", "SomePassphrase", "-s"])
subprocess.run(["adb", "shell", "cmd", "wifi", "add-suggestion", ssid, "wpa3", "SomePassphrase", "-s"])
if __name__ == '__main__':
exit_code = main()
sys.exit(exit_code)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,136 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wifitrackerlib;
import static android.net.wifi.WifiInfo.SECURITY_TYPE_PSK;
import static com.android.wifitrackerlib.StandardWifiEntry.ssidAndSecurityTypeToStandardWifiEntryKey;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.net.wifi.sharedconnectivity.app.KnownNetwork;
import android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus;
import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo;
import android.net.wifi.sharedconnectivity.app.SharedConnectivityManager;
import android.os.Handler;
import android.os.test.TestLooper;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class KnownNetworkEntryTest {
@Mock private WifiEntry.WifiEntryCallback mMockListener;
@Mock private WifiEntry.ConnectCallback mMockConnectCallback;
@Mock private WifiTrackerInjector mMockInjector;
@Mock private Context mMockContext;
@Mock private WifiManager mMockWifiManager;
@Mock private SharedConnectivityManager mMockSharedConnectivityManager;
private TestLooper mTestLooper;
private Handler mTestHandler;
private static final KnownNetwork TEST_KNOWN_NETWORK_DATA = new KnownNetwork.Builder()
.setNetworkSource(KnownNetwork.NETWORK_SOURCE_NEARBY_SELF)
.setSsid("ssid")
.addSecurityType(SECURITY_TYPE_PSK)
.setNetworkProviderInfo(new NetworkProviderInfo
.Builder("My Phone", "Pixel 7")
.setDeviceType(NetworkProviderInfo.DEVICE_TYPE_PHONE)
.setBatteryPercentage(100)
.setConnectionStrength(3)
.build())
.build();
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
mTestHandler = new Handler(mTestLooper.getLooper());
when(mMockInjector.getContext()).thenReturn(mMockContext);
when(mMockContext.getString(eq(R.string.wifitrackerlib_known_network_summary), anyString()))
.thenAnswer(invocation -> {
Object[] args = invocation.getArguments();
return "Available from " + args[1];
});
}
@Test
public void testGetSummary_usesKnownNetworkData() {
final KnownNetworkEntry entry = new KnownNetworkEntry(
mMockInjector, mTestHandler,
ssidAndSecurityTypeToStandardWifiEntryKey("ssid", SECURITY_TYPE_PSK),
mMockWifiManager, mMockSharedConnectivityManager, TEST_KNOWN_NETWORK_DATA);
assertThat(entry.getSummary()).isEqualTo("Available from My Phone");
}
@Test
public void testConnect_serviceCalled() {
final KnownNetworkEntry entry = new KnownNetworkEntry(
mMockInjector, mTestHandler,
ssidAndSecurityTypeToStandardWifiEntryKey("ssid", SECURITY_TYPE_PSK),
mMockWifiManager, mMockSharedConnectivityManager, TEST_KNOWN_NETWORK_DATA);
entry.connect(null);
verify(mMockSharedConnectivityManager).connectKnownNetwork(TEST_KNOWN_NETWORK_DATA);
}
@Test
public void testConnect_nullManager_failureCallback() {
final KnownNetworkEntry entry = new KnownNetworkEntry(
mMockInjector, mTestHandler,
ssidAndSecurityTypeToStandardWifiEntryKey("ssid", SECURITY_TYPE_PSK),
mMockWifiManager, /* sharedConnectivityManager= */ null, TEST_KNOWN_NETWORK_DATA);
entry.setListener(mMockListener);
entry.connect(mMockConnectCallback);
mTestLooper.dispatchAll();
verify(mMockConnectCallback)
.onConnectResult(WifiEntry.ConnectCallback.CONNECT_STATUS_FAILURE_UNKNOWN);
}
@Test
public void testConnect_onConnectionStatusChanged_failureCallback() {
final KnownNetworkEntry entry = new KnownNetworkEntry(
mMockInjector, mTestHandler,
ssidAndSecurityTypeToStandardWifiEntryKey("ssid", SECURITY_TYPE_PSK),
mMockWifiManager, mMockSharedConnectivityManager, TEST_KNOWN_NETWORK_DATA);
entry.setListener(mMockListener);
entry.connect(mMockConnectCallback);
mTestLooper.dispatchAll();
verify(mMockConnectCallback, never()).onConnectResult(anyInt());
entry.onConnectionStatusChanged(KnownNetworkConnectionStatus.CONNECTION_STATUS_SAVE_FAILED);
mTestLooper.dispatchAll();
verify(mMockConnectCallback)
.onConnectResult(WifiEntry.ConnectCallback.CONNECT_STATUS_FAILURE_UNKNOWN);
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright (C) 2020 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.wifitrackerlib;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
import android.os.test.TestLooper;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class MergedCarrierEntryTest {
@Mock private WifiTrackerInjector mMockInjector;
@Mock private WifiEntry.ConnectCallback mMockConnectCallback;
@Mock private WifiManager mMockWifiManager;
@Mock private WifiInfo mMockWifiInfo;
@Mock private Network mMockNetwork;
@Mock private NetworkCapabilities mMockNetworkCapabilities;
@Mock private Context mMockContext;
@Mock private Resources mMockResources;
private TestLooper mTestLooper;
private Handler mTestHandler;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mMockWifiInfo.getNetworkId()).thenReturn(WifiConfiguration.INVALID_NETWORK_ID);
when(mMockWifiInfo.getRssi()).thenReturn(WifiInfo.INVALID_RSSI);
when(mMockWifiInfo.isPrimary()).thenReturn(true);
when(mMockNetworkCapabilities.getTransportInfo()).thenReturn(mMockWifiInfo);
mTestLooper = new TestLooper();
mTestHandler = new Handler(mTestLooper.getLooper());
when(mMockInjector.getContext()).thenReturn(mMockContext);
when(mMockContext.getMainLooper()).thenReturn(Looper.getMainLooper());
when(mMockContext.getResources()).thenReturn(mMockResources);
when(mMockContext.getString(R.string.wifitrackerlib_summary_separator)).thenReturn("/");
when(mMockResources.getText(R.string.wifitrackerlib_wifi_wont_autoconnect_for_now))
.thenReturn("Wi-Fi won't auto-connect for now");
}
@Test
public void testGetConnectedState_wifiInfoMatches_returnsConnected() {
final int subId = 1;
final MergedCarrierEntry entry = new MergedCarrierEntry(mMockInjector, mTestHandler,
mMockWifiManager, false, subId);
when(mMockWifiInfo.isCarrierMerged()).thenReturn(true);
when(mMockWifiInfo.getSubscriptionId()).thenReturn(subId);
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.getConnectedState()).isEqualTo(WifiEntry.CONNECTED_STATE_CONNECTED);
}
@Test
public void testConnect_disablesNonCarrierMergedWifi() {
Looper.prepare();
final int subId = 1;
final MergedCarrierEntry entry = new MergedCarrierEntry(mMockInjector, mTestHandler,
mMockWifiManager, false, subId);
entry.connect(mMockConnectCallback);
mTestLooper.dispatchAll();
verify(mMockConnectCallback)
.onConnectResult(WifiEntry.ConnectCallback.CONNECT_STATUS_SUCCESS);
verify(mMockWifiManager).startRestrictingAutoJoinToSubscriptionId(subId);
}
@Test
public void testDisconnect_enablesNonCarrierMergedWifiAndTriggersScan() {
final int subId = 1;
final MergedCarrierEntry entry = new MergedCarrierEntry(mMockInjector, mTestHandler,
mMockWifiManager, false, subId);
entry.disconnect(null);
mTestLooper.dispatchAll();
verify(mMockWifiManager).stopRestrictingAutoJoinToSubscriptionId();
verify(mMockWifiManager).startScan();
}
@Test
public void testCanConnect_cellIsDefaultRoute_returnsFalse() {
final int subId = 1;
final MergedCarrierEntry entry = new MergedCarrierEntry(mMockInjector, mTestHandler,
mMockWifiManager, false, subId);
entry.updateIsCellDefaultRoute(false);
assertThat(entry.canConnect()).isTrue();
entry.updateIsCellDefaultRoute(true);
assertThat(entry.canConnect()).isFalse();
}
@Test
public void testGetSsid_connected_returnsSanitizedWifiInfoSsid() {
final int subId = 1;
final MergedCarrierEntry entry = new MergedCarrierEntry(mMockInjector, mTestHandler,
mMockWifiManager, false, subId);
when(mMockWifiInfo.isCarrierMerged()).thenReturn(true);
when(mMockWifiInfo.getSubscriptionId()).thenReturn(subId);
final String ssid = "ssid";
when(mMockWifiInfo.getSSID()).thenReturn("\"" + ssid + "\"");
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.getSsid()).isEqualTo(ssid);
}
}

View File

@@ -0,0 +1,144 @@
/*
* 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.wifitrackerlib;
import static com.android.wifitrackerlib.NetworkDetailsTracker.createNetworkDetailsTracker;
import static com.android.wifitrackerlib.StandardWifiEntry.ScanResultKey;
import static com.android.wifitrackerlib.StandardWifiEntry.StandardWifiEntryKey;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.sharedconnectivity.app.HotspotNetwork;
import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo;
import android.os.Handler;
import android.os.test.TestLooper;
import androidx.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Collections;
public class NetworkDetailsTrackerTest {
private static final long START_MILLIS = 123_456_789;
private static final long MAX_SCAN_AGE_MILLIS = 15_000;
private static final long SCAN_INTERVAL_MILLIS = 10_000;
@Mock private WifiTrackerInjector mInjector;
@Mock private Lifecycle mMockLifecycle;
@Mock private Context mMockContext;
@Mock private Resources mResources;
@Mock private WifiManager mMockWifiManager;
@Mock private ConnectivityManager mMockConnectivityManager;
@Mock private Clock mMockClock;
private TestLooper mTestLooper;
private NetworkDetailsTracker createTestNetworkDetailsTracker(String key) {
final Handler testHandler = new Handler(mTestLooper.getLooper());
return createNetworkDetailsTracker(
mInjector,
mMockLifecycle,
mMockContext,
mMockWifiManager,
mMockConnectivityManager,
testHandler,
testHandler,
mMockClock,
MAX_SCAN_AGE_MILLIS,
SCAN_INTERVAL_MILLIS,
key);
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
when(mMockWifiManager.getScanResults()).thenReturn(new ArrayList<>());
when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
when(mMockClock.millis()).thenReturn(START_MILLIS);
when(mMockContext.getResources()).thenReturn(mResources);
}
/**
* Tests that an invalid WifiEntry key passed into the constructor throws an exception.
*/
@Test
public void testCreateNetworkDetailsTracker_invalidKey_throwsError() {
try {
createTestNetworkDetailsTracker("Invalid Key");
fail("Invalid key should have thrown an error!");
} catch (IllegalArgumentException e) {
// Test succeeded
}
}
/**
* Tests that createNetworkDetailsTracker() returns a StandardNetworkDetailsTracker if a
* StandardWifiEntry key is passed in.
*/
@Test
public void testCreateNetworkDetailsTracker_returnsStandardNetworkDetailsTracker()
throws Exception {
final NetworkDetailsTracker tracker = createTestNetworkDetailsTracker(
new StandardWifiEntryKey(new ScanResultKey("ssid",
Collections.singletonList(WifiEntry.SECURITY_NONE))).toString());
assertThat(tracker).isInstanceOf(StandardNetworkDetailsTracker.class);
}
/**
* Tests that createNetworkDetailsTracker() returns a HotspotNetworkDetailsTracker if a
* HotspotNetworkEntry key is passed in.
*/
@Test
public void testCreateNetworkDetailsTracker_returnsHotspotNetworkDetailsTracker()
throws Exception {
final NetworkDetailsTracker tracker = createTestNetworkDetailsTracker(
new HotspotNetworkEntry.HotspotNetworkEntryKey(new HotspotNetwork.Builder()
.setDeviceId(1)
.setNetworkProviderInfo(new NetworkProviderInfo
.Builder("Phone", "Pixel")
.setDeviceType(NetworkProviderInfo.DEVICE_TYPE_PHONE)
.setBatteryPercentage(100)
.setConnectionStrength(3).build())
.setHostNetworkType(HotspotNetwork.NETWORK_TYPE_CELLULAR)
.setNetworkName("Google Fi")
.setHotspotSsid("SSID")
.setHotspotBssid("BSSID")
.addHotspotSecurityType(WifiInfo.SECURITY_TYPE_WEP)
.build()).toString());
assertThat(tracker).isInstanceOf(HotspotNetworkDetailsTracker.class);
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2021 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.wifitrackerlib;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.net.NetworkCapabilities;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
import android.text.Annotation;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ClickableSpan;
import org.junit.Test;
public class NonSdkApiWrapperTest {
@Test
public void testLinkifyAnnotation_annotation_returnTextWithClickableSpan() {
final String annotationId = "id";
final CharSequence testText = "test text ";
final CharSequence testLink = "link";
final CharSequence expectedText = "test text link";
final SpannableStringBuilder builder = new SpannableStringBuilder(testText);
builder.append(testLink, new Annotation("key", annotationId),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
final CharSequence output = NonSdkApiWrapper.linkifyAnnotation(
mock(Context.class), builder, annotationId, "url");
final SpannableString outputSpannableString = new SpannableString(output);
assertEquals(output.toString(), expectedText.toString());
assertEquals(outputSpannableString.getSpans(0, outputSpannableString.length(),
ClickableSpan.class).length, 1);
}
@Test
public void testLinkifyAnnotation_annotationWithEmptyUriString_returnOriginalText() {
final String annotationId = "url";
final CharSequence testText = "test text ";
final CharSequence testLink = "Learn More";
final CharSequence expectedText = "test text Learn More";
final SpannableStringBuilder builder = new SpannableStringBuilder(testText);
builder.append(testLink, new Annotation("key", annotationId),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
final CharSequence output = NonSdkApiWrapper.linkifyAnnotation(
mock(Context.class), builder, annotationId, "");
final SpannableString outputSpannableString = new SpannableString(output);
assertEquals(output.toString(), expectedText.toString());
assertEquals(outputSpannableString.getSpans(0, outputSpannableString.length(),
ClickableSpan.class).length, 0);
}
/**
* Verifies the functionality of {@link NonSdkApiWrapper#getWifiInfoIfVcn(NetworkCapabilities)}
*/
@Test
public void testGetVcnWifiInfo() {
NetworkCapabilities networkCapabilities = mock(NetworkCapabilities.class);
assertThat(NonSdkApiWrapper.getWifiInfoIfVcn(networkCapabilities)).isNull();
VcnTransportInfo vcnTransportInfo = mock(VcnTransportInfo.class);
when(networkCapabilities.getTransportInfo()).thenReturn(vcnTransportInfo);
assertThat(NonSdkApiWrapper.getWifiInfoIfVcn(networkCapabilities)).isNull();
WifiInfo wifiInfo = mock(WifiInfo.class);
when(vcnTransportInfo.getWifiInfo()).thenReturn(wifiInfo);
assertThat(NonSdkApiWrapper.getWifiInfoIfVcn(networkCapabilities)).isEqualTo(wifiInfo);
}
}

View File

@@ -0,0 +1,363 @@
/*
* Copyright (C) 2020 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.wifitrackerlib;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
import android.net.ConnectivityDiagnosticsManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Handler;
import android.os.test.TestLooper;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import java.util.Arrays;
public class PasspointWifiEntryTest {
@Mock private WifiTrackerInjector mMockInjector;
@Mock private Context mMockContext;
@Mock private WifiManager mMockWifiManager;
@Mock private Resources mMockResources;
@Mock private WifiInfo mMockWifiInfo;
@Mock private Network mMockNetwork;
@Mock private NetworkCapabilities mMockNetworkCapabilities;
@Mock private ConnectivityManager mMockConnectivityManager;
private TestLooper mTestLooper;
private Handler mTestHandler;
private static final String FQDN = "fqdn";
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
mTestHandler = new Handler(mTestLooper.getLooper());
when(mMockWifiInfo.isPrimary()).thenReturn(true);
when(mMockWifiInfo.getNetworkId()).thenReturn(WifiConfiguration.INVALID_NETWORK_ID);
when(mMockWifiInfo.getRssi()).thenReturn(WifiInfo.INVALID_RSSI);
when(mMockNetworkCapabilities.getTransportInfo()).thenReturn(mMockWifiInfo);
when(mMockInjector.getContext()).thenReturn(mMockContext);
when(mMockContext.getResources()).thenReturn(mMockResources);
when(mMockContext.getString(R.string.wifitrackerlib_summary_separator)).thenReturn("/");
when(mMockContext.getSystemService(ConnectivityManager.class))
.thenReturn(mMockConnectivityManager);
}
@Test
public void testGetSummary_expiredTimeNotAvailable_notShowExpired() {
// default SubscriptionExpirationTimeInMillis is unset
PasspointConfiguration passpointConfiguration = getPasspointConfiguration();
String expired = "Expired";
when(mMockContext.getString(R.string.wifitrackerlib_wifi_passpoint_expired))
.thenReturn(expired);
PasspointWifiEntry passpointWifiEntry = new PasspointWifiEntry(mMockInjector,
mTestHandler, passpointConfiguration, mMockWifiManager,
false /* forSavedNetworksPage */);
assertThat(passpointWifiEntry.getSummary()).isNotEqualTo(expired);
}
@Test
public void testGetSummary_expired_showExpired() {
PasspointConfiguration passpointConfiguration = getPasspointConfiguration();
String expired = "Expired";
when(mMockContext.getString(R.string.wifitrackerlib_wifi_passpoint_expired))
.thenReturn(expired);
PasspointWifiEntry passpointWifiEntry = new PasspointWifiEntry(mMockInjector,
mTestHandler, passpointConfiguration, mMockWifiManager,
false /* forSavedNetworksPage */);
PasspointWifiEntry spyEntry = spy(passpointWifiEntry);
when(spyEntry.isExpired()).thenReturn(true);
assertThat(spyEntry.getSummary()).isEqualTo(expired);
}
private PasspointConfiguration getPasspointConfiguration() {
PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
HomeSp homeSp = new HomeSp();
homeSp.setFqdn(FQDN);
passpointConfiguration.setHomeSp(homeSp);
passpointConfiguration.setCredential(new Credential());
return passpointConfiguration;
}
@Test
public void testGetMeteredChoice_afterSetMeteredChoice_getCorrectValue() {
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
entry.setMeteredChoice(WifiEntry.METERED_CHOICE_UNMETERED);
assertThat(entry.getMeteredChoice()).isEqualTo(WifiEntry.METERED_CHOICE_UNMETERED);
}
@Test
public void testGetSummary_connectedWifiNetwork_showsConnected() {
String summarySeparator = " / ";
String[] wifiStatusArray = new String[]{"", "Scanning", "Connecting",
"Authenticating", "Obtaining IP address", "Connected"};
when(mMockContext.getString(R.string.wifitrackerlib_summary_separator))
.thenReturn(summarySeparator);
when(mMockResources.getStringArray(R.array.wifitrackerlib_wifi_status))
.thenReturn(wifiStatusArray);
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(FQDN);
when(mMockNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED))
.thenReturn(true);
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
entry.onDefaultNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.getSummary()).isEqualTo("Connected");
}
@Test
public void testGetSummary_connectedButNotDefault_doesNotShowConnected() {
String summarySeparator = " / ";
String[] wifiStatusArray = new String[]{"", "Scanning", "Connecting",
"Authenticating", "Obtaining IP address", "Connected"};
when(mMockContext.getString(R.string.wifitrackerlib_summary_separator))
.thenReturn(summarySeparator);
when(mMockResources.getStringArray(R.array.wifitrackerlib_wifi_status))
.thenReturn(wifiStatusArray);
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(FQDN);
when(mMockNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED))
.thenReturn(true);
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.getSummary()).isEqualTo("");
}
@Test
public void testGetSecurityTypes_connectedWifiNetwork_showsCurrentSecurityType() {
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(FQDN);
when(mMockWifiInfo.getCurrentSecurityType())
.thenReturn(WifiInfo.SECURITY_TYPE_PASSPOINT_R1_R2);
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
assertThat(entry.getSecurityTypes()).containsExactlyElementsIn(Arrays.asList(
WifiInfo.SECURITY_TYPE_PASSPOINT_R1_R2,
WifiInfo.SECURITY_TYPE_PASSPOINT_R3));
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.getSecurityTypes())
.containsExactly(WifiInfo.SECURITY_TYPE_PASSPOINT_R1_R2);
when(mMockWifiInfo.getCurrentSecurityType())
.thenReturn(WifiInfo.SECURITY_TYPE_PASSPOINT_R3);
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.getSecurityTypes()).containsExactly(WifiInfo.SECURITY_TYPE_PASSPOINT_R3);
}
@Test
public void testGetSecurityString_showsPasspoint() {
PasspointConfiguration passpointConfiguration = getPasspointConfiguration();
String passpointSecurity = "Passpoint";
when(mMockContext.getString(R.string.wifitrackerlib_wifi_security_passpoint))
.thenReturn(passpointSecurity);
PasspointWifiEntry passpointWifiEntry = new PasspointWifiEntry(mMockInjector,
mTestHandler, passpointConfiguration, mMockWifiManager,
false /* forSavedNetworksPage */);
assertThat(passpointWifiEntry.getSecurityString(false)).isEqualTo(passpointSecurity);
}
@Test
public void testShouldShowXLevelIcon_unvalidatedOrLowQuality_returnsTrue() {
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(FQDN);
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
// Disconnected should return false;
assertThat(entry.shouldShowXLevelIcon()).isEqualTo(false);
// Connected but validation attempt not complete, should not show X level icon yet.
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.shouldShowXLevelIcon()).isEqualTo(false);
// Validation attempt complete, should show X level icon.
ConnectivityDiagnosticsManager.ConnectivityReport connectivityReport = mock(
ConnectivityDiagnosticsManager.ConnectivityReport.class);
when(connectivityReport.getNetwork()).thenReturn(mMockNetwork);
entry.updateConnectivityReport(connectivityReport);
assertThat(entry.shouldShowXLevelIcon()).isEqualTo(true);
// Internet validated, should not show X level icon.
when(mMockNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED))
.thenReturn(true);
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.shouldShowXLevelIcon()).isEqualTo(false);
// Cell becomes default (i.e. low quality wifi), show X level icon.
entry.onDefaultNetworkCapabilitiesChanged(Mockito.mock(Network.class),
new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build());
assertThat(entry.shouldShowXLevelIcon()).isEqualTo(true);
}
@Test
public void testGetMacAddress_wifiInfoAvailable_usesWifiInfoMacAddress() {
final String factoryMac = "01:23:45:67:89:ab";
final String wifiInfoMac = "11:23:45:67:89:ab";
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
config.FQDN = FQDN;
when(mMockWifiManager.getFactoryMacAddresses()).thenReturn(new String[]{factoryMac});
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(FQDN);
when(mMockWifiInfo.getMacAddress()).thenReturn(wifiInfoMac);
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.getMacAddress()).isEqualTo(wifiInfoMac);
}
@Test
public void testIsAutoJoinEnabled_nullConfigs_returnsFalse() {
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
entry.updatePasspointConfig(null);
assertThat(entry.isAutoJoinEnabled()).isFalse();
}
@Test
public void testCanSignIn_captivePortalCapability_returnsTrue() {
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(FQDN);
when(mMockNetworkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL)).thenReturn(true);
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.canSignIn()).isTrue();
}
@Test
public void testUpdateNetworkCapabilities_userConnect_autoOpenCaptivePortalOnce() {
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
MockitoSession session = mockitoSession().spyStatic(NonSdkApiWrapper.class).startMocking();
try {
// Simulate user tapping on the network and receiving captive portal capabilities.
// This should trigger the captive portal app.
entry.connect(null /* callback */);
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(FQDN);
when(mMockNetworkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL)).thenReturn(true);
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
verify(() -> NonSdkApiWrapper.startCaptivePortalApp(any(), any()), times(1));
// Update network capabilities again. This should not trigger the captive portal app.
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
verify(() -> NonSdkApiWrapper.startCaptivePortalApp(any(), any()), times(1));
} finally {
session.finishMocking();
}
}
@Test
public void testDisconnect_noScansOrWifiConfig_disconnectIsSuccessful() {
// Setup a connected PasspointWifiEntry
String summarySeparator = " / ";
String[] wifiStatusArray = new String[]{"", "Scanning", "Connecting",
"Authenticating", "Obtaining IP address", "Connected"};
when(mMockContext.getString(R.string.wifitrackerlib_summary_separator))
.thenReturn(summarySeparator);
when(mMockResources.getStringArray(R.array.wifitrackerlib_wifi_status))
.thenReturn(wifiStatusArray);
when(mMockWifiInfo.isPasspointAp()).thenReturn(true);
when(mMockWifiInfo.getPasspointFqdn()).thenReturn(FQDN);
when(mMockNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED))
.thenReturn(true);
PasspointWifiEntry entry = new PasspointWifiEntry(mMockInjector, mTestHandler,
getPasspointConfiguration(), mMockWifiManager,
false /* forSavedNetworksPage */);
entry.onNetworkCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
// Disconnect the entry before it can be updated with scans and a WifiConfiguration
entry.disconnect(null);
verify(mMockWifiManager).disableEphemeralNetwork(FQDN);
verify(mMockWifiManager).disconnect();
}
}

View File

@@ -0,0 +1,750 @@
/*
* 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.wifitrackerlib;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.wifitrackerlib.TestUtils.GOOD_RSSI;
import static com.android.wifitrackerlib.TestUtils.buildScanResult;
import static com.android.wifitrackerlib.TestUtils.buildWifiConfiguration;
import static com.android.wifitrackerlib.WifiEntry.CONNECTED_STATE_CONNECTED;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
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.content.res.Resources;
import android.net.ConnectivityDiagnosticsManager;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Handler;
import android.os.test.TestLooper;
import androidx.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class SavedNetworkTrackerTest {
private static final long START_MILLIS = 123_456_789;
private static final long MAX_SCAN_AGE_MILLIS = 15_000;
private static final long SCAN_INTERVAL_MILLIS = 10_000;
private static final String TEST_CACERT_NOT_REQUIRED_ALIAS = "cacert_not_required";
@Mock private WifiTrackerInjector mInjector;
@Mock private Lifecycle mMockLifecycle;
@Mock private Context mMockContext;
@Mock private Resources mResources;
@Mock private WifiManager mMockWifiManager;
@Mock private ConnectivityManager mMockConnectivityManager;
@Mock private ConnectivityDiagnosticsManager mMockConnectivityDiagnosticsManager;
@Mock private Clock mMockClock;
@Mock private SavedNetworkTracker.SavedNetworkTrackerCallback mMockCallback;
@Mock private WifiInfo mMockWifiInfo;
@Mock private Network mMockNetwork;
@Mock private NetworkCapabilities mMockNetworkCapabilities;
@Mock private LinkProperties mMockLinkProperties;
private TestLooper mTestLooper;
private final ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor =
ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
private final ArgumentCaptor<ConnectivityManager.NetworkCallback>
mDefaultNetworkCallbackCaptor =
ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
private final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
private SavedNetworkTracker createTestSavedNetworkTracker() {
final Handler testHandler = new Handler(mTestLooper.getLooper());
return new SavedNetworkTracker(
mInjector,
mMockLifecycle,
mMockContext,
mMockWifiManager,
mMockConnectivityManager,
testHandler,
testHandler,
mMockClock,
MAX_SCAN_AGE_MILLIS,
SCAN_INTERVAL_MILLIS,
mMockCallback);
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
when(mMockWifiManager.getScanResults()).thenReturn(new ArrayList<>());
when(mMockWifiManager.getConnectionInfo()).thenReturn(mMockWifiInfo);
when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true);
when(mMockWifiManager.isWpa3SuiteBSupported()).thenReturn(true);
when(mMockWifiManager.isEnhancedOpenSupported()).thenReturn(true);
when(mMockWifiManager.getCurrentNetwork()).thenReturn(mMockNetwork);
when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
when(mMockWifiInfo.isPrimary()).thenReturn(true);
when(mMockWifiInfo.getNetworkId()).thenReturn(WifiConfiguration.INVALID_NETWORK_ID);
when(mMockWifiInfo.getRssi()).thenReturn(WifiInfo.INVALID_RSSI);
when(mMockWifiInfo.makeCopy(anyLong())).thenReturn(mMockWifiInfo);
when(mMockNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
.thenReturn(true);
when(mMockNetworkCapabilities.getTransportInfo()).thenReturn(mMockWifiInfo);
// A real NetworkCapabilities is needed here in order to create a copy (with location info)
// using the NetworkCapabilities constructor in handleOnStart.
when(mMockConnectivityManager.getNetworkCapabilities(mMockNetwork))
.thenReturn(new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build());
when(mMockConnectivityManager.getLinkProperties(mMockNetwork))
.thenReturn(mMockLinkProperties);
when(mInjector.getContext()).thenReturn(mMockContext);
when(mMockContext.getResources()).thenReturn(mResources);
when(mMockContext.getSystemService(ConnectivityDiagnosticsManager.class))
.thenReturn(mMockConnectivityDiagnosticsManager);
when(mMockClock.millis()).thenReturn(START_MILLIS);
}
/**
* Tests that receiving a wifi state change broadcast updates getWifiState().
*/
@Test
public void testWifiStateChangeBroadcast_updatesWifiState() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
// Set the wifi state to disabled
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)
.putExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED));
assertThat(savedNetworkTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_DISABLED);
// Change the wifi state to enabled
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION)
.putExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_ENABLED));
assertThat(savedNetworkTracker.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED);
}
/**
* Tests that receiving a wifi state change broadcast notifies the listener.
*/
@Test
public void testWifiStateChangeBroadcast_notifiesListener() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
mTestLooper.dispatchAll();
verify(mMockCallback, atLeastOnce()).onWifiStateChanged();
}
/**
* Tests that a CONFIGURED_NETWORKS_CHANGED broadcast notifies the listener for
* onSavedWifiEntriesChanged().
*/
@Test
public void testConfiguredNetworksChanged_notifiesListener() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
mTestLooper.dispatchAll();
verify(mMockCallback, atLeastOnce()).onSavedWifiEntriesChanged();
}
/**
* Tests that a WifiEntry is created for each configured network for getSavedWifiEntries().
*/
@Test
public void testGetSavedWifiEntries_onStart_entryForEachConfiguredNetwork() {
when(mMockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(
buildWifiConfiguration("ssid0"),
buildWifiConfiguration("ssid1"),
buildWifiConfiguration("ssid2")
));
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
assertThat(savedNetworkTracker.getSavedWifiEntries().stream()
.map(WifiEntry::getTitle)
.collect(Collectors.toSet()))
.containsExactly("ssid0", "ssid1", "ssid2");
}
/**
* Tests that a CONFIGURED_NETWORKS_CHANGED broadcast after adding a config
* adds the corresponding WifiEntry from getSavedWifiEntries().
*/
@Test
public void testGetSavedWifiEntries_configuredNetworksChanged_addsEntry() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
assertThat(savedNetworkTracker.getSavedWifiEntries()).isEmpty();
final WifiConfiguration config = buildWifiConfiguration("ssid");
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
assertThat(savedNetworkTracker.getSavedWifiEntries().stream()
.filter(entry -> entry.mForSavedNetworksPage)
.collect(Collectors.toSet()))
.hasSize(1);
}
/**
* Tests that a CONFIGURED_NETWORKS_CHANGED broadcast after removing a config
* removes the corresponding WifiEntry from getSavedWifiEntries().
*/
@Test
public void testGetSavedWifiEntries_configuredNetworksChanged_removesEntry() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final WifiConfiguration config = buildWifiConfiguration("ssid");
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
assertThat(savedNetworkTracker.getSavedWifiEntries()).hasSize(1);
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.emptyList());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
assertThat(savedNetworkTracker.getSavedWifiEntries()).isEmpty();
}
/**
* Tests that receiving a scan results available broadcast notifies the listener.
*/
@Test
public void testScanResultsAvailableAction_notifiesListener() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
verify(mMockCallback, atLeastOnce()).onSavedWifiEntriesChanged();
}
/**
* Tests that the scan results available broadcast changes the level of saved WifiEntries.
*/
@Test
public void testGetSavedWifiEntries_scanResultsAvailableAction_changesLevel() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final WifiConfiguration config = buildWifiConfiguration("ssid");
config.networkId = 1;
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
final WifiEntry entry = savedNetworkTracker.getSavedWifiEntries().get(0);
assertThat(entry.getLevel()).isEqualTo(WifiEntry.WIFI_LEVEL_UNREACHABLE);
when(mMockWifiManager.getScanResults()).thenReturn(Collections.singletonList(
buildScanResult("ssid", "bssid", START_MILLIS, -50 /* rssi */)));
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
assertThat(entry.getLevel()).isNotEqualTo(WifiEntry.WIFI_LEVEL_UNREACHABLE);
when(mMockClock.millis()).thenReturn(START_MILLIS + MAX_SCAN_AGE_MILLIS + 1);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
assertThat(entry.getLevel()).isEqualTo(WifiEntry.WIFI_LEVEL_UNREACHABLE);
}
@Test
public void testGetSubscriptionWifiEntries_returnsPasspointEntries() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final PasspointConfiguration passpointConfig = new PasspointConfiguration();
final HomeSp homeSp = new HomeSp();
homeSp.setFqdn("fqdn");
homeSp.setFriendlyName("friendlyName");
passpointConfig.setHomeSp(homeSp);
passpointConfig.setCredential(new Credential());
when(mMockWifiManager.getPasspointConfigurations())
.thenReturn(Collections.singletonList(passpointConfig));
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
assertThat(savedNetworkTracker.getSubscriptionWifiEntries()).isNotEmpty();
assertThat(savedNetworkTracker.getSubscriptionWifiEntries().get(0).getTitle())
.isEqualTo("friendlyName");
}
@Test
public void testGetSavedNetworks_splitConfigs_entriesMergedBySecurityFamily() {
final String ssid = "ssid";
WifiConfiguration openConfig = buildWifiConfiguration(ssid);
openConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
openConfig.networkId = 1;
WifiConfiguration oweConfig = buildWifiConfiguration(ssid);
oweConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
oweConfig.networkId = 1;
WifiConfiguration wepConfig = buildWifiConfiguration(ssid);
wepConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WEP);
wepConfig.wepKeys = new String[]{"key"};
wepConfig.networkId = 2;
WifiConfiguration pskConfig = buildWifiConfiguration(ssid);
pskConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
pskConfig.networkId = 3;
WifiConfiguration saeConfig = buildWifiConfiguration(ssid);
saeConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
saeConfig.networkId = 3;
WifiConfiguration eapConfig = buildWifiConfiguration(ssid);
eapConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
eapConfig.networkId = 4;
WifiConfiguration eapWpa3Config = buildWifiConfiguration(ssid);
eapWpa3Config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE);
eapWpa3Config.networkId = 4;
WifiConfiguration eapWpa3SuiteBConfig = buildWifiConfiguration(ssid);
eapWpa3SuiteBConfig.setSecurityParams(
WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT);
eapWpa3SuiteBConfig.networkId = 5;
when(mMockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(
openConfig, oweConfig, wepConfig, pskConfig, saeConfig, eapConfig, eapWpa3Config,
eapWpa3SuiteBConfig
));
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
final List<WifiEntry> savedWifiEntries = savedNetworkTracker.getSavedWifiEntries();
assertThat(savedWifiEntries.size()).isEqualTo(5);
assertThat(savedWifiEntries.stream()
.map(entry -> entry.getSecurityTypes())
.collect(Collectors.toList()))
.containsExactly(
Arrays.asList(WifiInfo.SECURITY_TYPE_OPEN, WifiInfo.SECURITY_TYPE_OWE),
Arrays.asList(WifiInfo.SECURITY_TYPE_WEP),
Arrays.asList(WifiInfo.SECURITY_TYPE_PSK, WifiInfo.SECURITY_TYPE_SAE),
Arrays.asList(WifiInfo.SECURITY_TYPE_EAP,
WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE),
Arrays.asList(WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT));
}
/**
* Tests that entries with configs that have scans matching the security family but NOT the
* actual configs on hand will ignore the scans and be returned as saved with the configs.
*/
@Test
public void testGetSavedNetworks_mismatchedScans_returnsCorrectEntries() {
// Set up scans for Open, PSK, WPA2-Enterprise
final ArrayList scanList = new ArrayList();
final String ssid = "ssid";
final String bssid = "bssid";
int bssidNum = 0;
for (String capabilities : Arrays.asList(
"",
"[PSK]",
"[EAP/SHA1]"
)) {
final ScanResult scan = buildScanResult(ssid, bssid + bssidNum++, START_MILLIS);
scan.capabilities = capabilities;
scanList.add(scan);
}
when(mMockWifiManager.getScanResults()).thenReturn(scanList);
// Set up configs for OWE, SAE, WPA3-Enterprise
WifiConfiguration oweConfig = buildWifiConfiguration(ssid);
oweConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
oweConfig.networkId = 1;
WifiConfiguration saeConfig = buildWifiConfiguration(ssid);
saeConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
saeConfig.networkId = 2;
WifiConfiguration eapWpa3Config = buildWifiConfiguration(ssid);
eapWpa3Config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE);
eapWpa3Config.networkId = 3;
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Arrays.asList(oweConfig, saeConfig, eapWpa3Config));
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
// Entries should appear correctly in the saved entry list with the security type of their
// configs, ignoring the scans present.
final List<WifiEntry> savedWifiEntries = savedNetworkTracker.getSavedWifiEntries();
assertThat(savedWifiEntries.size()).isEqualTo(3);
assertThat(savedWifiEntries.stream()
.map(entry -> entry.getSecurityTypes())
.collect(Collectors.toList()))
.containsExactly(
Arrays.asList(WifiInfo.SECURITY_TYPE_OWE),
Arrays.asList(WifiInfo.SECURITY_TYPE_SAE),
Arrays.asList(WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE));
}
/**
* Tests that a saved network has CONNECTED_STATE_CONNECTED if it is the connected network on
* start.
*/
@Test
public void testConnectedEntry_alreadyConnectedOnStart_isConnected() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
WifiEntry entry = savedNetworkTracker.getSavedWifiEntries().get(0);
assertThat(entry.getConnectedState()).isEqualTo(CONNECTED_STATE_CONNECTED);
}
/**
* Tests that connecting to a network will update that network to CONNECTED_STATE_CONNECTED.
*/
@Test
public void testDisconnectedEntry_connectToNetwork_becomesConnected() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockConnectivityManager).registerNetworkCallback(
any(), mNetworkCallbackCaptor.capture(), any());
final WifiEntry entry = savedNetworkTracker.getSavedWifiEntries().get(0);
assertThat(entry.getConnectedState()).isEqualTo(WifiEntry.CONNECTED_STATE_DISCONNECTED);
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(
mMockNetwork, mMockNetworkCapabilities);
assertThat(entry.getConnectedState()).isEqualTo(CONNECTED_STATE_CONNECTED);
}
/**
* Tests that disconnecting from a network will update that network to
* CONNECTED_STATE_DISCONNECTED.
*/
@Test
public void testConnectedEntry_disconnectFromNetwork_becomesDisconnected() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockConnectivityManager).registerNetworkCallback(
any(), mNetworkCallbackCaptor.capture(), any());
final WifiEntry entry = savedNetworkTracker.getSavedWifiEntries().get(0);
assertThat(entry.getConnectedState()).isEqualTo(CONNECTED_STATE_CONNECTED);
mNetworkCallbackCaptor.getValue().onLost(mMockNetwork);
assertThat(entry.getConnectedState()).isEqualTo(WifiEntry.CONNECTED_STATE_DISCONNECTED);
}
/**
* Tests that disconnecting from a network during the stopped state will result in the network
* being disconnected once we've started again.
*/
@Test
public void testGetConnectedEntry_disconnectFromNetworkWhileStopped_becomesDisconnected() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockConnectivityManager).registerNetworkCallback(
any(), mNetworkCallbackCaptor.capture(), any());
final WifiEntry entry = savedNetworkTracker.getSavedWifiEntries().get(0);
assertThat(entry.getConnectedState()).isEqualTo(CONNECTED_STATE_CONNECTED);
// Simulate network disconnecting while in stopped state
savedNetworkTracker.onStop();
mTestLooper.dispatchAll();
when(mMockWifiManager.getCurrentNetwork()).thenReturn(null);
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
assertThat(entry.getConnectedState()).isEqualTo(WifiEntry.CONNECTED_STATE_DISCONNECTED);
}
/**
* Tests that getConnectedEntry() will return the correct primary network after an MBB sequence.
*/
@Test
public void testConnectedEntry_mbbFlow_matchesNewPrimary() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
final WifiConfiguration mbbConfig = new WifiConfiguration();
mbbConfig.SSID = "\"otherSsid\"";
mbbConfig.networkId = 2;
when(mMockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(config, mbbConfig));
when(mMockWifiInfo.getNetworkId()).thenReturn(config.networkId);
when(mMockWifiInfo.getRssi()).thenReturn(GOOD_RSSI);
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockConnectivityManager).registerNetworkCallback(
any(), mNetworkCallbackCaptor.capture(), any());
// Start off connected
List<WifiEntry> savedEntries = savedNetworkTracker.getSavedWifiEntries();
assertThat(savedEntries.size()).isEqualTo(2);
WifiEntry originalEntry = null;
WifiEntry mbbEntry = null;
for (WifiEntry entry : savedNetworkTracker.getSavedWifiEntries()) {
if (entry.getTitle().equals("ssid")) {
originalEntry = entry;
} else if (entry.getTitle().equals("otherSsid")) {
mbbEntry = entry;
}
}
assertThat(originalEntry).isNotNull();
assertThat(originalEntry.getConnectedState())
.isEqualTo(CONNECTED_STATE_CONNECTED);
assertThat(mbbEntry).isNotNull();
assertThat(mbbEntry.getConnectedState())
.isEqualTo(WifiEntry.CONNECTED_STATE_DISCONNECTED);
MockitoSession session = mockitoSession().spyStatic(NonSdkApiWrapper.class).startMocking();
try {
// MBB network connected but not primary yet.
Network mbbNetwork = mock(Network.class);
NetworkCapabilities mbbNetworkCapabilities = mock(NetworkCapabilities.class);
WifiInfo mbbWifiInfo = mock(WifiInfo.class);
when(mbbWifiInfo.getNetworkId()).thenReturn(mbbConfig.networkId);
when(mbbWifiInfo.getRssi()).thenReturn(GOOD_RSSI);
when(mbbNetworkCapabilities.getTransportInfo()).thenReturn(mbbWifiInfo);
doReturn(false).when(() -> NonSdkApiWrapper.isPrimary(mbbWifiInfo));
mNetworkCallbackCaptor.getValue()
.onCapabilitiesChanged(mbbNetwork, mbbNetworkCapabilities);
// Original network should still be connected.
assertThat(originalEntry.getConnectedState())
.isEqualTo(CONNECTED_STATE_CONNECTED);
assertThat(mbbEntry.getConnectedState())
.isEqualTo(WifiEntry.CONNECTED_STATE_DISCONNECTED);
// Original network becomes non-primary and MBB network becomes primary.
doReturn(false).when(() -> NonSdkApiWrapper.isPrimary(mMockWifiInfo));
mNetworkCallbackCaptor.getValue()
.onCapabilitiesChanged(mMockNetwork, mMockNetworkCapabilities);
doReturn(true).when(() -> NonSdkApiWrapper.isPrimary(mbbWifiInfo));
mNetworkCallbackCaptor.getValue()
.onCapabilitiesChanged(mbbNetwork, mbbNetworkCapabilities);
// MBB network should be connected now.
assertThat(originalEntry.getConnectedState())
.isEqualTo(WifiEntry.CONNECTED_STATE_DISCONNECTED);
assertThat(mbbEntry.getConnectedState())
.isEqualTo(CONNECTED_STATE_CONNECTED);
// Original network is lost. MBB network should still be connected
assertThat(originalEntry.getConnectedState())
.isEqualTo(WifiEntry.CONNECTED_STATE_DISCONNECTED);
assertThat(mbbEntry.getConnectedState())
.isEqualTo(CONNECTED_STATE_CONNECTED);
} finally {
session.finishMocking();
}
}
@Test
public void testCertificateRequired() throws Exception {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
// Check another CA cert alias.
assertFalse(savedNetworkTracker.isCertificateRequired(TEST_CACERT_NOT_REQUIRED_ALIAS));
assertEquals(0, savedNetworkTracker
.getCertificateRequesterNames(TEST_CACERT_NOT_REQUIRED_ALIAS).size());
}
/**
* Tests that a connected WifiEntry's isDefaultNetwork() will reflect updates from the default
* network changing.
*/
@Test
public void testGetConnectedEntry_defaultNetworkChanges_isDefaultNetworkChanges() {
final SavedNetworkTracker savedNetworkTracker = createTestSavedNetworkTracker();
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"ssid\"";
config.networkId = 1;
when(mMockWifiManager.getConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
when(mMockWifiManager.getScanResults()).thenReturn(Arrays.asList(
buildScanResult("ssid", "bssid", START_MILLIS)));
when(mMockWifiInfo.getNetworkId()).thenReturn(1);
when(mMockWifiInfo.getRssi()).thenReturn(-50);
savedNetworkTracker.onStart();
mTestLooper.dispatchAll();
verify(mMockConnectivityManager)
.registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any());
verify(mMockConnectivityManager, atLeast(0)).registerSystemDefaultNetworkCallback(
mDefaultNetworkCallbackCaptor.capture(), any());
verify(mMockConnectivityManager, atLeast(0)).registerDefaultNetworkCallback(
mDefaultNetworkCallbackCaptor.capture(), any());
WifiEntry connectedWifiEntry = savedNetworkTracker.getSavedWifiEntries().get(0);
assertThat(connectedWifiEntry).isNotNull();
assertThat(connectedWifiEntry.getConnectedState()).isEqualTo(CONNECTED_STATE_CONNECTED);
// No default
assertThat(connectedWifiEntry.isDefaultNetwork()).isFalse();
// Cell is default
mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(Mockito.mock(Network.class),
new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build());
assertThat(connectedWifiEntry.isDefaultNetwork()).isFalse();
// Other Wi-Fi network is default
Network otherWifiNetwork = mock(Network.class);
WifiInfo otherWifiInfo = mock(WifiInfo.class);
when(otherWifiInfo.getNetworkId()).thenReturn(2);
NetworkCapabilities otherNetworkCapabilities = mock(NetworkCapabilities.class);
when(otherNetworkCapabilities.getTransportInfo()).thenReturn(otherWifiInfo);
when(otherNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
.thenReturn(true);
mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(otherWifiNetwork,
otherNetworkCapabilities);
assertThat(connectedWifiEntry.isDefaultNetwork()).isFalse();
// This Wi-Fi network is default
mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(mMockNetwork,
mMockNetworkCapabilities);
assertThat(connectedWifiEntry.isDefaultNetwork()).isTrue();
// Lose the default network
mDefaultNetworkCallbackCaptor.getValue().onLost(mock(Network.class));
assertThat(connectedWifiEntry.isDefaultNetwork()).isFalse();
}
}

View File

@@ -0,0 +1,148 @@
/*
* 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.wifitrackerlib;
import static com.android.wifitrackerlib.TestUtils.buildScanResult;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;
import android.net.wifi.ScanResult;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.time.Clock;
import java.util.Arrays;
import java.util.List;
public class ScanResultUpdaterTest {
private static final String SSID = "ssid";
private static final String BSSID_1 = "11:11:11:11:11:11";
private static final String BSSID_2 = "22:22:22:22:22:22";
private static final String BSSID_3 = "33:33:33:33:33:33";
private static final long NOW_MILLIS = 123_456_789;
@Mock private Clock mMockClock;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mMockClock.millis()).thenReturn(NOW_MILLIS);
}
/**
* Verify that scan results of the same BSSID are merged to latest one.
*/
@Test
public void testGetScanResults_mergeSameBssid() {
ScanResult oldResult = buildScanResult(SSID, BSSID_1, 10);
ScanResult newResult = buildScanResult(SSID, BSSID_1, 20);
// Add initial scan result. List should have 1 scan.
ScanResultUpdater sru = new ScanResultUpdater(mMockClock);
sru.update(Arrays.asList(oldResult));
assertThat(sru.getScanResults()).containsExactly(oldResult);
// Add new scan result. Old scan result should be replaced.
sru.update(Arrays.asList(newResult));
assertThat(sru.getScanResults()).containsExactly(newResult);
// Add old scan result back. New scan result should still remain.
sru.update(Arrays.asList(oldResult));
assertThat(sru.getScanResults()).containsExactly(newResult);
}
/**
* Verify that scan results are filtered out by age.
*/
@Test
public void testGetScanResults_filtersOldScans() {
long maxScanAge = 15_000;
ScanResult oldResult = buildScanResult(SSID, BSSID_1, NOW_MILLIS - (maxScanAge + 1));
ScanResult newResult = buildScanResult(SSID, BSSID_2, NOW_MILLIS);
// Add a new scan result and an out-of-date scan result.
ScanResultUpdater sru = new ScanResultUpdater(mMockClock);
sru.update(Arrays.asList(newResult, oldResult));
// New scan result should remain and out-of-date scan result should not be returned.
assertThat(sru.getScanResults(maxScanAge)).containsExactly(newResult);
}
/**
* Verify that an exception is thrown if the getScanResults max scan age is larger than the
* constructor's max scan age.
*/
@Test
public void testGetScanResults_invalidMaxScanAgeMillis_throwsException() {
ScanResultUpdater sru = new ScanResultUpdater(mMockClock, 15_000);
try {
sru.getScanResults(20_000);
fail("Should have thrown exception for maxScanAgeMillis too large.");
} catch (IllegalArgumentException ok) {
// Expected
}
}
/**
* Verify that the constructor max scan age is obeyed when getting scan results.
*/
@Test
public void testConstructor_maxScanAge_filtersOldScans() {
ScanResultUpdater sru = new ScanResultUpdater(mMockClock, 15_000);
ScanResult scan1 = buildScanResult(SSID, BSSID_1, NOW_MILLIS - 10_000);
ScanResult scan2 = buildScanResult(SSID, BSSID_2, NOW_MILLIS - 15_000);
ScanResult scan3 = buildScanResult(SSID, BSSID_3, NOW_MILLIS - 20_000);
sru.update(Arrays.asList(scan1, scan2, scan3));
List<ScanResult> scanResults = sru.getScanResults();
assertThat(scanResults).containsExactly(scan1, scan2);
}
/**
* Verify that getScanResults returns results aged by the passed in max scan age even if there
* is a max scan age set by the constructor.
*/
@Test
public void testGetScanResults_overridesConstructorMaxScanAge() {
ScanResultUpdater sru = new ScanResultUpdater(mMockClock, 15_000);
ScanResult scan1 = buildScanResult(SSID, BSSID_1, NOW_MILLIS - 10_000);
ScanResult scan2 = buildScanResult(SSID, BSSID_2, NOW_MILLIS - 15_000);
ScanResult scan3 = buildScanResult(SSID, BSSID_3, NOW_MILLIS - 20_000);
sru.update(Arrays.asList(scan1, scan2, scan3));
// Aged getScanResults should override the constructor max scan age.
List<ScanResult> scanResults = sru.getScanResults(11_000);
assertThat(scanResults).containsExactly(scan1);
// Non-aged getScanResults should revert to the constructor max scan age.
scanResults = sru.getScanResults();
assertThat(scanResults).containsExactly(scan1, scan2);
}
}

View File

@@ -0,0 +1,320 @@
/*
* 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.wifitrackerlib;
import static android.net.wifi.WifiInfo.SECURITY_TYPE_PSK;
import static com.android.wifitrackerlib.StandardWifiEntry.StandardWifiEntryKey;
import static com.android.wifitrackerlib.StandardWifiEntry.ssidAndSecurityTypeToStandardWifiEntryKey;
import static com.android.wifitrackerlib.TestUtils.BAD_LEVEL;
import static com.android.wifitrackerlib.TestUtils.BAD_RSSI;
import static com.android.wifitrackerlib.TestUtils.GOOD_RSSI;
import static com.android.wifitrackerlib.TestUtils.buildScanResult;
import static com.android.wifitrackerlib.TestUtils.buildWifiConfiguration;
import static com.android.wifitrackerlib.WifiEntry.SECURITY_NONE;
import static com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_UNREACHABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
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.content.res.Resources;
import android.net.ConnectivityDiagnosticsManager;
import android.net.ConnectivityManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.os.Handler;
import android.os.test.TestLooper;
import androidx.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Collections;
public class StandardNetworkDetailsTrackerTest {
private static final long START_MILLIS = 123_456_789;
private static final long MAX_SCAN_AGE_MILLIS = 15_000;
private static final long SCAN_INTERVAL_MILLIS = 10_000;
@Mock private WifiTrackerInjector mInjector;
@Mock private Lifecycle mMockLifecycle;
@Mock private Context mMockContext;
@Mock private Resources mResources;
@Mock private WifiManager mMockWifiManager;
@Mock private WifiScanner mWifiScanner;
@Mock private ConnectivityManager mMockConnectivityManager;
@Mock private ConnectivityDiagnosticsManager mMockConnectivityDiagnosticsManager;
@Mock private Clock mMockClock;
private TestLooper mTestLooper;
private final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
private StandardNetworkDetailsTracker createTestStandardNetworkDetailsTracker(
String key) {
final Handler testHandler = new Handler(mTestLooper.getLooper());
return new StandardNetworkDetailsTracker(
mInjector,
mMockLifecycle,
mMockContext,
mMockWifiManager,
mMockConnectivityManager,
testHandler,
testHandler,
mMockClock,
MAX_SCAN_AGE_MILLIS,
SCAN_INTERVAL_MILLIS,
key);
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true);
when(mMockWifiManager.isWpa3SuiteBSupported()).thenReturn(true);
when(mMockWifiManager.isEnhancedOpenSupported()).thenReturn(true);
when(mMockWifiManager.getScanResults()).thenReturn(new ArrayList<>());
when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED);
when(mMockWifiManager.calculateSignalLevel(TestUtils.GOOD_RSSI))
.thenReturn(TestUtils.GOOD_LEVEL);
when(mMockWifiManager.calculateSignalLevel(TestUtils.OKAY_RSSI))
.thenReturn(TestUtils.OKAY_LEVEL);
when(mMockWifiManager.calculateSignalLevel(TestUtils.BAD_RSSI))
.thenReturn(TestUtils.BAD_LEVEL);
when(mMockContext.getResources()).thenReturn(mResources);
when(mMockContext.getSystemService(ConnectivityDiagnosticsManager.class))
.thenReturn(mMockConnectivityDiagnosticsManager);
when(mMockContext.getSystemService(WifiScanner.class)).thenReturn(mWifiScanner);
when(mMockClock.millis()).thenReturn(START_MILLIS);
}
/**
* Tests that the key of the created WifiEntry matches the key passed into the constructor.
*/
@Test
public void testGetWifiEntry_HasCorrectKey() throws Exception {
final StandardWifiEntryKey key =
ssidAndSecurityTypeToStandardWifiEntryKey("ssid", SECURITY_NONE);
final StandardNetworkDetailsTracker tracker =
createTestStandardNetworkDetailsTracker(key.toString());
assertThat(tracker.getWifiEntry().getKey()).isEqualTo(key.toString());
}
/**
* Tests that SCAN_RESULTS_AVAILABLE_ACTION updates the level of the entry.
*/
@Test
public void testScanResultsAvailableAction_updates_getLevel() throws Exception {
// Starting without any scans available should make level WIFI_LEVEL_UNREACHABLE
final ScanResult scan = buildScanResult("ssid", "bssid", START_MILLIS, -50 /* rssi */);
final StandardWifiEntryKey key =
ssidAndSecurityTypeToStandardWifiEntryKey("ssid", SECURITY_NONE);
final StandardNetworkDetailsTracker tracker =
createTestStandardNetworkDetailsTracker(key.toString());
tracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
final WifiEntry wifiEntry = tracker.getWifiEntry();
assertThat(wifiEntry.getLevel()).isEqualTo(WIFI_LEVEL_UNREACHABLE);
// Received fresh scan. Level should not be WIFI_LEVEL_UNREACHABLE anymore
when(mMockWifiManager.getScanResults()).thenReturn(Collections.singletonList(scan));
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, true));
assertThat(wifiEntry.getLevel()).isNotEqualTo(WIFI_LEVEL_UNREACHABLE);
// Scan returned with no scans, old scans timed out. Level should be WIFI_LEVEL_UNREACHABLE.
when(mMockWifiManager.getScanResults()).thenReturn(Collections.emptyList());
when(mMockClock.millis()).thenReturn(START_MILLIS + MAX_SCAN_AGE_MILLIS + 1);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, true));
assertThat(wifiEntry.getLevel()).isEqualTo(WIFI_LEVEL_UNREACHABLE);
}
/**
* Tests that CONFIGURED_NETWORKS_CHANGED_ACTION updates the isSaved() value of the entry.
*/
@Test
public void testConfiguredNetworksChangedAction_updates_isSaved() throws Exception {
// Initialize with no config. isSaved() should return false.
final StandardWifiEntryKey key =
ssidAndSecurityTypeToStandardWifiEntryKey("ssid", SECURITY_NONE);
final StandardNetworkDetailsTracker tracker =
createTestStandardNetworkDetailsTracker(key.toString());
tracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
final WifiEntry wifiEntry = tracker.getWifiEntry();
assertThat(wifiEntry.isSaved()).isFalse();
// Add a config and send a broadcast. isSaved() should return true.
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"" + "ssid" + "\"";
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
assertThat(wifiEntry.isSaved()).isTrue();
// Remove the config and send a broadcast. isSaved() should be false.
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.emptyList());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
assertThat(wifiEntry.isSaved()).isFalse();
}
/**
* Tests that WIFI_STATE_DISABLED will clear the scan results of the chosen entry regardless if
* the scan results are still valid.
*/
@Test
public void testWifiStateChanged_disabled_clearsLevel() throws Exception {
// Start with scan result and wifi state enabled. Level should not be unreachable.
final ScanResult scan = buildScanResult("ssid", "bssid", START_MILLIS, -50 /* rssi */);
final StandardWifiEntryKey key =
ssidAndSecurityTypeToStandardWifiEntryKey("ssid", SECURITY_NONE);
when(mMockWifiManager.getScanResults()).thenReturn(Collections.singletonList(scan));
final StandardNetworkDetailsTracker tracker =
createTestStandardNetworkDetailsTracker(key.toString());
tracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
final WifiEntry wifiEntry = tracker.getWifiEntry();
assertThat(wifiEntry.getLevel()).isNotEqualTo(WIFI_LEVEL_UNREACHABLE);
// Disable wifi. Level should be unreachable.
when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_DISABLED);
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
assertThat(wifiEntry.getLevel()).isEqualTo(WIFI_LEVEL_UNREACHABLE);
}
@Test
public void testSecurityTargeting_pskScansWithSaeConfig_correspondsToNewNetworkTargeting() {
final String ssid = "ssid";
final WifiConfiguration config = buildWifiConfiguration(ssid);
config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
final ScanResult scan = buildScanResult(ssid, "bssid", START_MILLIS, -50 /* rssi */);
scan.capabilities = "[PSK]";
when(mMockWifiManager.getScanResults()).thenReturn(Collections.singletonList(scan));
// Start without targeting new networks
StandardNetworkDetailsTracker tracker = createTestStandardNetworkDetailsTracker(
ssidAndSecurityTypeToStandardWifiEntryKey(ssid, SECURITY_TYPE_PSK).toString());
tracker.onStart();
mTestLooper.dispatchAll();
// WifiEntry should correspond to the saved config
WifiEntry wifiEntry = tracker.getWifiEntry();
assertThat(wifiEntry.getSecurityTypes().get(0)).isEqualTo(WifiInfo.SECURITY_TYPE_SAE);
assertThat(wifiEntry.getLevel()).isEqualTo(WIFI_LEVEL_UNREACHABLE);
// Now target new networks as if we got the key from WifiPickerTracker
tracker = createTestStandardNetworkDetailsTracker(
ssidAndSecurityTypeToStandardWifiEntryKey(ssid, SECURITY_TYPE_PSK,
true /* isTargetingNewNetworks */).toString());
tracker.onStart();
mTestLooper.dispatchAll();
// WifiEntry should correspond to the unsaved scan
wifiEntry = tracker.getWifiEntry();
assertThat(wifiEntry.getSecurityTypes().get(0)).isEqualTo(SECURITY_TYPE_PSK);
assertThat(wifiEntry.getLevel()).isNotEqualTo(WIFI_LEVEL_UNREACHABLE);
}
/**
* Tests that we update the chosen entry's ScanResults correctly after a WifiScanner scan.
*/
@Test
public void testScanner_wifiScannerResultReceived_scanResultsUpdated() {
final String ssid = "ssid";
final WifiConfiguration config = buildWifiConfiguration(ssid);
when(mMockWifiManager.getPrivilegedConfiguredNetworks())
.thenReturn(Collections.singletonList(config));
StandardNetworkDetailsTracker tracker = createTestStandardNetworkDetailsTracker(
ssidAndSecurityTypeToStandardWifiEntryKey(ssid, SECURITY_NONE).toString());
tracker.onStart();
mTestLooper.dispatchAll();
verify(mMockContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
any(), any(), any());
mBroadcastReceiverCaptor.getValue().onReceive(mMockContext,
new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION).putExtra(
WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_ENABLED));
ArgumentCaptor<WifiScanner.ScanListener> mScanListenerCaptor =
ArgumentCaptor.forClass(WifiScanner.ScanListener.class);
verify(mWifiScanner).startScan(any(), mScanListenerCaptor.capture());
ScanResult[] scanResults = new ScanResult[]{
buildScanResult(ssid, "bssid", START_MILLIS, BAD_RSSI),
buildScanResult("different ssid", "bssid", START_MILLIS, GOOD_RSSI),
};
WifiScanner.ScanData scanData = mock(WifiScanner.ScanData.class);
when(scanData.getResults()).thenReturn(scanResults);
mScanListenerCaptor.getValue().onResults(new WifiScanner.ScanData[]{scanData});
mTestLooper.dispatchAll();
// Updated with the correct SSID and ignored the different SSID.
assertThat(tracker.getWifiEntry().getLevel()).isEqualTo(BAD_LEVEL);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
/*
* 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.wifitrackerlib;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiSsid;
import java.nio.charset.StandardCharsets;
/**
* Utility methods for testing purposes.
*/
class TestUtils {
public static final int GOOD_RSSI = -50;
public static final int OKAY_RSSI = -60;
public static final int BAD_RSSI = -70;
public static final int GOOD_LEVEL = 5;
public static final int OKAY_LEVEL = 3;
public static final int BAD_LEVEL = 1;
/**
* Creates a mock scan result with SSID, BSSID, and timestamp.
*/
static ScanResult buildScanResult(String utf8Ssid, String bssid, long timestampMillis) {
final ScanResult result = new ScanResult();
result.SSID = utf8Ssid;
if (utf8Ssid != null) {
result.setWifiSsid(WifiSsid.fromBytes(utf8Ssid.getBytes(StandardCharsets.UTF_8)));
}
result.BSSID = bssid;
result.timestamp = timestampMillis * 1000;
result.capabilities = "";
return result;
}
static ScanResult buildScanResult(
String utf8Ssid, String bssid, long timestampMillis, int rssi) {
final ScanResult result = buildScanResult(utf8Ssid, bssid, timestampMillis);
result.level = rssi;
result.capabilities = "";
return result;
}
static ScanResult buildScanResult(
String utf8Ssid, String bssid, long timestampMillis, String securityTypesString) {
final ScanResult result = buildScanResult(utf8Ssid, bssid, timestampMillis);
result.capabilities = securityTypesString;
return result;
}
static WifiConfiguration buildWifiConfiguration(String utf8Ssid) {
final WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"" + utf8Ssid + "\"";
return config;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2020 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.wifitrackerlib.shadow;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
/**
* A shadow object of {@link System}.
*/
@Implements(System.class)
public class ShadowSystem {
/**
* Implements {@link System#currentTimeMillis}.
*
* @return a fixed time milli throughout tests.
*/
@Implementation
public static long currentTimeMillis() {
// It's 2100/01/02 00:00:00.
return 4102531200000L;
}
}