1# Copyright (C) 2024 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# Lint as: python3 16"""ACTS Wi-Fi Aware Attached test reimplemented in Mobly.""" 17import sys 18 19from aware import aware_lib_utils as autils 20from aware import constants 21from mobly import asserts 22from mobly import base_test 23from mobly import records 24from mobly import test_runner 25from mobly import utils 26from mobly.controllers import android_device 27 28 29RUNTIME_PERMISSIONS = ( 30 'android.permission.ACCESS_FINE_LOCATION', 31 'android.permission.ACCESS_COARSE_LOCATION', 32 'android.permission.NEARBY_WIFI_DEVICES', 33) 34PACKAGE_NAME = constants.WIFI_AWARE_SNIPPET_PACKAGE_NAME 35 36 37class WifiAwareAttachTest(base_test.BaseTestClass): 38 """Wi-Fi Aware Attach test class.""" 39 40 ads: list[android_device.AndroidDevice] 41 42 def setup_class(self): 43 # Register two Android devices. 44 self.ads = self.register_controller(android_device, min_number=1) 45 46 def setup_device(device: android_device.AndroidDevice): 47 device.load_snippet('wifi_aware_snippet', PACKAGE_NAME) 48 for permission in RUNTIME_PERMISSIONS: 49 device.adb.shell(['pm', 'grant', PACKAGE_NAME, permission]) 50 asserts.abort_all_if( 51 not device.wifi_aware_snippet.wifiAwareIsAvailable(), 52 f'{device} Wi-Fi Aware is not available.', 53 ) 54 55 # Set up devices in parallel. 56 utils.concurrent_exec( 57 setup_device, 58 param_list=[[ad] for ad in self.ads], 59 max_workers=1, 60 raise_on_exception=True, 61 ) 62 63 def setup_test(self): 64 for ad in self.ads: 65 autils.control_wifi(ad, True) 66 aware_avail = ad.wifi_aware_snippet.wifiAwareIsAvailable() 67 if not aware_avail: 68 ad.log.info('Aware not available. Waiting ...') 69 state_handler = ad.wifi_aware_snippet.wifiAwareMonitorStateChange() 70 state_handler.waitAndGet(constants.WifiAwareBroadcast.WIFI_AWARE_AVAILABLE) 71 72 def teardown_test(self): 73 utils.concurrent_exec( 74 self._teardown_test_on_device, 75 param_list=[[ad] for ad in self.ads], 76 max_workers=1, 77 raise_on_exception=True, 78 ) 79 utils.concurrent_exec( 80 lambda d: d.services.create_output_excerpts_all(self.current_test_info), 81 param_list=[[ad] for ad in self.ads], 82 raise_on_exception=True, 83 ) 84 85 def _teardown_test_on_device(self, ad: android_device.AndroidDevice) -> None: 86 ad.wifi_aware_snippet.wifiAwareCloseAllWifiAwareSession() 87 ad.wifi_aware_snippet.wifiAwareMonitorStopStateChange() 88 autils.set_airplane_mode(ad, False) 89 autils.control_wifi(ad, True) 90 91 def on_fail(self, record: records.TestResult) -> None: 92 android_device.take_bug_reports( 93 self.ads, destination=self.current_test_info.output_path 94 ) 95 96 def test_attach(self) -> None: 97 """Basic attaching request. 98 99 Validates that attaching to the Wi-Fi Aware service works 100 without IdentityChanged callback. 101 """ 102 dut = self.ads[0] 103 handler = dut.wifi_aware_snippet.wifiAwareAttached(False) 104 handler.waitAndGet(constants.AttachCallBackMethodType.ATTACHED) 105 autils.callback_no_response( 106 handler, constants.AttachCallBackMethodType.ID_CHANGED 107 ) 108 109 def test_attach_with_identity(self) -> None: 110 """Basic attaching request with extra callback. 111 112 Validates that attaching to the Wi-Fi Aware service works 113 with IdentityChanged callback. 114 """ 115 dut = self.ads[0] 116 handler = dut.wifi_aware_snippet.wifiAwareAttached(True) 117 handler.waitAndGet(constants.AttachCallBackMethodType.ATTACHED) 118 handler.waitAndGet(constants.AttachCallBackMethodType.ID_CHANGED) 119 120 def test_attach_multiple_sessions(self): 121 """Multiple attaching request. 122 123 Validates that attaching to the Wi-Fi Aware service works with 124 multiple request at same time. 125 """ 126 dut = self.ads[0] 127 handler_1 = dut.wifi_aware_snippet.wifiAwareAttached(False) 128 handler_2 = dut.wifi_aware_snippet.wifiAwareAttached(True) 129 handler_3 = dut.wifi_aware_snippet.wifiAwareAttached(False) 130 handler_1.waitAndGet(constants.AttachCallBackMethodType.ATTACHED) 131 autils.callback_no_response( 132 handler_1, constants.AttachCallBackMethodType.ID_CHANGED, 10, True 133 ) 134 handler_2.waitAndGet(constants.AttachCallBackMethodType.ATTACHED) 135 handler_2.waitAndGet(constants.AttachCallBackMethodType.ID_CHANGED) 136 handler_3.waitAndGet(constants.AttachCallBackMethodType.ATTACHED) 137 autils.callback_no_response( 138 handler_3, constants.AttachCallBackMethodType.ID_CHANGED, 10, True 139 ) 140 141 def test_attach_with_no_wifi(self): 142 """WiFi Aware attempt to attach with wifi off. 143 144 Validates that if trying to attach with Wi-Fi disabled will receive 145 the expected failure callback. As a side-effect also validates that the 146 broadcast for Aware unavailable is received. 147 """ 148 dut = self.ads[0] 149 state_handler = dut.wifi_aware_snippet.wifiAwareMonitorStateChange() 150 autils.control_wifi(dut, False) 151 state_handler.waitAndGet(constants.WifiAwareBroadcast.WIFI_AWARE_NOT_AVAILABLE) 152 attach_callback = dut.wifi_aware_snippet.wifiAwareAttached(True) 153 attach_callback.waitAndGet(constants.AttachCallBackMethodType.ATTACH_FAILED) 154 dut.wifi_aware_snippet.wifiAwareMonitorStopStateChange() 155 156 def test_attach_with_location_off(self): 157 """Function/Attach test cases/attempt to attach with location mode off. 158 159 Validates that if trying to attach with device location mode off will 160 receive the expected failure callback. As a side-effect also validates 161 that the broadcast for Aware unavailable is received. 162 """ 163 dut = self.ads[0] 164 asserts.skip_if( 165 autils.check_android_os_version( 166 dut, constants.Operator.GREATER_EQUAL, constants.AndroidVersion.T 167 ), 168 'From T build Aware will not be disabled due to location off', 169 ) 170 state_handler = dut.wifi_aware_snippet.wifiAwareMonitorStateChange() 171 dut.adb.shell('settings put secure location_mode 0') 172 state_handler.waitAndGet(constants.WifiAwareBroadcast.WIFI_AWARE_NOT_AVAILABLE) 173 attach_callback = dut.wifi_aware_snippet.wifiAwareAttached(True) 174 attach_callback.waitAndGet(constants.AttachCallBackMethodType.ATTACH_FAILED) 175 dut.adb.shell('settings put secure location_mode 3') 176 state_handler.waitAndGet(constants.WifiAwareBroadcast.WIFI_AWARE_AVAILABLE) 177 dut.wifi_aware_snippet.wifiAwareMonitorStopStateChange() 178 179 def test_attach_apm_toggle_attach_again(self): 180 """Function/Attach test cases/attempt to attach with airplane mode on. 181 182 Validates that enabling Airplane mode while Aware is on resets it 183 correctly, and allows it to be re-enabled when Airplane mode is then 184 disabled. 185 """ 186 dut = self.ads[0] 187 asserts.skip_if( 188 not dut.is_adb_root, 189 'APM toggle needs Android device(s) with root permission', 190 ) 191 state_handler = dut.wifi_aware_snippet.wifiAwareMonitorStateChange() 192 attach_callback = dut.wifi_aware_snippet.wifiAwareAttached(True) 193 attach_callback.waitAndGet(constants.AttachCallBackMethodType.ATTACHED) 194 autils.set_airplane_mode(dut, True) 195 if autils.check_android_os_version( 196 dut, constants.Operator.GREATER_EQUAL, constants.AndroidVersion.T 197 ): 198 if not autils._check_wifi_status(dut): 199 return 200 else: 201 autils.control_wifi(dut, False) 202 autils.callback_no_response( 203 state_handler, 204 constants.WifiAwareBroadcast.WIFI_AWARE_AVAILABLE, 205 10, 206 True,) 207 state_handler.waitAndGet(constants.WifiAwareBroadcast.WIFI_AWARE_NOT_AVAILABLE) 208 autils.set_airplane_mode(dut, False) 209 state_handler.waitAndGet(constants.WifiAwareBroadcast.WIFI_AWARE_AVAILABLE) 210 attach_callback = dut.wifi_aware_snippet.wifiAwareAttached(True) 211 attach_callback.waitAndGet(constants.AttachCallBackMethodType.ATTACHED) 212 dut.wifi_aware_snippet.wifiAwareMonitorStopStateChange() 213 214 215if __name__ == '__main__': 216 # Take test args 217 if '--' in sys.argv: 218 index = sys.argv.index('--') 219 sys.argv = sys.argv[:1] + sys.argv[index + 1 :] 220 221 test_runner.main() 222