• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3.4
2#
3#   Copyright 2017 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17import itertools
18import pprint
19import queue
20import time
21
22import acts.base_test
23import acts.test_utils.wifi.wifi_test_utils as wutils
24
25
26import WifiManagerTest
27from acts import asserts
28from acts import signals
29from acts.libs.uicd.uicd_cli import UicdCli
30from acts.libs.uicd.uicd_cli import UicdError
31from acts.test_decorators import test_tracker_info
32from acts.test_utils.tel.tel_test_utils import get_operator_name
33from acts.utils import force_airplane_mode
34
35WifiEnums = wutils.WifiEnums
36
37DEFAULT_TIMEOUT = 10
38OSU_TEST_TIMEOUT = 300
39
40# Constants for providers.
41GLOBAL_RE = 0
42OSU_BOINGO = 0
43BOINGO = 1
44ATT = 2
45
46# Constants used for various device operations.
47RESET = 1
48TOGGLE = 2
49
50UNKNOWN_FQDN = "@#@@!00fffffx"
51
52class WifiPasspointTest(acts.base_test.BaseTestClass):
53    """Tests for APIs in Android's WifiManager class.
54
55    Test Bed Requirement:
56    * One Android device
57    * Several Wi-Fi networks visible to the device, including an open Wi-Fi
58      network.
59    """
60
61    def setup_class(self):
62        self.dut = self.android_devices[0]
63        wutils.wifi_test_device_init(self.dut)
64        req_params = ["passpoint_networks", "uicd_workflows", "uicd_zip"]
65        opt_param = []
66        self.unpack_userparams(
67            req_param_names=req_params, opt_param_names=opt_param)
68        self.unpack_userparams(req_params)
69        asserts.assert_true(
70            len(self.passpoint_networks) > 0,
71            "Need at least one Passpoint network.")
72        wutils.wifi_toggle_state(self.dut, True)
73        self.unknown_fqdn = UNKNOWN_FQDN
74        # Setup Uicd cli object for UI interation.
75        self.ui = UicdCli(self.uicd_zip[0], self.uicd_workflows)
76
77
78    def setup_test(self):
79        self.dut.droid.wakeLockAcquireBright()
80        self.dut.droid.wakeUpNow()
81
82
83    def teardown_test(self):
84        self.dut.droid.wakeLockRelease()
85        self.dut.droid.goToSleepNow()
86        wutils.reset_wifi(self.dut)
87
88
89    def on_fail(self, test_name, begin_time):
90        self.dut.take_bug_report(test_name, begin_time)
91
92
93    """Helper Functions"""
94
95
96    def install_passpoint_profile(self, passpoint_config):
97        """Install the Passpoint network Profile.
98
99        Args:
100            passpoint_config: A JSON dict of the Passpoint configuration.
101
102        """
103        asserts.assert_true(WifiEnums.SSID_KEY in passpoint_config,
104                "Key '%s' must be present in network definition." %
105                WifiEnums.SSID_KEY)
106        # Install the Passpoint profile.
107        self.dut.droid.addUpdatePasspointConfig(passpoint_config)
108
109
110    def check_passpoint_connection(self, passpoint_network):
111        """Verify the device is automatically able to connect to the Passpoint
112           network.
113
114           Args:
115               passpoint_network: SSID of the Passpoint network.
116
117        """
118        ad = self.dut
119        ad.ed.clear_all_events()
120        wutils.start_wifi_connection_scan(ad)
121        scan_results = ad.droid.wifiGetScanResults()
122        # Wait for scan to complete.
123        time.sleep(5)
124        ssid = passpoint_network
125        wutils.assert_network_in_list({WifiEnums.SSID_KEY: ssid}, scan_results)
126        # Passpoint network takes longer time to connect than normal networks.
127        # Every try comes with a timeout of 30s. Setting total timeout to 120s.
128        wutils.wifi_passpoint_connect(self.dut, passpoint_network, num_of_tries=4)
129        # Re-verify we are connected to the correct network.
130        network_info = self.dut.droid.wifiGetConnectionInfo()
131        if network_info[WifiEnums.SSID_KEY] != passpoint_network:
132            raise signals.TestFailure("Device did not connect to the passpoint"
133                                      " network.")
134
135
136    def get_configured_passpoint_and_delete(self):
137        """Get configured Passpoint network and delete using its FQDN."""
138        passpoint_config = self.dut.droid.getPasspointConfigs()
139        if not len(passpoint_config):
140            raise signals.TestFailure("Failed to fetch the list of configured"
141                                      "passpoint networks.")
142        if not wutils.delete_passpoint(self.dut, passpoint_config[0]):
143            raise signals.TestFailure("Failed to delete Passpoint configuration"
144                                      " with FQDN = %s" % passpoint_config[0])
145
146    def start_subscription_provisioning(self, state):
147        """Start subscription provisioning with a default provider."""
148
149        self.unpack_userparams(('osu_configs',))
150        asserts.assert_true(
151            len(self.osu_configs) > 0,
152            "Need at least one osu config.")
153        osu_config = self.osu_configs[OSU_BOINGO]
154        # Clear all previous events.
155        self.dut.ed.clear_all_events()
156        self.dut.droid.startSubscriptionProvisioning(osu_config)
157        start_time = time.time()
158        while time.time() < start_time + OSU_TEST_TIMEOUT:
159            dut_event = self.dut.ed.pop_event("onProvisioningCallback",
160                                              DEFAULT_TIMEOUT * 18)
161            if dut_event['data']['tag'] == 'success':
162                self.log.info("Passpoint Provisioning Success")
163                # Reset WiFi after provisioning success.
164                if state == RESET:
165                    wutils.reset_wifi(self.dut)
166                    time.sleep(DEFAULT_TIMEOUT)
167                # Toggle WiFi after provisioning success.
168                elif state == TOGGLE:
169                    wutils.toggle_wifi_off_and_on(self.dut)
170                    time.sleep(DEFAULT_TIMEOUT)
171                break
172            if dut_event['data']['tag'] == 'failure':
173                raise signals.TestFailure(
174                    "Passpoint Provisioning is failed with %s" %
175                    dut_event['data'][
176                        'reason'])
177                break
178            if dut_event['data']['tag'] == 'status':
179                self.log.info(
180                    "Passpoint Provisioning status %s" % dut_event['data'][
181                        'status'])
182                if int(dut_event['data']['status']) == 7:
183                    self.ui.run(self.dut.serial, "passpoint-login")
184        # Clear all previous events.
185        self.dut.ed.clear_all_events()
186
187        # Verify device connects to the Passpoint network.
188        time.sleep(DEFAULT_TIMEOUT)
189        current_passpoint = self.dut.droid.wifiGetConnectionInfo()
190        if current_passpoint[WifiEnums.SSID_KEY] not in osu_config[
191            "expected_ssids"]:
192            raise signals.TestFailure("Device did not connect to the %s"
193                                      " passpoint network" % osu_config[
194                                          "expected_ssids"])
195        # Delete the Passpoint profile.
196        self.get_configured_passpoint_and_delete()
197        wutils.wait_for_disconnect(self.dut)
198
199
200    """Tests"""
201
202    @test_tracker_info(uuid="b0bc0153-77bb-4594-8f19-cea2c6bd2f43")
203    def test_add_passpoint_network(self):
204        """Add a Passpoint network and verify device connects to it.
205
206        Steps:
207            1. Install a Passpoint Profile.
208            2. Verify the device connects to the required Passpoint SSID.
209            3. Get the Passpoint configuration added above.
210            4. Delete Passpoint configuration using its FQDN.
211            5. Verify that we are disconnected from the Passpoint network.
212
213        """
214        passpoint_config = self.passpoint_networks[BOINGO]
215        self.install_passpoint_profile(passpoint_config)
216        ssid = passpoint_config[WifiEnums.SSID_KEY]
217        self.check_passpoint_connection(ssid)
218        self.get_configured_passpoint_and_delete()
219        wutils.wait_for_disconnect(self.dut)
220
221
222    @test_tracker_info(uuid="eb29d6e2-a755-4c9c-9e4e-63ea2277a64a")
223    def test_update_passpoint_network(self):
224        """Update a previous Passpoint network and verify device still connects
225           to it.
226
227        1. Install a Passpoint Profile.
228        2. Verify the device connects to the required Passpoint SSID.
229        3. Update the Passpoint Profile.
230        4. Verify device is still connected to the Passpoint SSID.
231        5. Get the Passpoint configuration added above.
232        6. Delete Passpoint configuration using its FQDN.
233
234        """
235        passpoint_config = self.passpoint_networks[BOINGO]
236        self.install_passpoint_profile(passpoint_config)
237        ssid = passpoint_config[WifiEnums.SSID_KEY]
238        self.check_passpoint_connection(ssid)
239
240        # Update passpoint configuration using the original profile because we
241        # do not have real profile with updated credentials to use.
242        self.install_passpoint_profile(passpoint_config)
243
244        # Wait for a Disconnect event from the supplicant.
245        wutils.wait_for_disconnect(self.dut)
246
247        # Now check if we are again connected with the updated profile.
248        self.check_passpoint_connection(ssid)
249
250        self.get_configured_passpoint_and_delete()
251        wutils.wait_for_disconnect(self.dut)
252
253
254    @test_tracker_info(uuid="b6e8068d-faa1-49f2-b421-c60defaed5f0")
255    def test_add_delete_list_of_passpoint_network(self):
256        """Add multiple passpoint networks, list them and delete one by one.
257
258        1. Install Passpoint Profile A.
259        2. Install Passpoint Profile B.
260        3. Get all the Passpoint configurations added above and verify.
261        6. Ensure all Passpoint configurations can be deleted.
262
263        """
264        for passpoint_config in self.passpoint_networks[:2]:
265            self.install_passpoint_profile(passpoint_config)
266            time.sleep(DEFAULT_TIMEOUT)
267        configs = self.dut.droid.getPasspointConfigs()
268        #  It is length -1 because ATT profile will be handled separately
269        if not len(configs) or len(configs) != len(self.passpoint_networks[:2]):
270            raise signals.TestFailure("Failed to fetch some or all of the"
271                                      " configured passpoint networks.")
272        for config in configs:
273            if not wutils.delete_passpoint(self.dut, config):
274                raise signals.TestFailure("Failed to delete Passpoint"
275                                          " configuration with FQDN = %s" %
276                                          config)
277
278
279    @test_tracker_info(uuid="a53251be-7aaf-41fc-a5f3-63984269d224")
280    def test_delete_unknown_fqdn(self):
281        """Negative test to delete Passpoint profile using an unknown FQDN.
282
283        1. Pass an unknown FQDN for removal.
284        2. Verify that it was not successful.
285
286        """
287        if wutils.delete_passpoint(self.dut, self.unknown_fqdn):
288            raise signals.TestFailure("Failed because an unknown FQDN"
289                                      " was successfully deleted.")
290
291
292    @test_tracker_info(uuid="bf03c03a-e649-4e2b-a557-1f791bd98951")
293    def test_passpoint_failover(self):
294        """Add a pair of passpoint networks and test failover when one of the"
295           profiles is removed.
296
297        1. Install a Passpoint Profile A and B.
298        2. Verify device connects to a Passpoint network and get SSID.
299        3. Delete the current Passpoint profile using its FQDN.
300        4. Verify device fails over and connects to the other Passpoint SSID.
301        5. Delete Passpoint configuration using its FQDN.
302
303        """
304        # Install both Passpoint profiles on the device.
305        passpoint_ssid = list()
306        for passpoint_config in self.passpoint_networks[:2]:
307            passpoint_ssid.append(passpoint_config[WifiEnums.SSID_KEY])
308            self.install_passpoint_profile(passpoint_config)
309            time.sleep(DEFAULT_TIMEOUT)
310
311        # Get the current network and the failover network.
312        wutils.wait_for_connect(self.dut)
313        current_passpoint = self.dut.droid.wifiGetConnectionInfo()
314        current_ssid = current_passpoint[WifiEnums.SSID_KEY]
315        if current_ssid not in passpoint_ssid:
316           raise signals.TestFailure("Device did not connect to any of the "
317                                     "configured Passpoint networks.")
318
319        expected_ssid =  self.passpoint_networks[0][WifiEnums.SSID_KEY]
320        if current_ssid == expected_ssid:
321            expected_ssid = self.passpoint_networks[1][WifiEnums.SSID_KEY]
322
323        # Remove the current Passpoint profile.
324        for network in self.passpoint_networks[:2]:
325            if network[WifiEnums.SSID_KEY] == current_ssid:
326                if not wutils.delete_passpoint(self.dut, network["fqdn"]):
327                    raise signals.TestFailure("Failed to delete Passpoint"
328                                              " configuration with FQDN = %s" %
329                                              network["fqdn"])
330        # Verify device fails over and connects to the other passpoint network.
331        time.sleep(DEFAULT_TIMEOUT)
332
333        current_passpoint = self.dut.droid.wifiGetConnectionInfo()
334        if current_passpoint[WifiEnums.SSID_KEY] != expected_ssid:
335            raise signals.TestFailure("Device did not failover to the %s"
336                                      " passpoint network" % expected_ssid)
337
338        # Delete the remaining Passpoint profile.
339        self.get_configured_passpoint_and_delete()
340        wutils.wait_for_disconnect(self.dut)
341
342
343    def test_install_att_passpoint_profile(self):
344        """Add an AT&T Passpoint profile.
345
346        It is used for only installing the profile for other tests.
347        """
348        isFound = False
349        for passpoint_config in self.passpoint_networks:
350            if 'att' in passpoint_config['fqdn']:
351                isFound = True
352                self.install_passpoint_profile(passpoint_config)
353                break
354        if not isFound:
355            raise signals.TestFailure("cannot find ATT profile.")
356
357
358    @test_tracker_info(uuid="e3e826d2-7c39-4c37-ab3f-81992d5aa0e8")
359    def test_att_passpoint_network(self):
360        """Add a AT&T Passpoint network and verify device connects to it.
361
362        Steps:
363            1. Install a AT&T Passpoint Profile.
364            2. Verify the device connects to the required Passpoint SSID.
365            3. Get the Passpoint configuration added above.
366            4. Delete Passpoint configuration using its FQDN.
367            5. Verify that we are disconnected from the Passpoint network.
368
369        """
370        carriers = ["att"]
371        operator = get_operator_name(self.log, self.dut)
372        asserts.skip_if(operator not in carriers,
373                        "Device %s does not have a ATT sim" % self.dut.model)
374
375        passpoint_config = self.passpoint_networks[ATT]
376        self.install_passpoint_profile(passpoint_config)
377        ssid = passpoint_config[WifiEnums.SSID_KEY]
378        self.check_passpoint_connection(ssid)
379        self.get_configured_passpoint_and_delete()
380        wutils.wait_for_disconnect(self.dut)
381
382
383    @test_tracker_info(uuid="c85c81b2-7133-4635-8328-9498169ae802")
384    def test_start_subscription_provisioning(self):
385        self.start_subscription_provisioning(0)
386
387
388    @test_tracker_info(uuid="fd09a643-0d4b-45a9-881a-a771f9707ab1")
389    def test_start_subscription_provisioning_and_reset_wifi(self):
390        self.start_subscription_provisioning(RESET)
391
392
393    @test_tracker_info(uuid="f43ea759-673f-4567-aa11-da3bc2cabf08")
394    def test_start_subscription_provisioning_and_toggle_wifi(self):
395        self.start_subscription_provisioning(TOGGLE)
396