1# Copyright (C) 2025 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# Licensed under the Apache License, Version 2.0 (the "License"); 16# you may not use this file except in compliance with the License. 17# You may obtain a copy of the License at 18# 19# http://www.apache.org/licenses/LICENSE-2.0 20# 21# Unless required by applicable law or agreed to in writing, software 22# distributed under the License is distributed on an "AS IS" BASIS, 23# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24# See the License for the specific language governing permissions and 25# limitations under the License. 26 27# Lint as: python3 28"""ACTS Wifi P2p Group Test reimplemented in Mobly.""" 29 30from collections.abc import Sequence 31import datetime 32import time 33 34from android.platform.test.annotations import ApiTest 35from direct import constants 36from direct import p2p_utils 37from mobly import base_test 38from mobly import test_runner 39from mobly import utils 40from mobly.controllers import android_device 41import wifi_p2p_lib as wp2putils 42 43 44_DEFAULT_TIMEOUT = datetime.timedelta(seconds=30) 45DEFAULT_SLEEPTIME = 5 46_DEFAULT_FUNCTION_SWITCH_TIME = 10 47_DEFAULT_GROUP_CLIENT_LOST_TIME = 60 48 49P2P_CONNECT_NEGOTIATION = 0 50P2P_CONNECT_JOIN = 1 51P2P_CONNECT_INVITATION = 2 52 53WPS_PBC = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC 54WPS_DISPLAY = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_DISPLAY 55WPS_KEYPAD = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_KEYPAD 56 57 58class WifiP2pGroupTest(base_test.BaseTestClass): 59 """Tests Wi-Fi Direct between 2 Android devices.""" 60 61 ads: Sequence[android_device.AndroidDevice] 62 group_owner_ad: android_device.AndroidDevice 63 client_ad: android_device.AndroidDevice 64 network_name = 'DIRECT-xy-Hello' 65 passphrase = 'P2pWorld1234' 66 group_band = '2' 67 68 def setup_class(self) -> None: 69 super().setup_class() 70 self.ads = self.register_controller(android_device, min_number=2) 71 utils.concurrent_exec( 72 self._setup_device, 73 param_list=[[ad] for ad in self.ads], 74 raise_on_exception=True, 75 ) 76 self.group_owner_ad, self.client_ad, *_ = self.ads 77 self.group_owner_ad.debug_tag = ( 78 f'{self.group_owner_ad.serial}(Group Owner)' 79 ) 80 self.client_ad.debug_tag = f'{self.client_ad.serial}(Client)' 81 82 def _setup_device(self, ad: android_device.AndroidDevice) -> None: 83 ad.load_snippet('wifi', constants.WIFI_SNIPPET_PACKAGE_NAME) 84 # Clear all saved Wi-Fi networks. 85 ad.wifi.wifiDisable() 86 ad.wifi.wifiClearConfiguredNetworks() 87 ad.wifi.wifiEnable() 88 89 def teardown_test(self) -> None: 90 for ad in self.ads: 91 ad.wifi.p2pClose() 92 93 utils.concurrent_exec( 94 lambda d: d.services.create_output_excerpts_all( 95 self.current_test_info 96 ), 97 param_list=[[ad] for ad in self.ads], 98 raise_on_exception=True, 99 ) 100 101 def p2p_group_join(self, wps_config: constants.WpsInfo): 102 """General flow for p2p group join. 103 104 Steps: 105 1. GO creates a group. 106 2. GC joins the group. 107 3. connection check via ping from GC to GO 108 109 Args: 110 wps_config: WPS configuration for the group. 111 """ 112 go_dut = self.ads[0] 113 gc_dut = self.ads[1] 114 115 go_dut.log.info('Initializing Wi-Fi p2p.') 116 group_owner = p2p_utils.setup_wifi_p2p(go_dut) 117 client = p2p_utils.setup_wifi_p2p(gc_dut) 118 # Create a group. 119 p2p_utils.create_group(group_owner, config=None) 120 time.sleep(_DEFAULT_FUNCTION_SWITCH_TIME) 121 122 # Request the connection. 123 wp2putils.p2p_connect(client, group_owner, False, wps_config, 124 p2p_connect_type=P2P_CONNECT_JOIN) 125 126 go_ip = wp2putils.p2p_go_ip(gc_dut) 127 wp2putils.p2p_connection_ping_test(gc_dut, go_ip) 128 # Trigger p2p disconnect. 129 p2p_utils.remove_group_and_verify_disconnected( 130 client, group_owner, is_group_negotiation=False 131 ) 132 time.sleep(_DEFAULT_FUNCTION_SWITCH_TIME) 133 134 @ApiTest([ 135 'android.net.wifi.WpsInfo#PBC', 136 'android.net.wifi.p2p.WifiP2pManager#createGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener)', 137 'android.net.wifi.p2p.WifiP2pManager#connect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener)', 138 'android.net.wifi.p2p.WifiP2pManager#removeGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener)', 139 ]) 140 def test_p2p_group_join_via_pbc(self): 141 """Verify the p2p creates a group and join this group via WPS PBC method.""" 142 self.p2p_group_join(constants.WpsInfo.PBC) 143 144 @ApiTest([ 145 'android.net.wifi.WpsInfo#DISPLAY', 146 'android.net.wifi.p2p.WifiP2pManager#createGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener)', 147 'android.net.wifi.p2p.WifiP2pManager#connect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener)', 148 'android.net.wifi.p2p.WifiP2pManager#removeGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener)', 149 ]) 150 def test_p2p_group_join_via_display(self): 151 """Verify the p2p creates a group and join this group via WPS DISPLAY method.""" 152 self.p2p_group_join(WPS_DISPLAY) 153 154 @ApiTest([ 155 'android.net.wifi.p2p.WifiP2pConfig.Builder#setPassphrase(String passphrase)', 156 'android.net.wifi.p2p.WifiP2pConfig.Builder#setGroupOperatingBand(int band)', 157 'android.net.wifi.p2p.WifiP2pManager#createGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener)', 158 'android.net.wifi.p2p.WifiP2pManager#connect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener)', 159 'android.net.wifi.p2p.WifiP2pManager#removeGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener)', 160 ]) 161 def test_p2p_group_with_config(self): 162 """Verify the p2p creates a group and join this group with config. 163 164 Steps: 165 1. GO creates a group with config. 166 2. GC joins the group with config. 167 3. connection check via ping from GC to GO 168 """ 169 go_dut = self.ads[0] 170 gc_dut = self.ads[1] 171 # Initialize Wi-Fi p2p on both devices. 172 group_owner = p2p_utils.setup_wifi_p2p(go_dut) 173 client = p2p_utils.setup_wifi_p2p(gc_dut) 174 175 # Create a p2p group on one device (group owner device) with 176 # specific group configuration. 177 p2p_config = constants.WifiP2pConfig( 178 network_name='DIRECT-XY-HELLO-%s' % utils.rand_ascii_str(5), 179 passphrase=self.passphrase, 180 group_operating_band=self.group_band, 181 ) 182 p2p_utils.create_group(group_owner, config=p2p_config) 183 time.sleep(_DEFAULT_FUNCTION_SWITCH_TIME) 184 # Request the connection. Since config is known, this is reconnection. 185 p2p_utils.p2p_connect(client, group_owner, p2p_config) 186 187 go_ip = wp2putils.p2p_go_ip(gc_dut) 188 wp2putils.p2p_connection_ping_test(gc_dut, go_ip) 189 # Trigger disconnect. 190 p2p_utils.remove_group_and_verify_disconnected( 191 client, group_owner, is_group_negotiation=False 192 ) 193 time.sleep(_DEFAULT_FUNCTION_SWITCH_TIME) 194 195if __name__ == '__main__': 196 test_runner.main() 197 198