diff options
author | Xin Li <delphij@google.com> | 2020-08-31 21:21:38 -0700 |
---|---|---|
committer | Xin Li <delphij@google.com> | 2020-08-31 21:21:38 -0700 |
commit | 628590d7ec80e10a3fc24b1c18a1afb55cca10a8 (patch) | |
tree | 4b1c3f52d86d7fb53afbe9e9438468588fa489f8 /wifi/tests | |
parent | b11b8ec3aec8bb42f2c07e1c5ac7942da293baa8 (diff) | |
parent | d2d3a20624d968199353ccf6ddbae6f3ac39c9af (diff) |
Merge Android R (rvc-dev-plus-aosp-without-vendor@6692709)
Bug: 166295507
Merged-In: I3d92a6de21a938f6b352ec26dc23420c0fe02b27
Change-Id: Ifdb80563ef042738778ebb8a7581a97c4e3d96e2
Diffstat (limited to 'wifi/tests')
45 files changed, 5794 insertions, 1265 deletions
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp new file mode 100644 index 000000000000..6a39959e8cfd --- /dev/null +++ b/wifi/tests/Android.bp @@ -0,0 +1,50 @@ +// 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. + +// Make test APK +// ============================================================ + +android_test { + name: "FrameworksWifiApiTests", + + defaults: ["framework-wifi-test-defaults"], + + srcs: ["**/*.java"], + + jacoco: { + include_filter: ["android.net.wifi.*"], + // TODO(b/147521214) need to exclude test classes + exclude_filter: [], + }, + + static_libs: [ + "androidx.test.rules", + "core-test-rules", + "guava", + "mockito-target-minus-junit4", + "net-tests-utils", + "frameworks-base-testutils", + "truth-prebuilt", + ], + + libs: [ + "android.test.runner", + "android.test.base", + ], + + test_suites: [ + "device-tests", + "mts", + ], +} diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk deleted file mode 100644 index 3453d6ec827f..000000000000 --- a/wifi/tests/Android.mk +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH:= $(call my-dir) - -# Make test APK -# ============================================================ -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -# This list is generated from the java source files in this module -# The list is a comma separated list of class names with * matching zero or more characters. -# Example: -# Input files: src/com/android/server/wifi/Test.java src/com/android/server/wifi/AnotherTest.java -# Generated exclude list: com.android.server.wifi.Test*,com.android.server.wifi.AnotherTest* - -# Filter all src files to just java files -local_java_files := $(filter %.java,$(LOCAL_SRC_FILES)) -# Transform java file names into full class names. -# This only works if the class name matches the file name and the directory structure -# matches the package. -local_classes := $(subst /,.,$(patsubst src/%.java,%,$(local_java_files))) -# Convert class name list to jacoco exclude list -# This appends a * to all classes and replace the space separators with commas. -# These patterns will match all classes in this module and their inner classes. -jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes))) - -jacoco_include := android.net.wifi.* - -LOCAL_JACK_COVERAGE_INCLUDE_FILTER := $(jacoco_include) -LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx.test.rules \ - core-test-rules \ - guava \ - mockito-target-minus-junit4 \ - net-tests-utils \ - frameworks-base-testutils \ - truth-prebuilt \ - -LOCAL_JAVA_LIBRARIES := \ - android.test.runner \ - android.test.base \ - -LOCAL_PACKAGE_NAME := FrameworksWifiApiTests -LOCAL_PRIVATE_PLATFORM_APIS := true -LOCAL_COMPATIBILITY_SUITE := device-tests - -include $(BUILD_PACKAGE) diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml index cae19e46c6af..34e2e3af9cda 100644 --- a/wifi/tests/AndroidTest.xml +++ b/wifi/tests/AndroidTest.xml @@ -14,7 +14,7 @@ limitations under the License. --> <configuration description="Runs Frameworks Wifi API Tests."> - <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="test-file-name" value="FrameworksWifiApiTests.apk" /> </target_preparer> @@ -25,4 +25,10 @@ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="hidden-api-checks" value="false"/> </test> + + <!-- Only run FrameworksWifiApiTests in MTS if the Wifi Mainline module is installed. --> + <object type="module_controller" + class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController"> + <option name="mainline-module-package-name" value="com.google.android.wifi" /> + </object> </configuration> diff --git a/wifi/tests/README.md b/wifi/tests/README.md index b0594f2d29b1..f90940470432 100644 --- a/wifi/tests/README.md +++ b/wifi/tests/README.md @@ -8,12 +8,9 @@ libraries. The easiest way to run tests is simply run ``` -frameworks/base/wifi/tests/runtests.sh +atest android.net.wifi ``` -`runtests.sh` will build the test project and all of its dependencies and push the APK to the -connected device. It will then run the tests on the device. - To pick up changes in framework/base, you will need to: 1. rebuild the framework library 'make -j32' 2. sync over the updated library to the device 'adb sync' @@ -24,22 +21,6 @@ To enable syncing data to the device for first time after clean reflash: 2. adb reboot 3. adb remount -See below for a few example of options to limit which tests are run. -See the -[AndroidJUnitRunner Documentation](https://developer.android.com/reference/android/support/test/runner/AndroidJUnitRunner.html) -for more details on the supported options. - -``` -runtests.sh -e package android.net.wifi -runtests.sh -e class android.net.wifi.WifiScannerTest -``` - -If you manually build and push the test APK to the device you can run tests using - -``` -adb shell am instrument -w 'android.net.wifi.test/androidx.test.runner.AndroidJUnitRunner' -``` - ## Adding Tests Tests can be added by adding classes to the src directory. JUnit4 style test cases can be written by simply annotating test methods with `org.junit.Test`. diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 index 56919c25de46..760c8395e659 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 @@ -12,75 +12,75 @@ VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1 dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB -OFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklDQWdQQzlPYjJS -bFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrWlJSRTQ4 -TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1MWF6d3ZWbUZz -ZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0Fn -SUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2ClpHVk9ZVzFs -UGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpoYkhWbFBnb2dJ -Q0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4VG05a1pUNEtJ -Q0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVoYldVK0NpQWdJ -Q0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhiRzA4CkwwNXZa -R1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHljbVZrTG1OdmJU -d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lD -QWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThMMDV2WkdWT1lX -MWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0ClpU -NVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDVxWVcx -bGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05 -a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BDOU9iMlJsVG1G -dFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3dlZtRnNkV1Ur -CkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn -SUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0Fn -SUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1GdFpUNUZRVkJV -ZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrTWpFOEwxWmhi -SFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxQ -Z29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2WkR3dlRtOWta -VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0VmpJOEwxWmhi -SFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0Np -QWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BF -NXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD -QWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQa05sY25ScFpt -bGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDU0TlRB -NWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1 -dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1qVTJSbWx1WjJW -eWNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdVKwpNV1l4WmpG +OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1 +dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF +VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0 +Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP +YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0 +VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO +alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ +Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU +bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi +V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH +VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH +VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt +OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH +Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW +bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB +Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05 +a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo +CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn +SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n +SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur +UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ +QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU +bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM +MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ +QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy +UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD +QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn +b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY +SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV +K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB +Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta +cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt -TVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBOEwwNXZaR1Ur -Q2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0Fn -UEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVDRL -SUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJ -Q0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBOEwwNXZa -R1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2WkdWT1lXMWxQ -a1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrTWpROApM -MVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lD -QWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQQzlOWjIxMFZI -SmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1MDktY2Et -Y2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVkSlRpQkRS -VkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxNYkVaa2Qz -cE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlLUWtGTlZF -SXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFxV1hkTlZF -RTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJGZUUxSlNV -Skpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJVVVZCQ25w -dVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldkVzFFWWxs -SWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZSMWhhZGto -M2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRaV1pXYW1v -d2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1FqZzFNVEpR -UWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1IVjVhM1Jr -WW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FFUTRjRkIy -WmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFYQllOREY0 -UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJreGRIRXdO -R3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hkWU5IWnpP -RUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVGR1NYZFlO -SFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJuCldVUldV -VkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJVUWtGVmQw -RjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVCVVVWTVFs -RkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxIUlZBdmRX -OW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpWV00zCmQy -azNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBhWE5rUW5F -eWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdUQW94Y1VK -S2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVWR3c0ZUVW -WFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNFb3hkVlk0 -Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VDdHNlRllL -YlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1RrNTJRMWw2 -YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFWUkZMUzB0 -TFMwSwotLXtib3VuZGFyeX0tLQo= +TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP +YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn +SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2 +WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ +Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ +Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i +MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi +SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww +NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq +d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt +eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS +VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV +bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs +WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr +MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU +QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO +QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO +V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0 +dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG +RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT +UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py +TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz +YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK +YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN +Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT +WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi +VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw +Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq +QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw +NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq +bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk +SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5 +MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx +V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx +dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo +U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL +VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr +VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE +UVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg==
\ No newline at end of file diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf index a44b54222589..5b4e4cb947cd 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf @@ -13,38 +13,38 @@ YTptbzpob3RzcG90MmRvdDAtcGVycHJvdmlkZXJzdWJzY3JpcHRpb246MS4wPC9EREZOYW1lPgog ICAgICA8L1R5cGU+CiAgICA8L1JUUHJvcGVydGllcz4KICAgIDxOb2RlPgogICAgICA8Tm9kZU5h bWU+aTAwMTwvTm9kZU5hbWU+CiAgICAgIDxOb2RlPgogICAgICAgIDxOb2RlTmFtZT5Ib21lU1A8 L05vZGVOYW1lPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPkZyaWVuZGx5TmFt -ZTwvTm9kZU5hbWU+CiAgICAgICAgICA8VmFsdWU+Q2VudHVyeSBIb3VzZTwvVmFsdWU+CiAgICAg -ICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPkZRRE48L05vZGVO -YW1lPgogICAgICAgICAgPFZhbHVlPm1pNi5jby51azwvVmFsdWU+CiAgICAgICAgPC9Ob2RlPgog -ICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlJvYW1pbmdDb25zb3J0aXVtT0k8L05v -ZGVOYW1lPgogICAgICAgICAgPFZhbHVlPjExMjIzMyw0NDU1NjY8L1ZhbHVlPgogICAgICAgIDwv -Tm9kZT4KICAgICAgPC9Ob2RlPgogICAgICA8Tm9kZT4KICAgICAgICA8Tm9kZU5hbWU+Q3JlZGVu -dGlhbDwvTm9kZU5hbWU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+UmVhbG08 -L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPnNoYWtlbi5zdGlycmVkLmNvbTwvVmFsdWU+CiAg -ICAgICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlVzZXJuYW1l -UGFzc3dvcmQ8L05vZGVOYW1lPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFt -ZT5Vc2VybmFtZTwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxWYWx1ZT5qYW1lczwvVmFsdWU+CiAg -ICAgICAgICA8L05vZGU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5vZGVOYW1lPlBh -c3N3b3JkPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZhbHVlPlltOXVaREF3Tnc9PTwvVmFsdWU+ -CiAgICAgICAgICA8L05vZGU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5vZGVOYW1l -PkVBUE1ldGhvZDwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxOb2RlPgogICAgICAgICAgICAgIDxO -b2RlTmFtZT5FQVBUeXBlPC9Ob2RlTmFtZT4KICAgICAgICAgICAgICA8VmFsdWU+MjE8L1ZhbHVl -PgogICAgICAgICAgICA8L05vZGU+CiAgICAgICAgICAgIDxOb2RlPgogICAgICAgICAgICAgIDxO -b2RlTmFtZT5Jbm5lck1ldGhvZDwvTm9kZU5hbWU+CiAgICAgICAgICAgICAgPFZhbHVlPk1TLUNI -QVAtVjI8L1ZhbHVlPgogICAgICAgICAgICA8L05vZGU+CiAgICAgICAgICA8L05vZGU+CiAgICAg -ICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPkRpZ2l0YWxDZXJ0 -aWZpY2F0ZTwvTm9kZU5hbWU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5vZGVOYW1l -PkNlcnRpZmljYXRlVHlwZTwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxWYWx1ZT54NTA5djM8L1Zh +ZTwvTm9kZU5hbWU+CiAgICAgICAgICA8VmFsdWU+RXhhbXBsZSBOZXR3b3JrPC9WYWx1ZT4KICAg +ICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+RlFETjwvTm9k +ZU5hbWU+CiAgICAgICAgICA8VmFsdWU+aG90c3BvdC5leGFtcGxlLm5ldDwvVmFsdWU+CiAgICAg +ICAgPC9Ob2RlPgogICAgICAgIDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlJvYW1pbmdDb25z +b3J0aXVtT0k8L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPjExMjIzMyw0NDU1NjY8L1ZhbHVl +PgogICAgICAgIDwvTm9kZT4KICAgICAgPC9Ob2RlPgogICAgICA8Tm9kZT4KICAgICAgICA8Tm9k +ZU5hbWU+Q3JlZGVudGlhbDwvTm9kZU5hbWU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9k +ZU5hbWU+UmVhbG08L05vZGVOYW1lPgogICAgICAgICAgPFZhbHVlPmV4YW1wbGUuY29tPC9WYWx1 +ZT4KICAgICAgICA8L05vZGU+CiAgICAgICAgPE5vZGU+CiAgICAgICAgICA8Tm9kZU5hbWU+VXNl +cm5hbWVQYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAgPE5v +ZGVOYW1lPlVzZXJuYW1lPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZhbHVlPnVzZXI8L1ZhbHVl +PgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFt +ZT5QYXNzd29yZDwvTm9kZU5hbWU+CiAgICAgICAgICAgIDxWYWx1ZT5jR0Z6YzNkdmNtUT08L1Zh bHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl -TmFtZT5DZXJ0U0hBMjU2RmluZ2VycHJpbnQ8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFsdWU+ -MWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYx -ZjFmMWYxZjwvVmFsdWU+CiAgICAgICAgICA8L05vZGU+CiAgICAgICAgPC9Ob2RlPgogICAgICAg -IDxOb2RlPgogICAgICAgICAgPE5vZGVOYW1lPlNJTTwvTm9kZU5hbWU+CiAgICAgICAgICA8Tm9k -ZT4KICAgICAgICAgICAgPE5vZGVOYW1lPklNU0k8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFs -dWU+aW1zaTwvVmFsdWU+CiAgICAgICAgICA8L05vZGU+CiAgICAgICAgICA8Tm9kZT4KICAgICAg -ICAgICAgPE5vZGVOYW1lPkVBUFR5cGU8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFsdWU+MjQ8 -L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgIDwvTm9kZT4KICAgICAgPC9Ob2RlPgog -ICAgPC9Ob2RlPgogIDwvTm9kZT4KPC9NZ210VHJlZT4K +TmFtZT5FQVBNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg +ICA8Tm9kZU5hbWU+RUFQVHlwZTwvTm9kZU5hbWU+CiAgICAgICAgICAgICAgPFZhbHVlPjIxPC9W +YWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgICA8Tm9kZT4KICAgICAgICAgICAg +ICA8Tm9kZU5hbWU+SW5uZXJNZXRob2Q8L05vZGVOYW1lPgogICAgICAgICAgICAgIDxWYWx1ZT5N +Uy1DSEFQLVYyPC9WYWx1ZT4KICAgICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPC9Ob2RlPgog +ICAgICAgIDwvTm9kZT4KICAgICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5EaWdpdGFs +Q2VydGlmaWNhdGU8L05vZGVOYW1lPgogICAgICAgICAgPE5vZGU+CiAgICAgICAgICAgIDxOb2Rl +TmFtZT5DZXJ0aWZpY2F0ZVR5cGU8L05vZGVOYW1lPgogICAgICAgICAgICA8VmFsdWU+eDUwOXYz +PC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICAgIDxOb2RlPgogICAgICAgICAgICA8 +Tm9kZU5hbWU+Q2VydFNIQTI1NkZpbmdlcnByaW50PC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh +bHVlPjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYxZjFmMWYx +ZjFmMWYxZjFmMWY8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgIDwvTm9kZT4KICAg +ICAgICA8Tm9kZT4KICAgICAgICAgIDxOb2RlTmFtZT5TSU08L05vZGVOYW1lPgogICAgICAgICAg +PE5vZGU+CiAgICAgICAgICAgIDxOb2RlTmFtZT5JTVNJPC9Ob2RlTmFtZT4KICAgICAgICAgICAg +PFZhbHVlPjEyMzQ1Nio8L1ZhbHVlPgogICAgICAgICAgPC9Ob2RlPgogICAgICAgICAgPE5vZGU+ +CiAgICAgICAgICAgIDxOb2RlTmFtZT5FQVBUeXBlPC9Ob2RlTmFtZT4KICAgICAgICAgICAgPFZh +bHVlPjIzPC9WYWx1ZT4KICAgICAgICAgIDwvTm9kZT4KICAgICAgICA8L05vZGU+CiAgICAgIDwv +Tm9kZT4KICAgIDwvTm9kZT4KICA8L05vZGU+CjwvTWdtdFRyZWU+ --{boundary} Content-Type: application/x-x509-ca-cert diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 index 906bfb397464..2775a9f419f9 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithInvalidContentType.base64 @@ -1,85 +1,86 @@ -Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu -dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh -cHBsaWNhdGlvbi9wYXNzcG9pbnQtcHJvZmlsZQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBi -YXNlNjQKClBFMW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lE -eFdaWEpFVkVRK01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJX -VStVR1Z5VUhKdmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BG -SlVVSEp2Y0dWeWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldV -K2RYSnVPbmRtCllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNK -cGNIUnBiMjQ2TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFK -VVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRB -d01Ud3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0 -WlQ1SWIyMWxVMUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0Fn -SUNBZ1BFNXZaR1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0Fn -SUNBZ0lDQThWbUZzZFdVK1EyVnVkSFZ5ZVNCSWIzVnpaVHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0Fn -UEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQ -a1pSUkU0OEwwNXZaR1ZPCllXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbTFwTmk1amJ5NTFh -end2Vm1Gc2RXVStDaUFnSUNBZ0lDQWdQQzlPYjJSbFBnb2cKSUNBZ0lDQWdJRHhPYjJSbFBnb2dJ -Q0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6YjNKMGFYVnRUMGs4TDA1dgpa -R1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFOalk4TDFaaGJI -VmxQZ29nSUNBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBOFRt -OWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUTNKbFpHVnUKZEdsaGJEd3ZUbTlrWlU1aGJX -VStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStVbVZoYkcw -OApMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbk5vWVd0bGJpNXpkR2x5Y21W -a0xtTnZiVHd2Vm1Gc2RXVStDaUFnCklDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJS -bFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbFZ6WlhKdVlXMWwKVUdGemMzZHZjbVE4TDA1 -dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJs -VG1GdApaVDVWYzJWeWJtRnRaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gx -WlQ1cVlXMWxjend2Vm1Gc2RXVStDaUFnCklDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0Fn -SUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsQmgKYzNOM2IzSmtQQzlP -YjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGxsdE9YVmFSRUYzVG5jOVBUd3ZW -bUZzZFdVKwpDaUFnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJ -Q0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsClBrVkJVRTFsZEdodlpEd3ZUbTlrWlU1aGJXVStD -aUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRa -VDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdVK01q -RThMMVpoYkhWbApQZ29nSUNBZ0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lE -eE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhPCmIyUmxUbUZ0WlQ1SmJtNWxjazFsZEdodlpE -d3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGsxVExVTkkKUVZBdFZq -SThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4TDA1 -dlpHVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNB -Z0lDQWdQRTV2WkdWT1lXMWxQa1JwWjJsMFlXeERaWEowCmFXWnBZMkYwWlR3dlRtOWtaVTVoYldV -K0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtO -bGNuUnBabWxqWVhSbFZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gx -WlQ1NE5UQTVkak04TDFaaApiSFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0Fn -SUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVEWlhKMFUwaEJNalUy -Um1sdVoyVnlVSEpwYm5ROEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSsK -TVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1N -V1l4WmpGbU1XWXhaakZtTVdZeApaakZtTVdZeFpqd3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ0lDQThM -MDV2WkdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnCklEeE9iMlJsUGdvZ0lDQWdJ -Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBsTkpUVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFRt -OWsKWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQa2xOVTBrOEwwNXZaR1ZPWVcxbFBn -b2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1GcwpkV1UrYVcxemFUd3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ0lD -QThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnCklDQWdJQ0FnUEU1dlpH -Vk9ZVzFsUGtWQlVGUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV -K01qUTgKTDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHd2VG05 -a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnUEM5T2IyUmxQZ29nSUR3dlRtOWtaVDRLUEM5 -TloyMTBWSEpsWlQ0SwoKLS17Ym91bmRhcnl9CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC14 -NTA5LWNhLWNlcnQKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgpMUzB0TFMxQ1JV -ZEpUaUJEUlZKVVNVWkpRMEZVUlMwdExTMHRDazFKU1VSTFJFTkRRV2hEWjBGM1NVSkJaMGxLUVVs -TWJFWmtkM3BNClZuVnlUVUV3UjBOVGNVZFRTV0l6UkZGRlFrTjNWVUZOUWtsNFJVUkJUMEpuVGxZ -S1FrRk5WRUl3VmtKVlEwSkVVVlJGZDBob1kwNU4KVkZsM1RWUkZlVTFVUlRGTlJFVXhWMmhqVGsx -cVdYZE5WRUUxVFZSRk1VMUVSVEZYYWtGVFRWSkJkd3BFWjFsRVZsRlJSRVYzWkVaUgpWa0ZuVVRC -RmVFMUpTVUpKYWtGT1FtZHJjV2hyYVVjNWR6QkNRVkZGUmtGQlQwTkJVVGhCVFVsSlFrTm5TME5C -VVVWQkNucHVRVkJWCmVqSTJUWE5oWlRSM2N6UXpZM3BTTkRFdlNqSlJkSEpUU1ZwVlMyMVdWWE5X -ZFcxRVlsbEljbEJPZGxSWVMxTk5XRUZqWlhkUFVrUlIKV1ZnS1VuRjJTSFp3YmpoRGMyTkNNU3R2 -UjFoYWRraDNlR28wZWxZd1YwdHZTeko2WlZocllYVXpkbU41YkROSVNVdDFjRXBtY1RKVQpSVUZE -WldaV2Ftb3dkQXBLVnl0WU16VlFSMWR3T1M5SU5YcEpWVTVXVGxacVV6ZFZiWE00TkVsMlMyaFNR -amcxTVRKUVFqbFZlVWhoCloxaFpWbGcxUjFkd1FXTldjSGxtY214U0NrWkpPVkZrYUdnclVHSnJN -SFY1YTNSa1ltWXZRMlJtWjBoUGIyVmljbFIwZDFKc2FrMHcKYjBSMFdDc3lRM1kyYWpCM1FrczNh -RVE0Y0ZCMlpqRXJkWGtLUjNwamVtbG5RVlV2TkV0M04yVmFjWGxrWmpsQ0t6VlNkWEJTSzBsYQph -WEJZTkRGNFJXbEpja3RTZDNGcE5URTNWMWQ2V0dOcVlVY3lZMDVpWmpRMU1RcDRjRWcxVUc1V00y -a3hkSEV3TkdwTlIxRlZla1ozClNVUkJVVUZDYnpSSFFVMUlOSGRJVVZsRVZsSXdUMEpDV1VWR1NY -ZFlOSFp6T0VKcFFtTlRZMjlrQ2pWdWIxcElVazA0UlRRcmFVMUYKU1VkQk1WVmtTWGRSTjAxRWJV -RkdTWGRZTkhaek9FSnBRbU5UWTI5a05XNXZXa2hTVFRoRk5DdHBiMUpoYTBaRVFWTUtUVkpCZDBS -bgpXVVJXVVZGRVJYZGtSbEZXUVdkUk1FVjRaMmRyUVdkMVZWWXpSRTEwVnpaemQwUkJXVVJXVWpC -VVFrRlZkMEYzUlVJdmVrRk1RbWRPClZncElVVGhGUWtGTlEwRlJXWGRFVVZsS1MyOWFTV2gyWTA1 -QlVVVk1RbEZCUkdkblJVSkJSbVpSY1U5VVFUZFNkamRMSzJ4MVVUZHcKYm1Gek5FSlpkMGhGQ2ps -SFJWQXZkVzlvZGpaTFQza3dWRWRSUm1KeVVsUnFSbTlNVms1Q09VSmFNWGx0VFVSYU1DOVVTWGRK -VldNMwpkMmszWVRoME5XMUZjVmxJTVRVemQxY0tZVmR2YjJsVGFubE1UR2gxU1RSelRuSk9RMDkw -YVhOa1FuRXljakpOUmxoME5tZ3diVUZSCldVOVFkamhTT0VzM0wyWm5VM2hIUm5GNmFIbE9iVzFX -VEFveGNVSktiR1I0TXpSVGNIZHpWRUZNVVZaUVlqUm9SM2RLZWxwbWNqRlEKWTNCRlVYZzJlRTF1 -Vkd3NGVFVlhXa1V6VFhNNU9YVmhWWGhpVVhGSmQxSjFDa3huUVU5clRrTnRXVEp0T0RsV2FIcGhT -RW94ZFZZNApOVUZrVFM5MFJDdFpjMjFzYm01cWREbE1Va05sYW1KQ2FYQnFTVWRxVDFoeVp6RktV -Q3RzZUZZS2JYVk5OSFpJSzFBdmJXeHRlSE5RClVIb3daRFkxWWl0RlIyMUtXbkJ2VEd0UEwzUmtU -azUyUTFsNmFrcHdWRVZYY0VWelR6Wk9UV2hMV1c4OUNpMHRMUzB0UlU1RUlFTkYKVWxSSlJrbERR -VlJGTFMwdExTMEsKLS17Ym91bmRhcnl9LS0K +TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5 +PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz +ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9wYXNzcG9pbnQtcHJv +ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF +MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR +K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK +dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW +eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt +CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2 +TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5 +ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr +WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV +MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa +R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW +bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa +R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq +d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH +eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy +UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw +azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ +OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB +Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05 +a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV +K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1 +WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur +Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr +WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP +WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ +blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ +RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta +VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi +SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD +QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD +QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV +RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5 +VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05 +a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1 +dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5 +V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs +UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn +SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n +SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow +YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl +RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ +RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi +bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N +V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X +WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy +UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD +QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH +VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB +Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB +Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS +bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW +bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2 +WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2 +VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1 +MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk +SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN +YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL +UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx +V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG +ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV +VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk +VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS +MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa +V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq +ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I +VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF +UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY +QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr +eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk +WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG +R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu +CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV +UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC +VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI +UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW +V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh +WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU +QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW +R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF +b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD +dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr +NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW +UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
\ No newline at end of file diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 index 3fa97d1cdd76..7023453b3992 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithMissingBoundary.base64 @@ -1,85 +1,86 @@ -Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu -dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh -cHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6 -IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29n -SUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVo -YldVK1VHVnlVSEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0Fn -UEZKVVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhi -V1UrZFhKdU9uZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZ -M0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThM -MUpVVUhKdmNHVnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSth -VEF3TVR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRt -RnRaVDVJYjIxbFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD -QWdJQ0FnSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklD -QWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx -bFBrWlJSRTQ4TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1 -MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdv -Z0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2 -ClpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpo -YkhWbFBnb2dJQ0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4 -VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVo -YldVK0NpQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhi -RzA4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHlj -bVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9i -MlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThM -MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2Iy -UmxUbUZ0ClpUNVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lD -QWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BD -OU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3 -dlZtRnNkV1UrCkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0 -S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldV -K0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1G -dFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1Ur -TWpFOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0Fn -SUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2 -WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0 -VmpJOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThM -MDV2WkdVK0NpQWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJ -Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhi -V1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQ -a05sY25ScFptbGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDU0TlRBNWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1q -VTJSbWx1WjJWeVVISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV -KwpNV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpG -bU1XWXhaakZtTVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNB -OEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNB -Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4 -VG05awpaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFs -UGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0Fn -SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2 -WkdWT1lXMWxQa1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk -V1UrTWpROApMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZU -bTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQ -QzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94 -LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFD -UlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtR -VWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5U -bFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpU -azFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5V -VEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMw -TkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZY -TldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01T -dHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJV -RkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJo -U1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdK -ck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtz -M2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxh -CmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVX -TTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZH -U1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFF -YlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJk -MFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldV -akJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZ -MDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZD -amxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNY -ZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1Ew -OTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JX -MVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVF -MXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhw -aFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpG -S1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNS -a1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmts -RFFWUkZMUzB0TFMwSwo= +TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5 +PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz +ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w +cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK +UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW +RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV +SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj +R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u +ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy +NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH +VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt +OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx +bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1 +dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB +OFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0FnCklDQWdJQ0E4TDA1 +dlpHVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStSbEZF +VGp3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVSthRzkwYzNCdmRDNWxlR0Z0 +Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZwpJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhP +YjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERiMjV6CmIzSjBhWFZ0 +VDBrOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhNakl6TXl3ME5EVTFO +alk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ +Q0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldVK1EzSmxaR1Z1ZEdsaGJEd3ZU +bTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrClpVNWhi +V1UrVW1WaGJHMDhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbVY0WVcxd2JH +VXVZMjl0UEM5V1lXeDEKWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpH +VStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObApjbTVoYldWUVlYTnpkMjl5WkR3dlRt +OWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2ClpH +Vk9ZVzFsUGxWelpYSnVZVzFsUEM5T2IyUmxUbUZ0WlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhW +bFBuVnpaWEk4TDFaaGJIVmwKUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNB +Z1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdApaVDVRWVhOemQyOXlaRHd2VG05 +a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5rZG1OdFVUMDhMMVpo +CmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFn +SUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNUZRVkJOWlhSb2IyUThMMDV2WkdWT1lXMWxQZ29n +SUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZwpJQ0E4VG05a1pVNWhiV1Ur +UlVGUVZIbHdaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqSXhQ +QzlXCllXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThU +bTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1NXNXVaWEpOWlhSb2IyUThM +MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TgpVeTFEU0VGUUxWWXlQ +QzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy +UmxQZ29nCklDQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD +QWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnMKUTJWeWRHbG1hV05oZEdVOEwwNXZaR1ZPWVcxbFBn +b2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbApUbUZ0WlQ1RFpY +SjBhV1pwWTJGMFpWUjVjR1U4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV +K2VEVXdPWFl6ClBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNB +Z0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQTgKVG05a1pVNWhiV1UrUTJWeWRGTklRVEkxTmta +cGJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApiSFZsUGpG +bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt +TVdZeFpqRm1NV1l4ClpqRm1NV1l4WmpGbU1XWThMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlP +YjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWcKSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn +SUNBZ0lEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZwpQRTV2 +WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVKVFZOSlBDOU9iMlJsVG1GdFpUNEtJ +Q0FnSUNBZ0lDQWdJQ0FnClBGWmhiSFZsUGpFeU16UTFOaW84TDFaaGJIVmxQZ29nSUNBZ0lDQWdJ +Q0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9i +MlJsVG1GdFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaApi +SFZsUGpJelBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEww +NXZaR1UrQ2lBZ0lDQWdJRHd2ClRtOWtaVDRLSUNBZ0lEd3ZUbTlrWlQ0S0lDQThMMDV2WkdVK0Nq +d3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL3gt +eDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKTFMwdExTMUNS +VWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFowRjNTVUpCWjBsS1FV +bE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFrbDRSVVJCVDBKblRs +WUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJURk5SRVV4VjJoalRr +MXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVWM1pFWlIKVmtGblVU +QkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRoQlRVbEpRa05uUzBO +QlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhKVFNWcFZTMjFXVlhO +V2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0had2JqaERjMk5DTVN0 +dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQxY0VwbWNUSlUKUlVG +RFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRWYlhNNE5FbDJTMmhT +UWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pKT1ZGa2FHZ3JVR0py +TUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5UTNZMmFqQjNRa3Mz +YUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENLelZTZFhCU0swbGEK +YVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFNUXA0Y0VnMVVHNVdN +Mmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVWbEl3VDBKQ1dVVkdT +WGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJNVlZrU1hkUk4wMUVi +VUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEwWkVRVk1LVFZKQmQw +Um4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6WnpkMFJCV1VSV1Vq +QlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVWbEtTMjlhU1doMlkw +NUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJtRnpORUpaZDBoRkNq +bEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhsdFRVUmFNQzlVU1hk +SlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdoMVNUUnpUbkpPUTA5 +MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNoSFJuRjZhSGxPYlcx +V1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZRClkzQkZVWGcyZUUx +dVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050V1RKdE9EbFdhSHBo +U0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJxU1VkcVQxaHlaekZL +VUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFLV25CdlRHdFBMM1Jr +VGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJRU5GClVsUkpSa2xE +UVZSRkxTMHRMUzBLCg==
\ No newline at end of file diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 index 975f8e539cc3..5c23f61b1711 100644 --- a/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithNonBase64Part.base64 @@ -1,85 +1,86 @@ -Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu -dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTMyCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh -cHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6 -IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29n -SUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVo -YldVK1VHVnlVSEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0Fn -UEZKVVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhi -V1UrZFhKdU9uZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZ -M0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThM -MUpVVUhKdmNHVnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSth -VEF3TVR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRt -RnRaVDVJYjIxbFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD -QWdJQ0FnSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklD -QWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx -bFBrWlJSRTQ4TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1 -MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdv -Z0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2 -ClpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpo -YkhWbFBnb2dJQ0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4 -VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVo -YldVK0NpQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhi -RzA4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHlj -bVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9i -MlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThM -MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2Iy -UmxUbUZ0ClpUNVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lD -QWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BD -OU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3 -dlZtRnNkV1UrCkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0 -S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldV -K0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1G -dFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1Ur -TWpFOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0Fn -SUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2 -WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0 -VmpJOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThM -MDV2WkdVK0NpQWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJ -Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhi -V1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQ -a05sY25ScFptbGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDU0TlRBNWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1q -VTJSbWx1WjJWeVVISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV -KwpNV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpG -bU1XWXhaakZtTVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNB -OEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNB -Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4 -VG05awpaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFs -UGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0Fn -SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2 -WkdWT1lXMWxQa1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk -V1UrTWpROApMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZU -bTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQ -QzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94 -LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFD -UlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtR -VWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5U -bFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpU -azFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5V -VEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMw -TkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZY -TldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01T -dHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJV -RkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJo -U1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdK -ck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtz -M2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxh -CmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVX -TTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZH -U1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFF -YlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJk -MFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldV -akJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZ -MDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZD -amxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNY -ZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1Ew -OTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JX -MVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVF -MXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhw -aFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpG -S1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNS -a1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmts -RFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo= +TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5 +PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogOGJp +dAoKLS17Ym91bmRhcnl9CkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24veC1wYXNzcG9pbnQtcHJv +ZmlsZTsgY2hhcnNldD1VVEYtOApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKClBF +MW5iWFJVY21WbElIaHRiRzV6UFNKemVXNWpiV3c2Wkcxa1pHWXhMaklpUGdvZ0lEeFdaWEpFVkVR +K01TNHlQQzlXWlhKRVZFUSsKQ2lBZ1BFNXZaR1UrQ2lBZ0lDQThUbTlrWlU1aGJXVStVR1Z5VUhK +dmRtbGtaWEpUZFdKelkzSnBjSFJwYjI0OEwwNXZaR1ZPWVcxbApQZ29nSUNBZ1BGSlVVSEp2Y0dW +eWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRt +CllUcHRienBvYjNSemNHOTBNbVJ2ZERBdGNHVnljSEp2ZG1sa1pYSnpkV0p6WTNKcGNIUnBiMjQ2 +TVM0d1BDOUVSRVpPWVcxbFBnb2cKSUNBZ0lDQThMMVI1Y0dVK0NpQWdJQ0E4TDFKVVVISnZjR1Z5 +ZEdsbGN6NEtJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQThUbTlrWlU1aApiV1UrYVRBd01Ud3ZUbTlr +WlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxV +MUE4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZa +R1ZPWVcxbFBrWnlhV1Z1Wkd4NVRtRnQKWlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThW +bUZzZFdVK1JYaGhiWEJzWlNCT1pYUjNiM0pyUEM5V1lXeDFaVDRLSUNBZwpJQ0FnSUNBOEwwNXZa +R1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUmxGRVRq +d3ZUbTlrClpVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrYUc5MGMzQnZkQzVsZUdGdGNH +eGxMbTVsZER3dlZtRnNkV1UrQ2lBZ0lDQWcKSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2Iy +UmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxKdllXMXBibWREYjI1egpiM0owYVhWdFQw +azhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV4TWpJek15dzBORFUxTmpZ +OEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNB +Z0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWsKWlU1aGJXVStRM0psWkdWdWRHbGhiRHd2VG05 +a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVTVoYldV +K1VtVmhiRzA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUG1WNFlXMXdiR1V1 +WTI5dFBDOVdZV3gxClpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1Ur +Q2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1ZYTmwKY201aGJXVlFZWE56ZDI5eVpEd3ZUbTlr +WlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dgpaR1ZP +WVcxbFBsVnpaWEp1WVcxbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQ +blZ6WlhJOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQ +RTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnQKWlQ1UVlYTnpkMjl5WkR3dlRtOWta +VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNWpSMFo2WXpOa2RtTnRVVDA4TDFaaApi +SFZsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lD +QWdJQ0FnSUNBZ0lEeE9iMlJsClRtRnRaVDVGUVZCTlpYUm9iMlE4TDA1dlpHVk9ZVzFsUGdvZ0lD +QWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWcKSUNBOFRtOWtaVTVoYldVK1JV +RlFWSGx3WlR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakl4UEM5 +VwpZV3gxWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05 +a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnCklDQThUbTlrWlU1aGJXVStTVzV1WlhKTlpYUm9iMlE4TDA1 +dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNU4KVXkxRFNFRlFMVll5UEM5 +V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BDOU9iMlJs +UGdvZwpJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0Fn +SUR4T2IyUmxUbUZ0WlQ1RWFXZHBkR0ZzClEyVnlkR2xtYVdOaGRHVThMMDV2WkdWT1lXMWxQZ29n +SUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEow +YVdacFkyRjBaVlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStl +RFV3T1hZegpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJ +RHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4ClRtOWtaVTVoYldVK1EyVnlkRk5JUVRJMU5rWnBi +bWRsY25CeWFXNTBQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhWbFBqRm1N +V1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1X +WXhaakZtTVdZeApaakZtTVdZeFpqRm1NV1k4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2Iy +UmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lD +QWdJRHhPYjJSbFRtRnRaVDVUU1UwOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWcKUEU1dlpH +VStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SlRWTkpQQzlPYjJSbFRtRnRaVDRLSUNB +Z0lDQWdJQ0FnSUNBZwpQRlpoYkhWbFBqRXlNelExTmlvOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNB +Z1BDOU9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1UrCkNpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS +bFRtRnRaVDVGUVZCVWVYQmxQQzlPYjJSbFRtRnRaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BGWmgKYkhW +bFBqSXpQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQThMMDV2 +WkdVK0NpQWdJQ0FnSUR3dgpUbTlrWlQ0S0lDQWdJRHd2VG05a1pUNEtJQ0E4TDA1dlpHVStDand2 +VFdkdGRGUnlaV1UrCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1 +MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVk +SlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxN +YkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlL +UWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFx +V1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJG +ZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJV +VVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldk +VzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZS +MWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRa +V1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1Fq +ZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1I +VjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FF +UTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFY +QllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJr +eGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hk +WU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVG +R1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJu +CldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJV +UWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVC +VVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxI +UlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpW +V00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBh +WE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdU +QW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVW +R3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNF +b3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VD +dHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1Rr +NTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFW +UkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
\ No newline at end of file diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 new file mode 100644 index 000000000000..bab7607512c8 --- /dev/null +++ b/wifi/tests/assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64 @@ -0,0 +1,88 @@ +TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5 +PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz +ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w +cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK +UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW +RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV +SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj +R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u +ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy +NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH +VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVStWWEJrWVhSbFNX +UmxiblJwWm1sbGNqd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lEeFdZV3gxWlQ0eE1qTTBQQzlXWVd4 +MVpUNEsKSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoYldV +K2FUQXdNVHd2VG05a1pVNWhiV1UrQ2lBZwpJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJS +bFRtRnRaVDVJYjIxbFUxQThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJRHhPCmIyUmxQZ29nSUNB +Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdFpUd3ZUbTlrWlU1aGJXVStDaUFn +SUNBZ0lDQWcKSUNBOFZtRnNkV1UrUlhoaGJYQnNaU0JPWlhSM2IzSnJQQzlXWVd4MVpUNEtJQ0Fn +SUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZwpQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlr +WlU1aGJXVStSbEZFVGp3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthRzkw +YzNCdmRDNWxlR0Z0Y0d4bExtNWxkRHd2Vm1Gc2RXVStDaUFnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJ +Q0FnSUNBZ0lEeE8KYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEp2WVcxcGJtZERi +MjV6YjNKMGFYVnRUMGs4TDA1dlpHVk9ZVzFsUGdvZwpJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBqRXhN +akl6TXl3ME5EVTFOalk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnCklDQWdQ +QzlPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrUTNKbFpH +VnVkR2xoYkR3dlRtOWsKWlU1aGJXVStDaUFnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lD +QThUbTlrWlU1aGJXVStVbVZoYkcwOEwwNXZaR1ZPWVcxbApQZ29nSUNBZ0lDQWdJQ0FnUEZaaGJI +VmxQbVY0WVcxd2JHVXVZMjl0UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnCklD +QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVlhObGNtNWhiV1ZRWVhO +emQyOXlaRHd2VG05a1pVNWgKYldVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNB +Z0lDQWdQRTV2WkdWT1lXMWxQbFZ6WlhKdVlXMWxQQzlPYjJSbApUbUZ0WlQ0S0lDQWdJQ0FnSUNB +Z0lDQWdQRlpoYkhWbFBuVnpaWEk4TDFaaGJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29n +CklDQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE9iMlJsVG1GdFpUNVFZWE56 +ZDI5eVpEd3ZUbTlrWlU1aGJXVSsKQ2lBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1alIwWjZZek5r +ZG1OdFVUMDhMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbApQZ29nSUNBZ0lDQWdJQ0Fn +UEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1RlFWQk5aWFJvYjJROEwwNXZa +R1ZPCllXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQThU +bTlrWlU1aGJXVStSVUZRVkhsd1pUd3YKVG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdQ +RlpoYkhWbFBqSXhQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEM5TwpiMlJsUGdvZ0lDQWdJ +Q0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrU1c1dVpY +Sk5aWFJvCmIyUThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeFdZV3gxWlQ1TlV5 +MURTRUZRTFZZeVBDOVdZV3gxWlQ0S0lDQWcKSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD +QWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZwpJQ0E4VG05a1pU +NEtJQ0FnSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVFYVdkcGRHRnNRMlZ5ZEdsbWFXTmhkR1U4TDA1 +dlpHVk9ZVzFsClBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJS +bFRtRnRaVDVEWlhKMGFXWnBZMkYwWlZSNWNHVTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNB +Z0lDQThWbUZzZFdVK2VEVXdPWFl6UEM5V1lXeDFaVDRLSUNBZ0lDQWdJQ0FnSUR3dgpUbTlrWlQ0 +S0lDQWdJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRMlZ5 +ZEZOSVFUSTFOa1pwCmJtZGxjbkJ5YVc1MFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0Fn +UEZaaGJIVmxQakZtTVdZeFpqRm1NV1l4WmpGbU1XWXgKWmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4 +WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZOEwxWmhiSFZsUGdvZwpJQ0Fn +SUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOFRtOWta +VDRLSUNBZ0lDQWdJQ0FnCklEeE9iMlJsVG1GdFpUNVRTVTA4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJ +Q0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKVFZOSlBDOU9i +MlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQakV5TXpRMU5pbzhMMVpoYkhWbApQ +Z29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lD +QWdJQ0FnSUR4T2IyUmxUbUZ0ClpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lD +QWdJQ0FnUEZaaGJIVmxQakl6UEM5V1lXeDFaVDRLSUNBZ0lDQWcKSUNBZ0lEd3ZUbTlrWlQ0S0lD +QWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUR3dlRtOWtaVDRLSUNB +OApMMDV2WkdVK0Nqd3ZUV2R0ZEZSeVpXVSsKCi0te2JvdW5kYXJ5fQpDb250ZW50LVR5cGU6IGFw +cGxpY2F0aW9uL3gteDUwOS1jYS1jZXJ0CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2 +NAoKTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUkxSRU5EUVdoRFow +RjNTVUpCWjBsS1FVbE1iRVprZDNwTQpWblZ5VFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlFr +bDRSVVJCVDBKblRsWUtRa0ZOVkVJd1ZrSlZRMEpFVVZSRmQwaG9ZMDVOClZGbDNUVlJGZVUxVVJU +Rk5SRVV4VjJoalRrMXFXWGROVkVFMVRWUkZNVTFFUlRGWGFrRlRUVkpCZHdwRVoxbEVWbEZSUkVW +M1pFWlIKVmtGblVUQkZlRTFKU1VKSmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CVVRo +QlRVbEpRa05uUzBOQlVVVkJDbnB1UVZCVgplakkyVFhOaFpUUjNjelF6WTNwU05ERXZTakpSZEhK +VFNWcFZTMjFXVlhOV2RXMUVZbGxJY2xCT2RsUllTMU5OV0VGalpYZFBVa1JSCldWZ0tVbkYyU0ha +d2JqaERjMk5DTVN0dlIxaGFka2gzZUdvMGVsWXdWMHR2U3pKNlpWaHJZWFV6ZG1ONWJETklTVXQx +Y0VwbWNUSlUKUlVGRFpXWldhbW93ZEFwS1Z5dFlNelZRUjFkd09TOUlOWHBKVlU1V1RsWnFVemRW +YlhNNE5FbDJTMmhTUWpnMU1USlFRamxWZVVoaApaMWhaVmxnMVIxZHdRV05XY0hsbWNteFNDa1pK +T1ZGa2FHZ3JVR0pyTUhWNWEzUmtZbVl2UTJSbVowaFBiMlZpY2xSMGQxSnNhazB3CmIwUjBXQ3N5 +UTNZMmFqQjNRa3MzYUVRNGNGQjJaakVyZFhrS1IzcGplbWxuUVZVdk5FdDNOMlZhY1hsa1pqbENL +elZTZFhCU0swbGEKYVhCWU5ERjRSV2xKY2t0U2QzRnBOVEUzVjFkNldHTnFZVWN5WTA1aVpqUTFN +UXA0Y0VnMVVHNVdNMmt4ZEhFd05HcE5SMUZWZWtaMwpTVVJCVVVGQ2J6UkhRVTFJTkhkSVVWbEVW +bEl3VDBKQ1dVVkdTWGRZTkhaek9FSnBRbU5UWTI5a0NqVnViMXBJVWswNFJUUXJhVTFGClNVZEJN +VlZrU1hkUk4wMUViVUZHU1hkWU5IWnpPRUpwUW1OVFkyOWtOVzV2V2toU1RUaEZOQ3RwYjFKaGEw +WkVRVk1LVFZKQmQwUm4KV1VSV1VWRkVSWGRrUmxGV1FXZFJNRVY0WjJkclFXZDFWVll6UkUxMFZ6 +WnpkMFJCV1VSV1VqQlVRa0ZWZDBGM1JVSXZla0ZNUW1kTwpWZ3BJVVRoRlFrRk5RMEZSV1hkRVVW +bEtTMjlhU1doMlkwNUJVVVZNUWxGQlJHZG5SVUpCUm1aUmNVOVVRVGRTZGpkTEsyeDFVVGR3CmJt +RnpORUpaZDBoRkNqbEhSVkF2ZFc5b2RqWkxUM2t3VkVkUlJtSnlVbFJxUm05TVZrNUNPVUphTVhs +dFRVUmFNQzlVU1hkSlZXTTMKZDJrM1lUaDBOVzFGY1ZsSU1UVXpkMWNLWVZkdmIybFRhbmxNVEdo +MVNUUnpUbkpPUTA5MGFYTmtRbkV5Y2pKTlJsaDBObWd3YlVGUgpXVTlRZGpoU09FczNMMlpuVTNo +SFJuRjZhSGxPYlcxV1RBb3hjVUpLYkdSNE16UlRjSGR6VkVGTVVWWlFZalJvUjNkS2VscG1jakZR +ClkzQkZVWGcyZUUxdVZHdzRlRVZYV2tVelRYTTVPWFZoVlhoaVVYRkpkMUoxQ2t4blFVOXJUa050 +V1RKdE9EbFdhSHBoU0VveGRWWTQKTlVGa1RTOTBSQ3RaYzIxc2JtNXFkRGxNVWtObGFtSkNhWEJx +U1VkcVQxaHlaekZLVUN0c2VGWUtiWFZOTkhaSUsxQXZiV3h0ZUhOUQpVSG93WkRZMVlpdEZSMjFL +V25CdlRHdFBMM1JrVGs1MlExbDZha3B3VkVWWGNFVnpUelpPVFdoTFdXODlDaTB0TFMwdFJVNUVJ +RU5GClVsUkpSa2xEUVZSRkxTMHRMUzBLCi0te2JvdW5kYXJ5fS0tCg==
\ No newline at end of file diff --git a/wifi/tests/assets/hsr1/README.txt b/wifi/tests/assets/hsr1/README.txt index d1f8384fc979..9f3cdc274ee1 100644 --- a/wifi/tests/assets/hsr1/README.txt +++ b/wifi/tests/assets/hsr1/README.txt @@ -2,4 +2,5 @@ HSR1ProfileWithCACert.conf - unencoded installation file that contains a Passpoi HSR1ProfileWithCACert.base64 - base64 encoded of the data contained in HSR1ProfileWithCAWith.conf HSR1ProfileWithNonBase64Part.base64 - base64 encoded installation file that contains a part of non-base64 encoding type HSR1ProfileWithMissingBoundary.base64 - base64 encoded installation file with missing end-boundary in the MIME data -HSR1ProfileWithInvalidContentType.base64 - base64 encoded installation file with that contains a MIME part with an invalid content type. +HSR1ProfileWithInvalidContentType.base64 - base64 encoded installation file with that contains a MIME part with an invalid content type +HSR1ProfileWithUpdateIdentifier.base64 - base64 encoded installation file with that contains an R2 update identifier diff --git a/wifi/tests/assets/pps/PerProviderSubscription.xml b/wifi/tests/assets/pps/PerProviderSubscription.xml index e4472ce19d51..e9afb35fec94 100644 --- a/wifi/tests/assets/pps/PerProviderSubscription.xml +++ b/wifi/tests/assets/pps/PerProviderSubscription.xml @@ -19,6 +19,30 @@ <NodeName>VendorSpecific</NodeName> <Value>Test</Value> </Node> + <Node> + <NodeName>VendorExtension</NodeName> + <Node> + <NodeName>VendorAttribute</NodeName> + <Value>VendorValue</Value> + </Node> + </Node> + <Node> + <NodeName>Android</NodeName> + <Node> + <NodeName>AAAServerTrustedNames</NodeName> + <Node> + <NodeName>FQDN</NodeName> + <Value>trusted.fqdn.com;another-trusted.fqdn.com</Value> + </Node> + </Node> + <Node> + <NodeName>NewSubTree</NodeName> + <Node> + <NodeName>NewAttribute</NodeName> + <Value>NewValue</Value> + </Node> + </Node> + </Node> </Node> <Node> <NodeName>HomeSP</NodeName> diff --git a/wifi/tests/runtests.sh b/wifi/tests/runtests.sh deleted file mode 100755 index 219a45ee188f..000000000000 --- a/wifi/tests/runtests.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -if [ -z $ANDROID_BUILD_TOP ]; then - echo "You need to source and lunch before you can use this script" - exit 1 -fi - -echo "Running tests" - -set -e # fail early - -echo "+ mmma -j32 $ANDROID_BUILD_TOP/frameworks/base/wifi/tests" -# NOTE Don't actually run the command above since this shell doesn't inherit functions from the -# caller. -make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk MODULES-IN-frameworks-base-wifi-tests - -set -x # print commands - -adb root -adb wait-for-device - -TARGET_ARCH=$($ANDROID_BUILD_TOP/build/soong/soong_ui.bash --dumpvar-mode TARGET_ARCH) -adb install -r -g "$OUT/testcases/FrameworksWifiApiTests/$TARGET_ARCH/FrameworksWifiApiTests.apk" - -adb shell am instrument --no-hidden-api-checks -w "$@" \ - 'android.net.wifi.test/androidx.test.runner.AndroidJUnitRunner' diff --git a/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java b/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java new file mode 100644 index 000000000000..b10141434b0b --- /dev/null +++ b/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.util.SparseArray; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.EasyConnectStatusCallbackTest}. + */ +@SmallTest +public class EasyConnectStatusCallbackTest { + private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() { + @Override + public void onEnrolleeSuccess(int newNetworkId) { + + } + + @Override + public void onConfiguratorSuccess(int code) { + + } + + @Override + public void onProgress(int code) { + + } + + @Override + public void onFailure(int code) { + mOnFailureR1EventReceived = true; + mLastCode = code; + } + }; + private boolean mOnFailureR1EventReceived; + private int mLastCode; + + @Before + public void setUp() { + mOnFailureR1EventReceived = false; + mLastCode = 0; + } + + /** + * Test that the legacy R1 onFailure is called by default if the R2 onFailure is not overridden + * by the app. + */ + @Test + public void testR1OnFailureCalled() { + + SparseArray<int[]> channelList = new SparseArray<>(); + int[] channelArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + + channelList.append(81, channelArray); + mEasyConnectStatusCallback.onFailure( + EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK, + "SomeSSID", channelList, new int[] {81}); + + assertTrue(mOnFailureR1EventReceived); + assertEquals(mLastCode, + EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK); + } +} diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java index 54ec32502878..5516f433070f 100644 --- a/wifi/tests/src/android/net/wifi/ScanResultTest.java +++ b/wifi/tests/src/android/net/wifi/ScanResultTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.validateMockitoUsage; +import android.net.wifi.ScanResult.InformationElement; import android.os.Parcel; import androidx.test.filters.SmallTest; @@ -41,6 +42,70 @@ public class ScanResultTest { public static final int TEST_LEVEL = -56; public static final int TEST_FREQUENCY = 2412; public static final long TEST_TSF = 04660l; + public static final @WifiAnnotations.WifiStandard int TEST_WIFI_STANDARD = + ScanResult.WIFI_STANDARD_11AC; + + /** + * Frequency to channel map. This include some frequencies used outside the US. + * Representing it using a vector (instead of map) for simplification. + */ + private static final int[] FREQUENCY_TO_CHANNEL_MAP = { + 2412, WifiScanner.WIFI_BAND_24_GHZ, 1, + 2417, WifiScanner.WIFI_BAND_24_GHZ, 2, + 2422, WifiScanner.WIFI_BAND_24_GHZ, 3, + 2427, WifiScanner.WIFI_BAND_24_GHZ, 4, + 2432, WifiScanner.WIFI_BAND_24_GHZ, 5, + 2437, WifiScanner.WIFI_BAND_24_GHZ, 6, + 2442, WifiScanner.WIFI_BAND_24_GHZ, 7, + 2447, WifiScanner.WIFI_BAND_24_GHZ, 8, + 2452, WifiScanner.WIFI_BAND_24_GHZ, 9, + 2457, WifiScanner.WIFI_BAND_24_GHZ, 10, + 2462, WifiScanner.WIFI_BAND_24_GHZ, 11, + /* 12, 13 are only legitimate outside the US. */ + 2467, WifiScanner.WIFI_BAND_24_GHZ, 12, + 2472, WifiScanner.WIFI_BAND_24_GHZ, 13, + /* 14 is for Japan, DSSS and CCK only. */ + 2484, WifiScanner.WIFI_BAND_24_GHZ, 14, + /* 34 valid in Japan. */ + 5170, WifiScanner.WIFI_BAND_5_GHZ, 34, + 5180, WifiScanner.WIFI_BAND_5_GHZ, 36, + 5190, WifiScanner.WIFI_BAND_5_GHZ, 38, + 5200, WifiScanner.WIFI_BAND_5_GHZ, 40, + 5210, WifiScanner.WIFI_BAND_5_GHZ, 42, + 5220, WifiScanner.WIFI_BAND_5_GHZ, 44, + 5230, WifiScanner.WIFI_BAND_5_GHZ, 46, + 5240, WifiScanner.WIFI_BAND_5_GHZ, 48, + 5260, WifiScanner.WIFI_BAND_5_GHZ, 52, + 5280, WifiScanner.WIFI_BAND_5_GHZ, 56, + 5300, WifiScanner.WIFI_BAND_5_GHZ, 60, + 5320, WifiScanner.WIFI_BAND_5_GHZ, 64, + 5500, WifiScanner.WIFI_BAND_5_GHZ, 100, + 5520, WifiScanner.WIFI_BAND_5_GHZ, 104, + 5540, WifiScanner.WIFI_BAND_5_GHZ, 108, + 5560, WifiScanner.WIFI_BAND_5_GHZ, 112, + 5580, WifiScanner.WIFI_BAND_5_GHZ, 116, + /* 120, 124, 128 valid in Europe/Japan. */ + 5600, WifiScanner.WIFI_BAND_5_GHZ, 120, + 5620, WifiScanner.WIFI_BAND_5_GHZ, 124, + 5640, WifiScanner.WIFI_BAND_5_GHZ, 128, + /* 132+ valid in US. */ + 5660, WifiScanner.WIFI_BAND_5_GHZ, 132, + 5680, WifiScanner.WIFI_BAND_5_GHZ, 136, + 5700, WifiScanner.WIFI_BAND_5_GHZ, 140, + /* 144 is supported by a subset of WiFi chips. */ + 5720, WifiScanner.WIFI_BAND_5_GHZ, 144, + 5745, WifiScanner.WIFI_BAND_5_GHZ, 149, + 5765, WifiScanner.WIFI_BAND_5_GHZ, 153, + 5785, WifiScanner.WIFI_BAND_5_GHZ, 157, + 5805, WifiScanner.WIFI_BAND_5_GHZ, 161, + 5825, WifiScanner.WIFI_BAND_5_GHZ, 165, + 5845, WifiScanner.WIFI_BAND_5_GHZ, 169, + 5865, WifiScanner.WIFI_BAND_5_GHZ, 173, + /* Now some 6GHz channels */ + 5945, WifiScanner.WIFI_BAND_6_GHZ, 1, + 5960, WifiScanner.WIFI_BAND_6_GHZ, 4, + 6100, WifiScanner.WIFI_BAND_6_GHZ, 32 + }; /** * Setup before tests. @@ -124,17 +189,37 @@ public class ScanResultTest { } /** + * Verify parcel read/write for ScanResult with Information Element + */ + @Test + public void verifyScanResultParcelWithInformationElement() throws Exception { + ScanResult writeScanResult = createScanResult(); + writeScanResult.informationElements = new ScanResult.InformationElement[2]; + writeScanResult.informationElements[0] = new ScanResult.InformationElement(); + writeScanResult.informationElements[0].id = InformationElement.EID_HT_OPERATION; + writeScanResult.informationElements[0].idExt = 0; + writeScanResult.informationElements[0].bytes = new byte[]{0x11, 0x22, 0x33}; + writeScanResult.informationElements[1] = new ScanResult.InformationElement(); + writeScanResult.informationElements[1].id = InformationElement.EID_EXTENSION_PRESENT; + writeScanResult.informationElements[1].idExt = InformationElement.EID_EXT_HE_OPERATION; + writeScanResult.informationElements[1].bytes = new byte[]{0x44, 0x55, 0x66}; + ScanResult readScanResult = new ScanResult(writeScanResult); + assertScanResultEquals(writeScanResult, readScanResult); + } + + /** * Verify toString for ScanResult. */ @Test public void verifyScanResultToStringWithoutRadioChainInfo() throws Exception { ScanResult scanResult = createScanResult(); - assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " + - "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), distanceSd: 0(cm), " + - "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " + - "80211mcResponder: is not supported, Carrier AP: no, " + - "Carrier AP EAP Type: 0, Carrier name: null, " + - "Radio Chain Infos: null", scanResult.toString()); + assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " + + "level: -56, frequency: 2412, timestamp: 2480, " + + "distance: 0(cm), distanceSd: 0(cm), " + + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " + + "standard: 11ac, " + + "80211mcResponder: is not supported, " + + "Radio Chain Infos: null", scanResult.toString()); } /** @@ -150,13 +235,33 @@ public class ScanResultTest { scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo(); scanResult.radioChainInfos[1].id = 1; scanResult.radioChainInfos[1].level = -54; - assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " + - "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), distanceSd: 0(cm), " + - "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " + - "80211mcResponder: is not supported, Carrier AP: no, " + - "Carrier AP EAP Type: 0, Carrier name: null, " + - "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, " + - "RadioChainInfo: id=1, level=-54]", scanResult.toString()); + assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " + + "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), " + + "distanceSd: 0(cm), " + + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " + + "standard: 11ac, " + + "80211mcResponder: is not supported, " + + "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, " + + "RadioChainInfo: id=1, level=-54]", scanResult.toString()); + } + + /** + * verify frequency to channel conversion for all possible frequencies. + */ + @Test + public void convertFrequencyToChannel() throws Exception { + for (int i = 0; i < FREQUENCY_TO_CHANNEL_MAP.length; i += 3) { + assertEquals(FREQUENCY_TO_CHANNEL_MAP[i + 2], + ScanResult.convertFrequencyMhzToChannel(FREQUENCY_TO_CHANNEL_MAP[i])); + } + } + + /** + * Verify frequency to channel conversion failed for an invalid frequency. + */ + @Test + public void convertFrequencyToChannelWithInvalidFreq() throws Exception { + assertEquals(-1, ScanResult.convertFrequencyMhzToChannel(8000)); } /** @@ -177,6 +282,7 @@ public class ScanResultTest { result.level = TEST_LEVEL; result.frequency = TEST_FREQUENCY; result.timestamp = TEST_TSF; + result.setWifiStandard(TEST_WIFI_STANDARD); return result; } @@ -187,6 +293,8 @@ public class ScanResultTest { assertEquals(expected.level, actual.level); assertEquals(expected.frequency, actual.frequency); assertEquals(expected.timestamp, actual.timestamp); + assertEquals(expected.getWifiStandard(), actual.getWifiStandard()); assertArrayEquals(expected.radioChainInfos, actual.radioChainInfos); + assertArrayEquals(expected.informationElements, actual.informationElements); } } diff --git a/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java new file mode 100644 index 000000000000..73b501a4d8f2 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/SoftApCapabilityTest.java @@ -0,0 +1,73 @@ +/* + * 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 android.net.wifi; + +import android.os.Parcel; + +import static org.junit.Assert.assertEquals; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.SoftApCapability}. + */ +@SmallTest +public class SoftApCapabilityTest { + + /** + * Verifies copy constructor. + */ + @Test + public void testCopyOperator() throws Exception { + long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; + SoftApCapability capability = new SoftApCapability(testSoftApFeature); + capability.setMaxSupportedClients(10); + + SoftApCapability copiedCapability = new SoftApCapability(capability); + + assertEquals(capability, copiedCapability); + assertEquals(capability.hashCode(), copiedCapability.hashCode()); + } + + /** + * Verifies parcel serialization/deserialization. + */ + @Test + public void testParcelOperation() throws Exception { + long testSoftApFeature = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; + SoftApCapability capability = new SoftApCapability(testSoftApFeature); + capability.setMaxSupportedClients(10); + + Parcel parcelW = Parcel.obtain(); + capability.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + SoftApCapability fromParcel = SoftApCapability.CREATOR.createFromParcel(parcelR); + + assertEquals(capability, fromParcel); + assertEquals(capability.hashCode(), fromParcel.hashCode()); + } + +} diff --git a/wifi/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java b/wifi/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java new file mode 100644 index 000000000000..f49f387cbc6b --- /dev/null +++ b/wifi/tests/src/android/net/wifi/SoftApConfToXmlMigrationUtilTest.java @@ -0,0 +1,199 @@ +/* + * 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 android.net.wifi; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Unit tests for {@link android.net.wifi.SoftApConfToXmlMigrationUtilTest}. + */ +@SmallTest +public class SoftApConfToXmlMigrationUtilTest { + private static final String TEST_SSID = "SSID"; + private static final String TEST_PASSPHRASE = "TestPassphrase"; + private static final int TEST_CHANNEL = 0; + private static final boolean TEST_HIDDEN = false; + private static final int TEST_BAND = SoftApConfiguration.BAND_5GHZ; + private static final int TEST_SECURITY = SoftApConfiguration.SECURITY_TYPE_WPA2_PSK; + + private static final String TEST_EXPECTED_XML_STRING = + "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" + + "<WifiConfigStoreData>\n" + + "<int name=\"Version\" value=\"3\" />\n" + + "<SoftAp>\n" + + "<string name=\"SSID\">" + TEST_SSID + "</string>\n" + + "<int name=\"ApBand\" value=\"" + TEST_BAND + "\" />\n" + + "<int name=\"Channel\" value=\"" + TEST_CHANNEL + "\" />\n" + + "<boolean name=\"HiddenSSID\" value=\"" + TEST_HIDDEN + "\" />\n" + + "<int name=\"SecurityType\" value=\"" + TEST_SECURITY + "\" />\n" + + "<string name=\"Passphrase\">" + TEST_PASSPHRASE + "</string>\n" + + "<int name=\"MaxNumberOfClients\" value=\"0\" />\n" + + "<boolean name=\"ClientControlByUser\" value=\"false\" />\n" + + "<boolean name=\"AutoShutdownEnabled\" value=\"true\" />\n" + + "<long name=\"ShutdownTimeoutMillis\" value=\"0\" />\n" + + "<BlockedClientList />\n" + + "<AllowedClientList />\n" + + "</SoftAp>\n" + + "</WifiConfigStoreData>\n"; + + private byte[] createLegacyApConfFile(WifiConfiguration config) throws Exception { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(outputStream); + out.writeInt(3); + out.writeUTF(config.SSID); + out.writeInt(config.apBand); + out.writeInt(config.apChannel); + out.writeBoolean(config.hiddenSSID); + int authType = config.getAuthType(); + out.writeInt(authType); + if (authType != WifiConfiguration.KeyMgmt.NONE) { + out.writeUTF(config.preSharedKey); + } + out.close(); + return outputStream.toByteArray(); + } + + /** + * Generate a SoftApConfiguration based on the specified parameters. + */ + private SoftApConfiguration setupApConfig( + String ssid, String preSharedKey, int keyManagement, int band, int channel, + boolean hiddenSSID) { + SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); + configBuilder.setSsid(ssid); + configBuilder.setPassphrase(preSharedKey, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); + if (channel == 0) { + configBuilder.setBand(band); + } else { + configBuilder.setChannel(channel, band); + } + configBuilder.setHiddenSsid(hiddenSSID); + return configBuilder.build(); + } + + /** + * Generate a WifiConfiguration based on the specified parameters. + */ + private WifiConfiguration setupWifiConfigurationApConfig( + String ssid, String preSharedKey, int keyManagement, int band, int channel, + boolean hiddenSSID) { + WifiConfiguration config = new WifiConfiguration(); + config.SSID = ssid; + config.preSharedKey = preSharedKey; + config.allowedKeyManagement.set(keyManagement); + config.apBand = band; + config.apChannel = channel; + config.hiddenSSID = hiddenSSID; + return config; + } + + /** + * Asserts that the WifiConfigurations equal to SoftApConfiguration. + * This only compares the elements saved + * for softAp used. + */ + public static void assertWifiConfigurationEqualSoftApConfiguration( + WifiConfiguration backup, SoftApConfiguration restore) { + assertEquals(backup.SSID, restore.getSsid()); + assertEquals(backup.BSSID, restore.getBssid()); + assertEquals(SoftApConfToXmlMigrationUtil.convertWifiConfigBandToSoftApConfigBand( + backup.apBand), + restore.getBand()); + assertEquals(backup.apChannel, restore.getChannel()); + assertEquals(backup.preSharedKey, restore.getPassphrase()); + if (backup.getAuthType() == WifiConfiguration.KeyMgmt.WPA2_PSK) { + assertEquals(SoftApConfiguration.SECURITY_TYPE_WPA2_PSK, restore.getSecurityType()); + } else { + assertEquals(SoftApConfiguration.SECURITY_TYPE_OPEN, restore.getSecurityType()); + } + assertEquals(backup.hiddenSSID, restore.isHiddenSsid()); + } + + /** + * Note: This is a copy of {@link AtomicFile#readFully()} modified to use the passed in + * {@link InputStream} which was returned using {@link AtomicFile#openRead()}. + */ + private static byte[] readFully(InputStream stream) throws IOException { + try { + int pos = 0; + int avail = stream.available(); + byte[] data = new byte[avail]; + while (true) { + int amt = stream.read(data, pos, data.length - pos); + if (amt <= 0) { + return data; + } + pos += amt; + avail = stream.available(); + if (avail > data.length - pos) { + byte[] newData = new byte[pos + avail]; + System.arraycopy(data, 0, newData, 0, pos); + data = newData; + } + } + } finally { + stream.close(); + } + } + + /** + * Tests conversion from legacy .conf file to XML file format. + */ + @Test + public void testConversion() throws Exception { + WifiConfiguration backupConfig = setupWifiConfigurationApConfig( + TEST_SSID, /* SSID */ + TEST_PASSPHRASE, /* preshared key */ + WifiConfiguration.KeyMgmt.WPA2_PSK, /* key management */ + 1, /* AP band (5GHz) */ + TEST_CHANNEL, /* AP channel */ + TEST_HIDDEN /* Hidden SSID */); + SoftApConfiguration expectedConfig = setupApConfig( + TEST_SSID, /* SSID */ + TEST_PASSPHRASE, /* preshared key */ + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK, /* security type */ + SoftApConfiguration.BAND_5GHZ, /* AP band (5GHz) */ + TEST_CHANNEL, /* AP channel */ + TEST_HIDDEN /* Hidden SSID */); + + assertWifiConfigurationEqualSoftApConfiguration(backupConfig, expectedConfig); + + byte[] confBytes = createLegacyApConfFile(backupConfig); + assertNotNull(confBytes); + + InputStream xmlStream = SoftApConfToXmlMigrationUtil.convert( + new ByteArrayInputStream(confBytes)); + + byte[] xmlBytes = readFully(xmlStream); + assertNotNull(xmlBytes); + + assertEquals(TEST_EXPECTED_XML_STRING, new String(xmlBytes)); + } + +} diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java new file mode 100644 index 000000000000..1a4427034756 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -0,0 +1,334 @@ +/* + * 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 android.net.wifi; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.assertNull; + +import android.net.MacAddress; +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +@SmallTest +public class SoftApConfigurationTest { + private static final String TEST_CHAR_SET_AS_STRING = "abcdefghijklmnopqrstuvwxyz0123456789"; + + private SoftApConfiguration parcelUnparcel(SoftApConfiguration configIn) { + Parcel parcel = Parcel.obtain(); + parcel.writeParcelable(configIn, 0); + parcel.setDataPosition(0); + SoftApConfiguration configOut = + parcel.readParcelable(SoftApConfiguration.class.getClassLoader()); + parcel.recycle(); + return configOut; + } + + /** + * Helper method to generate random string. + * + * Note: this method has limited use as a random string generator. + * The characters used in this method do no not cover all valid inputs. + * @param length number of characters to generate for the string + * @return String generated string of random characters + */ + private String generateRandomString(int length) { + Random random = new Random(); + StringBuilder stringBuilder = new StringBuilder(length); + int index = -1; + while (stringBuilder.length() < length) { + index = random.nextInt(TEST_CHAR_SET_AS_STRING.length()); + stringBuilder.append(TEST_CHAR_SET_AS_STRING.charAt(index)); + } + return stringBuilder.toString(); + } + + @Test + public void testBasicSettings() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setSsid("ssid") + .setBssid(MacAddress.fromString("11:22:33:44:55:66")) + .build(); + assertThat(original.getSsid()).isEqualTo("ssid"); + assertThat(original.getBssid()).isEqualTo(MacAddress.fromString("11:22:33:44:55:66")); + assertThat(original.getPassphrase()).isNull(); + assertThat(original.getSecurityType()).isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); + assertThat(original.getChannel()).isEqualTo(0); + assertThat(original.isHiddenSsid()).isEqualTo(false); + assertThat(original.getMaxNumberOfClients()).isEqualTo(0); + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } + + @Test + public void testWpa2() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .build(); + assertThat(original.getPassphrase()).isEqualTo("secretsecret"); + assertThat(original.getSecurityType()).isEqualTo( + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); + assertThat(original.getChannel()).isEqualTo(0); + assertThat(original.isHiddenSsid()).isEqualTo(false); + assertThat(original.getMaxNumberOfClients()).isEqualTo(0); + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } + + @Test + public void testWpa2WithAllFieldCustomized() { + List<MacAddress> testBlockedClientList = new ArrayList<>(); + List<MacAddress> testAllowedClientList = new ArrayList<>(); + testBlockedClientList.add(MacAddress.fromString("11:22:33:44:55:66")); + testAllowedClientList.add(MacAddress.fromString("aa:bb:cc:dd:ee:ff")); + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .setMaxNumberOfClients(10) + .setAutoShutdownEnabled(true) + .setShutdownTimeoutMillis(500000) + .setClientControlByUserEnabled(true) + .setBlockedClientList(testBlockedClientList) + .setAllowedClientList(testAllowedClientList) + .build(); + assertThat(original.getPassphrase()).isEqualTo("secretsecret"); + assertThat(original.getSecurityType()).isEqualTo( + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); + assertThat(original.getChannel()).isEqualTo(149); + assertThat(original.isHiddenSsid()).isEqualTo(true); + assertThat(original.getMaxNumberOfClients()).isEqualTo(10); + assertThat(original.isAutoShutdownEnabled()).isEqualTo(true); + assertThat(original.getShutdownTimeoutMillis()).isEqualTo(500000); + assertThat(original.isClientControlByUserEnabled()).isEqualTo(true); + assertThat(original.getBlockedClientList()).isEqualTo(testBlockedClientList); + assertThat(original.getAllowedClientList()).isEqualTo(testAllowedClientList); + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } + + @Test + public void testWpa3Sae() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + assertThat(original.getPassphrase()).isEqualTo("secretsecret"); + assertThat(original.getSecurityType()).isEqualTo( + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); + assertThat(original.getChannel()).isEqualTo(149); + assertThat(original.isHiddenSsid()).isEqualTo(true); + + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } + + @Test + public void testWpa3SaeTransition() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + assertThat(original.getSecurityType()).isEqualTo( + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); + assertThat(original.getPassphrase()).isEqualTo("secretsecret"); + assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); + assertThat(original.getChannel()).isEqualTo(149); + assertThat(original.isHiddenSsid()).isEqualTo(true); + + + SoftApConfiguration unparceled = parcelUnparcel(original); + assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isEqualTo(original); + assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); + + SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); + assertThat(copy).isNotSameAs(original); + assertThat(copy).isEqualTo(original); + assertThat(copy.hashCode()).isEqualTo(original.hashCode()); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidShortPasswordLengthForWpa2() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1), + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidLongPasswordLengthForWpa2() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1), + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidShortPasswordLengthForWpa3SaeTransition() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MIN_LEN - 1), + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidLongPasswordLengthForWpa3SaeTransition() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setPassphrase(generateRandomString(SoftApConfiguration.PSK_MAX_LEN + 1), + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalieShutdownTimeoutMillis() { + SoftApConfiguration original = new SoftApConfiguration.Builder() + .setShutdownTimeoutMillis(-1) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetClientListExceptionWhenExistMacAddressInBothList() { + final MacAddress testMacAddress_1 = MacAddress.fromString("22:33:44:55:66:77"); + final MacAddress testMacAddress_2 = MacAddress.fromString("aa:bb:cc:dd:ee:ff"); + ArrayList<MacAddress> testAllowedClientList = new ArrayList<>(); + testAllowedClientList.add(testMacAddress_1); + testAllowedClientList.add(testMacAddress_2); + ArrayList<MacAddress> testBlockedClientList = new ArrayList<>(); + testBlockedClientList.add(testMacAddress_1); + SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); + configBuilder.setBlockedClientList(testBlockedClientList) + .setAllowedClientList(testAllowedClientList) + .build(); + } + + @Test + public void testToWifiConfigurationWithUnsupportedParameter() { + SoftApConfiguration sae_config = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) + .build(); + + assertNull(sae_config.toWifiConfiguration()); + SoftApConfiguration band_6g_config = new SoftApConfiguration.Builder() + .setBand(SoftApConfiguration.BAND_6GHZ) + .build(); + + assertNull(band_6g_config.toWifiConfiguration()); + SoftApConfiguration sae_transition_config = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) + .build(); + + assertNull(sae_transition_config.toWifiConfiguration()); + } + + @Test + public void testToWifiConfigurationWithSupportedParameter() { + SoftApConfiguration softApConfig_2g = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(11, SoftApConfiguration.BAND_2GHZ) + .setHiddenSsid(true) + .build(); + WifiConfiguration wifiConfig_2g = softApConfig_2g.toWifiConfiguration(); + assertThat(wifiConfig_2g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); + assertThat(wifiConfig_2g.preSharedKey).isEqualTo("secretsecret"); + assertThat(wifiConfig_2g.apBand).isEqualTo(WifiConfiguration.AP_BAND_2GHZ); + assertThat(wifiConfig_2g.apChannel).isEqualTo(11); + assertThat(wifiConfig_2g.hiddenSSID).isEqualTo(true); + + SoftApConfiguration softApConfig_5g = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(149, SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + WifiConfiguration wifiConfig_5g = softApConfig_5g.toWifiConfiguration(); + assertThat(wifiConfig_5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); + assertThat(wifiConfig_5g.preSharedKey).isEqualTo("secretsecret"); + assertThat(wifiConfig_5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_5GHZ); + assertThat(wifiConfig_5g.apChannel).isEqualTo(149); + assertThat(wifiConfig_5g.hiddenSSID).isEqualTo(true); + + SoftApConfiguration softApConfig_2g5g = new SoftApConfiguration.Builder() + .setPassphrase("secretsecret", + SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(true) + .build(); + WifiConfiguration wifiConfig_2g5g = softApConfig_2g5g.toWifiConfiguration(); + assertThat(wifiConfig_2g5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); + assertThat(wifiConfig_2g5g.preSharedKey).isEqualTo("secretsecret"); + assertThat(wifiConfig_2g5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_ANY); + assertThat(wifiConfig_2g5g.apChannel).isEqualTo(0); + assertThat(wifiConfig_2g5g.hiddenSSID).isEqualTo(true); + } +} diff --git a/wifi/tests/src/android/net/wifi/SoftApInfoTest.java b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java new file mode 100644 index 000000000000..929f3ab88fd8 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/SoftApInfoTest.java @@ -0,0 +1,71 @@ +/* + * 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 android.net.wifi; + +import android.os.Parcel; + +import static org.junit.Assert.assertEquals; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.SoftApInfo}. + */ +@SmallTest +public class SoftApInfoTest { + + /** + * Verifies copy constructor. + */ + @Test + public void testCopyOperator() throws Exception { + SoftApInfo info = new SoftApInfo(); + info.setFrequency(2412); + info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ); + + SoftApInfo copiedInfo = new SoftApInfo(info); + + assertEquals(info, copiedInfo); + assertEquals(info.hashCode(), copiedInfo.hashCode()); + } + + /** + * Verifies parcel serialization/deserialization. + */ + @Test + public void testParcelOperation() throws Exception { + SoftApInfo info = new SoftApInfo(); + info.setFrequency(2412); + info.setBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ); + + Parcel parcelW = Parcel.obtain(); + info.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + SoftApInfo fromParcel = SoftApInfo.CREATOR.createFromParcel(parcelR); + + assertEquals(info, fromParcel); + assertEquals(info.hashCode(), fromParcel.hashCode()); + } + +} diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index fe30ddd3765a..a7b6765e886a 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -16,10 +16,19 @@ package android.net.wifi; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OPEN; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_OWE; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_PSK; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_SAE; +import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_WAPI_PSK; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import android.net.MacAddress; @@ -33,9 +42,6 @@ import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; - /** * Unit tests for {@link android.net.wifi.WifiConfiguration}. */ @@ -77,7 +83,7 @@ public class WifiConfigurationTest { // lacking a useful config.equals, check two fields near the end. assertEquals(cookie, reconfig.getMoTree()); - assertEquals(macBeforeParcel, reconfig.getOrCreateRandomizedMacAddress()); + assertEquals(macBeforeParcel, reconfig.getRandomizedMacAddress()); assertEquals(config.updateIdentifier, reconfig.updateIdentifier); assertFalse(reconfig.trusted); assertTrue(config.fromWifiNetworkSpecifier); @@ -92,37 +98,6 @@ public class WifiConfigurationTest { } @Test - public void testNetworkSelectionStatusCopy() { - NetworkSelectionStatus networkSelectionStatus = new NetworkSelectionStatus(); - networkSelectionStatus.setNotRecommended(true); - - NetworkSelectionStatus copy = new NetworkSelectionStatus(); - copy.copy(networkSelectionStatus); - - assertEquals(networkSelectionStatus.isNotRecommended(), copy.isNotRecommended()); - } - - @Test - public void testNetworkSelectionStatusParcel() { - NetworkSelectionStatus networkSelectionStatus = new NetworkSelectionStatus(); - networkSelectionStatus.setNotRecommended(true); - - Parcel parcelW = Parcel.obtain(); - networkSelectionStatus.writeToParcel(parcelW); - byte[] bytes = parcelW.marshall(); - parcelW.recycle(); - - Parcel parcelR = Parcel.obtain(); - parcelR.unmarshall(bytes, 0, bytes.length); - parcelR.setDataPosition(0); - - NetworkSelectionStatus copy = new NetworkSelectionStatus(); - copy.readFromParcel(parcelR); - - assertEquals(networkSelectionStatus.isNotRecommended(), copy.isNotRecommended()); - } - - @Test public void testIsOpenNetwork_IsOpen_NullWepKeys() { WifiConfiguration config = new WifiConfiguration(); config.allowedKeyManagement.clear(); @@ -195,19 +170,6 @@ public class WifiConfigurationTest { } @Test - public void testGetOrCreateRandomizedMacAddress_SavesAndReturnsSameAddress() { - WifiConfiguration config = new WifiConfiguration(); - MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); - assertEquals(defaultMac, config.getRandomizedMacAddress()); - - MacAddress firstMacAddress = config.getOrCreateRandomizedMacAddress(); - MacAddress secondMacAddress = config.getOrCreateRandomizedMacAddress(); - - assertNotEquals(defaultMac, firstMacAddress); - assertEquals(firstMacAddress, secondMacAddress); - } - - @Test public void testSetRandomizedMacAddress_ChangesSavedAddress() { WifiConfiguration config = new WifiConfiguration(); MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); @@ -221,36 +183,6 @@ public class WifiConfigurationTest { } @Test - public void testGetOrCreateRandomizedMacAddress_ReRandomizesInvalidAddress() { - WifiConfiguration config = new WifiConfiguration(); - - MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); - MacAddress macAddressZeroes = MacAddress.ALL_ZEROS_ADDRESS; - MacAddress macAddressMulticast = MacAddress.fromString("03:ff:ff:ff:ff:ff"); - MacAddress macAddressGlobal = MacAddress.fromString("fc:ff:ff:ff:ff:ff"); - - config.setRandomizedMacAddress(null); - MacAddress macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, null); - - config.setRandomizedMacAddress(defaultMac); - macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, defaultMac); - - config.setRandomizedMacAddress(macAddressZeroes); - macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, macAddressZeroes); - - config.setRandomizedMacAddress(macAddressMulticast); - macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, macAddressMulticast); - - config.setRandomizedMacAddress(macAddressGlobal); - macAfterChange = config.getOrCreateRandomizedMacAddress(); - assertNotEquals(macAfterChange, macAddressGlobal); - } - - @Test public void testSetRandomizedMacAddress_DoesNothingWhenNull() { WifiConfiguration config = new WifiConfiguration(); MacAddress defaultMac = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); @@ -271,33 +203,6 @@ public class WifiConfigurationTest { } /** - * Verifies that the serialization/de-serialization for softap config works. - */ - @Test - public void testSoftApConfigBackupAndRestore() throws Exception { - WifiConfiguration config = new WifiConfiguration(); - config.SSID = "TestAP"; - config.apBand = WifiConfiguration.AP_BAND_5GHZ; - config.apChannel = 40; - config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); - config.preSharedKey = "TestPsk"; - config.hiddenSSID = true; - - byte[] data = config.getBytesForBackup(); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream in = new DataInputStream(bais); - WifiConfiguration restoredConfig = WifiConfiguration.getWifiConfigFromBackup(in); - - assertEquals(config.SSID, restoredConfig.SSID); - assertEquals(config.preSharedKey, restoredConfig.preSharedKey); - assertEquals(config.getAuthType(), restoredConfig.getAuthType()); - assertEquals(config.apBand, restoredConfig.apBand); - assertEquals(config.apChannel, restoredConfig.apChannel); - assertEquals(config.hiddenSSID, restoredConfig.hiddenSSID); - } - - - /** * Verifies that getKeyIdForCredentials returns the expected string for Enterprise networks * @throws Exception */ @@ -436,7 +341,23 @@ public class WifiConfigurationTest { config.allowedKeyManagement.clear(); assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString()); + // set WEP key and give a valid index. + config.wepKeys[0] = null; + config.wepKeys[2] = "TestWep"; + config.wepTxKeyIndex = 2; + config.allowedKeyManagement.clear(); + assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString()); + + // set WEP key but does not give a valid index. + config.wepKeys[0] = null; + config.wepKeys[2] = "TestWep"; + config.wepTxKeyIndex = 0; + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.OWE); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString()); + config.wepKeys[0] = null; + config.wepTxKeyIndex = 0; config.allowedKeyManagement.clear(); config.allowedKeyManagement.set(KeyMgmt.OWE); assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString()); @@ -453,5 +374,167 @@ public class WifiConfigurationTest { config.allowedKeyManagement.clear(); config.allowedKeyManagement.set(KeyMgmt.NONE); assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.NONE], config.getSsidAndSecurityTypeString()); + + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.WAPI_PSK); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WAPI_PSK], + config.getSsidAndSecurityTypeString()); + + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.WAPI_CERT); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WAPI_CERT], + config.getSsidAndSecurityTypeString()); + } + + /** + * Ensure that the {@link NetworkSelectionStatus.DisableReasonInfo}s are populated in + * {@link NetworkSelectionStatus#DISABLE_REASON_INFOS} for reason codes from 0 to + * {@link NetworkSelectionStatus#NETWORK_SELECTION_DISABLED_MAX} - 1. + */ + @Test + public void testNetworkSelectionDisableReasonInfosPopulated() { + assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX, + NetworkSelectionStatus.DISABLE_REASON_INFOS.size()); + for (int i = 0; i < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; i++) { + assertNotNull(NetworkSelectionStatus.DISABLE_REASON_INFOS.get(i)); + } + } + + /** + * Ensure that {@link NetworkSelectionStatus#getMaxNetworkSelectionDisableReason()} returns + * the maximum disable reason. + */ + @Test + public void testNetworkSelectionGetMaxNetworkSelectionDisableReason() { + int maxReason = Integer.MIN_VALUE; + for (int i = 0; i < NetworkSelectionStatus.DISABLE_REASON_INFOS.size(); i++) { + int reason = NetworkSelectionStatus.DISABLE_REASON_INFOS.keyAt(i); + maxReason = Math.max(maxReason, reason); + } + assertEquals(maxReason, NetworkSelectionStatus.getMaxNetworkSelectionDisableReason()); + } + + /** + * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the + * {@link WifiConfiguration} object correctly for SAE security type. + * @throws Exception + */ + @Test + public void testSetSecurityParamsForSae() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + + config.setSecurityParams(SECURITY_TYPE_SAE); + + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)); + assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP)); + assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256)); + assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP)); + assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256)); + assertTrue(config.requirePmf); + } + + /** + * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the + * {@link WifiConfiguration} object correctly for OWE security type. + * @throws Exception + */ + @Test + public void testSetSecurityParamsForOwe() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + + config.setSecurityParams(SECURITY_TYPE_OWE); + + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE)); + assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP)); + assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256)); + assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP)); + assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256)); + assertTrue(config.requirePmf); + } + + /** + * Ensure that {@link WifiConfiguration#setSecurityParams(int)} sets up the + * {@link WifiConfiguration} object correctly for Suite-B security type. + * @throws Exception + */ + @Test + public void testSetSecurityParamsForSuiteB() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + + config.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B); + + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192)); + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)); + assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)); + assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.GCMP_256)); + assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256)); + assertTrue(config.allowedGroupManagementCiphers + .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); + assertTrue(config.requirePmf); + } + + /** + * Test that the NetworkSelectionStatus Builder returns the same values that was set, and that + * calling build multiple times returns different instances. + */ + @Test + public void testNetworkSelectionStatusBuilder() throws Exception { + NetworkSelectionStatus.Builder builder = new NetworkSelectionStatus.Builder() + .setNetworkSelectionDisableReason( + NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION) + .setNetworkSelectionStatus( + NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED); + + NetworkSelectionStatus status1 = builder.build(); + + assertEquals(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, + status1.getNetworkSelectionDisableReason()); + assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED, + status1.getNetworkSelectionStatus()); + + NetworkSelectionStatus status2 = builder + .setNetworkSelectionDisableReason(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD) + .build(); + + // different instances + assertNotSame(status1, status2); + + // assert that status1 didn't change + assertEquals(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, + status1.getNetworkSelectionDisableReason()); + assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED, + status1.getNetworkSelectionStatus()); + + // assert that status2 changed + assertEquals(NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD, + status2.getNetworkSelectionDisableReason()); + assertEquals(NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED, + status2.getNetworkSelectionStatus()); + } + + @Test + public void testNeedsPreSharedKey() throws Exception { + WifiConfiguration configuration = new WifiConfiguration(); + + configuration.setSecurityParams(SECURITY_TYPE_PSK); + assertTrue(configuration.needsPreSharedKey()); + + configuration.setSecurityParams(SECURITY_TYPE_SAE); + assertTrue(configuration.needsPreSharedKey()); + + configuration.setSecurityParams(SECURITY_TYPE_WAPI_PSK); + assertTrue(configuration.needsPreSharedKey()); + + configuration.setSecurityParams(SECURITY_TYPE_OPEN); + assertFalse(configuration.needsPreSharedKey()); + + configuration.setSecurityParams(SECURITY_TYPE_OWE); + assertFalse(configuration.needsPreSharedKey()); + + configuration.setSecurityParams(SECURITY_TYPE_EAP); + assertFalse(configuration.needsPreSharedKey()); + + configuration.setSecurityParams(SECURITY_TYPE_EAP_SUITE_B); + assertFalse(configuration.needsPreSharedKey()); } } diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java index beed6666f28f..62485ecb6f7b 100644 --- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java +++ b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.net.wifi.WifiEnterpriseConfig.Eap; import android.net.wifi.WifiEnterpriseConfig.Phase2; @@ -46,6 +47,7 @@ public class WifiEnterpriseConfigTest { public static final String KEYSTORE_URI = "keystore://"; public static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE; public static final String KEYSTORES_URI = "keystores://"; + private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch"; private WifiEnterpriseConfig mEnterpriseConfig; @@ -343,11 +345,13 @@ public class WifiEnterpriseConfigTest { enterpriseConfig.setPassword("*"); enterpriseConfig.setEapMethod(Eap.TTLS); enterpriseConfig.setPhase2Method(Phase2.GTC); + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS); mEnterpriseConfig = new WifiEnterpriseConfig(); mEnterpriseConfig.copyFromExternal(enterpriseConfig, "*"); assertEquals("TTLS", getSupplicantEapMethod()); assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method()); assertNotEquals("*", mEnterpriseConfig.getPassword()); + assertEquals(enterpriseConfig.getOcsp(), mEnterpriseConfig.getOcsp()); } /** Verfies that parceling a WifiEnterpriseConfig preseves method information. */ @@ -487,4 +491,87 @@ public class WifiEnterpriseConfigTest { assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert()); assertTrue(mEnterpriseConfig.isAppInstalledCaCert()); } + + /** Verifies that OCSP value is set correctly. */ + @Test + public void testOcspSetGet() throws Exception { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_NONE); + assertEquals(WifiEnterpriseConfig.OCSP_NONE, enterpriseConfig.getOcsp()); + + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS); + assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS, enterpriseConfig.getOcsp()); + + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS); + assertEquals(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS, enterpriseConfig.getOcsp()); + + enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS); + assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS, + enterpriseConfig.getOcsp()); + } + + /** Verifies that an exception is thrown when invalid OCSP is set. */ + @Test + public void testInvalidOcspValue() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + try { + enterpriseConfig.setOcsp(-1); + fail("Should raise an IllegalArgumentException here."); + } catch (IllegalArgumentException e) { + // expected exception. + } + } + + /** Verifies that the EAP inner method is reset when we switch to Unauth-TLS */ + @Test + public void eapPhase2MethodForUnauthTls() { + // Initially select an EAP method that supports an phase2. + mEnterpriseConfig.setEapMethod(Eap.PEAP); + mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2); + assertEquals("PEAP", getSupplicantEapMethod()); + assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method()); + + // Change the EAP method to another type which supports a phase2. + mEnterpriseConfig.setEapMethod(Eap.TTLS); + assertEquals("TTLS", getSupplicantEapMethod()); + assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method()); + + // Change the EAP method to Unauth-TLS which does not support a phase2. + mEnterpriseConfig.setEapMethod(Eap.UNAUTH_TLS); + assertEquals(null, getSupplicantPhase2Method()); + } + + @Test + public void testIsEnterpriseConfigSecure() { + WifiEnterpriseConfig baseConfig = new WifiEnterpriseConfig(); + baseConfig.setEapMethod(Eap.PEAP); + baseConfig.setPhase2Method(Phase2.MSCHAPV2); + assertTrue(baseConfig.isInsecure()); + + WifiEnterpriseConfig noMatchConfig = new WifiEnterpriseConfig(baseConfig); + noMatchConfig.setCaCertificate(FakeKeys.CA_CERT0); + // Missing match is insecure. + assertTrue(noMatchConfig.isInsecure()); + + WifiEnterpriseConfig noCaConfig = new WifiEnterpriseConfig(baseConfig); + noCaConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + // Missing CA certificate is insecure. + assertTrue(noCaConfig.isInsecure()); + + WifiEnterpriseConfig secureConfig = new WifiEnterpriseConfig(); + secureConfig.setEapMethod(Eap.PEAP); + secureConfig.setPhase2Method(Phase2.MSCHAPV2); + secureConfig.setCaCertificate(FakeKeys.CA_CERT0); + secureConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + assertFalse(secureConfig.isInsecure()); + + WifiEnterpriseConfig secureConfigWithCaAlias = new WifiEnterpriseConfig(); + secureConfigWithCaAlias.setEapMethod(Eap.PEAP); + secureConfigWithCaAlias.setPhase2Method(Phase2.MSCHAPV2); + secureConfigWithCaAlias.setCaCertificateAliases(new String[]{"alias1", "alisa2"}); + secureConfigWithCaAlias.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + assertFalse(secureConfigWithCaAlias.isInsecure()); + } + } diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java index 0ce5d66cf4f7..311bbc41b8fe 100644 --- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java +++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java @@ -18,6 +18,7 @@ package android.net.wifi; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import android.os.Parcel; @@ -26,6 +27,8 @@ import androidx.test.filters.SmallTest; import org.junit.Test; +import java.nio.charset.StandardCharsets; + /** * Unit tests for {@link android.net.wifi.WifiInfo}. */ @@ -38,6 +41,14 @@ public class WifiInfoTest { private static final String TEST_PACKAGE_NAME = "com.test.example"; private static final String TEST_FQDN = "test.com"; private static final String TEST_PROVIDER_NAME = "test"; + private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC; + private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866; + private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200; + private static final String TEST_SSID = "Test123"; + private static final String TEST_BSSID = "12:12:12:12:12:12"; + private static final int TEST_RSSI = -60; + private static final int TEST_NETWORK_ID = 5; + private static final int TEST_NETWORK_ID2 = 6; /** * Verify parcel write/read with WifiInfo. @@ -53,7 +64,10 @@ public class WifiInfoTest { writeWifiInfo.setOsuAp(true); writeWifiInfo.setFQDN(TEST_FQDN); writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME); - writeWifiInfo.setNetworkSuggestionOrSpecifierPackageName(TEST_PACKAGE_NAME); + writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME); + writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD); + writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS); + writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS); Parcel parcel = Parcel.obtain(); writeWifiInfo.writeToParcel(parcel, 0); @@ -69,8 +83,69 @@ public class WifiInfoTest { assertTrue(readWifiInfo.isTrusted()); assertTrue(readWifiInfo.isOsuAp()); assertTrue(readWifiInfo.isPasspointAp()); - assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getNetworkSuggestionOrSpecifierPackageName()); + assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName()); assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn()); assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName()); + assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard()); + assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, + readWifiInfo.getMaxSupportedTxLinkSpeedMbps()); + assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, + readWifiInfo.getMaxSupportedRxLinkSpeedMbps()); + } + + /** + * Verify values after reset() + */ + @Test + public void testWifiInfoResetValue() throws Exception { + WifiInfo wifiInfo = new WifiInfo(); + wifiInfo.reset(); + assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedTxLinkSpeedMbps()); + assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedRxLinkSpeedMbps()); + assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getTxLinkSpeedMbps()); + assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getRxLinkSpeedMbps()); + assertEquals(WifiInfo.INVALID_RSSI, wifiInfo.getRssi()); + assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID()); + assertEquals(null, wifiInfo.getBSSID()); + assertEquals(-1, wifiInfo.getNetworkId()); + } + + /** + * Test that the WifiInfo Builder returns the same values that was set, and that + * calling build multiple times returns different instances. + */ + @Test + public void testWifiInfoBuilder() throws Exception { + WifiInfo.Builder builder = new WifiInfo.Builder() + .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8)) + .setBssid(TEST_BSSID) + .setRssi(TEST_RSSI) + .setNetworkId(TEST_NETWORK_ID); + + WifiInfo info1 = builder.build(); + + assertEquals("\"" + TEST_SSID + "\"", info1.getSSID()); + assertEquals(TEST_BSSID, info1.getBSSID()); + assertEquals(TEST_RSSI, info1.getRssi()); + assertEquals(TEST_NETWORK_ID, info1.getNetworkId()); + + WifiInfo info2 = builder + .setNetworkId(TEST_NETWORK_ID2) + .build(); + + // different instances + assertNotSame(info1, info2); + + // assert that info1 didn't change + assertEquals("\"" + TEST_SSID + "\"", info1.getSSID()); + assertEquals(TEST_BSSID, info1.getBSSID()); + assertEquals(TEST_RSSI, info1.getRssi()); + assertEquals(TEST_NETWORK_ID, info1.getNetworkId()); + + // assert that info2 changed + assertEquals("\"" + TEST_SSID + "\"", info2.getSSID()); + assertEquals(TEST_BSSID, info2.getBSSID()); + assertEquals(TEST_RSSI, info2.getRssi()); + assertEquals(TEST_NETWORK_ID2, info2.getNetworkId()); } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index b130c1737c62..1398bfeef031 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -16,18 +16,31 @@ package android.net.wifi; -import static android.net.wifi.WifiManager.HOTSPOT_FAILED; -import static android.net.wifi.WifiManager.HOTSPOT_STARTED; -import static android.net.wifi.WifiManager.HOTSPOT_STOPPED; +import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED; +import static android.net.wifi.WifiManager.ActionListener; +import static android.net.wifi.WifiManager.BUSY; +import static android.net.wifi.WifiManager.ERROR; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED; import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED; +import static android.net.wifi.WifiManager.NOT_AUTHORIZED; +import static android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener; import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL; +import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS; +import static android.net.wifi.WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING; import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; +import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP; +import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE; +import static android.net.wifi.WifiManager.WIFI_FEATURE_P2P; +import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT; +import static android.net.wifi.WifiManager.WIFI_FEATURE_SCANNER; +import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE; +import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B; +import static android.net.wifi.WifiManager.WpsCallback; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -37,6 +50,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyList; @@ -52,9 +66,11 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; +import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.net.DhcpInfo; +import android.net.MacAddress; import android.net.wifi.WifiManager.LocalOnlyHotspotCallback; import android.net.wifi.WifiManager.LocalOnlyHotspotObserver; import android.net.wifi.WifiManager.LocalOnlyHotspotReservation; @@ -62,15 +78,20 @@ import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription; import android.net.wifi.WifiManager.NetworkRequestMatchCallback; import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.net.wifi.WifiManager.OnWifiUsabilityStatsListener; +import android.net.wifi.WifiManager.ScanResultsCallback; import android.net.wifi.WifiManager.SoftApCallback; +import android.net.wifi.WifiManager.SuggestionConnectionStatusListener; import android.net.wifi.WifiManager.TrafficStateCallback; +import android.net.wifi.WifiManager.WifiConnectedNetworkScorer; +import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.HandlerExecutor; import android.os.IBinder; -import android.os.Message; -import android.os.Messenger; +import android.os.RemoteException; +import android.os.connectivity.WifiActivityEnergyInfo; import android.os.test.TestLooper; +import android.util.SparseArray; import androidx.test.filters.SmallTest; @@ -85,6 +106,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.Executor; /** @@ -98,25 +120,78 @@ public class WifiManagerTest { private static final int TEST_UID = 14553; private static final int TEST_NETWORK_ID = 143; private static final String TEST_PACKAGE_NAME = "TestPackage"; + private static final String TEST_FEATURE_ID = "TestFeature"; private static final String TEST_COUNTRY_CODE = "US"; private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"}; + private static final int TEST_AP_FREQUENCY = 2412; + private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ; @Mock Context mContext; @Mock android.net.wifi.IWifiManager mWifiService; @Mock ApplicationInfo mApplicationInfo; @Mock WifiConfiguration mApConfig; - @Mock IBinder mAppBinder; @Mock SoftApCallback mSoftApCallback; @Mock TrafficStateCallback mTrafficStateCallback; @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback; @Mock OnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener; + @Mock OnWifiActivityEnergyInfoListener mOnWifiActivityEnergyInfoListener; + @Mock SuggestionConnectionStatusListener mListener; + @Mock Runnable mRunnable; + @Mock Executor mExecutor; + @Mock Executor mAnotherExecutor; + @Mock ActivityManager mActivityManager; + @Mock WifiConnectedNetworkScorer mWifiConnectedNetworkScorer; - private Executor mExecutor; private Handler mHandler; private TestLooper mLooper; private WifiManager mWifiManager; - private Messenger mWifiServiceMessenger; - final ArgumentCaptor<Messenger> mMessengerCaptor = ArgumentCaptor.forClass(Messenger.class); + private WifiNetworkSuggestion mWifiNetworkSuggestion; + private ScanResultsCallback mScanResultsCallback; + private WifiActivityEnergyInfo mWifiActivityEnergyInfo; + + /** + * Util function to check public field which used for softap in WifiConfiguration + * same as the value in SoftApConfiguration. + * + */ + private boolean compareWifiAndSoftApConfiguration( + SoftApConfiguration softApConfig, WifiConfiguration wifiConfig) { + if (!Objects.equals(wifiConfig.SSID, softApConfig.getSsid())) { + return false; + } + if (!Objects.equals(wifiConfig.BSSID, softApConfig.getBssid())) { + return false; + } + if (!Objects.equals(wifiConfig.preSharedKey, softApConfig.getPassphrase())) { + return false; + } + + if (wifiConfig.hiddenSSID != softApConfig.isHiddenSsid()) { + return false; + } + switch (softApConfig.getSecurityType()) { + case SoftApConfiguration.SECURITY_TYPE_OPEN: + if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.NONE) { + return false; + } + break; + case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK: + if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.WPA2_PSK) { + return false; + } + break; + default: + return false; + } + return true; + } + + private SoftApConfiguration generatorTestSoftApConfig() { + return new SoftApConfiguration.Builder() + .setSsid("TestSSID") + .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .build(); + } @Before public void setUp() throws Exception { @@ -126,10 +201,16 @@ public class WifiManagerTest { mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.Q; when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo); when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME); - - mWifiServiceMessenger = new Messenger(mHandler); mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper()); verify(mWifiService).getVerboseLoggingLevel(); + mWifiNetworkSuggestion = new WifiNetworkSuggestion(); + mScanResultsCallback = new ScanResultsCallback() { + @Override + public void onScanResultsAvailable() { + mRunnable.run(); + } + }; + mWifiActivityEnergyInfo = new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0); } /** @@ -171,19 +252,50 @@ public class WifiManagerTest { } /** + * Check the call to startSoftAp calls WifiService to startSoftAp with the provided + * WifiConfiguration. Verify that the return value is propagated to the caller. + */ + @Test + public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); + when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(true); + assertTrue(mWifiManager.startTetheredHotspot(softApConfig)); + + when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(false); + assertFalse(mWifiManager.startTetheredHotspot(softApConfig)); + } + + /** + * Check the call to startSoftAp calls WifiService to startSoftAp with a null config. Verify + * that the return value is propagated to the caller. + */ + @Test + public void testStartTetheredHotspotCallsServiceWithNullConfig() throws Exception { + when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(true); + assertTrue(mWifiManager.startTetheredHotspot(null)); + + when(mWifiService.startTetheredHotspot(eq(null))).thenReturn(false); + assertFalse(mWifiManager.startTetheredHotspot(null)); + } + + /** * Test creation of a LocalOnlyHotspotReservation and verify that close properly calls * WifiService.stopLocalOnlyHotspot. */ @Test public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); - callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig)); + callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig)); + + assertEquals(softApConfig, callback.mRes.getSoftApConfiguration()); + WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration(); + assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig)); - assertEquals(mApConfig, callback.mRes.getWifiConfiguration()); callback.mRes.close(); verify(mWifiService).stopLocalOnlyHotspot(); } @@ -194,15 +306,18 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources() throws Exception { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); - callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig)); + callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig)); try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) { - assertEquals(mApConfig, res.getWifiConfiguration()); + assertEquals(softApConfig, res.getSoftApConfiguration()); + WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration(); + assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig)); } verify(mWifiService).stopLocalOnlyHotspot(); @@ -252,6 +367,7 @@ public class WifiManagerTest { */ @Test public void testLocalOnlyHotspotCallback() { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); assertFalse(callback.mOnStartedCalled); assertFalse(callback.mOnStoppedCalled); @@ -260,7 +376,7 @@ public class WifiManagerTest { // test onStarted WifiManager.LocalOnlyHotspotReservation res = - mWifiManager.new LocalOnlyHotspotReservation(mApConfig); + mWifiManager.new LocalOnlyHotspotReservation(softApConfig); callback.onStarted(res); assertEquals(res, callback.mRes); assertTrue(callback.mOnStartedCalled); @@ -286,7 +402,7 @@ public class WifiManagerTest { public boolean mOnRegistered = false; public boolean mOnStartedCalled = false; public boolean mOnStoppedCalled = false; - public WifiConfiguration mConfig = null; + public SoftApConfiguration mConfig = null; public LocalOnlyHotspotSubscription mSub = null; public long mCallingThreadId = -1; @@ -298,7 +414,7 @@ public class WifiManagerTest { } @Override - public void onStarted(WifiConfiguration config) { + public void onStarted(SoftApConfiguration config) { mOnStartedCalled = true; mConfig = config; mCallingThreadId = Thread.currentThread().getId(); @@ -317,6 +433,7 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotObserver() { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); assertFalse(observer.mOnRegistered); assertFalse(observer.mOnStartedCalled); assertFalse(observer.mOnStoppedCalled); @@ -332,18 +449,18 @@ public class WifiManagerTest { assertEquals(null, observer.mConfig); assertEquals(sub, observer.mSub); - observer.onStarted(mApConfig); + observer.onStarted(softApConfig); assertTrue(observer.mOnRegistered); assertTrue(observer.mOnStartedCalled); assertFalse(observer.mOnStoppedCalled); - assertEquals(mApConfig, observer.mConfig); + assertEquals(softApConfig, observer.mConfig); assertEquals(sub, observer.mSub); observer.onStopped(); assertTrue(observer.mOnRegistered); assertTrue(observer.mOnStartedCalled); assertTrue(observer.mOnStoppedCalled); - assertEquals(mApConfig, observer.mConfig); + assertEquals(softApConfig, observer.mConfig); assertEquals(sub, observer.mSub); } @@ -355,8 +472,8 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); mWifiManager.startLocalOnlyHotspot(callback, mHandler); - verify(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), + anyString(), nullable(String.class), eq(null)); } /** @@ -366,8 +483,9 @@ public class WifiManagerTest { @Test(expected = SecurityException.class) public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot( + any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), + eq(null)); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -378,8 +496,9 @@ public class WifiManagerTest { @Test(expected = IllegalStateException.class) public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - doThrow(new IllegalStateException()).when(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + doThrow(new IllegalStateException()).when(mWifiService).startLocalOnlyHotspot( + any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), + eq(null)); mWifiManager.startLocalOnlyHotspot(callback, mHandler); } @@ -389,12 +508,13 @@ public class WifiManagerTest { @Test public void testCorrectLooperIsUsedForHandler() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); } /** @@ -405,15 +525,15 @@ public class WifiManagerTest { public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception { // record thread from looper.getThread and check ids. TestLooper altLooper = new TestLooper(); - when(mContext.getMainLooper()).thenReturn(altLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, null); altLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId); - verify(mContext).getMainLooper(); + verify(mContext).getMainExecutor(); } /** @@ -422,25 +542,58 @@ public class WifiManagerTest { */ @Test public void testOnStartedIsCalledWithReservation() throws Exception { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(callback.mOnStartedCalled); assertEquals(null, callback.mRes); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - msg.obj = mApConfig; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(softApConfig); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertTrue(callback.mOnStartedCalled); - assertEquals(mApConfig, callback.mRes.getWifiConfiguration()); + assertEquals(softApConfig, callback.mRes.getSoftApConfiguration()); + WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration(); + assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig)); + } + + /** + * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED + * message from WifiServiceImpl when softap enabled with SAE security type. + */ + @Test + public void testOnStartedIsCalledWithReservationAndSaeSoftApConfig() throws Exception { + SoftApConfiguration softApConfig = new SoftApConfiguration.Builder() + .setSsid("TestSSID") + .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) + .build(); + TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); + TestLooper callbackLooper = new TestLooper(); + Handler callbackHandler = new Handler(callbackLooper.getLooper()); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); + mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); + callbackLooper.dispatchAll(); + mLooper.dispatchAll(); + assertFalse(callback.mOnStartedCalled); + assertEquals(null, callback.mRes); + // now trigger the callback + internalCallback.getValue().onHotspotStarted(softApConfig); + mLooper.dispatchAll(); + callbackLooper.dispatchAll(); + assertTrue(callback.mOnStartedCalled); + assertEquals(softApConfig, callback.mRes.getSoftApConfiguration()); + assertEquals(null, callback.mRes.getWifiConfiguration()); } /** @@ -452,17 +605,17 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(callback.mOnStartedCalled); assertEquals(null, callback.mRes); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(null); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertFalse(callback.mOnStartedCalled); @@ -477,16 +630,16 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(callback.mOnStoppedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STOPPED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStopped(); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertTrue(callback.mOnStoppedCalled); @@ -500,17 +653,16 @@ public class WifiManagerTest { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); TestLooper callbackLooper = new TestLooper(); Handler callbackHandler = new Handler(callbackLooper.getLooper()); - when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, callbackHandler); callbackLooper.dispatchAll(); mLooper.dispatchAll(); assertEquals(ERROR_NOT_SET, callback.mFailureReason); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_FAILED; - msg.arg1 = ERROR_NO_CHANNEL; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotFailed(ERROR_NO_CHANNEL); mLooper.dispatchAll(); callbackLooper.dispatchAll(); assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason); @@ -522,8 +674,8 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -538,8 +690,8 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(ERROR_TETHERING_DISALLOWED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_TETHERING_DISALLOWED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason); @@ -555,8 +707,9 @@ public class WifiManagerTest { @Test(expected = SecurityException.class) public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - doThrow(new SecurityException()).when(mWifiService) - .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString()); + doThrow(new SecurityException()).when(mWifiService).startLocalOnlyHotspot( + any(ILocalOnlyHotspotCallback.class), anyString(), nullable(String.class), + eq(null)); try { mWifiManager.startLocalOnlyHotspot(callback, mHandler); } catch (SecurityException e) { @@ -576,8 +729,8 @@ public class WifiManagerTest { @Test public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); //assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason); @@ -592,8 +745,8 @@ public class WifiManagerTest { @Test public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); verify(mWifiService).stopLocalOnlyHotspot(); @@ -614,8 +767,8 @@ public class WifiManagerTest { @Test public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(REQUEST_REGISTERED); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mWifiManager.cancelLocalOnlyHotspotRequest(); verify(mWifiService).stopLocalOnlyHotspot(); @@ -633,8 +786,8 @@ public class WifiManagerTest { @Test public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception { TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); - when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), - anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE); + when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(), + nullable(String.class), eq(null))).thenReturn(ERROR_INCOMPATIBLE_MODE); mWifiManager.startLocalOnlyHotspot(callback, mHandler); mLooper.dispatchAll(); assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason); @@ -645,6 +798,17 @@ public class WifiManagerTest { verify(mWifiService, never()).stopLocalOnlyHotspot(); } + @Test + public void testStartLocalOnlyHotspotForwardsCustomConfig() throws Exception { + SoftApConfiguration customConfig = new SoftApConfiguration.Builder() + .setSsid("customSsid") + .build(); + TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(); + mWifiManager.startLocalOnlyHotspot(customConfig, mExecutor, callback); + verify(mWifiService).startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), + anyString(), nullable(String.class), eq(customConfig)); + } + /** * Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl. */ @@ -653,7 +817,7 @@ public class WifiManagerTest { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); mWifiManager.watchLocalOnlyHotspot(observer, mHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)); + verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); } /** @@ -664,7 +828,7 @@ public class WifiManagerTest { public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); doThrow(new SecurityException()).when(mWifiService) - .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)); + .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); mWifiManager.watchLocalOnlyHotspot(observer, mHandler); } @@ -676,7 +840,7 @@ public class WifiManagerTest { public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); doThrow(new IllegalStateException()).when(mWifiService) - .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)); + .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); mWifiManager.watchLocalOnlyHotspot(observer, mHandler); } @@ -773,11 +937,74 @@ public class WifiManagerTest { verify(mSoftApCallback).onConnectedClientsChanged(testClients); } + + /* + * Verify client-provided callback is being called through callback proxy + */ + @Test + public void softApCallbackProxyCallsOnSoftApInfoChanged() throws Exception { + SoftApInfo testSoftApInfo = new SoftApInfo(); + testSoftApInfo.setFrequency(TEST_AP_FREQUENCY); + testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); + ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = + ArgumentCaptor.forClass(ISoftApCallback.Stub.class); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); + verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), + anyInt()); + + callbackCaptor.getValue().onInfoChanged(testSoftApInfo); + mLooper.dispatchAll(); + verify(mSoftApCallback).onInfoChanged(testSoftApInfo); + } + + + /* + * Verify client-provided callback is being called through callback proxy + */ + @Test + public void softApCallbackProxyCallsOnCapabilityChanged() throws Exception { + SoftApCapability testSoftApCapability = new SoftApCapability(0); + testSoftApCapability.setMaxSupportedClients(10); + ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = + ArgumentCaptor.forClass(ISoftApCallback.Stub.class); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); + verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), + anyInt()); + + callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability); + mLooper.dispatchAll(); + verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); + } + + /* + * Verify client-provided callback is being called through callback proxy + */ + @Test + public void softApCallbackProxyCallsOnBlockedClientConnecting() throws Exception { + WifiClient testWifiClient = new WifiClient(MacAddress.fromString("22:33:44:55:66:77")); + ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = + ArgumentCaptor.forClass(ISoftApCallback.Stub.class); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); + verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), + anyInt()); + + callbackCaptor.getValue().onBlockedClientConnecting(testWifiClient, + WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS); + mLooper.dispatchAll(); + verify(mSoftApCallback).onBlockedClientConnecting(testWifiClient, + WifiManager.SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS); + } + /* * Verify client-provided callback is being called through callback proxy on multiple events */ @Test public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception { + SoftApInfo testSoftApInfo = new SoftApInfo(); + testSoftApInfo.setFrequency(TEST_AP_FREQUENCY); + testSoftApInfo.setBandwidth(TEST_AP_BANDWIDTH); + SoftApCapability testSoftApCapability = new SoftApCapability(0); + testSoftApCapability.setMaxSupportedClients(10); ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); @@ -787,12 +1014,17 @@ public class WifiManagerTest { final List<WifiClient> testClients = new ArrayList(); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_ENABLING, 0); callbackCaptor.getValue().onConnectedClientsChanged(testClients); + callbackCaptor.getValue().onInfoChanged(testSoftApInfo); callbackCaptor.getValue().onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); + callbackCaptor.getValue().onCapabilityChanged(testSoftApCapability); + mLooper.dispatchAll(); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLING, 0); verify(mSoftApCallback).onConnectedClientsChanged(testClients); + verify(mSoftApCallback).onInfoChanged(testSoftApInfo); verify(mSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED, SAP_START_FAILURE_GENERAL); + verify(mSoftApCallback).onCapabilityChanged(testSoftApCapability); } /* @@ -823,6 +1055,7 @@ public class WifiManagerTest { verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); } /** @@ -835,6 +1068,7 @@ public class WifiManagerTest { mLooper.dispatchAll(); assertTrue(observer.mOnRegistered); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); } /** @@ -845,13 +1079,13 @@ public class WifiManagerTest { public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception { // record thread from looper.getThread and check ids. TestLooper altLooper = new TestLooper(); - when(mContext.getMainLooper()).thenReturn(altLooper.getLooper()); + when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor()); TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); mWifiManager.watchLocalOnlyHotspot(observer, null); altLooper.dispatchAll(); assertTrue(observer.mOnRegistered); assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId); - verify(mContext).getMainLooper(); + verify(mContext).getMainExecutor(); } /** @@ -866,8 +1100,7 @@ public class WifiManagerTest { assertFalse(observer.mOnRegistered); assertEquals(null, observer.mSub); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class)); // now trigger the callback observerLooper.dispatchAll(); mLooper.dispatchAll(); @@ -881,24 +1114,23 @@ public class WifiManagerTest { */ @Test public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception { + SoftApConfiguration softApConfig = generatorTestSoftApConfig(); TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); observerLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - msg.obj = mApConfig; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(softApConfig); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertTrue(observer.mOnStartedCalled); - assertEquals(mApConfig, observer.mConfig); + assertEquals(softApConfig, observer.mConfig); } /** @@ -911,15 +1143,14 @@ public class WifiManagerTest { TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); observerLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STARTED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStarted(null); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertFalse(observer.mOnStartedCalled); @@ -937,15 +1168,14 @@ public class WifiManagerTest { TestLooper observerLooper = new TestLooper(); Handler observerHandler = new Handler(observerLooper.getLooper()); mWifiManager.watchLocalOnlyHotspot(observer, observerHandler); - verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(), - any(IBinder.class)); + ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback = + ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class); + verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture()); observerLooper.dispatchAll(); mLooper.dispatchAll(); assertFalse(observer.mOnStoppedCalled); // now trigger the callback - Message msg = new Message(); - msg.what = HOTSPOT_STOPPED; - mMessengerCaptor.getValue().send(msg); + internalCallback.getValue().onHotspotStopped(); mLooper.dispatchAll(); observerLooper.dispatchAll(); assertTrue(observer.mOnStoppedCalled); @@ -974,25 +1204,6 @@ public class WifiManagerTest { } /** - * Verify that calls WifiServiceImpl to set country code when no exception happens. - */ - @Test - public void testSetWifiCountryCode() throws Exception { - mWifiManager.setCountryCode(TEST_COUNTRY_CODE); - verify(mWifiService).setCountryCode(TEST_COUNTRY_CODE); - } - - /** - * Verify that WifiManager.setCountryCode() rethrows exceptions if caller does not - * have necessary permissions. - */ - @Test(expected = SecurityException.class) - public void testSetWifiCountryCodeFailedOnSecurityException() throws Exception { - doThrow(new SecurityException()).when(mWifiService).setCountryCode(anyString()); - mWifiManager.setCountryCode(TEST_COUNTRY_CODE); - } - - /** * Test that calls to get the current WPS config token return null and do not have any * interactions with WifiServiceImpl. */ @@ -1003,7 +1214,7 @@ public class WifiManagerTest { } - class WpsCallbackTester extends WifiManager.WpsCallback { + class WpsCallbackTester extends WpsCallback { public boolean mStarted = false; public boolean mSucceeded = false; public boolean mFailed = false; @@ -1035,7 +1246,7 @@ public class WifiManagerTest { WpsCallbackTester wpsCallback = new WpsCallbackTester(); mWifiManager.startWps(null, wpsCallback); assertTrue(wpsCallback.mFailed); - assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode); + assertEquals(ERROR, wpsCallback.mFailureCode); assertFalse(wpsCallback.mStarted); assertFalse(wpsCallback.mSucceeded); verifyNoMoreInteractions(mWifiService); @@ -1058,7 +1269,7 @@ public class WifiManagerTest { WpsCallbackTester wpsCallback = new WpsCallbackTester(); mWifiManager.cancelWps(wpsCallback); assertTrue(wpsCallback.mFailed); - assertEquals(WifiManager.ERROR, wpsCallback.mFailureCode); + assertEquals(ERROR, wpsCallback.mFailureCode); assertFalse(wpsCallback.mStarted); assertFalse(wpsCallback.mSucceeded); verifyNoMoreInteractions(mWifiService); @@ -1111,14 +1322,53 @@ public class WifiManagerTest { } /** + * Verify that a successful call properly returns true. + */ + @Test + public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception { + SoftApConfiguration apConfig = generatorTestSoftApConfig(); + + when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) + .thenReturn(true); + assertTrue(mWifiManager.setSoftApConfiguration(apConfig)); + } + + /** + * Verify that a failed call properly returns false. + */ + @Test + public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception { + SoftApConfiguration apConfig = generatorTestSoftApConfig(); + + when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME))) + .thenReturn(false); + assertFalse(mWifiManager.setSoftApConfiguration(apConfig)); + } + + /** + * Verify Exceptions are rethrown when underlying calls to WifiService throw exceptions. + */ + @Test + public void testSetSoftApConfigurationRethrowsException() throws Exception { + doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any()); + + try { + mWifiManager.setSoftApConfiguration(generatorTestSoftApConfig()); + fail("setWifiApConfiguration should rethrow Exceptions from WifiService"); + } catch (SecurityException e) { } + } + + /** * Check the call to startScan calls WifiService. */ @Test public void testStartScan() throws Exception { - when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(true); + when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn( + true); assertTrue(mWifiManager.startScan()); - when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(false); + when(mWifiService.startScan(eq(TEST_PACKAGE_NAME), nullable(String.class))).thenReturn( + false); assertFalse(mWifiManager.startScan()); } @@ -1128,10 +1378,10 @@ public class WifiManagerTest { @Test public void registerTrafficStateCallbackUsesMainLooperOnNullArgumentForHandler() throws Exception { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, null); + mWifiManager.registerTrafficStateCallback( + new HandlerExecutor(new Handler(mLooper.getLooper())), mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1147,7 +1397,8 @@ public class WifiManagerTest { @Test public void unregisterTrafficStateCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler); + mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler), + mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback(any(IBinder.class), any(ITrafficStateCallback.Stub.class), callbackIdentifier.capture()); @@ -1163,7 +1414,8 @@ public class WifiManagerTest { public void trafficStateCallbackProxyCallsOnMultipleUpdates() throws Exception { ArgumentCaptor<ITrafficStateCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, mHandler); + mWifiManager.registerTrafficStateCallback(new HandlerExecutor(mHandler), + mTrafficStateCallback); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1182,7 +1434,7 @@ public class WifiManagerTest { TrafficStateCallback.DATA_ACTIVITY_OUT); } - /* + /** * Verify client-provided callback is being called on the correct thread */ @Test @@ -1191,8 +1443,10 @@ public class WifiManagerTest { ArgumentCaptor.forClass(ITrafficStateCallback.Stub.class); TestLooper altLooper = new TestLooper(); Handler altHandler = new Handler(altLooper.getLooper()); - mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, altHandler); + mWifiManager.registerTrafficStateCallback(new HandlerExecutor(altHandler), + mTrafficStateCallback); verify(mContext, never()).getMainLooper(); + verify(mContext, never()).getMainExecutor(); verify(mWifiService).registerTrafficStateCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1208,10 +1462,11 @@ public class WifiManagerTest { @Test public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null); + mWifiManager.registerNetworkRequestMatchCallback( + new HandlerExecutor(new Handler(mLooper.getLooper())), + mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1245,7 +1500,8 @@ public class WifiManagerTest { @Test public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, mHandler); + mWifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler), + mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), any(INetworkRequestMatchCallback.class), callbackIdentifier.capture()); @@ -1262,10 +1518,11 @@ public class WifiManagerTest { @Test public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl() throws Exception { - when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class); - mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null); + mWifiManager.registerNetworkRequestMatchCallback( + new HandlerExecutor(new Handler(mLooper.getLooper())), + mNetworkRequestMatchCallback); verify(mWifiService).registerNetworkRequestMatchCallback( any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -1293,14 +1550,15 @@ public class WifiManagerTest { */ @Test public void testGetAllMatchingWifiConfigs() throws Exception { - Map<String, List<ScanResult>> fqdns = new HashMap<>(); - fqdns.put("www.test.com", new ArrayList<>()); - when(mWifiService.getAllMatchingFqdnsForScanResults(any(List.class))).thenReturn(fqdns); + Map<String, List<ScanResult>> passpointProfiles = new HashMap<>(); + passpointProfiles.put("www.test.com_987a69bca26", new ArrayList<>()); + when(mWifiService.getAllMatchingPasspointProfilesForScanResults( + any(List.class))).thenReturn(passpointProfiles); InOrder inOrder = inOrder(mWifiService); mWifiManager.getAllMatchingWifiConfigs(new ArrayList<>()); - inOrder.verify(mWifiService).getAllMatchingFqdnsForScanResults(any(List.class)); + inOrder.verify(mWifiService).getAllMatchingPasspointProfilesForScanResults(any(List.class)); inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any(List.class)); } @@ -1316,21 +1574,29 @@ public class WifiManagerTest { } /** - * Verify calls to {@link WifiManager#addNetworkSuggestions(List)} and + * Verify calls to {@link WifiManager#addNetworkSuggestions(List)}, + * {@link WifiManager#getNetworkSuggestions()} and * {@link WifiManager#removeNetworkSuggestions(List)}. */ @Test - public void addRemoveNetworkSuggestions() throws Exception { - when(mWifiService.addNetworkSuggestions(any(List.class), anyString())) - .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); - when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())) - .thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); + public void addGetRemoveNetworkSuggestions() throws Exception { + List<WifiNetworkSuggestion> testList = new ArrayList<>(); + when(mWifiService.addNetworkSuggestions(any(List.class), anyString(), + nullable(String.class))).thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS); + when(mWifiService.removeNetworkSuggestions(any(List.class), anyString())).thenReturn( + STATUS_NETWORK_SUGGESTIONS_SUCCESS); + when(mWifiService.getNetworkSuggestions(anyString())) + .thenReturn(testList); + + assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS, + mWifiManager.addNetworkSuggestions(testList)); + verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME), + nullable(String.class)); - assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, - mWifiManager.addNetworkSuggestions(new ArrayList<>())); - verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME)); + assertEquals(testList, mWifiManager.getNetworkSuggestions()); + verify(mWifiService).getNetworkSuggestions(eq(TEST_PACKAGE_NAME)); - assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS, mWifiManager.removeNetworkSuggestions(new ArrayList<>())); verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME)); } @@ -1340,8 +1606,15 @@ public class WifiManagerTest { */ @Test public void getMaxNumberOfNetworkSuggestionsPerApp() { - assertEquals(WifiManager.NETWORK_SUGGESTIONS_MAX_PER_APP, - mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp()); + when(mContext.getSystemServiceName(ActivityManager.class)) + .thenReturn(Context.ACTIVITY_SERVICE); + when(mContext.getSystemService(Context.ACTIVITY_SERVICE)) + .thenReturn(mActivityManager); + when(mActivityManager.isLowRamDevice()).thenReturn(true); + assertEquals(256, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp()); + + when(mActivityManager.isLowRamDevice()).thenReturn(false); + assertEquals(1024, mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp()); } /** @@ -1382,24 +1655,15 @@ public class WifiManagerTest { } /** - * Defined for testing purpose. - */ - class SynchronousExecutor implements Executor { - public void execute(Runnable r) { - r.run(); - } - } - - /** * Test behavior of isEnhancedOpenSupported */ @Test public void testIsEnhancedOpenSupported() throws Exception { when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(WifiManager.WIFI_FEATURE_OWE)); + .thenReturn(new Long(WIFI_FEATURE_OWE)); assertTrue(mWifiManager.isEnhancedOpenSupported()); when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(~WifiManager.WIFI_FEATURE_OWE)); + .thenReturn(new Long(~WIFI_FEATURE_OWE)); assertFalse(mWifiManager.isEnhancedOpenSupported()); } @@ -1409,10 +1673,10 @@ public class WifiManagerTest { @Test public void testIsWpa3SaeSupported() throws Exception { when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SAE)); + .thenReturn(new Long(WIFI_FEATURE_WPA3_SAE)); assertTrue(mWifiManager.isWpa3SaeSupported()); when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SAE)); + .thenReturn(new Long(~WIFI_FEATURE_WPA3_SAE)); assertFalse(mWifiManager.isWpa3SaeSupported()); } @@ -1422,10 +1686,10 @@ public class WifiManagerTest { @Test public void testIsWpa3SuiteBSupported() throws Exception { when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SUITE_B)); + .thenReturn(new Long(WIFI_FEATURE_WPA3_SUITE_B)); assertTrue(mWifiManager.isWpa3SuiteBSupported()); when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SUITE_B)); + .thenReturn(new Long(~WIFI_FEATURE_WPA3_SUITE_B)); assertFalse(mWifiManager.isWpa3SuiteBSupported()); } @@ -1435,10 +1699,10 @@ public class WifiManagerTest { @Test public void testIsEasyConnectSupported() throws Exception { when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(WifiManager.WIFI_FEATURE_DPP)); + .thenReturn(new Long(WIFI_FEATURE_DPP)); assertTrue(mWifiManager.isEasyConnectSupported()); when(mWifiService.getSupportedFeatures()) - .thenReturn(new Long(~WifiManager.WIFI_FEATURE_DPP)); + .thenReturn(new Long(~WIFI_FEATURE_DPP)); assertFalse(mWifiManager.isEasyConnectSupported()); } @@ -1502,6 +1766,49 @@ public class WifiManagerTest { } /** + * Test behavior of {@link WifiManager#allowAutojoin(int, boolean)} + * @throws Exception + */ + @Test + public void testAllowAutojoin() throws Exception { + mWifiManager.allowAutojoin(1, true); + verify(mWifiService).allowAutojoin(1, true); + } + + /** + * Test behavior of {@link WifiManager#allowAutojoinPasspoint(String, boolean)} + * @throws Exception + */ + @Test + public void testAllowAutojoinPasspoint() throws Exception { + final String fqdn = "FullyQualifiedDomainName"; + mWifiManager.allowAutojoinPasspoint(fqdn, true); + verify(mWifiService).allowAutojoinPasspoint(fqdn, true); + } + + /** + * Test behavior of + * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)} + */ + @Test + public void testSetMacRandomizationSettingPasspointEnabled() throws Exception { + final String fqdn = "FullyQualifiedDomainName"; + mWifiManager.setMacRandomizationSettingPasspointEnabled(fqdn, true); + verify(mWifiService).setMacRandomizationSettingPasspointEnabled(fqdn, true); + } + + /** + * Test behavior of + * {@link WifiManager#setMacRandomizationSettingPasspointEnabled(String, boolean)} + */ + @Test + public void testSetPasspointMeteredOverride() throws Exception { + final String fqdn = "FullyQualifiedDomainName"; + mWifiManager.setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED); + verify(mWifiService).setPasspointMeteredOverride(fqdn, METERED_OVERRIDE_METERED); + } + + /** * Test behavior of {@link WifiManager#disconnect()} */ @Test @@ -1537,9 +1844,9 @@ public class WifiManagerTest { @Test public void testGetSupportedFeatures() throws Exception { long supportedFeatures = - WifiManager.WIFI_FEATURE_SCANNER - | WifiManager.WIFI_FEATURE_PASSPOINT - | WifiManager.WIFI_FEATURE_P2P; + WIFI_FEATURE_SCANNER + | WIFI_FEATURE_PASSPOINT + | WIFI_FEATURE_P2P; when(mWifiService.getSupportedFeatures()) .thenReturn(Long.valueOf(supportedFeatures)); @@ -1547,7 +1854,6 @@ public class WifiManagerTest { assertTrue(mWifiManager.isPasspointSupported()); assertTrue(mWifiManager.isP2pSupported()); assertFalse(mWifiManager.isPortableHotspotSupported()); - assertFalse(mWifiManager.is5GHzBandSupported()); assertFalse(mWifiManager.isDeviceToDeviceRttSupported()); assertFalse(mWifiManager.isDeviceToApRttSupported()); assertFalse(mWifiManager.isPreferredNetworkOffloadSupported()); @@ -1558,15 +1864,55 @@ public class WifiManagerTest { } /** - * Test behavior of {@link WifiManager#getControllerActivityEnergyInfo()} + * Tests that passing a null Executor to {@link WifiManager#getWifiActivityEnergyInfoAsync} + * throws an exception. + */ + @Test(expected = NullPointerException.class) + public void testGetWifiActivityInfoNullExecutor() throws Exception { + mWifiManager.getWifiActivityEnergyInfoAsync(null, mOnWifiActivityEnergyInfoListener); + } + + /** + * Tests that passing a null listener to {@link WifiManager#getWifiActivityEnergyInfoAsync} + * throws an exception. */ + @Test(expected = NullPointerException.class) + public void testGetWifiActivityInfoNullListener() throws Exception { + mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, null); + } + + /** Tests that the listener runs on the correct Executor. */ + @Test + public void testGetWifiActivityInfoRunsOnCorrectExecutor() throws Exception { + mWifiManager.getWifiActivityEnergyInfoAsync(mExecutor, mOnWifiActivityEnergyInfoListener); + ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor = + ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class); + verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture()); + IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue(); + listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); + verify(mExecutor).execute(any()); + + // ensure that the executor is only triggered once + listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); + verify(mExecutor).execute(any()); + } + + /** Tests that the correct listener runs. */ @Test - public void testGetControllerActivityEnergyInfo() throws Exception { - WifiActivityEnergyInfo activityEnergyInfo = - new WifiActivityEnergyInfo(5, 3, 3, new long[]{5L, 5L, 5L}, 5, 5, 5, 5); - when(mWifiService.reportActivityInfo()).thenReturn(activityEnergyInfo); + public void testGetWifiActivityInfoRunsCorrectListener() throws Exception { + int[] flag = {0}; + mWifiManager.getWifiActivityEnergyInfoAsync( + new SynchronousExecutor(), info -> flag[0]++); + ArgumentCaptor<IOnWifiActivityEnergyInfoListener> listenerCaptor = + ArgumentCaptor.forClass(IOnWifiActivityEnergyInfoListener.class); + verify(mWifiService).getWifiActivityEnergyInfoAsync(listenerCaptor.capture()); + IOnWifiActivityEnergyInfoListener listener = listenerCaptor.getValue(); + listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); + assertEquals(1, flag[0]); - assertEquals(activityEnergyInfo, mWifiManager.getControllerActivityEnergyInfo()); + // ensure that the listener is only triggered once + listener.onWifiActivityEnergyInfo(mWifiActivityEnergyInfo); + assertEquals(1, flag[0]); } /** @@ -1575,29 +1921,41 @@ public class WifiManagerTest { @Test public void testGetConnectionInfo() throws Exception { WifiInfo wifiInfo = new WifiInfo(); - when(mWifiService.getConnectionInfo(anyString())).thenReturn(wifiInfo); + when(mWifiService.getConnectionInfo(anyString(), nullable(String.class))).thenReturn( + wifiInfo); assertEquals(wifiInfo, mWifiManager.getConnectionInfo()); } /** - * Test behavior of {@link WifiManager#isDualModeSupported()} ()} + * Test behavior of {@link WifiManager#is5GHzBandSupported()} */ @Test - public void testIsDualModeSupported() throws Exception { - when(mWifiService.needs5GHzToAnyApBandConversion()).thenReturn(true); - assertTrue(mWifiManager.isDualModeSupported()); - verify(mWifiService).needs5GHzToAnyApBandConversion(); + public void testIs5GHzBandSupported() throws Exception { + when(mWifiService.is5GHzBandSupported()).thenReturn(true); + assertTrue(mWifiManager.is5GHzBandSupported()); + verify(mWifiService).is5GHzBandSupported(); } /** - * Test behavior of {@link WifiManager#isDualBandSupported()} + * Test behavior of {@link WifiManager#is6GHzBandSupported()} */ @Test - public void testIsDualBandSupported() throws Exception { - when(mWifiService.isDualBandSupported()).thenReturn(true); - assertTrue(mWifiManager.isDualBandSupported()); - verify(mWifiService).isDualBandSupported(); + public void testIs6GHzBandSupported() throws Exception { + when(mWifiService.is6GHzBandSupported()).thenReturn(true); + assertTrue(mWifiManager.is6GHzBandSupported()); + verify(mWifiService).is6GHzBandSupported(); + } + + /** + * Test behavior of {@link WifiManager#isWifiStandardSupported()} + */ + @Test + public void testIsWifiStandardSupported() throws Exception { + int standard = ScanResult.WIFI_STANDARD_11AX; + when(mWifiService.isWifiStandardSupported(standard)).thenReturn(true); + assertTrue(mWifiManager.isWifiStandardSupported(standard)); + verify(mWifiService).isWifiStandardSupported(standard); } /** @@ -1623,4 +1981,409 @@ public class WifiManagerTest { assertTrue(mWifiManager.setWifiEnabled(false)); verify(mWifiService).setWifiEnabled(mContext.getOpPackageName(), false); } + + /** + * Test behavior of {@link WifiManager#connect(int, ActionListener)} + */ + @Test + public void testConnectWithListener() throws Exception { + ActionListener externalListener = mock(ActionListener.class); + mWifiManager.connect(TEST_NETWORK_ID, externalListener); + + ArgumentCaptor<IActionListener> binderListenerCaptor = + ArgumentCaptor.forClass(IActionListener.class); + verify(mWifiService).connect(eq(null), eq(TEST_NETWORK_ID), any(Binder.class), + binderListenerCaptor.capture(), anyInt()); + assertNotNull(binderListenerCaptor.getValue()); + + // Trigger on success. + binderListenerCaptor.getValue().onSuccess(); + mLooper.dispatchAll(); + verify(externalListener).onSuccess(); + + // Trigger on failure. + binderListenerCaptor.getValue().onFailure(BUSY); + mLooper.dispatchAll(); + verify(externalListener).onFailure(BUSY); + } + + /** + * Test behavior of {@link WifiManager#connect(int, ActionListener)} + */ + @Test + public void testConnectWithListenerHandleSecurityException() throws Exception { + doThrow(new SecurityException()).when(mWifiService) + .connect(eq(null), anyInt(), any(IBinder.class), + any(IActionListener.class), anyInt()); + ActionListener externalListener = mock(ActionListener.class); + mWifiManager.connect(TEST_NETWORK_ID, externalListener); + + mLooper.dispatchAll(); + verify(externalListener).onFailure(NOT_AUTHORIZED); + } + + /** + * Test behavior of {@link WifiManager#connect(int, ActionListener)} + */ + @Test + public void testConnectWithListenerHandleRemoteException() throws Exception { + doThrow(new RemoteException()).when(mWifiService) + .connect(eq(null), anyInt(), any(IBinder.class), + any(IActionListener.class), anyInt()); + ActionListener externalListener = mock(ActionListener.class); + mWifiManager.connect(TEST_NETWORK_ID, externalListener); + + mLooper.dispatchAll(); + verify(externalListener).onFailure(ERROR); + } + + /** + * Test behavior of {@link WifiManager#connect(int, ActionListener)} + */ + @Test + public void testConnectWithoutListener() throws Exception { + WifiConfiguration configuration = new WifiConfiguration(); + mWifiManager.connect(configuration, null); + + verify(mWifiService).connect(configuration, WifiConfiguration.INVALID_NETWORK_ID, null, + null, 0); + } + + /** + * Verify an IllegalArgumentException is thrown if callback is not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testRegisterScanResultsCallbackWithNullCallback() throws Exception { + mWifiManager.registerScanResultsCallback(mExecutor, null); + } + + /** + * Verify an IllegalArgumentException is thrown if executor is not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testRegisterCallbackWithNullExecutor() throws Exception { + mWifiManager.registerScanResultsCallback(null, mScanResultsCallback); + } + + /** + * Verify client provided callback is being called to the right callback. + */ + @Test + public void testAddScanResultsCallbackAndReceiveEvent() throws Exception { + ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor = + ArgumentCaptor.forClass(IScanResultsCallback.Stub.class); + mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback); + verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture()); + callbackCaptor.getValue().onScanResultsAvailable(); + verify(mRunnable).run(); + } + + /** + * Verify client provided callback is being called to the right executor. + */ + @Test + public void testRegisterScanResultsCallbackWithTheTargetExecutor() throws Exception { + ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor = + ArgumentCaptor.forClass(IScanResultsCallback.Stub.class); + mWifiManager.registerScanResultsCallback(mExecutor, mScanResultsCallback); + verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture()); + mWifiManager.registerScanResultsCallback(mAnotherExecutor, mScanResultsCallback); + callbackCaptor.getValue().onScanResultsAvailable(); + verify(mExecutor, never()).execute(any(Runnable.class)); + verify(mAnotherExecutor).execute(any(Runnable.class)); + } + + /** + * Verify client register unregister then register again, to ensure callback still works. + */ + @Test + public void testRegisterUnregisterThenRegisterAgainWithScanResultCallback() throws Exception { + ArgumentCaptor<IScanResultsCallback.Stub> callbackCaptor = + ArgumentCaptor.forClass(IScanResultsCallback.Stub.class); + mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback); + verify(mWifiService).registerScanResultsCallback(callbackCaptor.capture()); + mWifiManager.unregisterScanResultsCallback(mScanResultsCallback); + callbackCaptor.getValue().onScanResultsAvailable(); + verify(mRunnable, never()).run(); + mWifiManager.registerScanResultsCallback(new SynchronousExecutor(), mScanResultsCallback); + callbackCaptor.getValue().onScanResultsAvailable(); + verify(mRunnable).run(); + } + + /** + * Verify client unregisterScanResultsCallback. + */ + @Test + public void testUnregisterScanResultsCallback() throws Exception { + mWifiManager.unregisterScanResultsCallback(mScanResultsCallback); + verify(mWifiService).unregisterScanResultsCallback(any()); + } + + /** + * Verify client unregisterScanResultsCallback with null callback will cause an exception. + */ + @Test(expected = IllegalArgumentException.class) + public void testUnregisterScanResultsCallbackWithNullCallback() throws Exception { + mWifiManager.unregisterScanResultsCallback(null); + } + + /** + * Verify an IllegalArgumentException is thrown if executor not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testAddSuggestionConnectionStatusListenerWithNullExecutor() { + mWifiManager.addSuggestionConnectionStatusListener(null, mListener); + } + + /** + * Verify an IllegalArgumentException is thrown if listener is not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testAddSuggestionConnectionStatusListenerWithNullListener() { + mWifiManager.addSuggestionConnectionStatusListener(mExecutor, null); + } + + /** + * Verify client provided listener is being called to the right listener. + */ + @Test + public void testAddSuggestionConnectionStatusListenerAndReceiveEvent() throws Exception { + int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; + ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor = + ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); + Executor executor = new SynchronousExecutor(); + mWifiManager.addSuggestionConnectionStatusListener(executor, mListener); + verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class), + callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class)); + callbackCaptor.getValue().onConnectionStatus(mWifiNetworkSuggestion, errorCode); + verify(mListener).onConnectionStatus(any(WifiNetworkSuggestion.class), eq(errorCode)); + } + + /** + * Verify client provided listener is being called to the right executor. + */ + @Test + public void testAddSuggestionConnectionStatusListenerWithTheTargetExecutor() throws Exception { + int errorCode = STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION; + ArgumentCaptor<ISuggestionConnectionStatusListener.Stub> callbackCaptor = + ArgumentCaptor.forClass(ISuggestionConnectionStatusListener.Stub.class); + mWifiManager.addSuggestionConnectionStatusListener(mExecutor, mListener); + verify(mWifiService).registerSuggestionConnectionStatusListener(any(IBinder.class), + callbackCaptor.capture(), anyInt(), anyString(), nullable(String.class)); + callbackCaptor.getValue().onConnectionStatus(any(WifiNetworkSuggestion.class), errorCode); + verify(mExecutor).execute(any(Runnable.class)); + } + + /** + * Verify an IllegalArgumentException is thrown if listener is not provided. + */ + @Test(expected = IllegalArgumentException.class) + public void testRemoveSuggestionConnectionListenerWithNullListener() { + mWifiManager.removeSuggestionConnectionStatusListener(null); + } + + /** + * Verify removeSuggestionConnectionListener. + */ + @Test + public void testRemoveSuggestionConnectionListener() throws Exception { + mWifiManager.removeSuggestionConnectionStatusListener(mListener); + verify(mWifiService).unregisterSuggestionConnectionStatusListener(anyInt(), anyString()); + } + + /** Test {@link WifiManager#calculateSignalLevel(int)} */ + @Test + public void testCalculateSignalLevel() throws Exception { + when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(3); + int actual = mWifiManager.calculateSignalLevel(-60); + verify(mWifiService).calculateSignalLevel(-60); + assertEquals(3, actual); + } + + /** Test {@link WifiManager#getMaxSignalLevel()} */ + @Test + public void testGetMaxSignalLevel() throws Exception { + when(mWifiService.calculateSignalLevel(anyInt())).thenReturn(4); + int actual = mWifiManager.getMaxSignalLevel(); + verify(mWifiService).calculateSignalLevel(Integer.MAX_VALUE); + assertEquals(4, actual); + } + + /* + * Test behavior of isWapiSupported + * @throws Exception + */ + @Test + public void testIsWapiSupported() throws Exception { + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(WifiManager.WIFI_FEATURE_WAPI)); + assertTrue(mWifiManager.isWapiSupported()); + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WAPI)); + assertFalse(mWifiManager.isWapiSupported()); + } + + /* + * Test that DPP channel list is parsed correctly + */ + @Test + public void testparseDppChannelList() throws Exception { + String channelList = "81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48"; + SparseArray<int[]> expectedResult = new SparseArray<>(); + expectedResult.append(81, new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}); + expectedResult.append(115, new int[]{36, 40, 44, 48}); + + SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList); + assertEquals(expectedResult.size(), result.size()); + + int index = 0; + int key; + + // Compare the two primitive int arrays + do { + try { + key = result.keyAt(index); + } catch (java.lang.ArrayIndexOutOfBoundsException e) { + break; + } + int[] expected = expectedResult.get(key); + int[] output = result.get(key); + assertEquals(expected.length, output.length); + for (int i = 0; i < output.length; i++) { + assertEquals(expected[i], output[i]); + } + index++; + } while (true); + } + + /* + * Test that DPP channel list parser gracefully fails for invalid input + */ + @Test + public void testparseDppChannelListWithInvalidFormats() throws Exception { + String channelList = "1,2,3,4,5,6,7,8,9,10,11,36,40,44,48"; + SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + + channelList = "ajgalskgjalskjg3-09683dh"; + result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + + channelList = "13/abc,46////"; + result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + + channelList = "11/4,5,13/"; + result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + + channelList = "/24,6"; + result = WifiManager.parseDppChannelList(channelList); + assertEquals(result.size(), 0); + } + + /** + * Test getWifiConfigsForMatchedNetworkSuggestions for given scanResults. + */ + @Test + public void testGetWifiConfigsForMatchedNetworkSuggestions() throws Exception { + List<WifiConfiguration> testResults = new ArrayList<>(); + testResults.add(new WifiConfiguration()); + + when(mWifiService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any(List.class))) + .thenReturn(testResults); + assertEquals(testResults, mWifiManager + .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>())); + } + + /** + * Verify the call to setWifiConnectedNetworkScorer goes to WifiServiceImpl. + */ + @Test + public void setWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception { + mExecutor = new SynchronousExecutor(); + mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); + verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), + any(IWifiConnectedNetworkScorer.Stub.class)); + } + + /** + * Verify the call to clearWifiConnectedNetworkScorer goes to WifiServiceImpl. + */ + @Test + public void clearWifiConnectedNetworkScorerGoesToWifiServiceImpl() throws Exception { + mExecutor = new SynchronousExecutor(); + mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); + verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), + any(IWifiConnectedNetworkScorer.Stub.class)); + + mWifiManager.clearWifiConnectedNetworkScorer(); + verify(mWifiService).clearWifiConnectedNetworkScorer(); + } + + /** + * Verify that Wi-Fi connected scorer receives score update observer after registeration. + */ + @Test + public void verifyScorerReceiveScoreUpdateObserverAfterRegistration() throws Exception { + mExecutor = new SynchronousExecutor(); + mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); + ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> scorerCaptor = + ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class); + verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), + scorerCaptor.capture()); + scorerCaptor.getValue().onSetScoreUpdateObserver(any()); + mLooper.dispatchAll(); + verify(mWifiConnectedNetworkScorer).onSetScoreUpdateObserver(any()); + } + + /** + * Verify that Wi-Fi connected scorer receives session ID when onStart/onStop methods + * are called. + */ + @Test + public void verifyScorerReceiveSessionIdWhenStartStopIsCalled() throws Exception { + mExecutor = new SynchronousExecutor(); + mWifiManager.setWifiConnectedNetworkScorer(mExecutor, mWifiConnectedNetworkScorer); + ArgumentCaptor<IWifiConnectedNetworkScorer.Stub> callbackCaptor = + ArgumentCaptor.forClass(IWifiConnectedNetworkScorer.Stub.class); + verify(mWifiService).setWifiConnectedNetworkScorer(any(IBinder.class), + callbackCaptor.capture()); + callbackCaptor.getValue().onStart(0); + callbackCaptor.getValue().onStop(10); + mLooper.dispatchAll(); + verify(mWifiConnectedNetworkScorer).onStart(0); + verify(mWifiConnectedNetworkScorer).onStop(10); + } + + @Test + public void testScanThrottle() throws Exception { + mWifiManager.setScanThrottleEnabled(true); + verify(mWifiService).setScanThrottleEnabled(true); + + when(mWifiService.isScanThrottleEnabled()).thenReturn(false); + assertFalse(mWifiManager.isScanThrottleEnabled()); + verify(mWifiService).isScanThrottleEnabled(); + } + + @Test + public void testAutoWakeup() throws Exception { + mWifiManager.setAutoWakeupEnabled(true); + verify(mWifiService).setAutoWakeupEnabled(true); + + when(mWifiService.isAutoWakeupEnabled()).thenReturn(false); + assertFalse(mWifiManager.isAutoWakeupEnabled()); + verify(mWifiService).isAutoWakeupEnabled(); + } + + + @Test + public void testScanAvailable() throws Exception { + mWifiManager.setScanAlwaysAvailable(true); + verify(mWifiService).setScanAlwaysAvailable(true); + + when(mWifiService.isScanAlwaysAvailable()).thenReturn(false); + assertFalse(mWifiManager.isScanAlwaysAvailable()); + verify(mWifiService).isScanAlwaysAvailable(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java index b58b3215e5ea..d479aacdd296 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java @@ -35,10 +35,6 @@ import org.junit.Test; */ @SmallTest public class WifiNetworkAgentSpecifierTest { - private static final int TEST_UID = 5; - private static final int TEST_UID_1 = 8; - private static final String TEST_PACKAGE = "com.test"; - private static final String TEST_PACKAGE_1 = "com.test.1"; private static final String TEST_SSID = "Test123"; private static final String TEST_SSID_PATTERN = "Test"; private static final String TEST_SSID_1 = "456test"; @@ -94,15 +90,13 @@ public class WifiNetworkAgentSpecifierTest { WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration(); WifiNetworkAgentSpecifier specifier1 = new WifiNetworkAgentSpecifier( - wifiConfiguration1, - TEST_UID, TEST_PACKAGE); + wifiConfiguration1); WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1); wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkAgentSpecifier specifier2 = new WifiNetworkAgentSpecifier( - wifiConfiguration2, - TEST_UID, TEST_PACKAGE); + wifiConfiguration2); assertFalse(specifier2.equals(specifier1)); } @@ -118,15 +112,13 @@ public class WifiNetworkAgentSpecifierTest { WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration(); WifiNetworkAgentSpecifier specifier1 = new WifiNetworkAgentSpecifier( - wifiConfiguration1, - TEST_UID, TEST_PACKAGE); + wifiConfiguration1); WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1); wifiConfiguration2.SSID = TEST_SSID_1; WifiNetworkAgentSpecifier specifier2 = new WifiNetworkAgentSpecifier( - wifiConfiguration2, - TEST_UID, TEST_PACKAGE); + wifiConfiguration2); assertFalse(specifier2.equals(specifier1)); } @@ -142,15 +134,13 @@ public class WifiNetworkAgentSpecifierTest { WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration(); WifiNetworkAgentSpecifier specifier1 = new WifiNetworkAgentSpecifier( - wifiConfiguration1, - TEST_UID, TEST_PACKAGE); + wifiConfiguration1); WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1); wifiConfiguration2.BSSID = TEST_BSSID_1; WifiNetworkAgentSpecifier specifier2 = new WifiNetworkAgentSpecifier( - wifiConfiguration2, - TEST_UID, TEST_PACKAGE); + wifiConfiguration2); assertFalse(specifier2.equals(specifier1)); } @@ -197,15 +187,14 @@ public class WifiNetworkAgentSpecifierTest { PatternMatcher ssidPattern = new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX); Pair<MacAddress, MacAddress> bssidPattern = - Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS); WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration(); wificonfigurationNetworkSpecifier.allowedKeyManagement .set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier)); assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier)); @@ -233,8 +222,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier)); assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier)); @@ -262,8 +250,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertTrue(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier)); assertTrue(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier)); @@ -282,21 +269,19 @@ public class WifiNetworkAgentSpecifierTest { wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\""; WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = new WifiNetworkAgentSpecifier( - wifiConfigurationNetworkAgent, - TEST_UID, TEST_PACKAGE); + wifiConfigurationNetworkAgent); PatternMatcher ssidPattern = new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX); Pair<MacAddress, MacAddress> bssidPattern = - Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS); + Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, WifiManager.ALL_ZEROS_MAC_ADDRESS); WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration(); wificonfigurationNetworkSpecifier.allowedKeyManagement .set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier)); assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier)); @@ -315,8 +300,7 @@ public class WifiNetworkAgentSpecifierTest { wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1; WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = new WifiNetworkAgentSpecifier( - wifiConfigurationNetworkAgent, - TEST_UID, TEST_PACKAGE); + wifiConfigurationNetworkAgent); PatternMatcher ssidPattern = new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB); @@ -329,8 +313,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier)); assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier)); @@ -349,8 +332,7 @@ public class WifiNetworkAgentSpecifierTest { wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1; WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = new WifiNetworkAgentSpecifier( - wifiConfigurationNetworkAgent, - TEST_UID, TEST_PACKAGE); + wifiConfigurationNetworkAgent); PatternMatcher ssidPattern = new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX); @@ -363,8 +345,7 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier)); assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier)); @@ -391,41 +372,12 @@ public class WifiNetworkAgentSpecifierTest { WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( ssidPattern, bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID, TEST_PACKAGE); + wificonfigurationNetworkSpecifier); assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier)); assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier)); } - /** - * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching. - * a) Create network agent specifier for WPA_PSK network - * b) Create network specifier with matching SSID and BSSID pattern, but different UID. - * c) Ensure that the agent specifier is not satisfied by specifier. - */ - @Test - public void - testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentUid() { - WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier(); - - PatternMatcher ssidPattern = - new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX); - Pair<MacAddress, MacAddress> bssidPattern = - Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), - MacAddress.fromString(TEST_BSSID_OUI_MASK)); - WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration(); - wificonfigurationNetworkSpecifier.allowedKeyManagement - .set(WifiConfiguration.KeyMgmt.WPA_PSK); - WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier( - ssidPattern, - bssidPattern, - wificonfigurationNetworkSpecifier, - TEST_UID_1, TEST_PACKAGE_1); - - assertFalse(wifiNetworkSpecifier.canBeSatisfiedBy(wifiNetworkAgentSpecifier)); - assertFalse(wifiNetworkAgentSpecifier.canBeSatisfiedBy(wifiNetworkSpecifier)); - } private WifiConfiguration createDefaultWifiConfiguration() { WifiConfiguration wifiConfiguration = new WifiConfiguration(); @@ -437,8 +389,7 @@ public class WifiNetworkAgentSpecifierTest { } private WifiNetworkAgentSpecifier createDefaultNetworkAgentSpecifier() { - return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration(), TEST_UID, - TEST_PACKAGE); + return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration()); } } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java index 5261e7ac83e4..fc0ef469ad80 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java @@ -29,7 +29,6 @@ import android.net.MatchAllNetworkSpecifier; import android.net.NetworkSpecifier; import android.os.Parcel; import android.os.PatternMatcher; -import android.os.Process; import android.util.Pair; import androidx.test.filters.SmallTest; @@ -41,8 +40,6 @@ import org.junit.Test; */ @SmallTest public class WifiNetworkSpecifierTest { - private static final int TEST_UID = 5; - private static final String TEST_PACKAGE_NAME = "com.test"; private static final String TEST_SSID = "Test123"; private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00"; private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00"; @@ -62,11 +59,12 @@ public class WifiNetworkSpecifierTest { assertTrue(specifier instanceof WifiNetworkSpecifier); WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier; - assertEquals(Process.myUid(), wifiNetworkSpecifier.requestorUid); assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath()); assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType()); - assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.first); - assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.second); + assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS, + wifiNetworkSpecifier.bssidPatternMatcher.first); + assertEquals(WifiManager.ALL_ZEROS_MAC_ADDRESS, + wifiNetworkSpecifier.bssidPatternMatcher.second); assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.NONE)); } @@ -210,7 +208,8 @@ public class WifiNetworkSpecifierTest { @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithMatchAllBssidPattern() { new WifiNetworkSpecifier.Builder() - .setBssidPattern(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS) + .setBssidPattern(WifiManager.ALL_ZEROS_MAC_ADDRESS, + WifiManager.ALL_ZEROS_MAC_ADDRESS) .build(); } @@ -265,7 +264,7 @@ public class WifiNetworkSpecifierTest { @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern3() { new WifiNetworkSpecifier.Builder() - .setBssid(MacAddress.ALL_ZEROS_ADDRESS) + .setBssid(WifiManager.ALL_ZEROS_MAC_ADDRESS) .build(); } @@ -364,8 +363,7 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); Parcel parcelW = Parcel.obtain(); specifier.writeToParcel(parcelW, 0); @@ -384,11 +382,11 @@ public class WifiNetworkSpecifierTest { /** * Validate NetworkSpecifier matching. * a) Create a network specifier for WPA_PSK network - * b) Ensure that the specifier matches {@code null} and {@link MatchAllNetworkSpecifier} + * b) Ensure that the specifier does not match {@code null} and {@link MatchAllNetworkSpecifier} * specifiers. */ @Test - public void testWifiNetworkSpecifierSatisfiesNullAndAllMatch() { + public void testWifiNetworkSpecifierDoesNotSatisfyNullAndAllMatch() { WifiConfiguration wifiConfiguration = new WifiConfiguration(); wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY; @@ -396,11 +394,10 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); - assertTrue(specifier.canBeSatisfiedBy(null)); - assertTrue(specifier.canBeSatisfiedBy(new MatchAllNetworkSpecifier())); + assertFalse(specifier.canBeSatisfiedBy(null)); + assertFalse(specifier.canBeSatisfiedBy(new MatchAllNetworkSpecifier())); } /** @@ -419,15 +416,13 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); assertTrue(specifier2.canBeSatisfiedBy(specifier1)); } @@ -448,8 +443,7 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration1, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration1); WifiConfiguration wifiConfiguration2 = new WifiConfiguration(); wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); @@ -457,8 +451,7 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration2, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration2); assertFalse(specifier2.canBeSatisfiedBy(specifier1)); } @@ -479,15 +472,13 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher("", PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); assertFalse(specifier2.canBeSatisfiedBy(specifier1)); } @@ -508,43 +499,13 @@ public class WifiNetworkSpecifierTest { new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); + wifiConfiguration); WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), - Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); - - assertFalse(specifier2.canBeSatisfiedBy(specifier1)); - } - - /** - * Validate NetworkSpecifier matching. - * a) Create network specifier 1 for WPA_PSK network - * b) Create network specifier 2 with different package name . - * c) Ensure that the specifier 2 is not satisfied by specifier 1. - */ - @Test - public void testWifiNetworkSpecifierDoesNotSatisfyWhenPackageNameDifferent() { - WifiConfiguration wifiConfiguration = new WifiConfiguration(); - wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); - wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY; - - WifiNetworkSpecifier specifier1 = - new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), - Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), - MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME); - - WifiNetworkSpecifier specifier2 = - new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL), - Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), - MacAddress.fromString(TEST_BSSID_OUI_MASK)), - wifiConfiguration, - TEST_UID, TEST_PACKAGE_NAME + "blah"); + Pair.create(WifiManager.ALL_ZEROS_MAC_ADDRESS, + WifiManager.ALL_ZEROS_MAC_ADDRESS), + wifiConfiguration); assertFalse(specifier2.canBeSatisfiedBy(specifier1)); } diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 4dfa96b8c606..16b4ad08a830 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -19,8 +19,9 @@ package android.net.wifi; import static org.junit.Assert.*; import android.net.MacAddress; +import android.net.wifi.hotspot2.PasspointConfiguration; +import android.net.wifi.hotspot2.PasspointTestUtils; import android.os.Parcel; -import android.os.Process; import androidx.test.filters.SmallTest; @@ -31,14 +32,13 @@ import org.junit.Test; */ @SmallTest public class WifiNetworkSuggestionTest { - private static final int TEST_UID = 45677; - private static final int TEST_UID_OTHER = 45673; - private static final String TEST_PACKAGE_NAME = "com.test.packagename"; - private static final String TEST_PACKAGE_NAME_OTHER = "com.test.packagenameother"; private static final String TEST_SSID = "\"Test123\""; private static final String TEST_BSSID = "12:12:12:12:12:12"; private static final String TEST_SSID_1 = "\"Test1234\""; private static final String TEST_PRESHARED_KEY = "Test123"; + private static final String TEST_FQDN = "fqdn"; + private static final String TEST_WAPI_CERT_SUITE = "suite"; + private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch"; /** * Validate correctness of WifiNetworkSuggestion object created by @@ -52,7 +52,6 @@ public class WifiNetworkSuggestionTest { .setIsAppInteractionRequired(true) .build(); - assertEquals(Process.myUid(), suggestion.suggestorUid); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.NONE)); @@ -61,12 +60,14 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, suggestion.wifiConfiguration.meteredOverride); assertEquals(-1, suggestion.wifiConfiguration.priority); + assertFalse(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); } /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkSuggestion.Builder#build()} for WPA_EAP network which requires - * app interaction and has a priority of zero set. + * app interaction, not share credential and has a priority of zero set. */ @Test public void @@ -75,6 +76,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsAppInteractionRequired(true) + .setCredentialSharedWithUser(false) .setPriority(0) .build(); @@ -88,6 +90,8 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, suggestion.wifiConfiguration.meteredOverride); assertEquals(0, suggestion.wifiConfiguration.priority); + assertFalse(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); } /** @@ -102,6 +106,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsUserInteractionRequired(true) + .setIsInitialAutojoinEnabled(false) .setIsMetered(true) .build(); @@ -115,6 +120,38 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED, suggestion.wifiConfiguration.meteredOverride); assertEquals(-1, suggestion.wifiConfiguration.priority); + assertTrue(suggestion.isUserAllowedToManuallyConnect); + assertFalse(suggestion.isInitialAutoJoinEnabled); + } + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WPA_PSK network which requires + * user interaction and is not metered. + */ + @Test + public void + testWifiNetworkSuggestionBuilderForWpa2PskNetworkWithNotMeteredAndReqUserInteraction() { + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa2Passphrase(TEST_PRESHARED_KEY) + .setIsUserInteractionRequired(true) + .setIsInitialAutojoinEnabled(false) + .setIsMetered(false) + .build(); + + assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WPA_PSK)); + assertEquals("\"" + TEST_PRESHARED_KEY + "\"", + suggestion.wifiConfiguration.preSharedKey); + assertFalse(suggestion.isAppInteractionRequired); + assertTrue(suggestion.isUserInteractionRequired); + assertEquals(WifiConfiguration.METERED_OVERRIDE_NOT_METERED, + suggestion.wifiConfiguration.meteredOverride); + assertEquals(-1, suggestion.wifiConfiguration.priority); + assertTrue(suggestion.isUserAllowedToManuallyConnect); + assertFalse(suggestion.isInitialAutoJoinEnabled); } /** @@ -134,7 +171,9 @@ public class WifiNetworkSuggestionTest { assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.OWE)); assertNull(suggestion.wifiConfiguration.preSharedKey); - assertTrue(suggestion.wifiConfiguration.requirePMF); + assertTrue(suggestion.wifiConfiguration.requirePmf); + assertFalse(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); } /** @@ -146,6 +185,8 @@ public class WifiNetworkSuggestionTest { WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) .setWpa3Passphrase(TEST_PRESHARED_KEY) + .setCredentialSharedWithUser(true) + .setIsInitialAutojoinEnabled(false) .build(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); @@ -153,7 +194,9 @@ public class WifiNetworkSuggestionTest { .get(WifiConfiguration.KeyMgmt.SAE)); assertEquals("\"" + TEST_PRESHARED_KEY + "\"", suggestion.wifiConfiguration.preSharedKey); - assertTrue(suggestion.wifiConfiguration.requirePMF); + assertTrue(suggestion.wifiConfiguration.requirePmf); + assertTrue(suggestion.isUserAllowedToManuallyConnect); + assertFalse(suggestion.isInitialAutoJoinEnabled); } @@ -166,6 +209,8 @@ public class WifiNetworkSuggestionTest { WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); + enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0); + enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) @@ -179,10 +224,149 @@ public class WifiNetworkSuggestionTest { .get(WifiConfiguration.GroupCipher.GCMP_256)); assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); - assertTrue(suggestion.wifiConfiguration.requirePMF); + assertTrue(suggestion.wifiConfiguration.requirePmf); assertNull(suggestion.wifiConfiguration.preSharedKey); // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested // here. + assertTrue(suggestion.isUserAllowedToManuallyConnect); + assertTrue(suggestion.isInitialAutoJoinEnabled); + } + + /** + * Ensure create enterprise suggestion requires CA, when CA certificate is missing, will throw + * an exception. + */ + @Test (expected = IllegalArgumentException.class) + public void testWifiNetworkSuggestionBuilderForEapNetworkWithoutCa() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); + enterpriseConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH); + + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa2EnterpriseConfig(enterpriseConfig) + .build(); + } + + /** + * Ensure create enterprise suggestion requires CA, when both domain suffix and alt subject + * match are missing, will throw an exception. + */ + @Test (expected = IllegalArgumentException.class) + public void testWifiNetworkSuggestionBuilderForEapNetworkWithoutMatch() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); + enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); + enterpriseConfig.setCaCertificate(FakeKeys.CA_CERT0); + + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa3EnterpriseConfig(enterpriseConfig) + .build(); + } + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-PSK network. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWapiPskNetwork() { + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWapiPassphrase(TEST_PRESHARED_KEY) + .build(); + + assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WAPI_PSK)); + assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers + .get(WifiConfiguration.PairwiseCipher.SMS4)); + assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.SMS4)); + assertEquals("\"" + TEST_PRESHARED_KEY + "\"", + suggestion.wifiConfiguration.preSharedKey); + } + + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-CERT network. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWapiCertNetwork() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.WAPI_CERT); + enterpriseConfig.setWapiCertSuite(TEST_WAPI_CERT_SUITE); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWapiEnterpriseConfig(enterpriseConfig) + .build(); + + assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WAPI_CERT)); + assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers + .get(WifiConfiguration.PairwiseCipher.SMS4)); + assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.SMS4)); + assertNull(suggestion.wifiConfiguration.preSharedKey); + assertNotNull(suggestion.wifiConfiguration.enterpriseConfig); + assertEquals(WifiEnterpriseConfig.Eap.WAPI_CERT, + suggestion.wifiConfiguration.enterpriseConfig.getEapMethod()); + assertEquals(TEST_WAPI_CERT_SUITE, + suggestion.wifiConfiguration.enterpriseConfig.getWapiCertSuite()); + } + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for WAPI-CERT network + * which selects the certificate suite automatically. + */ + @Test + public void testWifiNetworkSuggestionBuilderForWapiCertAutoNetwork() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.WAPI_CERT); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWapiEnterpriseConfig(enterpriseConfig) + .build(); + + assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); + assertTrue(suggestion.wifiConfiguration.allowedKeyManagement + .get(WifiConfiguration.KeyMgmt.WAPI_CERT)); + assertTrue(suggestion.wifiConfiguration.allowedPairwiseCiphers + .get(WifiConfiguration.PairwiseCipher.SMS4)); + assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers + .get(WifiConfiguration.GroupCipher.SMS4)); + assertNull(suggestion.wifiConfiguration.preSharedKey); + assertNotNull(suggestion.wifiConfiguration.enterpriseConfig); + assertEquals(WifiEnterpriseConfig.Eap.WAPI_CERT, + suggestion.wifiConfiguration.enterpriseConfig.getEapMethod()); + assertEquals("", + suggestion.wifiConfiguration.enterpriseConfig.getWapiCertSuite()); + } + + /** + * Validate correctness of WifiNetworkSuggestion object created by + * {@link WifiNetworkSuggestion.Builder#build()} for Passpoint network which requires + * app interaction and metered. + */ + @Test + public void testWifiNetworkSuggestionBuilderForPasspointNetworkWithReqAppInteractionMetered() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration) + .setIsAppInteractionRequired(true) + .setIsMetered(true) + .build(); + assertEquals(TEST_FQDN, suggestion.wifiConfiguration.FQDN); + assertTrue(suggestion.isAppInteractionRequired); + assertEquals(suggestion.wifiConfiguration.meteredOverride, + WifiConfiguration.METERED_OVERRIDE_METERED); + assertEquals(suggestion.getPasspointConfig().getMeteredOverride(), + WifiConfiguration.METERED_OVERRIDE_METERED); + assertTrue(suggestion.isUserAllowedToManuallyConnect); } /** @@ -209,6 +393,18 @@ public class WifiNetworkSuggestionTest { } /** + * Ensure {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)}} + * throws an exception when the PasspointConfiguration is not valid. + */ + @Test(expected = IllegalArgumentException.class) + public void testWifiNetworkSuggestionBuilderSetPasspointConfigWithNonValid() { + PasspointConfiguration passpointConfiguration = new PasspointConfiguration(); + new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration) + .build(); + } + + /** * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception * when {@link WifiNetworkSuggestion.Builder#setSsid(String)} is not set. */ @@ -251,7 +447,7 @@ public class WifiNetworkSuggestionTest { public void testWifiNetworkSuggestionBuilderWithInvalidAllZeroBssid() { new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) - .setBssid(MacAddress.ALL_ZEROS_ADDRESS) + .setBssid(WifiManager.ALL_ZEROS_MAC_ADDRESS) .build(); } @@ -311,6 +507,91 @@ public class WifiNetworkSuggestionTest { } /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when both {@link WifiNetworkSuggestion.Builder#setSsid(String)} and + * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked. + */ + @Test(expected = IllegalStateException.class) + public void testWifiNetworkSuggestionBuilderWithBothSsidAndPasspointConfig() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setPasspointConfig(passpointConfiguration) + .build(); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when both {@link WifiNetworkSuggestion.Builder#setWpa2Passphrase(String)} and + * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked. + */ + @Test(expected = IllegalStateException.class) + public void testWifiNetworkSuggestionBuilderWithBothWpa2PassphraseAndPasspointConfig() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + new WifiNetworkSuggestion.Builder() + .setWpa2Passphrase(TEST_PRESHARED_KEY) + .setPasspointConfig(passpointConfiguration) + .build(); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and + * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked. + */ + @Test(expected = IllegalStateException.class) + public void testWifiNetworkSuggestionBuilderWithBothWpa3PassphraseAndPasspointConfig() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + new WifiNetworkSuggestion.Builder() + .setWpa3Passphrase(TEST_PRESHARED_KEY) + .setPasspointConfig(passpointConfiguration) + .build(); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when both {@link WifiNetworkSuggestion.Builder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} + * and {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are + * invoked. + */ + @Test(expected = IllegalStateException.class) + public void testWifiNetworkSuggestionBuilderWithBothEnterpriseAndPasspointConfig() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + new WifiNetworkSuggestion.Builder() + .setWpa3EnterpriseConfig(new WifiEnterpriseConfig()) + .setPasspointConfig(passpointConfiguration) + .build(); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when both {@link WifiNetworkSuggestion.Builder#setIsEnhancedOpen(boolean)} and + * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked. + */ + @Test(expected = IllegalStateException.class) + public void testWifiNetworkSuggestionBuilderWithBothEnhancedOpenAndPasspointConfig() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + new WifiNetworkSuggestion.Builder() + .setIsEnhancedOpen(true) + .setPasspointConfig(passpointConfiguration) + .build(); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when both {@link WifiNetworkSuggestion.Builder#setIsHiddenSsid(boolean)} and + * {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} are invoked. + */ + @Test(expected = IllegalStateException.class) + public void testWifiNetworkSuggestionBuilderWithBothHiddenSsidAndPasspointConfig() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + new WifiNetworkSuggestion.Builder() + .setIsHiddenSsid(true) + .setPasspointConfig(passpointConfiguration) + .build(); + } + + /** * Check that parcel marshalling/unmarshalling works */ @Test @@ -319,8 +600,8 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, false, true, TEST_UID, TEST_PACKAGE_NAME); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion( + configuration, null, false, true, true, true); Parcel parcelW = Parcel.obtain(); suggestion.writeToParcel(parcelW, 0); @@ -337,10 +618,47 @@ public class WifiNetworkSuggestionTest { // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are // not considered for equality and hence needs to be checked for explicitly below. assertEquals(suggestion, parcelSuggestion); + assertEquals(suggestion.hashCode(), parcelSuggestion.hashCode()); assertEquals(suggestion.isAppInteractionRequired, parcelSuggestion.isAppInteractionRequired); assertEquals(suggestion.isUserInteractionRequired, parcelSuggestion.isUserInteractionRequired); + assertEquals(suggestion.isInitialAutoJoinEnabled, + parcelSuggestion.isInitialAutoJoinEnabled); + } + + /** + * Check that parcel marshalling/unmarshalling works + */ + @Test + public void testPasspointNetworkSuggestionParcel() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration) + .build(); + + Parcel parcelW = Parcel.obtain(); + suggestion.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + WifiNetworkSuggestion parcelSuggestion = + WifiNetworkSuggestion.CREATOR.createFromParcel(parcelR); + + // Two suggestion objects are considered equal if they point to the same network (i.e same + // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are + // not considered for equality and hence needs to be checked for explicitly below. + assertEquals(suggestion, parcelSuggestion); + assertEquals(suggestion.hashCode(), parcelSuggestion.hashCode()); + assertEquals(suggestion.isAppInteractionRequired, + parcelSuggestion.isAppInteractionRequired); + assertEquals(suggestion.isUserInteractionRequired, + parcelSuggestion.isUserInteractionRequired); + assertEquals(suggestion.isInitialAutoJoinEnabled, + parcelSuggestion.isInitialAutoJoinEnabled); } /** @@ -354,18 +672,17 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, true, false, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration, null, true, false, true, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.BSSID = TEST_BSSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, false, true, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration1, null, false, true, true, true); assertEquals(suggestion, suggestion1); + assertEquals(suggestion.hashCode(), suggestion1.hashCode()); } /** @@ -378,15 +695,13 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, false, false, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration, null, false, false, true, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID_1; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, false, false, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration1, null, false, false, true, true); assertNotEquals(suggestion, suggestion1); } @@ -402,15 +717,13 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, false, false, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration, null, false, false, true, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, false, false, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration1, null, false, false, true, true); assertNotEquals(suggestion, suggestion1); } @@ -425,55 +738,156 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, false, false, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration, null, false, false, true, true); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, false, false, TEST_UID, - TEST_PACKAGE_NAME); + new WifiNetworkSuggestion(configuration1, null, false, false, true, true); assertNotEquals(suggestion, suggestion1); } /** - * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same - * SSID, BSSID and key mgmt, but different UID. + * Check NetworkSuggestion equals returns {@code true} for 2 Passpoint network suggestions with + * same FQDN. */ @Test - public void testWifiNetworkSuggestionEqualsFailsWhenUidIsDifferent() { - WifiConfiguration configuration = new WifiConfiguration(); - configuration.SSID = TEST_SSID; - configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, false, false, TEST_UID, - TEST_PACKAGE_NAME); + public void testPasspointNetworkSuggestionEqualsSameWithSameFQDN() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + PasspointConfiguration passpointConfiguration1 = PasspointTestUtils.createConfig(); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration) + .build(); + WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration1) + .build(); + assertEquals(suggestion, suggestion1); + assertEquals(suggestion.hashCode(), suggestion1.hashCode()); + } - WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration, false, false, TEST_UID_OTHER, - TEST_PACKAGE_NAME); + /** + * Check NetworkSuggestion equals returns {@code false} for 2 Passpoint network suggestions with + * different FQDN. + */ + @Test + public void testPasspointNetworkSuggestionNotEqualsSameWithDifferentFQDN() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + PasspointConfiguration passpointConfiguration1 = PasspointTestUtils.createConfig(); + passpointConfiguration1.getHomeSp().setFqdn(TEST_FQDN + 1); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration) + .build(); + WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration1) + .build(); assertNotEquals(suggestion, suggestion1); } /** - * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same - * SSID, BSSID and key mgmt, but different package name. + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to + * true on a open network suggestion. + */ + @Test(expected = IllegalStateException.class) + public void testSetCredentialSharedWithUserWithOpenNetwork() { + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setCredentialSharedWithUser(true) + .build(); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)} to + * false on a open network suggestion. + */ + @Test(expected = IllegalStateException.class) + public void testSetIsAutoJoinDisabledWithOpenNetwork() { + new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setIsInitialAutojoinEnabled(false) + .build(); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)} + * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)} + * to false on a network suggestion. + */ + @Test(expected = IllegalStateException.class) + public void testSetIsAutoJoinDisabledWithSecureNetworkNotSharedWithUser() { + new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa2Passphrase(TEST_PRESHARED_KEY) + .setCredentialSharedWithUser(false) + .setIsInitialAutojoinEnabled(false) + .build(); + } + + /** + * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the + * correct value to the WifiConfiguration. */ @Test - public void testWifiNetworkSuggestionEqualsFailsWhenPackageNameIsDifferent() { - WifiConfiguration configuration = new WifiConfiguration(); - configuration.SSID = TEST_SSID; - configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, false, false, TEST_UID, TEST_PACKAGE_NAME); + public void testSetIsNetworkAsUntrusted() { + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa2Passphrase(TEST_PRESHARED_KEY) + .setUntrusted(true) + .build(); + assertTrue(suggestion.isUntrusted()); + assertFalse(suggestion.isUserAllowedToManuallyConnect); + } - WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration, false, false, TEST_UID, - TEST_PACKAGE_NAME_OTHER); + /** + * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the + * correct value to the WifiConfiguration. + * Also the {@link WifiNetworkSuggestion#isUserAllowedToManuallyConnect} should be false; + */ + @Test + public void testSetIsNetworkAsUntrustedOnPasspointNetwork() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration) + .setUntrusted(true) + .build(); + assertTrue(suggestion.isUntrusted()); + assertFalse(suggestion.isUserAllowedToManuallyConnect); + } - assertNotEquals(suggestion, suggestion1); + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when set {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)} to true and + * set {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to true + * together. + */ + @Test(expected = IllegalStateException.class) + public void testSetCredentialSharedWithUserWithSetIsNetworkAsUntrusted() { + new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setWpa2Passphrase(TEST_PRESHARED_KEY) + .setCredentialSharedWithUser(true) + .setUntrusted(true) + .build(); + } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)} + * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)} + * to false on a passpoint suggestion. + */ + @Test(expected = IllegalStateException.class) + public void testSetIsAutoJoinDisabledWithSecureNetworkNotSharedWithUserForPasspoint() { + PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig(); + new WifiNetworkSuggestion.Builder() + .setPasspointConfig(passpointConfiguration) + .setCredentialSharedWithUser(false) + .setIsInitialAutojoinEnabled(false) + .build(); } } diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java index dd05b47fbd4f..b68616f560f3 100644 --- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java @@ -22,8 +22,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.validateMockitoUsage; @@ -34,6 +35,7 @@ import android.content.Context; import android.net.wifi.WifiScanner.PnoSettings; import android.net.wifi.WifiScanner.PnoSettings.PnoNetwork; import android.net.wifi.WifiScanner.ScanData; +import android.net.wifi.WifiScanner.ScanListener; import android.net.wifi.WifiScanner.ScanSettings; import android.os.Bundle; import android.os.Handler; @@ -52,8 +54,10 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.Spy; import java.util.Arrays; +import java.util.concurrent.Executor; /** * Unit tests for {@link android.net.wifi.WifiScanner}. @@ -64,19 +68,23 @@ public class WifiScannerTest { private Context mContext; @Mock private IWifiScanner mService; + @Spy + private Executor mExecutor = new SynchronousExecutor(); + @Mock + private ScanListener mScanListener; + @Mock + private WifiScanner.ParcelableScanData mParcelableScanData; + private ScanData[] mScanData = {}; private static final boolean TEST_PNOSETTINGS_IS_CONNECTED = false; private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60; private static final int TEST_PNOSETTINGS_MIN_2GHZ_RSSI = -70; - private static final int TEST_PNOSETTINGS_INITIAL_SCORE_MAX = 50; - private static final int TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS = 10; - private static final int TEST_PNOSETTINGS_SAME_NETWORK_BONUS = 11; - private static final int TEST_PNOSETTINGS_SECURE_BONUS = 12; - private static final int TEST_PNOSETTINGS_BAND_5GHZ_BONUS = 13; + private static final int TEST_PNOSETTINGS_MIN_6GHZ_RSSI = -55; private static final String TEST_SSID_1 = "TEST1"; private static final String TEST_SSID_2 = "TEST2"; private static final int[] TEST_FREQUENCIES_1 = {}; - private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124, 6245}; + private static final String DESCRIPTION_NOT_AUTHORIZED = "Not authorized"; private WifiScanner mWifiScanner; private TestLooper mLooper; @@ -96,6 +104,7 @@ public class WifiScannerTest { when(mService.getMessenger()).thenReturn(mBidirectionalAsyncChannelServer.getMessenger()); mWifiScanner = new WifiScanner(mContext, mService, mLooper.getLooper()); mLooper.dispatchAll(); + when(mParcelableScanData.getResults()).thenReturn(mScanData); } /** @@ -112,7 +121,7 @@ public class WifiScannerTest { @Test public void verifyScanSettingsParcelWithBand() throws Exception { ScanSettings writeSettings = new ScanSettings(); - writeSettings.type = WifiScanner.TYPE_LOW_POWER; + writeSettings.type = WifiScanner.SCAN_TYPE_LOW_POWER; writeSettings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS; ScanSettings readSettings = parcelWriteRead(writeSettings); @@ -127,7 +136,7 @@ public class WifiScannerTest { @Test public void verifyScanSettingsParcelWithChannels() throws Exception { ScanSettings writeSettings = new ScanSettings(); - writeSettings.type = WifiScanner.TYPE_HIGH_ACCURACY; + writeSettings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY; writeSettings.band = WifiScanner.WIFI_BAND_UNSPECIFIED; writeSettings.channels = new WifiScanner.ChannelSpec[] { new WifiScanner.ChannelSpec(5), @@ -170,11 +179,7 @@ public class WifiScannerTest { pnoSettings.isConnected = TEST_PNOSETTINGS_IS_CONNECTED; pnoSettings.min5GHzRssi = TEST_PNOSETTINGS_MIN_5GHZ_RSSI; pnoSettings.min24GHzRssi = TEST_PNOSETTINGS_MIN_2GHZ_RSSI; - pnoSettings.initialScoreMax = TEST_PNOSETTINGS_INITIAL_SCORE_MAX; - pnoSettings.currentConnectionBonus = TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS; - pnoSettings.sameNetworkBonus = TEST_PNOSETTINGS_SAME_NETWORK_BONUS; - pnoSettings.secureBonus = TEST_PNOSETTINGS_SECURE_BONUS; - pnoSettings.band5GHzBonus = TEST_PNOSETTINGS_BAND_5GHZ_BONUS; + pnoSettings.min6GHzRssi = TEST_PNOSETTINGS_MIN_6GHZ_RSSI; Parcel parcel = Parcel.obtain(); pnoSettings.writeToParcel(parcel, 0); @@ -187,13 +192,7 @@ public class WifiScannerTest { assertEquals(TEST_PNOSETTINGS_IS_CONNECTED, pnoSettingsDeserialized.isConnected); assertEquals(TEST_PNOSETTINGS_MIN_5GHZ_RSSI, pnoSettingsDeserialized.min5GHzRssi); assertEquals(TEST_PNOSETTINGS_MIN_2GHZ_RSSI, pnoSettingsDeserialized.min24GHzRssi); - assertEquals(TEST_PNOSETTINGS_INITIAL_SCORE_MAX, pnoSettingsDeserialized.initialScoreMax); - assertEquals(TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS, - pnoSettingsDeserialized.currentConnectionBonus); - assertEquals(TEST_PNOSETTINGS_SAME_NETWORK_BONUS, - pnoSettingsDeserialized.sameNetworkBonus); - assertEquals(TEST_PNOSETTINGS_SECURE_BONUS, pnoSettingsDeserialized.secureBonus); - assertEquals(TEST_PNOSETTINGS_BAND_5GHZ_BONUS, pnoSettingsDeserialized.band5GHzBonus); + assertEquals(TEST_PNOSETTINGS_MIN_6GHZ_RSSI, pnoSettingsDeserialized.min6GHzRssi); // Test parsing of PnoNetwork assertEquals(pnoSettings.networkList.length, pnoSettingsDeserialized.networkList.length); @@ -244,13 +243,13 @@ public class WifiScannerTest { /** - * Test behavior of {@link WifiScanner#startScan(ScanSettings, WifiScanner.ScanListener)} + * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)} * @throws Exception */ @Test public void testStartScan() throws Exception { ScanSettings scanSettings = new ScanSettings(); - WifiScanner.ScanListener scanListener = mock(WifiScanner.ScanListener.class); + ScanListener scanListener = mock(ScanListener.class); mWifiScanner.startScan(scanSettings, scanListener); mLooper.dispatchAll(); @@ -268,17 +267,19 @@ public class WifiScannerTest { assertNull(messageBundle.getParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY)); assertEquals(mContext.getOpPackageName(), messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY)); + assertEquals(mContext.getAttributionTag(), + messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY)); } /** - * Test behavior of {@link WifiScanner#stopScan(WifiScanner.ScanListener)} + * Test behavior of {@link WifiScanner#stopScan(ScanListener)} * @throws Exception */ @Test public void testStopScan() throws Exception { ScanSettings scanSettings = new ScanSettings(); - WifiScanner.ScanListener scanListener = mock(WifiScanner.ScanListener.class); + ScanListener scanListener = mock(ScanListener.class); mWifiScanner.startScan(scanSettings, scanListener); mLooper.dispatchAll(); @@ -296,17 +297,18 @@ public class WifiScannerTest { Bundle messageBundle = (Bundle) message.obj; assertEquals(mContext.getOpPackageName(), messageBundle.getParcelable(WifiScanner.REQUEST_PACKAGE_NAME_KEY)); - + assertEquals(mContext.getAttributionTag(), + messageBundle.getParcelable(WifiScanner.REQUEST_FEATURE_ID_KEY)); } /** - * Test behavior of {@link WifiScanner#startScan(ScanSettings, WifiScanner.ScanListener)} + * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)} * @throws Exception */ @Test public void testStartScanListenerOnSuccess() throws Exception { ScanSettings scanSettings = new ScanSettings(); - WifiScanner.ScanListener scanListener = mock(WifiScanner.ScanListener.class); + ScanListener scanListener = mock(ScanListener.class); mWifiScanner.startScan(scanSettings, scanListener); mLooper.dispatchAll(); @@ -330,13 +332,13 @@ public class WifiScannerTest { } /** - * Test behavior of {@link WifiScanner#startScan(ScanSettings, WifiScanner.ScanListener)} + * Test behavior of {@link WifiScanner#startScan(ScanSettings, ScanListener)} * @throws Exception */ @Test public void testStartScanListenerOnResults() throws Exception { ScanSettings scanSettings = new ScanSettings(); - WifiScanner.ScanListener scanListener = mock(WifiScanner.ScanListener.class); + ScanListener scanListener = mock(ScanListener.class); mWifiScanner.startScan(scanSettings, scanListener); mLooper.dispatchAll(); @@ -364,7 +366,7 @@ public class WifiScannerTest { /** * Test behavior of {@link WifiScanner#startDisconnectedPnoScan(ScanSettings, PnoSettings, - * WifiScanner.PnoScanListener)} + * Executor, WifiScanner.PnoScanListener)} * @throws Exception */ @Test @@ -373,7 +375,8 @@ public class WifiScannerTest { PnoSettings pnoSettings = new PnoSettings(); WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class); - mWifiScanner.startDisconnectedPnoScan(scanSettings, pnoSettings, pnoScanListener); + mWifiScanner.startDisconnectedPnoScan( + scanSettings, pnoSettings, mock(Executor.class), pnoScanListener); mLooper.dispatchAll(); ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); @@ -394,7 +397,7 @@ public class WifiScannerTest { /** * Test behavior of {@link WifiScanner#startConnectedPnoScan(ScanSettings, PnoSettings, - * WifiScanner.PnoScanListener)} + * Executor, WifiScanner.PnoScanListener)} * @throws Exception */ @Test @@ -403,7 +406,8 @@ public class WifiScannerTest { PnoSettings pnoSettings = new PnoSettings(); WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class); - mWifiScanner.startConnectedPnoScan(scanSettings, pnoSettings, pnoScanListener); + mWifiScanner.startConnectedPnoScan( + scanSettings, pnoSettings, mock(Executor.class), pnoScanListener); mLooper.dispatchAll(); ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); @@ -423,8 +427,8 @@ public class WifiScannerTest { } /** - * Test behavior of {@link WifiScanner#stopPnoScan(WifiScanner.ScanListener)} - * WifiScanner.PnoScanListener)} + * Test behavior of {@link WifiScanner#stopPnoScan(ScanListener)} + * Executor, WifiScanner.PnoScanListener)} * @throws Exception */ @Test @@ -433,7 +437,8 @@ public class WifiScannerTest { PnoSettings pnoSettings = new PnoSettings(); WifiScanner.PnoScanListener pnoScanListener = mock(WifiScanner.PnoScanListener.class); - mWifiScanner.startDisconnectedPnoScan(scanSettings, pnoSettings, pnoScanListener); + mWifiScanner.startDisconnectedPnoScan( + scanSettings, pnoSettings, mock(Executor.class), pnoScanListener); mLooper.dispatchAll(); mWifiScanner.stopPnoScan(pnoScanListener); mLooper.dispatchAll(); @@ -445,4 +450,185 @@ public class WifiScannerTest { assertEquals(WifiScanner.CMD_STOP_PNO_SCAN, message.what); } + + @Test + public void testScanDataAddResults() throws Exception { + ScanResult scanResult1 = new ScanResult(); + scanResult1.SSID = TEST_SSID_1; + ScanData scanData = new ScanData(0, 0, new ScanResult[]{scanResult1}); + + ScanResult scanResult2 = new ScanResult(); + scanResult2.SSID = TEST_SSID_2; + scanData.addResults(new ScanResult[]{scanResult2}); + + ScanResult[] consolidatedScanResults = scanData.getResults(); + assertEquals(2, consolidatedScanResults.length); + assertEquals(TEST_SSID_1, consolidatedScanResults[0].SSID); + assertEquals(TEST_SSID_2, consolidatedScanResults[1].SSID); + } + + @Test + public void testScanDataParcel() throws Exception { + ScanResult scanResult1 = new ScanResult(); + scanResult1.SSID = TEST_SSID_1; + ScanData scanData = new ScanData(5, 4, new ScanResult[]{scanResult1}); + + Parcel parcel = Parcel.obtain(); + scanData.writeToParcel(parcel, 0); + parcel.setDataPosition(0); // Rewind data position back to the beginning for read. + ScanData readScanData = ScanData.CREATOR.createFromParcel(parcel); + + assertEquals(scanData.getId(), readScanData.getId()); + assertEquals(scanData.getFlags(), readScanData.getFlags()); + assertEquals(scanData.getResults().length, readScanData.getResults().length); + assertEquals(scanData.getResults()[0].SSID, readScanData.getResults()[0].SSID); + } + + /** Tests that upon registration success, {@link ScanListener#onSuccess()} is called. */ + @Test + public void testRegisterScanListenerSuccess() throws Exception { + mWifiScanner.registerScanListener(mExecutor, mScanListener); + mLooper.dispatchAll(); + + ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); + verify(mHandler).handleMessage(messageArgumentCaptor.capture()); + Message sentMessage = messageArgumentCaptor.getValue(); + assertNotNull(sentMessage); + + assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size()); + Messenger scannerMessenger = + mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next(); + + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_OP_SUCCEEDED; + responseMessage.arg2 = sentMessage.arg2; + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + + verify(mExecutor).execute(any()); + verify(mScanListener).onSuccess(); + } + + /** + * Tests that upon registration failed, {@link ScanListener#onFailure(int, String)} is called. + */ + @Test + public void testRegisterScanListenerFailed() throws Exception { + mWifiScanner.registerScanListener(mExecutor, mScanListener); + mLooper.dispatchAll(); + + ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); + verify(mHandler).handleMessage(messageArgumentCaptor.capture()); + Message sentMessage = messageArgumentCaptor.getValue(); + assertNotNull(sentMessage); + + assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size()); + Messenger scannerMessenger = + mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next(); + + { + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_OP_FAILED; + responseMessage.arg2 = sentMessage.arg2; + responseMessage.obj = new WifiScanner.OperationResult( + WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED); + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + } + + verify(mExecutor).execute(any()); + verify(mScanListener).onFailure( + WifiScanner.REASON_NOT_AUTHORIZED, DESCRIPTION_NOT_AUTHORIZED); + + // CMD_OP_FAILED should have caused the removal of the listener, verify this + { + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_SCAN_RESULT; + responseMessage.arg2 = sentMessage.arg2; + responseMessage.obj = mParcelableScanData; + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + } + // execute() called once before, not called again + verify(mExecutor, times(1)).execute(any()); + // onResults() never triggered + verify(mScanListener, never()).onResults(any()); + } + + /** + * Tests that when the ScanListener is triggered, {@link ScanListener#onResults(ScanData[])} + * is called. + */ + @Test + public void testRegisterScanListenerReceiveScanResults() throws Exception { + mWifiScanner.registerScanListener(mExecutor, mScanListener); + mLooper.dispatchAll(); + + ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); + verify(mHandler).handleMessage(messageArgumentCaptor.capture()); + Message sentMessage = messageArgumentCaptor.getValue(); + assertNotNull(sentMessage); + + assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size()); + Messenger scannerMessenger = + mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next(); + + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_SCAN_RESULT; + responseMessage.arg2 = sentMessage.arg2; + responseMessage.obj = mParcelableScanData; + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + + verify(mExecutor).execute(any()); + verify(mScanListener).onResults(mScanData); + } + + /** + * Tests that after unregistering a scan listener, {@link ScanListener#onResults(ScanData[])} + * is not called. + */ + @Test + public void testUnregisterScanListener() throws Exception { + mWifiScanner.registerScanListener(mExecutor, mScanListener); + mWifiScanner.unregisterScanListener(mScanListener); + mLooper.dispatchAll(); + + assertEquals(1, mBidirectionalAsyncChannelServer.getClientMessengers().size()); + Messenger scannerMessenger = + mBidirectionalAsyncChannelServer.getClientMessengers().iterator().next(); + + ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); + verify(mHandler, times(2)).handleMessage(messageArgumentCaptor.capture()); + Message sentMessage = messageArgumentCaptor.getValue(); + assertNotNull(sentMessage); + + Message responseMessage = Message.obtain(); + responseMessage.what = WifiScanner.CMD_SCAN_RESULT; + responseMessage.obj = mParcelableScanData; + responseMessage.arg2 = sentMessage.arg2; + scannerMessenger.send(responseMessage); + mLooper.dispatchAll(); + + verify(mExecutor, never()).execute(any()); + verify(mScanListener, never()).onResults(mScanData); + } + + /** + * Tests isFullBandScan() method with and without DFS check + */ + @Test + public void testIsFullBandScan() throws Exception { + assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_24_GHZ, true)); + assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_5_GHZ, true)); + assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_6_GHZ, true)); + assertFalse(WifiScanner.isFullBandScan( + WifiScanner.WIFI_BAND_6_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true)); + assertTrue(WifiScanner.isFullBandScan( + WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true)); + assertFalse(WifiScanner.isFullBandScan( + WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, false)); + assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, true)); + assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, false)); + } } diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java index 1b48a67e9f55..b65de6b9789d 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareAgentNetworkSpecifierTest.java @@ -171,6 +171,6 @@ public class WifiAwareAgentNetworkSpecifierTest { WifiAwareNetworkSpecifier getMockNetworkSpecifier(int clientId) { return new WifiAwareNetworkSpecifier(WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB, WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, clientId, 0, 0, new byte[6], - null, null, 10, 5, 0); + null, null, 10, 5); } } diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java index 7bc5f6260816..43d728bf593e 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java @@ -36,6 +36,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.net.MacAddress; import android.net.wifi.RttManager; +import android.net.wifi.util.HexEncoding; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -44,8 +45,6 @@ import android.os.test.TestLooper; import androidx.test.filters.SmallTest; -import libcore.util.HexEncoding; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -168,7 +167,7 @@ public class WifiAwareManagerTest { // (1) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(binder.capture(), any(), + inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -178,7 +177,8 @@ public class WifiAwareManagerTest { // (2) publish - should succeed PublishConfig publishConfig = new PublishConfig.Builder().build(); session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), any()); + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), + any()); // (3) disconnect session.close(); @@ -190,7 +190,7 @@ public class WifiAwareManagerTest { // (5) connect mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), isNull(), + inOrder.verify(mockAwareService).connect(binder.capture(), any(), any(), any(), isNull(), eq(false)); verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService); @@ -212,7 +212,7 @@ public class WifiAwareManagerTest { // (1) connect + failure mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectFail(reason); mMockLooper.dispatchAll(); @@ -220,7 +220,7 @@ public class WifiAwareManagerTest { // (2) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -230,7 +230,8 @@ public class WifiAwareManagerTest { // (4) subscribe: should succeed SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build(); session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).subscribe(any(), eq(clientId), eq(subscribeConfig), any()); + inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig), + any()); verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService); } @@ -249,7 +250,7 @@ public class WifiAwareManagerTest { // (1) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -257,7 +258,7 @@ public class WifiAwareManagerTest { // (2) connect + success mDut.attach(mockCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), isNull(), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId + 1); mMockLooper.dispatchAll(); @@ -304,7 +305,7 @@ public class WifiAwareManagerTest { // (0) connect + success mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -313,7 +314,7 @@ public class WifiAwareManagerTest { // (1) publish session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); // (2) publish session created @@ -396,7 +397,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -405,7 +406,7 @@ public class WifiAwareManagerTest { // (2) publish: successfully - then terminated session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); sessionProxyCallback.getValue().onSessionTerminated(0); @@ -453,7 +454,7 @@ public class WifiAwareManagerTest { // (0) connect + success mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -462,7 +463,7 @@ public class WifiAwareManagerTest { // (1) subscribe session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).subscribe(any(), eq(clientId), eq(subscribeConfig), + inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig), sessionProxyCallback.capture()); // (2) subscribe session created @@ -538,7 +539,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -547,7 +548,7 @@ public class WifiAwareManagerTest { // (2) subscribe: successfully - then terminated session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).subscribe(any(), eq(clientId), eq(subscribeConfig), + inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), eq(subscribeConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); sessionProxyCallback.getValue().onSessionTerminated(0); @@ -577,12 +578,15 @@ public class WifiAwareManagerTest { collector.checkThat("mMasterPreference", 0, equalTo(configRequest.mMasterPreference)); collector.checkThat("mSupport5gBand", true, equalTo(configRequest.mSupport5gBand)); - collector.checkThat("mDiscoveryWindowInterval.length", 2, + collector.checkThat("mSupport6gBand", false, equalTo(configRequest.mSupport6gBand)); + collector.checkThat("mDiscoveryWindowInterval.length", 3, equalTo(configRequest.mDiscoveryWindowInterval.length)); collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT, equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ])); collector.checkThat("mDiscoveryWindowInterval[5Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT, equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ])); + collector.checkThat("mDiscoveryWindowInterval[6Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT, + equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ])); } @Test @@ -591,12 +595,16 @@ public class WifiAwareManagerTest { final int clusterLow = 5; final int masterPreference = 55; final boolean supportBand5g = true; + final boolean supportBand6g = true; final int dwWindow5GHz = 3; + final int dwWindow6GHz = 4; ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh) .setClusterLow(clusterLow).setMasterPreference(masterPreference) .setSupport5gBand(supportBand5g) + .setSupport6gBand(supportBand6g) .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz) + .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz) .build(); collector.checkThat("mClusterHigh", clusterHigh, equalTo(configRequest.mClusterHigh)); @@ -604,12 +612,15 @@ public class WifiAwareManagerTest { collector.checkThat("mMasterPreference", masterPreference, equalTo(configRequest.mMasterPreference)); collector.checkThat("mSupport5gBand", supportBand5g, equalTo(configRequest.mSupport5gBand)); - collector.checkThat("mDiscoveryWindowInterval.length", 2, + collector.checkThat("mSupport6gBand", supportBand6g, equalTo(configRequest.mSupport6gBand)); + collector.checkThat("mDiscoveryWindowInterval.length", 3, equalTo(configRequest.mDiscoveryWindowInterval.length)); collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT, equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ])); collector.checkThat("mDiscoveryWindowInterval[5GHz]", dwWindow5GHz, equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ])); + collector.checkThat("mDiscoveryWindowInterval[6GHz]", dwWindow6GHz, + equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ])); } @Test(expected = IllegalArgumentException.class) @@ -688,14 +699,18 @@ public class WifiAwareManagerTest { final int clusterLow = 25; final int masterPreference = 177; final boolean supportBand5g = true; + final boolean supportBand6g = false; final int dwWindow24GHz = 1; final int dwWindow5GHz = 5; + final int dwWindow6GHz = 4; ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh) .setClusterLow(clusterLow).setMasterPreference(masterPreference) .setSupport5gBand(supportBand5g) + .setSupport6gBand(supportBand6g) .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwWindow24GHz) .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz) + .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_6GHZ, dwWindow6GHz) .build(); Parcel parcelW = Parcel.obtain(); @@ -942,7 +957,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -951,7 +966,7 @@ public class WifiAwareManagerTest { // (2) publish successfully session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); mMockLooper.dispatchAll(); @@ -1055,7 +1070,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -1239,7 +1254,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -1248,7 +1263,7 @@ public class WifiAwareManagerTest { // (2) publish successfully session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); mMockLooper.dispatchAll(); @@ -1474,7 +1489,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -1514,7 +1529,7 @@ public class WifiAwareManagerTest { // (1) connect successfully mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); - inOrder.verify(mockAwareService).connect(any(), any(), clientProxyCallback.capture(), + inOrder.verify(mockAwareService).connect(any(), any(), any(), clientProxyCallback.capture(), eq(configRequest), eq(false)); clientProxyCallback.getValue().onConnectSuccess(clientId); mMockLooper.dispatchAll(); @@ -1524,7 +1539,7 @@ public class WifiAwareManagerTest { if (isPublish) { // (2) publish successfully session.publish(publishConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).publish(any(), eq(clientId), eq(publishConfig), + inOrder.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); mMockLooper.dispatchAll(); @@ -1533,8 +1548,8 @@ public class WifiAwareManagerTest { } else { // (2) subscribe successfully session.subscribe(subscribeConfig, mockSessionCallback, mMockLooperHandler); - inOrder.verify(mockAwareService).subscribe(any(), eq(clientId), eq(subscribeConfig), - sessionProxyCallback.capture()); + inOrder.verify(mockAwareService).subscribe(any(), any(), eq(clientId), + eq(subscribeConfig), sessionProxyCallback.capture()); sessionProxyCallback.getValue().onSessionStarted(sessionId); mMockLooper.dispatchAll(); inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture()); @@ -1549,7 +1564,7 @@ public class WifiAwareManagerTest { WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(NETWORK_SPECIFIER_TYPE_IB, WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, 5, 568, 334, HexEncoding.decode("000102030405".toCharArray(), false), - "01234567890123456789012345678901".getBytes(), "blah blah", 666, 4, 10001); + "01234567890123456789012345678901".getBytes(), "blah blah", 666, 4); Parcel parcelW = Parcel.obtain(); ns.writeToParcel(parcelW, 0); diff --git a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java index d9a1d9afff61..439e67259cb9 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java @@ -54,6 +54,8 @@ public class ConfigParserTest { "assets/hsr1/HSR1ProfileWithInvalidContentType.base64"; private static final String PASSPOINT_INSTALLATION_FILE_WITHOUT_PROFILE = "assets/hsr1/HSR1ProfileWithoutProfile.base64"; + private static final String PASSPOINT_INSTALLATION_FILE_WITH_UPDATE_ID = + "assets/hsr1/HSR1ProfileWithUpdateIdentifier.base64"; /** * Read the content of the given resource file into a String. @@ -85,17 +87,17 @@ public class ConfigParserTest { // HomeSP configuration. HomeSp homeSp = new HomeSp(); - homeSp.setFriendlyName("Century House"); - homeSp.setFqdn("mi6.co.uk"); + homeSp.setFriendlyName("Example Network"); + homeSp.setFqdn("hotspot.example.net"); homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); config.setHomeSp(homeSp); // Credential configuration. Credential credential = new Credential(); - credential.setRealm("shaken.stirred.com"); + credential.setRealm("example.com"); Credential.UserCredential userCredential = new Credential.UserCredential(); - userCredential.setUsername("james"); - userCredential.setPassword("Ym9uZDAwNw=="); + userCredential.setUsername("user"); + userCredential.setPassword("cGFzc3dvcmQ="); userCredential.setEapType(21); userCredential.setNonEapInnerMethod("MS-CHAP-V2"); credential.setUserCredential(userCredential); @@ -106,8 +108,8 @@ public class ConfigParserTest { certCredential.setCertSha256Fingerprint(certSha256Fingerprint); credential.setCertCredential(certCredential); Credential.SimCredential simCredential = new Credential.SimCredential(); - simCredential.setImsi("imsi"); - simCredential.setEapType(24); + simCredential.setImsi("123456*"); + simCredential.setEapType(23); credential.setSimCredential(simCredential); credential.setCaCertificate(FakeKeys.CA_CERT0); config.setCredential(credential); @@ -201,4 +203,21 @@ public class ConfigParserTest { assertNull(ConfigParser.parsePasspointConfig( "application/x-wifi-config", configStr.getBytes())); } + + /** + * Verify a valid installation file is parsed successfully with the matching contents, and that + * Update identifier is cleared. + * + * @throws Exception + */ + @Test + public void parseConfigFileWithUpdateIdentifier() throws Exception { + String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_UPDATE_ID); + PasspointConfiguration expectedConfig = generateConfigurationFromProfile(); + PasspointConfiguration actualConfig = + ConfigParser.parsePasspointConfig( + "application/x-wifi-config", configStr.getBytes()); + // Expected configuration does not contain an update identifier + assertTrue(actualConfig.equals(expectedConfig)); + } }
\ No newline at end of file diff --git a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java index c7e009ee9864..2ded849331d7 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java @@ -19,7 +19,6 @@ package android.net.wifi.hotspot2; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import android.graphics.drawable.Icon; import android.net.Uri; import android.net.wifi.WifiSsid; import android.os.Parcel; @@ -56,7 +55,6 @@ public class OsuProviderTest { private static final String TEST_NAI = "test.access.com"; private static final List<Integer> TEST_METHOD_LIST = Arrays.asList(OsuProvider.METHOD_SOAP_XML_SPP); - private static final Icon TEST_ICON = Icon.createWithData(new byte[10], 0, 10); /** * Verify parcel write and read consistency for the given {@link OsuProvider}. @@ -82,7 +80,7 @@ public class OsuProviderTest { */ @Test public void verifyParcelWithEmptyProviderInfo() throws Exception { - verifyParcel(new OsuProvider(null, null, null, null, null, null, null)); + verifyParcel(new OsuProvider((WifiSsid) null, null, null, null, null, null)); } /** @@ -93,7 +91,7 @@ public class OsuProviderTest { @Test public void verifyParcelWithFullProviderInfo() throws Exception { verifyParcel(new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES, - TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON)); + TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST)); } /** @@ -102,7 +100,7 @@ public class OsuProviderTest { */ @Test public void verifyCopyConstructorWithNullSource() throws Exception { - OsuProvider expected = new OsuProvider(null, null, null, null, null, null, null); + OsuProvider expected = new OsuProvider((WifiSsid) null, null, null, null, null, null); assertEquals(expected, new OsuProvider(null)); } @@ -114,7 +112,7 @@ public class OsuProviderTest { @Test public void verifyCopyConstructorWithValidSource() throws Exception { OsuProvider source = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES, - TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON); + TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST); assertEquals(source, new OsuProvider(source)); } @@ -126,7 +124,7 @@ public class OsuProviderTest { @Test public void verifyGetters() throws Exception { OsuProvider provider = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAMES, - TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON); + TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST); assertTrue(TEST_SSID.equals(provider.getOsuSsid())); assertTrue(TEST_FRIENDLY_NAME.equals(provider.getFriendlyName())); @@ -135,6 +133,5 @@ public class OsuProviderTest { assertTrue(TEST_SERVER_URI.equals(provider.getServerUri())); assertTrue(TEST_NAI.equals(provider.getNetworkAccessIdentifier())); assertTrue(TEST_METHOD_LIST.equals(provider.getMethodList())); - assertTrue(TEST_ICON.sameAs(provider.getIcon())); } } diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index fc03e7eb6176..638efb9f14ee 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -16,26 +16,24 @@ package android.net.wifi.hotspot2; +import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; -import android.net.wifi.EAPConstants; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; -import android.net.wifi.hotspot2.pps.Policy; -import android.net.wifi.hotspot2.pps.UpdateParameter; import android.os.Parcel; -import android.util.Base64; import androidx.test.filters.SmallTest; import org.junit.Test; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -47,134 +45,6 @@ public class PasspointConfigurationTest { private static final int CERTIFICATE_FINGERPRINT_BYTES = 32; /** - * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}. - * - * @return {@link android.net.wifi.hotspot2.pps.HomeSP} - */ - private static HomeSp createHomeSp() { - HomeSp homeSp = new HomeSp(); - homeSp.setFqdn("fqdn"); - homeSp.setFriendlyName("friendly name"); - homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66}); - return homeSp; - } - - /** - * Utility function for creating a {@link android.net.wifi.hotspot2.pps.Credential}. - * - * @return {@link android.net.wifi.hotspot2.pps.Credential} - */ - private static Credential createCredential() { - Credential cred = new Credential(); - cred.setRealm("realm"); - cred.setUserCredential(null); - cred.setCertCredential(null); - cred.setSimCredential(new Credential.SimCredential()); - cred.getSimCredential().setImsi("1234*"); - cred.getSimCredential().setEapType(EAPConstants.EAP_SIM); - cred.setCaCertificate(null); - cred.setClientCertificateChain(null); - cred.setClientPrivateKey(null); - return cred; - } - - /** - * Helper function for creating a {@link Policy} for testing. - * - * @return {@link Policy} - */ - private static Policy createPolicy() { - Policy policy = new Policy(); - policy.setMinHomeDownlinkBandwidth(123); - policy.setMinHomeUplinkBandwidth(345); - policy.setMinRoamingDownlinkBandwidth(567); - policy.setMinRoamingUplinkBandwidth(789); - policy.setMaximumBssLoadValue(12); - policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"}); - HashMap<Integer, String> requiredProtoPortMap = new HashMap<>(); - requiredProtoPortMap.put(12, "23,342,123"); - requiredProtoPortMap.put(23, "789,372,1235"); - policy.setRequiredProtoPortMap(requiredProtoPortMap); - - List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>(); - Policy.RoamingPartner partner1 = new Policy.RoamingPartner(); - partner1.setFqdn("partner1.com"); - partner1.setFqdnExactMatch(true); - partner1.setPriority(12); - partner1.setCountries("us,jp"); - Policy.RoamingPartner partner2 = new Policy.RoamingPartner(); - partner2.setFqdn("partner2.com"); - partner2.setFqdnExactMatch(false); - partner2.setPriority(42); - partner2.setCountries("ca,fr"); - preferredRoamingPartnerList.add(partner1); - preferredRoamingPartnerList.add(partner2); - policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList); - - UpdateParameter policyUpdate = new UpdateParameter(); - policyUpdate.setUpdateIntervalInMinutes(1712); - policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM); - policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP); - policyUpdate.setServerUri("policy.update.com"); - policyUpdate.setUsername("username"); - policyUpdate.setBase64EncodedPassword( - Base64.encodeToString("password".getBytes(), Base64.DEFAULT)); - policyUpdate.setTrustRootCertUrl("trust.cert.com"); - policyUpdate.setTrustRootCertSha256Fingerprint( - new byte[CERTIFICATE_FINGERPRINT_BYTES]); - policy.setPolicyUpdate(policyUpdate); - - return policy; - } - - private static UpdateParameter createSubscriptionUpdate() { - UpdateParameter subUpdate = new UpdateParameter(); - subUpdate.setUpdateIntervalInMinutes(9021); - subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP); - subUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER); - subUpdate.setServerUri("subscription.update.com"); - subUpdate.setUsername("subUsername"); - subUpdate.setBase64EncodedPassword( - Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT)); - subUpdate.setTrustRootCertUrl("subscription.trust.cert.com"); - subUpdate.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_FINGERPRINT_BYTES]); - return subUpdate; - } - /** - * Helper function for creating a {@link PasspointConfiguration} for testing. - * - * @return {@link PasspointConfiguration} - */ - private static PasspointConfiguration createConfig() { - PasspointConfiguration config = new PasspointConfiguration(); - config.setUpdateIdentifier(1234); - config.setHomeSp(createHomeSp()); - config.setCredential(createCredential()); - config.setPolicy(createPolicy()); - config.setSubscriptionUpdate(createSubscriptionUpdate()); - Map<String, byte[]> trustRootCertList = new HashMap<>(); - trustRootCertList.put("trustRoot.cert1.com", - new byte[CERTIFICATE_FINGERPRINT_BYTES]); - trustRootCertList.put("trustRoot.cert2.com", - new byte[CERTIFICATE_FINGERPRINT_BYTES]); - config.setTrustRootCertList(trustRootCertList); - config.setUpdateIdentifier(1); - config.setCredentialPriority(120); - config.setSubscriptionCreationTimeInMillis(231200); - config.setSubscriptionExpirationTimeInMillis(2134232); - config.setSubscriptionType("Gold"); - config.setUsageLimitUsageTimePeriodInMinutes(3600); - config.setUsageLimitStartTimeInMillis(124214213); - config.setUsageLimitDataLimit(14121); - config.setUsageLimitTimeLimitInMinutes(78912); - Map<String, String> friendlyNames = new HashMap<>(); - friendlyNames.put("en", "ServiceName1"); - friendlyNames.put("kr", "ServiceName2"); - config.setServiceFriendlyNames(friendlyNames); - return config; - } - - /** * Verify parcel write and read consistency for the given configuration. * * @param writeConfig The configuration to verify @@ -207,7 +77,7 @@ public class PasspointConfigurationTest { */ @Test public void verifyParcelWithFullConfiguration() throws Exception { - verifyParcel(createConfig()); + verifyParcel(PasspointTestUtils.createConfig()); } /** @@ -217,7 +87,7 @@ public class PasspointConfigurationTest { */ @Test public void verifyParcelWithoutServiceNames() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setServiceFriendlyNames(null); verifyParcel(config); } @@ -229,7 +99,7 @@ public class PasspointConfigurationTest { */ @Test public void verifyParcelWithoutHomeSP() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setHomeSp(null); verifyParcel(config); } @@ -241,7 +111,7 @@ public class PasspointConfigurationTest { */ @Test public void verifyParcelWithoutCredential() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setCredential(null); verifyParcel(config); } @@ -253,7 +123,7 @@ public class PasspointConfigurationTest { */ @Test public void verifyParcelWithoutPolicy() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setPolicy(null); verifyParcel(config); } @@ -265,7 +135,7 @@ public class PasspointConfigurationTest { */ @Test public void verifyParcelWithoutSubscriptionUpdate() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setSubscriptionUpdate(null); verifyParcel(config); } @@ -278,12 +148,25 @@ public class PasspointConfigurationTest { */ @Test public void verifyParcelWithoutTrustRootCertList() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setTrustRootCertList(null); verifyParcel(config); } /** + * Verify parcel read/write for a configuration that doesn't contain AAA server trusted names + * list. + * + * @throws Exception + */ + @Test + public void verifyParcelWithoutAaaServerTrustedNames() throws Exception { + PasspointConfiguration config = PasspointTestUtils.createConfig(); + config.setAaaServerTrustedNames(null); + verifyParcel(config); + } + + /** * Verify that a default/empty configuration is invalid. * * @throws Exception @@ -294,6 +177,9 @@ public class PasspointConfigurationTest { assertFalse(config.validate()); assertFalse(config.validateForR2()); + assertTrue(config.isAutojoinEnabled()); + assertTrue(config.isMacRandomizationEnabled()); + assertTrue(config.getMeteredOverride() == METERED_OVERRIDE_NONE); } /** @@ -303,10 +189,10 @@ public class PasspointConfigurationTest { */ @Test public void validateFullConfig() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); assertTrue(config.validate()); - assertTrue(config.validateForR2()); + assertFalse(config.isOsuProvisioned()); } /** @@ -317,7 +203,7 @@ public class PasspointConfigurationTest { */ @Test public void validateFullConfigWithoutUpdateIdentifier() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setUpdateIdentifier(Integer.MIN_VALUE); assertTrue(config.validate()); @@ -331,7 +217,7 @@ public class PasspointConfigurationTest { */ @Test public void validateConfigWithoutCredential() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setCredential(null); assertFalse(config.validate()); @@ -345,7 +231,7 @@ public class PasspointConfigurationTest { */ @Test public void validateConfigWithoutHomeSp() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setHomeSp(null); assertFalse(config.validate()); @@ -360,11 +246,10 @@ public class PasspointConfigurationTest { */ @Test public void validateConfigWithoutPolicy() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setPolicy(null); assertTrue(config.validate()); - assertTrue(config.validateForR2()); } /** @@ -375,7 +260,7 @@ public class PasspointConfigurationTest { */ @Test public void validateConfigWithoutSubscriptionUpdate() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); config.setSubscriptionUpdate(null); assertTrue(config.validate()); @@ -383,6 +268,20 @@ public class PasspointConfigurationTest { } /** + * Verify that a configuration without AAA server trusted names is valid for R1 and R2, + * since AAA server trusted names are optional for R1 and R2. + * + * @throws Exception + */ + @Test + public void validateConfigWithoutAaaServerTrustedNames() throws Exception { + PasspointConfiguration config = PasspointTestUtils.createConfig(); + config.setAaaServerTrustedNames(null); + + assertTrue(config.validate()); + } + + /** * Verify that a configuration with a trust root certificate URL exceeding the max size * is invalid. * @@ -390,7 +289,7 @@ public class PasspointConfigurationTest { */ @Test public void validateConfigWithInvalidTrustRootCertUrl() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1]; Map<String, byte[]> trustRootCertList = new HashMap<>(); Arrays.fill(rawUrlBytes, (byte) 'a'); @@ -415,7 +314,7 @@ public class PasspointConfigurationTest { */ @Test public void validateConfigWithInvalidTrustRootCertFingerprint() throws Exception { - PasspointConfiguration config = createConfig(); + PasspointConfiguration config = PasspointTestUtils.createConfig(); Map<String, byte[]> trustRootCertList = new HashMap<>(); trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]); config.setTrustRootCertList(trustRootCertList); @@ -452,8 +351,98 @@ public class PasspointConfigurationTest { */ @Test public void validateCopyConstructorWithValidSource() throws Exception { - PasspointConfiguration sourceConfig = createConfig(); + PasspointConfiguration sourceConfig = PasspointTestUtils.createConfig(); PasspointConfiguration copyConfig = new PasspointConfiguration(sourceConfig); assertTrue(copyConfig.equals(sourceConfig)); } + + /** + * Verify that a configuration containing all fields is valid for R2. + * + * @throws Exception + */ + @Test + public void validateFullR2Config() throws Exception { + PasspointConfiguration config = PasspointTestUtils.createR2Config(); + assertTrue(config.validate()); + assertTrue(config.validateForR2()); + assertTrue(config.isOsuProvisioned()); + } + + /** + * Verify that the unique identifier generated is identical for two instances + * + * @throws Exception + */ + @Test + public void validateUniqueId() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + + assertEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Verify that the unique identifier generated is different for two instances with different + * HomeSp node + * + * @throws Exception + */ + @Test + public void validateUniqueIdDifferentHomeSp() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + + // Modify config2's RCOIs to a different set of values + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + HomeSp homeSp = config2.getHomeSp(); + homeSp.setRoamingConsortiumOis(new long[] {0xaa, 0xbb}); + config2.setHomeSp(homeSp); + + assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Verify that the unique identifier generated is different for two instances with different + * Credential node + * + * @throws Exception + */ + @Test + public void validateUniqueIdDifferentCredential() throws Exception { + PasspointConfiguration config1 = PasspointTestUtils.createConfig(); + + // Modify config2's RCOIs to a different set of values + PasspointConfiguration config2 = PasspointTestUtils.createConfig(); + Credential credential = config2.getCredential(); + credential.setRealm("realm2.example.com"); + credential.getSimCredential().setImsi("350460*"); + config2.setCredential(credential); + + assertNotEquals(config1.getUniqueId(), config2.getUniqueId()); + } + + /** + * Verify that the unique identifier API generates an exception if HomeSP is not initialized. + * + * @throws Exception + */ + @Test (expected = IllegalStateException.class) + public void validateUniqueIdExceptionWithEmptyHomeSp() throws Exception { + PasspointConfiguration config = PasspointTestUtils.createConfig(); + config.setHomeSp(null); + String uniqueId = config.getUniqueId(); + } + + /** + * Verify that the unique identifier API generates an exception if Credential is not + * initialized. + * + * @throws Exception + */ + @Test (expected = IllegalStateException.class) + public void validateUniqueIdExceptionWithEmptyCredential() throws Exception { + PasspointConfiguration config = PasspointTestUtils.createConfig(); + config.setCredential(null); + String uniqueId = config.getUniqueId(); + } } diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java new file mode 100644 index 000000000000..8d55acb87f15 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointTestUtils.java @@ -0,0 +1,172 @@ +/* + * 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 android.net.wifi.hotspot2; + +import android.net.wifi.EAPConstants; +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSp; +import android.net.wifi.hotspot2.pps.Policy; +import android.net.wifi.hotspot2.pps.UpdateParameter; +import android.util.Base64; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PasspointTestUtils { + private static final int CERTIFICATE_FINGERPRINT_BYTES = 32; + + /** + * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}. + * + * @return {@link android.net.wifi.hotspot2.pps.HomeSP} + */ + private static HomeSp createHomeSp() { + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("fqdn"); + homeSp.setFriendlyName("friendly name"); + homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66}); + return homeSp; + } + + /** + * Utility function for creating a {@link android.net.wifi.hotspot2.pps.Credential}. + * + * @return {@link android.net.wifi.hotspot2.pps.Credential} + */ + private static Credential createCredential() { + Credential cred = new Credential(); + cred.setRealm("realm"); + cred.setUserCredential(null); + cred.setCertCredential(null); + cred.setSimCredential(new Credential.SimCredential()); + cred.getSimCredential().setImsi("1234*"); + cred.getSimCredential().setEapType(EAPConstants.EAP_SIM); + cred.setCaCertificate(null); + cred.setClientCertificateChain(null); + cred.setClientPrivateKey(null); + return cred; + } + + /** + * Helper function for creating a {@link Policy} for testing. + * + * @return {@link Policy} + */ + private static Policy createPolicy() { + Policy policy = new Policy(); + policy.setMinHomeDownlinkBandwidth(123); + policy.setMinHomeUplinkBandwidth(345); + policy.setMinRoamingDownlinkBandwidth(567); + policy.setMinRoamingUplinkBandwidth(789); + policy.setMaximumBssLoadValue(12); + policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"}); + HashMap<Integer, String> requiredProtoPortMap = new HashMap<>(); + requiredProtoPortMap.put(12, "23,342,123"); + requiredProtoPortMap.put(23, "789,372,1235"); + policy.setRequiredProtoPortMap(requiredProtoPortMap); + + List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>(); + Policy.RoamingPartner partner1 = new Policy.RoamingPartner(); + partner1.setFqdn("partner1.com"); + partner1.setFqdnExactMatch(true); + partner1.setPriority(12); + partner1.setCountries("us,jp"); + Policy.RoamingPartner partner2 = new Policy.RoamingPartner(); + partner2.setFqdn("partner2.com"); + partner2.setFqdnExactMatch(false); + partner2.setPriority(42); + partner2.setCountries("ca,fr"); + preferredRoamingPartnerList.add(partner1); + preferredRoamingPartnerList.add(partner2); + policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList); + + UpdateParameter policyUpdate = new UpdateParameter(); + policyUpdate.setUpdateIntervalInMinutes(1712); + policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM); + policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP); + policyUpdate.setServerUri("policy.update.com"); + policyUpdate.setUsername("username"); + policyUpdate.setBase64EncodedPassword( + Base64.encodeToString("password".getBytes(), Base64.DEFAULT)); + policyUpdate.setTrustRootCertUrl("trust.cert.com"); + policyUpdate.setTrustRootCertSha256Fingerprint( + new byte[CERTIFICATE_FINGERPRINT_BYTES]); + policy.setPolicyUpdate(policyUpdate); + + return policy; + } + + private static UpdateParameter createSubscriptionUpdate() { + UpdateParameter subUpdate = new UpdateParameter(); + subUpdate.setUpdateIntervalInMinutes(9021); + subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP); + subUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER); + subUpdate.setServerUri("subscription.update.com"); + subUpdate.setUsername("subUsername"); + subUpdate.setBase64EncodedPassword( + Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT)); + subUpdate.setTrustRootCertUrl("subscription.trust.cert.com"); + subUpdate.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_FINGERPRINT_BYTES]); + return subUpdate; + } + /** + * Helper function for creating a {@link PasspointConfiguration} for testing. + * + * @return {@link PasspointConfiguration} + */ + public static PasspointConfiguration createConfig() { + PasspointConfiguration config = new PasspointConfiguration(); + config.setHomeSp(createHomeSp()); + config.setAaaServerTrustedNames( + new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"}); + config.setCredential(createCredential()); + config.setPolicy(createPolicy()); + config.setSubscriptionUpdate(createSubscriptionUpdate()); + Map<String, byte[]> trustRootCertList = new HashMap<>(); + trustRootCertList.put("trustRoot.cert1.com", + new byte[CERTIFICATE_FINGERPRINT_BYTES]); + trustRootCertList.put("trustRoot.cert2.com", + new byte[CERTIFICATE_FINGERPRINT_BYTES]); + config.setTrustRootCertList(trustRootCertList); + config.setCredentialPriority(120); + config.setSubscriptionCreationTimeInMillis(231200); + config.setSubscriptionExpirationTimeInMillis(2134232); + config.setSubscriptionType("Gold"); + config.setUsageLimitUsageTimePeriodInMinutes(3600); + config.setUsageLimitStartTimeInMillis(124214213); + config.setUsageLimitDataLimit(14121); + config.setUsageLimitTimeLimitInMinutes(78912); + Map<String, String> friendlyNames = new HashMap<>(); + friendlyNames.put("en", "ServiceName1"); + friendlyNames.put("kr", "ServiceName2"); + config.setServiceFriendlyNames(friendlyNames); + return config; + } + + /** + * Helper function for creating an R2 {@link PasspointConfiguration} for testing. + * + * @return {@link PasspointConfiguration} + */ + public static PasspointConfiguration createR2Config() { + PasspointConfiguration config = createConfig(); + config.setUpdateIdentifier(1234); + return config; + } +} diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java index 66c595f92861..1ac9cb87c0e1 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java @@ -135,6 +135,9 @@ public class PpsMoParserTest { homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"}); config.setHomeSp(homeSp); + config.setAaaServerTrustedNames( + new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"}); + // Credential configuration. Credential credential = new Credential(); credential.setCreationTimeInMillis(format.parse("2016-01-01T10:00:00Z").getTime()); diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java index 0a3e989d18f0..829d8f0a9a3a 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java @@ -18,6 +18,7 @@ package android.net.wifi.hotspot2.pps; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import android.net.wifi.EAPConstants; @@ -158,7 +159,7 @@ public class CredentialTest { } /** - * Verify parcel read/write for an user credential. + * Verify parcel read/write for a user credential. * * @throws Exception */ @@ -176,14 +177,14 @@ public class CredentialTest { Credential cred = createCredentialWithUserCredential(); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(false)); + assertTrue(cred.validate()); } /** - * Verify that an user credential without CA Certificate is invalid. + * Verify that a user credential without CA Certificate is valid. * * @throws Exception */ @@ -192,15 +193,12 @@ public class CredentialTest { Credential cred = createCredentialWithUserCredential(); cred.setCaCertificate(null); - // For R1 validation - assertFalse(cred.validate(true)); - - // For R2 validation - assertTrue(cred.validate(false)); + // Accept a configuration with no CA certificate, the system will use the default cert store + assertTrue(cred.validate()); } /** - * Verify that an user credential with EAP type other than EAP-TTLS is invalid. + * Verify that a user credential with EAP type other than EAP-TTLS is invalid. * * @throws Exception */ @@ -210,15 +208,15 @@ public class CredentialTest { cred.getUserCredential().setEapType(EAPConstants.EAP_TLS); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that an user credential without realm is invalid. + * Verify that a user credential without realm is invalid. * * @throws Exception */ @@ -228,14 +226,14 @@ public class CredentialTest { cred.setRealm(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that an user credential without username is invalid. + * Verify that a user credential without username is invalid. * * @throws Exception */ @@ -245,14 +243,14 @@ public class CredentialTest { cred.getUserCredential().setUsername(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that an user credential without password is invalid. + * Verify that a user credential without password is invalid. * * @throws Exception */ @@ -262,14 +260,14 @@ public class CredentialTest { cred.getUserCredential().setPassword(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that an user credential without auth methoh (non-EAP inner method) is invalid. + * Verify that a user credential without auth methoh (non-EAP inner method) is invalid. * * @throws Exception */ @@ -279,10 +277,10 @@ public class CredentialTest { cred.getUserCredential().setNonEapInnerMethod(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -297,10 +295,10 @@ public class CredentialTest { Credential cred = createCredentialWithCertificateCredential(); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); } /** @@ -313,11 +311,8 @@ public class CredentialTest { Credential cred = createCredentialWithCertificateCredential(); cred.setCaCertificate(null); - // For R1 validation - assertFalse(cred.validate(true)); - - // For R2 validation - assertTrue(cred.validate(false)); + // Accept a configuration with no CA certificate, the system will use the default cert store + assertTrue(cred.validate()); } /** @@ -331,10 +326,10 @@ public class CredentialTest { cred.setClientCertificateChain(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -348,10 +343,10 @@ public class CredentialTest { cred.setClientPrivateKey(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -366,10 +361,10 @@ public class CredentialTest { cred.getCertCredential().setCertSha256Fingerprint(new byte[32]); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -382,10 +377,10 @@ public class CredentialTest { Credential cred = createCredentialWithSimCredential(); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(false)); + assertTrue(cred.validate()); } /** @@ -399,10 +394,10 @@ public class CredentialTest { cred.getSimCredential().setEapType(EAPConstants.EAP_AKA); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(false)); + assertTrue(cred.validate()); } /** @@ -416,10 +411,10 @@ public class CredentialTest { cred.getSimCredential().setEapType(EAPConstants.EAP_AKA_PRIME); // For R1 validation - assertTrue(cred.validate(true)); + assertTrue(cred.validate()); // For R2 validation - assertTrue(cred.validate(false)); + assertTrue(cred.validate()); } /** @@ -433,10 +428,10 @@ public class CredentialTest { cred.getSimCredential().setImsi(null); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -450,10 +445,10 @@ public class CredentialTest { cred.getSimCredential().setImsi("dummy"); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -467,14 +462,14 @@ public class CredentialTest { cred.getSimCredential().setEapType(EAPConstants.EAP_TLS); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** - * Verify that a credential contained both an user and a SIM credential is invalid. + * Verify that a credential contained both a user and a SIM credential is invalid. * * @throws Exception */ @@ -488,10 +483,10 @@ public class CredentialTest { cred.setSimCredential(simCredential); // For R1 validation - assertFalse(cred.validate(true)); + assertFalse(cred.validate()); // For R2 validation - assertFalse(cred.validate(false)); + assertFalse(cred.validate()); } /** @@ -557,4 +552,68 @@ public class CredentialTest { public void validateTwoCertificateDifferent() { assertFalse(Credential.isX509CertificateEquals(FakeKeys.CA_CERT0, FakeKeys.CA_CERT1)); } + + /** + * Verify that unique identifiers are the same for objects with the same credentials + */ + @Test + public void testUniqueIdSameCredentialTypes() throws Exception { + assertEquals(createCredentialWithSimCredential().getUniqueId(), + createCredentialWithSimCredential().getUniqueId()); + assertEquals(createCredentialWithCertificateCredential().getUniqueId(), + createCredentialWithCertificateCredential().getUniqueId()); + assertEquals(createCredentialWithUserCredential().getUniqueId(), + createCredentialWithUserCredential().getUniqueId()); + } + + /** + * Verify that unique identifiers are different for each credential + */ + @Test + public void testUniqueIdDifferentForDifferentCredentialTypes() throws Exception { + Credential simCred = createCredentialWithSimCredential(); + Credential certCred = createCredentialWithCertificateCredential(); + Credential userCred = createCredentialWithUserCredential(); + + assertNotEquals(simCred.getUniqueId(), userCred.getUniqueId()); + assertNotEquals(simCred.getUniqueId(), certCred.getUniqueId()); + assertNotEquals(certCred.getUniqueId(), userCred.getUniqueId()); + } + + /** + * Verify that unique identifiers are different for a credential with different values + */ + @Test + public void testUniqueIdDifferentForSimCredentialsWithDifferentValues() throws Exception { + Credential simCred1 = createCredentialWithSimCredential(); + Credential simCred2 = createCredentialWithSimCredential(); + simCred2.getSimCredential().setImsi("567890*"); + + assertNotEquals(simCred1.getUniqueId(), simCred2.getUniqueId()); + } + + /** + * Verify that unique identifiers are different for a credential with different values + */ + @Test + public void testUniqueIdDifferentForUserCredentialsWithDifferentValues() throws Exception { + Credential userCred1 = createCredentialWithUserCredential(); + Credential userCred2 = createCredentialWithUserCredential(); + userCred2.getUserCredential().setUsername("anotheruser"); + + assertNotEquals(userCred1.getUniqueId(), userCred2.getUniqueId()); + } + + /** + * Verify that unique identifiers are different for a credential with different values + */ + @Test + public void testUniqueIdDifferentForCertCredentialsWithDifferentValues() throws Exception { + Credential certCred1 = createCredentialWithCertificateCredential(); + Credential certCred2 = createCredentialWithCertificateCredential(); + certCred2.getCertCredential().setCertSha256Fingerprint( + MessageDigest.getInstance("SHA-256").digest(FakeKeys.CA_CERT0.getEncoded())); + + assertNotEquals(certCred1.getUniqueId(), certCred2.getUniqueId()); + } } diff --git a/wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java b/wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java new file mode 100644 index 000000000000..7b900fec70a8 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/DeviceWiphyCapabilitiesTest.java @@ -0,0 +1,88 @@ +/* + * 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 android.net.wifi.nl80211; + +import static org.junit.Assert.assertEquals; + +import android.net.wifi.ScanResult; +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.nl80211.DeviceWiphyCapabilities}. + */ +@SmallTest +public class DeviceWiphyCapabilitiesTest { + @Before + public void setUp() {} + + /** + * DeviceWiphyCapabilities object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); + capa.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); + capa.setMaxNumberTxSpatialStreams(2); + capa.setMaxNumberRxSpatialStreams(1); + + Parcel parcel = Parcel.obtain(); + capa.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + DeviceWiphyCapabilities capaDeserialized = + DeviceWiphyCapabilities.CREATOR.createFromParcel(parcel); + + assertEquals(capa, capaDeserialized); + assertEquals(capa.hashCode(), capaDeserialized.hashCode()); + } + + /** + * Test mapping wifi standard support into channel width support + */ + @Test + public void testMappingWifiStandardIntoChannelWidthSupport() { + DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, false); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, false); + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); + assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); + assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); + assertEquals(false, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); + + capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)); + assertEquals(true, capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)); + } +} diff --git a/wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java b/wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java new file mode 100644 index 000000000000..8ddd1899179a --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/NativeScanResultTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nl80211; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Unit tests for {@link android.net.wifi.nl80211.NativeScanResult}. + */ +@SmallTest +public class NativeScanResultTest { + + private static final byte[] TEST_SSID = + new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_BSSID = + new byte[] {(byte) 0x12, (byte) 0xef, (byte) 0xa1, + (byte) 0x2c, (byte) 0x97, (byte) 0x8b}; + private static final byte[] TEST_INFO_ELEMENT = + new byte[] {(byte) 0x01, (byte) 0x03, (byte) 0x12, (byte) 0xbe, (byte) 0xff}; + private static final int TEST_FREQUENCY = 2456; + private static final int TEST_SIGNAL_MBM = -45; + private static final long TEST_TSF = 34455441; + private static final int TEST_CAPABILITY = (0x1 << 2) | (0x1 << 5); + private static final boolean TEST_ASSOCIATED = true; + private static final int[] RADIO_CHAIN_IDS = { 0, 1 }; + private static final int[] RADIO_CHAIN_LEVELS = { -56, -65 }; + + /** + * NativeScanResult object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + NativeScanResult scanResult = new NativeScanResult(); + scanResult.ssid = TEST_SSID; + scanResult.bssid = TEST_BSSID; + scanResult.infoElement = TEST_INFO_ELEMENT; + scanResult.frequency = TEST_FREQUENCY; + scanResult.signalMbm = TEST_SIGNAL_MBM; + scanResult.tsf = TEST_TSF; + scanResult.capability = TEST_CAPABILITY; + scanResult.associated = TEST_ASSOCIATED; + scanResult.radioChainInfos = new ArrayList<>(Arrays.asList( + new RadioChainInfo(RADIO_CHAIN_IDS[0], RADIO_CHAIN_LEVELS[0]), + new RadioChainInfo(RADIO_CHAIN_IDS[1], RADIO_CHAIN_LEVELS[1]))); + Parcel parcel = Parcel.obtain(); + scanResult.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + NativeScanResult scanResultDeserialized = NativeScanResult.CREATOR.createFromParcel(parcel); + + assertArrayEquals(scanResult.ssid, scanResultDeserialized.ssid); + assertArrayEquals(scanResult.bssid, scanResultDeserialized.bssid); + assertArrayEquals(scanResult.infoElement, scanResultDeserialized.infoElement); + assertEquals(scanResult.frequency, scanResultDeserialized.frequency); + assertEquals(scanResult.signalMbm, scanResultDeserialized.signalMbm); + assertEquals(scanResult.tsf, scanResultDeserialized.tsf); + assertEquals(scanResult.capability, scanResultDeserialized.capability); + assertEquals(scanResult.associated, scanResultDeserialized.associated); + assertTrue(scanResult.radioChainInfos.containsAll(scanResultDeserialized.radioChainInfos)); + } +} diff --git a/wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java b/wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java new file mode 100644 index 000000000000..dec1db8d274e --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/PnoSettingsTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nl80211; + +import static org.junit.Assert.assertEquals; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +/** + * Unit tests for {@link android.net.wifi.nl80211.PnoSettings}. + */ +@SmallTest +public class PnoSettingsTest { + + private static final byte[] TEST_SSID_1 = + new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_SSID_2 = + new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'}; + private static final int[] TEST_FREQUENCIES_1 = {}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final int TEST_INTERVAL_MS = 30000; + private static final int TEST_MIN_2G_RSSI = -60; + private static final int TEST_MIN_5G_RSSI = -65; + private static final int TEST_VALUE = 42; + + private PnoNetwork mPnoNetwork1; + private PnoNetwork mPnoNetwork2; + + @Before + public void setUp() { + mPnoNetwork1 = new PnoNetwork(); + mPnoNetwork1.setSsid(TEST_SSID_1); + mPnoNetwork1.setHidden(true); + mPnoNetwork1.setFrequenciesMhz(TEST_FREQUENCIES_1); + + mPnoNetwork2 = new PnoNetwork(); + mPnoNetwork2.setSsid(TEST_SSID_2); + mPnoNetwork2.setHidden(false); + mPnoNetwork2.setFrequenciesMhz(TEST_FREQUENCIES_2); + } + + /** + * PnoSettings object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + PnoSettings pnoSettings = new PnoSettings(); + pnoSettings.setIntervalMillis(TEST_INTERVAL_MS); + pnoSettings.setMin2gRssiDbm(TEST_MIN_2G_RSSI); + pnoSettings.setMin5gRssiDbm(TEST_MIN_5G_RSSI); + pnoSettings.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); + + Parcel parcel = Parcel.obtain(); + pnoSettings.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + PnoSettings pnoSettingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel); + + assertEquals(pnoSettings, pnoSettingsDeserialized); + assertEquals(pnoSettings.hashCode(), pnoSettingsDeserialized.hashCode()); + } + + /** + * Tests usage of {@link PnoSettings} as a HashMap key type. + */ + @Test + public void testAsHashMapKey() { + PnoSettings pnoSettings1 = new PnoSettings(); + pnoSettings1.setIntervalMillis(TEST_INTERVAL_MS); + pnoSettings1.setMin2gRssiDbm(TEST_MIN_2G_RSSI); + pnoSettings1.setMin5gRssiDbm(TEST_MIN_5G_RSSI); + pnoSettings1.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); + + PnoSettings pnoSettings2 = new PnoSettings(); + pnoSettings2.setIntervalMillis(TEST_INTERVAL_MS); + pnoSettings2.setMin2gRssiDbm(TEST_MIN_2G_RSSI); + pnoSettings2.setMin5gRssiDbm(TEST_MIN_5G_RSSI); + pnoSettings2.setPnoNetworks(new ArrayList<>(Arrays.asList(mPnoNetwork1, mPnoNetwork2))); + + assertEquals(pnoSettings1, pnoSettings2); + assertEquals(pnoSettings1.hashCode(), pnoSettings2.hashCode()); + + HashMap<PnoSettings, Integer> map = new HashMap<>(); + map.put(pnoSettings1, TEST_VALUE); + + assertEquals(TEST_VALUE, map.get(pnoSettings2).intValue()); + } +} diff --git a/wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java b/wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java new file mode 100644 index 000000000000..905920888012 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/SingleScanSettingsTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nl80211; + +import static org.junit.Assert.assertEquals; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +/** + * Unit tests for {@link android.net.wifi.nl80211.SingleScanSettingsResult}. + */ +@SmallTest +public class SingleScanSettingsTest { + + private static final byte[] TEST_SSID_1 = + new byte[] {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_SSID_2 = + new byte[] {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'T', 'e', 's', 't'}; + private static final int TEST_FREQUENCY_1 = 2456; + private static final int TEST_FREQUENCY_2 = 5215; + private static final int TEST_VALUE = 42; + + private ChannelSettings mChannelSettings1; + private ChannelSettings mChannelSettings2; + private HiddenNetwork mHiddenNetwork1; + private HiddenNetwork mHiddenNetwork2; + + @Before + public void setUp() { + mChannelSettings1 = new ChannelSettings(); + mChannelSettings1.frequency = TEST_FREQUENCY_1; + mChannelSettings2 = new ChannelSettings(); + mChannelSettings2.frequency = TEST_FREQUENCY_2; + + mHiddenNetwork1 = new HiddenNetwork(); + mHiddenNetwork1.ssid = TEST_SSID_1; + mHiddenNetwork2 = new HiddenNetwork(); + mHiddenNetwork2.ssid = TEST_SSID_2; + } + + /** + * SingleScanSettings object can be serialized and deserialized, while keeping the + * values unchanged. + */ + @Test + public void canSerializeAndDeserialize() { + SingleScanSettings scanSettings = new SingleScanSettings(); + scanSettings.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + + scanSettings.channelSettings = + new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); + scanSettings.hiddenNetworks = + new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); + + Parcel parcel = Parcel.obtain(); + scanSettings.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + SingleScanSettings scanSettingsDeserialized = + SingleScanSettings.CREATOR.createFromParcel(parcel); + + assertEquals(scanSettings, scanSettingsDeserialized); + assertEquals(scanSettings.hashCode(), scanSettingsDeserialized.hashCode()); + } + + /** + * Tests usage of {@link SingleScanSettings} as a HashMap key type. + */ + @Test + public void testAsHashMapKey() { + SingleScanSettings scanSettings1 = new SingleScanSettings(); + scanSettings1.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + scanSettings1.channelSettings = + new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); + scanSettings1.hiddenNetworks = + new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); + + SingleScanSettings scanSettings2 = new SingleScanSettings(); + scanSettings2.scanType = IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; + scanSettings2.channelSettings = + new ArrayList<>(Arrays.asList(mChannelSettings1, mChannelSettings2)); + scanSettings2.hiddenNetworks = + new ArrayList<>(Arrays.asList(mHiddenNetwork1, mHiddenNetwork2)); + + assertEquals(scanSettings1, scanSettings2); + assertEquals(scanSettings1.hashCode(), scanSettings2.hashCode()); + + HashMap<SingleScanSettings, Integer> map = new HashMap<>(); + map.put(scanSettings1, TEST_VALUE); + + assertEquals(TEST_VALUE, map.get(scanSettings2).intValue()); + } +} diff --git a/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java new file mode 100644 index 000000000000..9ee0acbfbaa2 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java @@ -0,0 +1,1265 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nl80211; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import android.app.AlarmManager; +import android.app.test.TestAlarmManager; +import android.content.Context; +import android.net.MacAddress; +import android.net.wifi.ScanResult; +import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiScanner; +import android.net.wifi.util.HexEncoding; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.test.TestLooper; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.AdditionalMatchers; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Unit tests for {@link android.net.wifi.nl80211.WifiNl80211Manager}. + */ +@SmallTest +public class WifiNl80211ManagerTest { + @Mock + private IWificond mWificond; + @Mock + private IBinder mWifiCondBinder; + @Mock + private IClientInterface mClientInterface; + @Mock + private IWifiScannerImpl mWifiScannerImpl; + @Mock + private IApInterface mApInterface; + @Mock + private WifiNl80211Manager.SoftApCallback mSoftApListener; + @Mock + private WifiNl80211Manager.SendMgmtFrameCallback mSendMgmtFrameCallback; + @Mock + private WifiNl80211Manager.ScanEventCallback mNormalScanCallback; + @Mock + private WifiNl80211Manager.ScanEventCallback mPnoScanCallback; + @Mock + private WifiNl80211Manager.PnoScanRequestCallback mPnoScanRequestCallback; + @Mock + private Context mContext; + private TestLooper mLooper; + private TestAlarmManager mTestAlarmManager; + private AlarmManager mAlarmManager; + private WifiNl80211Manager mWificondControl; + private static final String TEST_INTERFACE_NAME = "test_wlan_if"; + private static final String TEST_INTERFACE_NAME1 = "test_wlan_if1"; + private static final String TEST_INVALID_INTERFACE_NAME = "asdf"; + private static final byte[] TEST_SSID = + new byte[]{'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'}; + private static final byte[] TEST_PSK = + new byte[]{'T', 'e', 's', 't'}; + + private static final Set<Integer> SCAN_FREQ_SET = + new HashSet<Integer>() {{ + add(2410); + add(2450); + add(5050); + add(5200); + }}; + private static final String TEST_QUOTED_SSID_1 = "\"testSsid1\""; + private static final String TEST_QUOTED_SSID_2 = "\"testSsid2\""; + private static final int[] TEST_FREQUENCIES_1 = {}; + private static final int[] TEST_FREQUENCIES_2 = {2500, 5124}; + private static final MacAddress TEST_RAW_MAC_BYTES = MacAddress.fromBytes( + new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}); + + private static final List<byte[]> SCAN_HIDDEN_NETWORK_SSID_LIST = + new ArrayList<byte[]>() {{ + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); + add(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); + }}; + + private static final PnoSettings TEST_PNO_SETTINGS = new PnoSettings(); + static { + TEST_PNO_SETTINGS.setIntervalMillis(6000); + List<PnoNetwork> initPnoNetworks = new ArrayList<>(); + PnoNetwork network = new PnoNetwork(); + network.setSsid(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_1))); + network.setHidden(true); + network.setFrequenciesMhz(TEST_FREQUENCIES_1); + initPnoNetworks.add(network); + network.setSsid(LocalNativeUtil.byteArrayFromArrayList( + LocalNativeUtil.decodeSsid(TEST_QUOTED_SSID_2))); + network.setHidden(false); + network.setFrequenciesMhz(TEST_FREQUENCIES_2); + initPnoNetworks.add(network); + TEST_PNO_SETTINGS.setPnoNetworks(initPnoNetworks); + } + + private static final int TEST_MCS_RATE = 5; + private static final int TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS = 100; + private static final byte[] TEST_PROBE_FRAME = { + 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, + 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09, + (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66, + 0x00, 0x00 + }; + + @Before + public void setUp() throws Exception { + // Setup mocks for successful WificondControl operation. Failure case mocks should be + // created in specific tests + MockitoAnnotations.initMocks(this); + + mTestAlarmManager = new TestAlarmManager(); + mAlarmManager = mTestAlarmManager.getAlarmManager(); + when(mContext.getSystemServiceName(AlarmManager.class)).thenReturn(Context.ALARM_SERVICE); + when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager); + + mLooper = new TestLooper(); + when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); + + when(mWificond.asBinder()).thenReturn(mWifiCondBinder); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mWificond.createClientInterface(any())).thenReturn(mClientInterface); + when(mWificond.createApInterface(any())).thenReturn(mApInterface); + when(mWificond.tearDownClientInterface(any())).thenReturn(true); + when(mWificond.tearDownApInterface(any())).thenReturn(true); + when(mClientInterface.getWifiScannerImpl()).thenReturn(mWifiScannerImpl); + when(mClientInterface.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME); + mWificondControl = new WifiNl80211Manager(mContext, mWificond); + assertEquals(true, + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback)); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testSetupInterfaceForClientMode() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForClientMode(TEST_INTERFACE_NAME) calls subscribeScanEvents(). + */ + @Test + public void testSetupInterfaceForClientModeCallsScanEventSubscripiton() throws Exception { + verify(mWifiScannerImpl).subscribeScanEvents(any(IScanEvent.class)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceOnInvalidIface() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME1)); + verify(mWifiScannerImpl, never()).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceFailDueToExceptionScannerUnsubscribe() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(true); + doThrow(new RemoteException()).when(mWifiScannerImpl).unsubscribeScanEvents(); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl, never()).unsubscribePnoScanEvents(); + verify(mWificond, never()).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownClientInterfaceErrorWhenWificondFailed() throws Exception { + when(mWificond.tearDownClientInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + verify(mWifiScannerImpl).unsubscribePnoScanEvents(); + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the client handles are cleared after teardown. + */ + @Test + public void testTeardownClientInterfaceClearsHandles() throws Exception { + testTeardownClientInterface(); + + assertNull(mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + verify(mClientInterface, never()).signalPoll(); + + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any()); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) calls wificond. + */ + @Test + public void testSetupInterfaceForSoftApMode() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that setupInterfaceForSoftAp() returns null when wificond is not started. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondIsNotStarted() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that setupInterfaceForSoftApMode(TEST_INTERFACE_NAME) returns null when wificond + * failed to setup AP interface. + */ + @Test + public void testSetupInterfaceForSoftApModeErrorWhenWificondFailedToSetupInterface() + throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME)).thenReturn(null); + + assertEquals(false, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(true); + + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that tearDownSoftapInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceOnInvalidIface() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME1)).thenReturn(true); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + verify(mWificond, never()).tearDownApInterface(any()); + } + + /** + * Verifies that tearDownClientInterface(TEST_INTERFACE_NAME) calls Wificond. + */ + @Test + public void testTeardownSoftApInterfaceErrorWhenWificondFailed() throws Exception { + testSetupInterfaceForSoftApMode(); + when(mWificond.tearDownApInterface(TEST_INTERFACE_NAME)).thenReturn(false); + + assertFalse(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME)); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME); + } + + /** + * Verifies that the SoftAp handles are cleared after teardown. + */ + @Test + public void testTeardownSoftApInterfaceClearsHandles() throws Exception { + testTeardownSoftApInterface(); + + assertFalse(mWificondControl.registerApCallback( + TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); + verify(mApInterface, never()).registerCallback(any()); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testSetupMultipleInterfaces() throws Exception { + when(mWificond.createApInterface(TEST_INTERFACE_NAME1)).thenReturn(mApInterface); + + assertEquals(true, mWificondControl.setupInterfaceForSoftApMode(TEST_INTERFACE_NAME1)); + + verify(mWificond).createClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).createApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that we can setup concurrent interfaces. + */ + @Test + public void testTeardownMultipleInterfaces() throws Exception { + testSetupMultipleInterfaces(); + assertTrue(mWificondControl.tearDownClientInterface(TEST_INTERFACE_NAME)); + assertTrue(mWificondControl.tearDownSoftApInterface(TEST_INTERFACE_NAME1)); + + verify(mWificond).tearDownClientInterface(TEST_INTERFACE_NAME); + verify(mWificond).tearDownApInterface(TEST_INTERFACE_NAME1); + } + + /** + * Verifies that tearDownInterfaces() calls wificond. + */ + @Test + public void testTearDownInterfaces() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWificond).tearDownInterfaces(); + } + + /** + * Verifies that tearDownInterfaces() calls unsubscribeScanEvents() when there was + * a configured client interface. + */ + @Test + public void testTearDownInterfacesRemovesScanEventSubscription() throws Exception { + assertTrue(mWificondControl.tearDownInterfaces()); + verify(mWifiScannerImpl).unsubscribeScanEvents(); + } + + /** + * Verifies that tearDownInterfaces() returns false when wificond is not started. + */ + @Test + public void testTearDownInterfacesErrorWhenWificondIsNotStarterd() throws Exception { + // Invoke wificond death handler to clear the handle. + mWificondControl.binderDied(); + mLooper.dispatchAll(); + assertFalse(mWificondControl.tearDownInterfaces()); + } + + /** + * Verifies that signalPoll() calls wificond. + */ + @Test + public void testSignalPoll() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback); + mWificondControl.signalPoll(TEST_INTERFACE_NAME); + verify(mClientInterface).signalPoll(); + } + + /** + * Verifies that signalPoll() returns null when there is no configured client interface. + */ + @Test + public void testSignalPollErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.signalPoll(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getTxPacketCounters() calls wificond. + */ + @Test + public void testGetTxPacketCounters() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, Runnable::run, + mNormalScanCallback, mPnoScanCallback); + mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME); + verify(mClientInterface).getPacketCounters(); + } + + /** + * Verifies that getTxPacketCounters() returns null when there is no configured client + * interface. + */ + @Test + public void testGetTxPacketCountersErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // Signal poll should fail. + assertEquals(null, mWificondControl.getTxPacketCounters(TEST_INTERFACE_NAME)); + } + + /** + * Verifies that getScanResults() returns null when there is no configured client + * interface. + */ + @Test + public void testGetScanResultsErrorWhenNoClientInterfaceConfigured() throws Exception { + when(mWificond.createClientInterface(TEST_INTERFACE_NAME)).thenReturn(mClientInterface); + + // Configure client interface. + assertEquals(true, mWificondControl.setupInterfaceForClientMode(TEST_INTERFACE_NAME, + Runnable::run, mNormalScanCallback, mPnoScanCallback)); + + // Tear down interfaces. + assertTrue(mWificondControl.tearDownInterfaces()); + + // getScanResults should fail. + assertEquals(0, + mWificondControl.getScanResults(TEST_INTERFACE_NAME, + WifiNl80211Manager.SCAN_TYPE_SINGLE_SCAN).size()); + } + + /** + * Verifies that Scan() can convert input parameters to SingleScanSettings correctly. + */ + @Test + public void testScan() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() removes duplicates hiddenSsids passed in from input. + */ + @Test + public void testScanWithDuplicateHiddenSsids() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + // Create a list of hiddenSsid that has a duplicate element + List<byte[]> hiddenSsidWithDup = new ArrayList<>(SCAN_HIDDEN_NETWORK_SSID_LIST); + hiddenSsidWithDup.add(SCAN_HIDDEN_NETWORK_SSID_LIST.get(0)); + assertEquals(hiddenSsidWithDup.get(0), + hiddenSsidWithDup.get(hiddenSsidWithDup.size() - 1)); + // Pass the List with duplicate elements into scan() + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, hiddenSsidWithDup)); + // But the argument passed down should have the duplicate removed. + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_LOW_POWER, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST))); + } + + /** + * Verifies that Scan() can handle null input parameters correctly. + */ + @Test + public void testScanNullParameters() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(true); + assertTrue(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_HIGH_ACCURACY, null, null)); + verify(mWifiScannerImpl).scan(argThat(new ScanMatcher( + IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY, null, null))); + } + + /** + * Verifies that Scan() can handle wificond scan failure. + */ + @Test + public void testScanFailure() throws Exception { + when(mWifiScannerImpl.scan(any(SingleScanSettings.class))).thenReturn(false); + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, WifiScanner.SCAN_TYPE_LOW_LATENCY, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that Scan() can handle invalid type. + */ + @Test + public void testScanFailureDueToInvalidType() throws Exception { + assertFalse(mWificondControl.startScan( + TEST_INTERFACE_NAME, 100, + SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_LIST)); + verify(mWifiScannerImpl, never()).scan(any(SingleScanSettings.class)); + } + + /** + * Verifies that startPnoScan() can convert input parameters to PnoSettings correctly. + */ + @Test + public void testStartPnoScan() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(true); + assertTrue( + mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, + mPnoScanRequestCallback)); + verify(mWifiScannerImpl).startPnoScan(eq(TEST_PNO_SETTINGS)); + verify(mPnoScanRequestCallback).onPnoRequestSucceeded(); + } + + /** + * Verifies that stopPnoScan() calls underlying wificond. + */ + @Test + public void testStopPnoScan() throws Exception { + when(mWifiScannerImpl.stopPnoScan()).thenReturn(true); + assertTrue(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that stopPnoScan() can handle wificond failure. + */ + @Test + public void testStopPnoScanFailure() throws Exception { + + when(mWifiScannerImpl.stopPnoScan()).thenReturn(false); + assertFalse(mWificondControl.stopPnoScan(TEST_INTERFACE_NAME)); + verify(mWifiScannerImpl).stopPnoScan(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * result event. + */ + @Test + public void testScanResultEvent() throws Exception { + ArgumentCaptor<IScanEvent> messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanResultReady(); + + verify(mNormalScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon scan + * failed event. + */ + @Test + public void testScanFailedEvent() throws Exception { + ArgumentCaptor<IScanEvent> messageCaptor = ArgumentCaptor.forClass(IScanEvent.class); + verify(mWifiScannerImpl).subscribeScanEvents(messageCaptor.capture()); + IScanEvent scanEvent = messageCaptor.getValue(); + assertNotNull(scanEvent); + scanEvent.OnScanFailed(); + + verify(mNormalScanCallback).onScanFailed(); + } + + /** + * Verifies that WificondControl can invoke WifiMonitor broadcast methods upon pno scan + * result event. + */ + @Test + public void testPnoScanResultEvent() throws Exception { + ArgumentCaptor<IPnoScanEvent> messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + } + + /** + * Verifies that WificondControl can invoke WifiMetrics pno scan count methods upon pno event. + */ + @Test + public void testPnoScanEventsForMetrics() throws Exception { + ArgumentCaptor<IPnoScanEvent> messageCaptor = ArgumentCaptor.forClass(IPnoScanEvent.class); + verify(mWifiScannerImpl).subscribePnoScanEvents(messageCaptor.capture()); + IPnoScanEvent pnoScanEvent = messageCaptor.getValue(); + assertNotNull(pnoScanEvent); + + pnoScanEvent.OnPnoNetworkFound(); + verify(mPnoScanCallback).onScanResultReady(); + + pnoScanEvent.OnPnoScanFailed(); + verify(mPnoScanCallback).onScanFailed(); + } + + /** + * Verifies that startPnoScan() can invoke WifiMetrics pno scan count methods correctly. + */ + @Test + public void testStartPnoScanForMetrics() throws Exception { + when(mWifiScannerImpl.startPnoScan(any(PnoSettings.class))).thenReturn(false); + + assertFalse( + mWificondControl.startPnoScan(TEST_INTERFACE_NAME, TEST_PNO_SETTINGS, Runnable::run, + mPnoScanRequestCallback)); + verify(mPnoScanRequestCallback).onPnoRequestFailed(); + } + + /** + * Verifies that abortScan() calls underlying wificond. + */ + @Test + public void testAbortScan() throws Exception { + mWificondControl.abortScan(TEST_INTERFACE_NAME); + verify(mWifiScannerImpl).abortScan(); + } + + /** + * Ensures that the Ap interface callbacks are forwarded to the + * SoftApListener used for starting soft AP. + */ + @Test + public void testSoftApListenerInvocation() throws Exception { + testSetupInterfaceForSoftApMode(); + + WifiConfiguration config = new WifiConfiguration(); + config.SSID = new String(TEST_SSID, StandardCharsets.UTF_8); + + when(mApInterface.registerCallback(any())).thenReturn(true); + + final ArgumentCaptor<IApInterfaceEventCallback> apInterfaceCallbackCaptor = + ArgumentCaptor.forClass(IApInterfaceEventCallback.class); + + assertTrue(mWificondControl.registerApCallback( + TEST_INTERFACE_NAME, Runnable::run, mSoftApListener)); + verify(mApInterface).registerCallback(apInterfaceCallbackCaptor.capture()); + + final NativeWifiClient testClient = new NativeWifiClient(TEST_RAW_MAC_BYTES); + apInterfaceCallbackCaptor.getValue().onConnectedClientsChanged(testClient, true); + verify(mSoftApListener).onConnectedClientsChanged(eq(testClient), eq(true)); + + int channelFrequency = 2437; + int channelBandwidth = IApInterfaceEventCallback.BANDWIDTH_20; + apInterfaceCallbackCaptor.getValue().onSoftApChannelSwitched(channelFrequency, + channelBandwidth); + verify(mSoftApListener).onSoftApChannelSwitched(eq(channelFrequency), + eq(SoftApInfo.CHANNEL_WIDTH_20MHZ)); + } + + /** + * Verifies registration and invocation of wificond death handler. + */ + @Test + public void testRegisterDeathHandler() throws Exception { + Runnable deathHandler = mock(Runnable.class); + mWificondControl.setOnServiceDeadCallback(deathHandler); + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + } + + /** + * Verifies handling of wificond death and ensures that all internal state is cleared and + * handlers are invoked. + */ + @Test + public void testDeathHandling() throws Exception { + Runnable deathHandler = mock(Runnable.class); + mWificondControl.setOnServiceDeadCallback(deathHandler); + + testSetupInterfaceForClientMode(); + + mWificondControl.binderDied(); + mLooper.dispatchAll(); + verify(deathHandler).run(); + + // The handles should be cleared after death. + assertEquals(0, mWificondControl.getChannelsMhzForBand(WifiScanner.WIFI_BAND_5_GHZ).length); + verify(mWificond, never()).getAvailable5gNonDFSChannels(); + } + + /** + * sendMgmtFrame() should fail if a null callback is passed in. + */ + @Test + public void testSendMgmtFrameNullCallback() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, null); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * sendMgmtFrame() should fail if a null frame is passed in. + */ + @Test + public void testSendMgmtFrameNullFrame() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, null, TEST_MCS_RATE, Runnable::run, + mSendMgmtFrameCallback); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if an interface name that does not exist is passed in. + */ + @Test + public void testSendMgmtFrameInvalidInterfaceName() throws Exception { + mWificondControl.sendMgmtFrame(TEST_INVALID_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + verify(mClientInterface, never()).SendMgmtFrame(any(), any(), anyInt()); + verify(mSendMgmtFrameCallback).onFailure(anyInt()); + } + + /** + * sendMgmtFrame() should fail if it is called a second time before the first call completed. + */ + @Test + public void testSendMgmtFrameCalledTwiceBeforeFinished() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb1 = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + WifiNl80211Manager.SendMgmtFrameCallback cb2 = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb1); + verify(cb1, never()).onFailure(anyInt()); + verify(mClientInterface, times(1)) + .SendMgmtFrame(AdditionalMatchers.aryEq(TEST_PROBE_FRAME), + any(), eq(TEST_MCS_RATE)); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb2); + verify(cb2).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED); + // verify SendMgmtFrame() still was only called once i.e. not called again + verify(mClientInterface, times(1)) + .SendMgmtFrame(any(), any(), anyInt()); + } + + /** + * Tests that when a RemoteException is triggered on AIDL call, onFailure() is called only once. + */ + @Test + public void testSendMgmtFrameThrowsException() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor<ISendMgmtFrameEvent> sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + + doThrow(new RemoteException()).when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + + final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + mLooper.dispatchAll(); + + verify(cb).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + + verifyNoMoreInteractions(cb); + } + + /** + * Tests that the onAck() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameSuccess() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor<ISendMgmtFrameEvent> sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb).onAck(eq(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS)); + verify(cb, never()).onFailure(anyInt()); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, times(1)).onAck(anyInt()); + verify(cb, never()).onFailure(anyInt()); + } + + /** + * Tests that the onFailure() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameFailure() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor<ISendMgmtFrameEvent> sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + verify(mAlarmManager).cancel(eq(alarmListenerCaptor.getValue())); + + // verify that even if timeout is triggered afterwards, SendMgmtFrameCallback is not + // triggered again + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests that the onTimeout() callback is triggered correctly. + */ + @Test + public void testSendMgmtFrameTimeout() throws Exception { + WifiNl80211Manager.SendMgmtFrameCallback cb = mock( + WifiNl80211Manager.SendMgmtFrameCallback.class); + + final ArgumentCaptor<ISendMgmtFrameEvent> sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, cb); + + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb).onFailure(WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + + // verify that even if onAck() callback is triggered after timeout, + // SendMgmtFrameCallback is not triggered again + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(cb, never()).onAck(anyInt()); + verify(cb, times(1)).onFailure(anyInt()); + } + + /** + * Tests every possible test outcome followed by every other test outcome to ensure that the + * internal state is reset correctly between calls. + * i.e. (success, success), (success, failure), (success, timeout), + * (failure, failure), (failure, success), (failure, timeout), + * (timeout, timeout), (timeout, success), (timeout, failure) + * + * Also tests that internal state is reset correctly after a transient AIDL RemoteException. + */ + @Test + public void testSendMgmtFrameMixed() throws Exception { + testSendMgmtFrameThrowsException(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameFailure(); + testSendMgmtFrameFailure(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameSuccess(); + testSendMgmtFrameTimeout(); + testSendMgmtFrameFailure(); + testSendMgmtFrameSuccess(); + } + + /** + * Tests that OnAck() does not perform any non-thread-safe operations on the binder thread. + * + * The sequence of instructions are: + * 1. post onAlarm() onto main thread + * 2. OnAck() + * 3. mLooper.dispatchAll() + * + * The actual order of execution is: + * 1. binder thread portion of OnAck() + * 2. onAlarm() (which purely executes on the main thread) + * 3. main thread portion of OnAck() + * + * If the binder thread portion of OnAck() is not thread-safe, it can possibly mess up + * onAlarm(). Tests that this does not occur. + */ + @Test + public void testSendMgmtFrameTimeoutAckThreadSafe() throws Exception { + final ArgumentCaptor<ISendMgmtFrameEvent> sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnAck posts to the handler + sendMgmtFrameEventCaptor.getValue().OnAck(TEST_SEND_MGMT_FRAME_ELAPSED_TIME_MS); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback, never()).onAck(anyInt()); + verify(mSendMgmtFrameCallback).onFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + /** + * See {@link #testSendMgmtFrameTimeoutAckThreadSafe()}. This test replaces OnAck() with + * OnFailure(). + */ + @Test + public void testSendMgmtFrameTimeoutFailureThreadSafe() throws Exception { + final ArgumentCaptor<ISendMgmtFrameEvent> sendMgmtFrameEventCaptor = + ArgumentCaptor.forClass(ISendMgmtFrameEvent.class); + doNothing().when(mClientInterface) + .SendMgmtFrame(any(), sendMgmtFrameEventCaptor.capture(), anyInt()); + final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = + ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); + final ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class); + doNothing().when(mAlarmManager).set(anyInt(), anyLong(), any(), + alarmListenerCaptor.capture(), handlerCaptor.capture()); + mWificondControl.sendMgmtFrame(TEST_INTERFACE_NAME, TEST_PROBE_FRAME, TEST_MCS_RATE, + Runnable::run, mSendMgmtFrameCallback); + + // AlarmManager should post the onAlarm() callback onto the handler, but since we are + // triggering onAlarm() ourselves during the test, manually post onto handler + handlerCaptor.getValue().post(() -> alarmListenerCaptor.getValue().onAlarm()); + // OnFailure posts to the handler + sendMgmtFrameEventCaptor.getValue().OnFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN); + mLooper.dispatchAll(); + verify(mSendMgmtFrameCallback).onFailure( + WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT); + } + + /** + * Tests getDeviceWiphyCapabililties + */ + @Test + public void testGetDeviceWiphyCapabilities() throws Exception { + DeviceWiphyCapabilities capaExpected = new DeviceWiphyCapabilities(); + + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); + capaExpected.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); + capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_160MHZ, true); + capaExpected.setChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ, false); + capaExpected.setMaxNumberTxSpatialStreams(2); + capaExpected.setMaxNumberRxSpatialStreams(1); + + when(mWificond.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME)) + .thenReturn(capaExpected); + + DeviceWiphyCapabilities capaActual = + mWificondControl.getDeviceWiphyCapabilities(TEST_INTERFACE_NAME); + assertEquals(capaExpected, capaActual); + } + + // Create a ArgumentMatcher which captures a SingleScanSettings parameter and checks if it + // matches the provided frequency set and ssid set. + private class ScanMatcher implements ArgumentMatcher<SingleScanSettings> { + int mExpectedScanType; + private final Set<Integer> mExpectedFreqs; + private final List<byte[]> mExpectedSsids; + + ScanMatcher(int expectedScanType, Set<Integer> expectedFreqs, List<byte[]> expectedSsids) { + this.mExpectedScanType = expectedScanType; + this.mExpectedFreqs = expectedFreqs; + this.mExpectedSsids = expectedSsids; + } + + @Override + public boolean matches(SingleScanSettings settings) { + if (settings.scanType != mExpectedScanType) { + return false; + } + ArrayList<ChannelSettings> channelSettings = settings.channelSettings; + ArrayList<HiddenNetwork> hiddenNetworks = settings.hiddenNetworks; + if (mExpectedFreqs != null) { + Set<Integer> freqSet = new HashSet<Integer>(); + for (ChannelSettings channel : channelSettings) { + freqSet.add(channel.frequency); + } + if (!mExpectedFreqs.equals(freqSet)) { + return false; + } + } else { + if (channelSettings != null && channelSettings.size() > 0) { + return false; + } + } + + if (mExpectedSsids != null) { + List<byte[]> ssidSet = new ArrayList<>(); + for (HiddenNetwork network : hiddenNetworks) { + ssidSet.add(network.ssid); + } + if (!mExpectedSsids.equals(ssidSet)) { + return false; + } + + } else { + if (hiddenNetworks != null && hiddenNetworks.size() > 0) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "ScanMatcher{mExpectedFreqs=" + mExpectedFreqs + + ", mExpectedSsids=" + mExpectedSsids + '}'; + } + } + + private static class LocalNativeUtil { + private static final int SSID_BYTES_MAX_LEN = 32; + + /** + * Converts an ArrayList<Byte> of UTF_8 byte values to string. + * The string will either be: + * a) UTF-8 String encapsulated in quotes (if all the bytes are UTF-8 encodeable and non + * null), + * or + * b) Hex string with no delimiters. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String bytesToHexOrQuotedString(ArrayList<Byte> bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null ssid bytes"); + } + byte[] byteArray = byteArrayFromArrayList(bytes); + // Check for 0's in the byte stream in which case we cannot convert this into a string. + if (!bytes.contains(Byte.valueOf((byte) 0))) { + CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); + try { + CharBuffer decoded = decoder.decode(ByteBuffer.wrap(byteArray)); + return "\"" + decoded.toString() + "\""; + } catch (CharacterCodingException cce) { + } + } + return hexStringFromByteArray(byteArray); + } + + /** + * Converts an ssid string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param ssidStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList<Byte> decodeSsid(String ssidStr) { + ArrayList<Byte> ssidBytes = hexOrQuotedStringToBytes(ssidStr); + if (ssidBytes.size() > SSID_BYTES_MAX_LEN) { + throw new IllegalArgumentException( + "ssid bytes size out of range: " + ssidBytes.size()); + } + return ssidBytes; + } + + /** + * Convert from an array list of Byte to an array of primitive bytes. + */ + public static byte[] byteArrayFromArrayList(ArrayList<Byte> bytes) { + byte[] byteArray = new byte[bytes.size()]; + int i = 0; + for (Byte b : bytes) { + byteArray[i++] = b; + } + return byteArray; + } + + /** + * Converts a byte array to hex string. + * + * @param bytes List of bytes for ssid. + * @throws IllegalArgumentException for null bytes. + */ + public static String hexStringFromByteArray(byte[] bytes) { + if (bytes == null) { + throw new IllegalArgumentException("null hex bytes"); + } + return new String(HexEncoding.encode(bytes)).toLowerCase(); + } + + /** + * Converts an string to an arraylist of UTF_8 byte values. + * These forms are acceptable: + * a) UTF-8 String encapsulated in quotes, or + * b) Hex string with no delimiters. + * + * @param str String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static ArrayList<Byte> hexOrQuotedStringToBytes(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + int length = str.length(); + if ((length > 1) && (str.charAt(0) == '"') && (str.charAt(length - 1) == '"')) { + str = str.substring(1, str.length() - 1); + return stringToByteArrayList(str); + } else { + return byteArrayToArrayList(hexStringToByteArray(str)); + } + } + + /** + * Convert the string to byte array list. + * + * @return the UTF_8 char byte values of str, as an ArrayList. + * @throws IllegalArgumentException if a null or unencodable string is sent. + */ + public static ArrayList<Byte> stringToByteArrayList(String str) { + if (str == null) { + throw new IllegalArgumentException("null string"); + } + // Ensure that the provided string is UTF_8 encoded. + CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder(); + try { + ByteBuffer encoded = encoder.encode(CharBuffer.wrap(str)); + byte[] byteArray = new byte[encoded.remaining()]; + encoded.get(byteArray); + return byteArrayToArrayList(byteArray); + } catch (CharacterCodingException cce) { + throw new IllegalArgumentException("cannot be utf-8 encoded", cce); + } + } + + /** + * Convert from an array of primitive bytes to an array list of Byte. + */ + public static ArrayList<Byte> byteArrayToArrayList(byte[] bytes) { + ArrayList<Byte> byteList = new ArrayList<>(); + for (Byte b : bytes) { + byteList.add(b); + } + return byteList; + } + + /** + * Converts a hex string to byte array. + * + * @param hexStr String to be converted. + * @throws IllegalArgumentException for null string. + */ + public static byte[] hexStringToByteArray(String hexStr) { + if (hexStr == null) { + throw new IllegalArgumentException("null hex string"); + } + return HexEncoding.decode(hexStr.toCharArray(), false); + } + } +} diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java index 17ee75594c2f..6edc287068e8 100644 --- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pDeviceTest.java @@ -45,7 +45,7 @@ public class WifiP2pDeviceTest { assertEquals(devA.groupCapability, devB.groupCapability); assertEquals(devA.status, devB.status); if (devA.wfdInfo != null) { - assertEquals(devA.wfdInfo.isWfdEnabled(), devB.wfdInfo.isWfdEnabled()); + assertEquals(devA.wfdInfo.isEnabled(), devB.wfdInfo.isEnabled()); assertEquals(devA.wfdInfo.getDeviceInfoHex(), devB.wfdInfo.getDeviceInfoHex()); assertEquals(devA.wfdInfo.getControlPort(), devB.wfdInfo.getControlPort()); assertEquals(devA.wfdInfo.getMaxThroughput(), devB.wfdInfo.getMaxThroughput()); diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java index d2f11688e4e5..2a9b36b47172 100644 --- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java @@ -43,8 +43,9 @@ public class WifiP2pWfdInfoTest { @Before public void setUp() { // initialize device info flags. - mSourceInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); + mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE); mSourceInfo.setSessionAvailable(true); + mSourceInfo.setContentProtectionSupported(true); } /** @@ -54,28 +55,25 @@ public class WifiP2pWfdInfoTest { public void testSettersGetters() throws Exception { WifiP2pWfdInfo info = new WifiP2pWfdInfo(); - info.setWfdEnabled(true); - assertTrue(info.isWfdEnabled()); + info.setEnabled(true); + assertTrue(info.isEnabled()); - info.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); - assertEquals(WifiP2pWfdInfo.WFD_SOURCE, info.getDeviceType()); - - info.setCoupledSinkSupportAtSource(true); - assertTrue(info.isCoupledSinkSupportedAtSource()); - - info.setCoupledSinkSupportAtSink(true); - assertTrue(info.isCoupledSinkSupportedAtSink()); + info.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE); + assertEquals(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE, info.getDeviceType()); info.setSessionAvailable(true); assertTrue(info.isSessionAvailable()); + info.setContentProtectionSupported(true); + assertTrue(info.isContentProtectionSupported()); + info.setControlPort(TEST_CTRL_PORT); assertEquals(TEST_CTRL_PORT, info.getControlPort()); info.setMaxThroughput(TEST_MAX_TPUT); assertEquals(TEST_MAX_TPUT, info.getMaxThroughput()); - assertEquals("0018270f0400", info.getDeviceInfoHex()); + assertEquals("0110270f0400", info.getDeviceInfoHex()); } /** diff --git a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java index b02eebbe9a01..271339cecf1e 100644 --- a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java +++ b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java @@ -20,6 +20,7 @@ import android.location.Address; import android.location.Location; import android.net.MacAddress; import android.os.Parcel; +import android.util.SparseArray; import android.webkit.MimeTypeMap; import static junit.framework.Assert.assertEquals; @@ -505,6 +506,30 @@ public class ResponderLocationTest { } /** + * Test that a Civic Location sparseArray can be extracted from a valid lcr buffer. + */ + @Test + public void testLcrTestCivicLocationSparseArray() { + byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE); + byte[] testLcrBuffer = + concatenateArrays(sTestLcrBufferHeader, sTestCivicLocationSEWithAddress); + ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer); + + boolean valid = responderLocation.isValid(); + SparseArray<String> civicLocationSparseArray = responderLocation + .toCivicLocationSparseArray(); + + assertTrue(valid); + assertEquals("15", civicLocationSparseArray.get(CivicLocationKeys.HNO)); + assertEquals("Alto", + civicLocationSparseArray.get(CivicLocationKeys.PRIMARY_ROAD_NAME)); + assertEquals("Road", + civicLocationSparseArray.get(CivicLocationKeys.STREET_NAME_POST_MODIFIER)); + assertEquals("Mtn View", civicLocationSparseArray.get(CivicLocationKeys.CITY)); + assertEquals("94043", civicLocationSparseArray.get(CivicLocationKeys.POSTAL_CODE)); + } + + /** * Test that a URL can be extracted from a valid lcr buffer with a map image subelement. */ @Test diff --git a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java index 53bd837d29e0..e6eae416ba78 100644 --- a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java +++ b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java @@ -54,6 +54,7 @@ public class WifiRttManagerTest { private Executor mMockLooperExecutor; private final String packageName = "some.package.name.for.rtt.app"; + private final String featureId = "some.feature.id.in.rtt.app"; @Mock public Context mockContext; @@ -70,6 +71,7 @@ public class WifiRttManagerTest { mMockLooperExecutor = mMockLooper.getNewExecutor(); when(mockContext.getOpPackageName()).thenReturn(packageName); + when(mockContext.getAttributionTag()).thenReturn(featureId); } /** @@ -87,8 +89,8 @@ public class WifiRttManagerTest { // verify ranging request passed to service mDut.startRanging(request, mMockLooperExecutor, callbackMock); - verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(null), - eq(request), callbackCaptor.capture()); + verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId), + eq(null), eq(request), callbackCaptor.capture()); // service calls back with success callbackCaptor.getValue().onRangingResults(results); @@ -111,8 +113,8 @@ public class WifiRttManagerTest { // verify ranging request passed to service mDut.startRanging(request, mMockLooperExecutor, callbackMock); - verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(null), - eq(request), callbackCaptor.capture()); + verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId), + eq(null), eq(request), callbackCaptor.capture()); // service calls back with failure code callbackCaptor.getValue().onRangingFailure(failureCode); diff --git a/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java b/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java new file mode 100644 index 000000000000..0d751389e244 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/util/HexEncodingTest.java @@ -0,0 +1,130 @@ +/* + * 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 android.net.wifi.util; + +import static android.net.wifi.util.HexEncoding.decode; +import static android.net.wifi.util.HexEncoding.encode; +import static android.net.wifi.util.HexEncoding.encodeToString; + +import junit.framework.TestCase; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Locale; + +/** Copied from {@link libcore.libcore.util.HexEncodingTest}. */ +public class HexEncodingTest extends TestCase { + + public void testEncodeByte() { + Object[][] testCases = new Object[][]{ + {0x01, "01"}, + {0x09, "09"}, + {0x0A, "0A"}, + {0x0F, "0F"}, + {0x10, "10"}, + {0x1F, "1F"}, + {0x20, "20"}, + {0x7F, "7F"}, + {0x80, "80"}, + {0xFF, "FF"}, + }; + for (Object[] testCase : testCases) { + Number toEncode = (Number) testCase[0]; + String expected = (String) testCase[1]; + + String actualUpper = encodeToString(toEncode.byteValue(), true /* upperCase */); + assertEquals(upper(expected), actualUpper); + + String actualLower = encodeToString(toEncode.byteValue(), false /* upperCase */); + assertEquals(lower(expected), actualLower); + } + } + + public void testEncodeBytes() { + Object[][] testCases = new Object[][]{ + {"avocados".getBytes(StandardCharsets.UTF_8), "61766F6361646F73"}, + }; + + for (Object[] testCase : testCases) { + byte[] bytes = (byte[]) testCase[0]; + String encodedLower = lower((String) testCase[1]); + String encodedUpper = upper((String) testCase[1]); + + assertArraysEqual(encodedUpper.toCharArray(), encode(bytes)); + assertArraysEqual(encodedUpper.toCharArray(), encode(bytes, true /* upperCase */)); + assertArraysEqual(encodedLower.toCharArray(), encode(bytes, false /* upperCase */)); + + assertArraysEqual(bytes, decode(encode(bytes), false /* allowSingleChar */)); + + // Make sure we can handle lower case hex encodings as well. + assertArraysEqual(bytes, + decode(encodedLower.toCharArray(), false /* allowSingleChar */)); + } + } + + public void testDecode_allow4Bit() { + assertArraysEqual(new byte[]{6}, decode("6".toCharArray(), true)); + assertArraysEqual(new byte[]{6, 0x76}, decode("676".toCharArray(), true)); + } + + public void testDecode_disallow4Bit() { + try { + decode("676".toCharArray(), false /* allowSingleChar */); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + public void testDecode_invalid() { + try { + decode("DEADBARD".toCharArray(), false /* allowSingleChar */); + fail(); + } catch (IllegalArgumentException expected) { + } + + // This demonstrates a difference in behaviour from apache commons : apache + // commons uses Character.isDigit and would successfully decode a string with + // arabic and devanagari characters. + try { + decode("६१٧٥٥F6361646F73".toCharArray(), false /* allowSingleChar */); + fail(); + } catch (IllegalArgumentException expected) { + } + + try { + decode("#%6361646F73".toCharArray(), false /* allowSingleChar */); + fail(); + } catch (IllegalArgumentException expected) { + } + } + + private static void assertArraysEqual(char[] lhs, char[] rhs) { + assertEquals(new String(lhs), new String(rhs)); + } + + private static void assertArraysEqual(byte[] lhs, byte[] rhs) { + assertEquals(Arrays.toString(lhs), Arrays.toString(rhs)); + } + + private static String lower(String string) { + return string.toLowerCase(Locale.ROOT); + } + + private static String upper(String string) { + return string.toUpperCase(Locale.ROOT); + } +} |