• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3.4
2#
3#   Copyright 2018 - 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.signals as signals
24import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
25import acts.utils
26
27from acts import asserts
28from acts.controllers.android_device import SL4A_APK_NAME
29from acts.test_decorators import test_tracker_info
30from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
31from acts_contrib.test_utils.wifi import wifi_constants
32
33WifiEnums = wutils.WifiEnums
34# EAP Macros
35EAP = WifiEnums.Eap
36EapPhase2 = WifiEnums.EapPhase2
37# Enterprise Config Macros
38Ent = WifiEnums.Enterprise
39BOINGO = 1
40ATT = 2
41# Suggestion network Macros
42Untrusted = "untrusted"
43AutoJoin = "enableAutojoin"
44# Network request Macros
45ClearCapabilities = "ClearCapabilities"
46TransportType = "TransportType"
47
48
49# Default timeout used for reboot, toggle WiFi and Airplane mode,
50# for the system to settle down after the operation.
51DEFAULT_TIMEOUT = 10
52PASSPOINT_TIMEOUT = 30
53
54
55class WifiNetworkSuggestionTest(WifiBaseTest):
56    """Tests for WifiNetworkSuggestion API surface.
57
58    Test Bed Requirement:
59    * one Android device
60    * Several Wi-Fi networks visible to the device, including an open Wi-Fi
61      network.
62    """
63    def __init__(self, configs):
64        super().__init__(configs)
65        self.enable_packet_log = True
66
67    def setup_class(self):
68        super().setup_class()
69
70        self.dut = self.android_devices[0]
71        opt_param = [
72            "open_network", "reference_networks", "hidden_networks", "radius_conf_2g",
73            "radius_conf_5g", "ca_cert", "eap_identity", "eap_password", "passpoint_networks",
74            "domain_suffix_match", "wifi6_models"]
75        self.unpack_userparams(opt_param_names=opt_param,)
76
77        if "AccessPoint" in self.user_params:
78            self.legacy_configure_ap_and_start(
79                wpa_network=True, ent_network=True,
80                radius_conf_2g=self.radius_conf_2g,
81                radius_conf_5g=self.radius_conf_5g,)
82        elif "OpenWrtAP" in self.user_params:
83            self.configure_openwrt_ap_and_start(open_network=True,
84                                                wpa_network=True,)
85        if hasattr(self, "reference_networks") and \
86            isinstance(self.reference_networks, list):
87              self.wpa_psk_2g = self.reference_networks[0]["2g"]
88              self.wpa_psk_5g = self.reference_networks[0]["5g"]
89        if hasattr(self, "open_network") and isinstance(self.open_network,list):
90            self.open_2g = self.open_network[0]["2g"]
91            self.open_5g = self.open_network[0]["5g"]
92        if hasattr(self, "hidden_networks") and \
93            isinstance(self.hidden_networks, list):
94              self.hidden_network = self.hidden_networks[0]
95        if hasattr(self, "passpoint_networks"):
96            self.passpoint_network = self.passpoint_networks[BOINGO]
97            self.passpoint_network[WifiEnums.SSID_KEY] = \
98                self.passpoint_networks[BOINGO][WifiEnums.SSID_KEY][0]
99        self.dut.droid.wifiRemoveNetworkSuggestions([])
100        self.dut.adb.shell(
101            "pm disable com.google.android.apps.carrier.carrierwifi", ignore_status=True)
102
103    def setup_test(self):
104        super().setup_test()
105        self.dut.droid.wakeLockAcquireBright()
106        self.dut.droid.wakeUpNow()
107        self.dut.unlock_screen()
108        self.clear_user_disabled_networks()
109        wutils.wifi_toggle_state(self.dut, True)
110        self.dut.ed.clear_all_events()
111        self.clear_carrier_approved(str(self.dut.droid.telephonyGetSimCarrierId()))
112        if "_ent_" in self.test_name:
113            if "OpenWrtAP" in self.user_params:
114                self.access_points[0].close()
115                self.configure_openwrt_ap_and_start(
116                    ent_network=True,
117                    radius_conf_2g=self.radius_conf_2g,
118                    radius_conf_5g=self.radius_conf_5g,)
119            self.ent_network_2g = self.ent_networks[0]["2g"]
120            self.ent_network_5g = self.ent_networks[0]["5g"]
121
122    def teardown_test(self):
123        super().teardown_test()
124        self.dut.droid.wakeLockRelease()
125        self.dut.droid.goToSleepNow()
126        self.dut.droid.wifiRemoveNetworkSuggestions([])
127        self.dut.droid.wifiDisconnect()
128        wutils.reset_wifi(self.dut)
129        wutils.wifi_toggle_state(self.dut, False)
130        self.dut.ed.clear_all_events()
131        self.clear_carrier_approved(str(self.dut.droid.telephonyGetSimCarrierId()))
132
133    def teardown_class(self):
134        self.dut.adb.shell(
135            "pm enable com.google.android.apps.carrier.carrierwifi")
136        if "AccessPoint" in self.user_params:
137            del self.user_params["reference_networks"]
138            del self.user_params["open_network"]
139
140    """Helper Functions"""
141    def set_approved(self, approved):
142        self.dut.log.debug("Setting suggestions from sl4a app "
143                           + "approved" if approved else "not approved")
144        self.dut.adb.shell("cmd wifi network-suggestions-set-user-approved"
145                           + " " + SL4A_APK_NAME
146                           + " " + ("yes" if approved else "no"))
147
148    def is_approved(self):
149        is_approved_str = self.dut.adb.shell(
150            "cmd wifi network-suggestions-has-user-approved"
151            + " " + SL4A_APK_NAME)
152        return True if (is_approved_str == "yes") else False
153
154    def set_carrier_approved(self, carrier_id, approved):
155        self.dut.log.debug(("Setting IMSI protection exemption for carrier: " + carrier_id
156                                + "approved" if approved else "not approved"))
157        self.dut.adb.shell("cmd wifi imsi-protection-exemption-set-user-approved-for-carrier"
158                           + " " + carrier_id
159                           + " " + ("yes" if approved else "no"))
160
161    def is_carrier_approved(self, carrier_id):
162        is_approved_str = self.dut.adb.shell(
163            "cmd wifi imsi-protection-exemption-has-user-approved-for-carrier"
164            + " " + carrier_id)
165        return True if (is_approved_str == "yes") else False
166
167    def clear_carrier_approved(self, carrier_id):
168        self.dut.adb.shell(
169            "cmd wifi imsi-protection-exemption-clear-user-approved-for-carrier"
170            + " " + carrier_id)
171
172    def clear_user_disabled_networks(self):
173        self.dut.log.debug("Clearing user disabled networks")
174        self.dut.adb.shell(
175            "cmd wifi clear-user-disabled-networks")
176
177    def add_suggestions_and_ensure_connection(self, network_suggestions,
178                                              expected_ssid,
179                                              expect_post_connection_broadcast):
180        if expect_post_connection_broadcast is not None:
181            self.dut.droid.wifiStartTrackingNetworkSuggestionStateChange()
182
183        self.dut.log.info("Adding network suggestions")
184        asserts.assert_true(
185            self.dut.droid.wifiAddNetworkSuggestions(network_suggestions),
186            "Failed to add suggestions")
187        # Enable suggestions by the app.
188        self.dut.log.debug("Enabling suggestions from test")
189        self.set_approved(True)
190        wutils.start_wifi_connection_scan_and_return_status(self.dut)
191        # if suggestion is passpoint wait longer for connection.
192        if "profile" in network_suggestions:
193            time.sleep(PASSPOINT_TIMEOUT)
194        wutils.wait_for_connect(self.dut, expected_ssid)
195
196        if expect_post_connection_broadcast is None:
197            return
198
199        # Check if we expected to get the broadcast.
200        try:
201            event = self.dut.ed.pop_event(
202                wifi_constants.WIFI_NETWORK_SUGGESTION_POST_CONNECTION, 60)
203        except queue.Empty:
204            if expect_post_connection_broadcast:
205                raise signals.TestFailure(
206                    "Did not receive post connection broadcast")
207        else:
208            if not expect_post_connection_broadcast:
209                raise signals.TestFailure(
210                    "Received post connection broadcast")
211        finally:
212            self.dut.droid.wifiStopTrackingNetworkSuggestionStateChange()
213        self.dut.ed.clear_all_events()
214
215    def remove_suggestions_disconnect_and_ensure_no_connection_back(self,
216                                                                    network_suggestions,
217                                                                    expected_ssid):
218        # Remove suggestion trigger disconnect and wait for the disconnect.
219        self.dut.log.info("Removing network suggestions")
220        asserts.assert_true(
221            self.dut.droid.wifiRemoveNetworkSuggestions(network_suggestions),
222            "Failed to remove suggestions")
223        wutils.wait_for_disconnect(self.dut)
224        self.dut.ed.clear_all_events()
225
226        # Now ensure that we didn't connect back.
227        asserts.assert_false(
228            wutils.wait_for_connect(self.dut, expected_ssid, assert_on_fail=False),
229            "Device should not connect back")
230
231    def _test_connect_to_wifi_network_reboot_config_store(self,
232                                                          network_suggestions,
233                                                          wifi_network):
234        """ Test network suggestion with reboot config store
235
236        Args:
237        1. network_suggestions: network suggestions in list to add to the device.
238        2. wifi_network: expected wifi network to connect to
239        """
240
241        self.add_suggestions_and_ensure_connection(
242            network_suggestions, wifi_network[WifiEnums.SSID_KEY], None)
243        wutils.verify_11ax_wifi_connection(
244            self.dut, self.wifi6_models, "wifi6_ap" in self.user_params)
245
246        # Reboot and wait for connection back to the same suggestion.
247        self.dut.reboot()
248        time.sleep(DEFAULT_TIMEOUT)
249
250        wutils.wait_for_connect(self.dut, wifi_network[WifiEnums.SSID_KEY])
251        wutils.verify_11ax_wifi_connection(
252            self.dut, self.wifi6_models, "wifi6_ap" in self.user_params)
253
254        self.remove_suggestions_disconnect_and_ensure_no_connection_back(
255            network_suggestions, wifi_network[WifiEnums.SSID_KEY])
256
257        # Reboot with empty suggestion, verify user approval is kept.
258        self.dut.reboot()
259        time.sleep(DEFAULT_TIMEOUT)
260        asserts.assert_true(self.is_approved(), "User approval should be kept")
261
262    @test_tracker_info(uuid="bda8ed20-4382-4380-831a-64cf77eca108")
263    def test_connect_to_wpa_psk_2g(self):
264        """ Adds a network suggestion and ensure that the device connected.
265
266        Steps:
267        1. Send a network suggestion to the device.
268        2. Wait for the device to connect to it.
269        3. Ensure that we did not receive the post connection broadcast
270           (isAppInteractionRequired = False).
271        4. Remove the suggestions and ensure the device does not connect back.
272        """
273        self.add_suggestions_and_ensure_connection(
274            [self.wpa_psk_2g], self.wpa_psk_2g[WifiEnums.SSID_KEY],
275            False)
276
277        self.remove_suggestions_disconnect_and_ensure_no_connection_back(
278            [self.wpa_psk_2g], self.wpa_psk_2g[WifiEnums.SSID_KEY])
279
280    @test_tracker_info(uuid="b2df6ebe-9c5b-4e84-906a-e76f96fcef56")
281    def test_connect_to_wpa_psk_2g_with_screen_off(self):
282        """ Adds a network suggestion and ensure that the device connected
283        when the screen is off.
284
285        Steps:
286        1. Send an invalid suggestion to the device (Needed for PNO scan to start).
287        2. Toggle screen off.
288        3. Send a valid network suggestion to the device.
289        4. Wait for the device to connect to it.
290        5. Ensure that we did not receive the post connection broadcast
291           (isAppInteractionRequired = False).
292        6. Remove the suggestions and ensure the device does not connect back.
293        """
294        invalid_suggestion = self.wpa_psk_5g
295        network_ssid = invalid_suggestion.pop(WifiEnums.SSID_KEY)
296        invalid_suggestion[WifiEnums.SSID_KEY] = network_ssid + "blah"
297
298        self.dut.log.info("Adding invalid suggestions")
299        asserts.assert_true(
300            self.dut.droid.wifiAddNetworkSuggestions([invalid_suggestion]),
301            "Failed to add suggestions")
302
303        # Approve suggestions by the app.
304        self.set_approved(True)
305
306        # Turn screen off to ensure PNO kicks-in.
307        self.dut.droid.wakeLockRelease()
308        self.dut.droid.goToSleepNow()
309        time.sleep(10)
310
311        # Add valid suggestions & ensure we restart PNO and connect to it.
312        self.add_suggestions_and_ensure_connection(
313            [self.wpa_psk_2g], self.wpa_psk_2g[WifiEnums.SSID_KEY],
314            False)
315
316        self.remove_suggestions_disconnect_and_ensure_no_connection_back(
317            [self.wpa_psk_2g], self.wpa_psk_2g[WifiEnums.SSID_KEY])
318
319    @test_tracker_info(uuid="f18bf994-ef3b-45d6-aba0-dd6338b07979")
320    def test_connect_to_wpa_psk_2g_modify_meteredness(self):
321        """ Adds a network suggestion and ensure that the device connected.
322        Change the meteredness of the network after the connection.
323
324        Steps:
325        1. Send a network suggestion to the device.
326        2. Wait for the device to connect to it.
327        3. Ensure that we did not receive the post connection broadcast
328           (isAppInteractionRequired = False).
329        4. Mark the network suggestion metered.
330        5. Ensure that the device disconnected and reconnected back to the
331           suggestion.
332        6. Mark the network suggestion unmetered.
333        7. Ensure that the device did not disconnect.
334        8. Remove the suggestions and ensure the device does not connect back.
335        """
336        self.add_suggestions_and_ensure_connection(
337            [self.wpa_psk_2g], self.wpa_psk_2g[WifiEnums.SSID_KEY],
338            False)
339
340        mod_suggestion = self.wpa_psk_2g
341
342        # Mark the network metered.
343        self.dut.log.debug("Marking suggestion as metered")
344        mod_suggestion[WifiEnums.IS_SUGGESTION_METERED] = True
345        asserts.assert_true(
346            self.dut.droid.wifiAddNetworkSuggestions([mod_suggestion]),
347            "Failed to add suggestions")
348        # Wait for disconnect.
349        wutils.wait_for_disconnect(self.dut)
350        self.dut.log.info("Disconnected from network %s", mod_suggestion)
351        self.dut.ed.clear_all_events()
352        # Wait for reconnect.
353        wutils.wait_for_connect(self.dut, mod_suggestion[WifiEnums.SSID_KEY])
354
355        # Mark the network unmetered.
356        self.dut.log.debug("Marking suggestion as unmetered")
357        mod_suggestion[WifiEnums.IS_SUGGESTION_METERED] = False
358        asserts.assert_true(
359            self.dut.droid.wifiAddNetworkSuggestions([mod_suggestion]),
360            "Failed to add suggestions")
361        # Ensure there is no disconnect.
362        wutils.ensure_no_disconnect(self.dut)
363        self.dut.ed.clear_all_events()
364
365        self.remove_suggestions_disconnect_and_ensure_no_connection_back(
366            [mod_suggestion], mod_suggestion[WifiEnums.SSID_KEY])
367
368
369    @test_tracker_info(uuid="f54bc250-d9e9-4f00-8b5b-b866e8550b43")
370    def test_connect_to_highest_priority(self):
371        """
372        Adds network suggestions and ensures that device connects to
373        the suggestion with the highest priority.
374
375        Steps:
376        1. Send 2 network suggestions to the device (with different priorities).
377        2. Wait for the device to connect to the network with the highest
378           priority.
379        3. In-place modify network suggestions with priorities reversed
380        4. Restart wifi, wait for the device to connect to the network with the highest
381           priority.
382        5. Re-add the suggestions with the priorities reversed again.
383        6. Again wait for the device to connect to the network with the highest
384           priority.
385        """
386        network_suggestion_2g = self.wpa_psk_2g
387        network_suggestion_5g = self.wpa_psk_5g
388
389        # Add suggestions & wait for the connection event.
390        network_suggestion_2g[WifiEnums.PRIORITY] = 5
391        network_suggestion_5g[WifiEnums.PRIORITY] = 2
392        self.add_suggestions_and_ensure_connection(
393            [network_suggestion_2g, network_suggestion_5g],
394            self.wpa_psk_2g[WifiEnums.SSID_KEY],
395            None)
396
397        # In-place modify Reverse the priority, should be no disconnect
398        network_suggestion_2g[WifiEnums.PRIORITY] = 2
399        network_suggestion_5g[WifiEnums.PRIORITY] = 5
400        self.dut.log.info("Modifying network suggestions")
401        asserts.assert_true(
402            self.dut.droid.wifiAddNetworkSuggestions([network_suggestion_2g,
403                                                      network_suggestion_5g]),
404            "Failed to add suggestions")
405        wutils.ensure_no_disconnect(self.dut)
406
407        # Disable and re-enable wifi, should connect to higher priority
408        wutils.wifi_toggle_state(self.dut, False)
409        time.sleep(DEFAULT_TIMEOUT)
410        wutils.wifi_toggle_state(self.dut, True)
411        wutils.start_wifi_connection_scan_and_return_status(self.dut)
412        wutils.wait_for_connect(self.dut, self.wpa_psk_5g[WifiEnums.SSID_KEY])
413
414        self.remove_suggestions_disconnect_and_ensure_no_connection_back(
415            [], self.wpa_psk_5g[WifiEnums.SSID_KEY])
416
417        # Reverse the priority.
418        # Add suggestions & wait for the connection event.
419        network_suggestion_2g[WifiEnums.PRIORITY] = 5
420        network_suggestion_5g[WifiEnums.PRIORITY] = 2
421        self.add_suggestions_and_ensure_connection(
422            [network_suggestion_2g, network_suggestion_5g],
423            self.wpa_psk_2g[WifiEnums.SSID_KEY],
424            None)
425
426    @test_tracker_info(uuid="b1d27eea-23c8-4c4f-b944-ef118e4cc35f")
427    def test_connect_to_wpa_psk_2g_with_post_connection_broadcast(self):
428        """ Adds a network suggestion and ensure that the device connected.
429
430        Steps:
431        1. Send a network suggestion to the device with
432           isAppInteractionRequired set.
433        2. Wait for the device to connect to it.
434        3. Ensure that we did receive the post connection broadcast
435           (isAppInteractionRequired = True).
436        4. Remove the suggestions and ensure the device does not connect back.
437        """
438        network_suggestion = self.wpa_psk_2g
439        network_suggestion[WifiEnums.IS_APP_INTERACTION_REQUIRED] = True
440        self.add_suggestions_and_ensure_connection(
441            [network_suggestion], self.wpa_psk_2g[WifiEnums.SSID_KEY],
442            True)
443        self.remove_suggestions_disconnect_and_ensure_no_connection_back(
444            [self.wpa_psk_2g], self.wpa_psk_2g[WifiEnums.SSID_KEY])
445
446    @test_tracker_info(uuid="a036a24d-29c0-456d-ae6a-afdde34da710")
447    def test_connect_to_wpa_psk_5g_reboot_config_store(self):
448        """
449        Adds a network suggestion and ensure that the device connects to it
450        after reboot.
451
452        Steps:
453        1. Send a network suggestion to the device.
454        2. Wait for the device to connect to it.
455        3. Ensure that we did not receive the post connection broadcast
456           (isAppInteractionRequired = False).
457        4. Reboot the device.
458        5. Wait for the device to connect to back to it.
459        6. Remove the suggestions and ensure the device does not connect back.
460        7. Reboot the device again, ensure user approval is kept
461        """
462        self._test_connect_to_wifi_network_reboot_config_store(
463            [self.wpa_psk_5g], self.wpa_psk_5g)
464
465    @test_tracker_info(uuid="61649a2b-0f00-4272-9b9b-40ad5944da31")
466    def test_connect_to_wpa_ent_config_aka_reboot_config_store(self):
467        """
468        Adds a network suggestion and ensure that the device connects to it
469        after reboot.
470
471        Steps:
472        1. Send a Enterprise AKA network suggestion to the device.
473        2. Wait for the device to connect to it.
474        3. Ensure that we did not receive the post connection broadcast.
475        4. Reboot the device.
476        5. Wait for the device to connect to the wifi network.
477        6. Remove suggestions and ensure device doesn't connect back to it.
478        7. Reboot the device again, ensure user approval is kept
479        """
480        self.config_aka = {
481            Ent.EAP: int(EAP.AKA),
482            WifiEnums.SSID_KEY: self.ent_network_2g[WifiEnums.SSID_KEY],
483            "carrierId": str(self.dut.droid.telephonyGetSimCarrierId()),
484        }
485        if "carrierId" in self.config_aka:
486            self.set_carrier_approved(self.config_aka["carrierId"], True)
487        self._test_connect_to_wifi_network_reboot_config_store(
488            [self.config_aka], self.ent_network_2g)
489        if "carrierId" in self.config_aka:
490            self.clear_carrier_approved(self.config_aka["carrierId"])
491
492    @test_tracker_info(uuid="98b2d40a-acb4-4a2f-aba1-b069e2a1d09d")
493    def test_connect_to_wpa_ent_config_ttls_pap_reboot_config_store(self):
494        """
495        Adds a network suggestion and ensure that the device connects to it
496        after reboot.
497
498        Steps:
499        1. Send a Enterprise TTLS PAP network suggestion to the device.
500        2. Wait for the device to connect to it.
501        3. Ensure that we did not receive the post connection broadcast.
502        4. Reboot the device.
503        5. Wait for the device to connect to the wifi network.
504        6. Remove suggestions and ensure device doesn't connect back to it.
505        7. Reboot the device again, ensure user approval is kept
506        """
507        self.config_ttls = {
508            Ent.EAP: int(EAP.TTLS),
509            Ent.CA_CERT: self.ca_cert,
510            Ent.IDENTITY: self.eap_identity,
511            Ent.PASSWORD: self.eap_password,
512            Ent.PHASE2: int(EapPhase2.MSCHAPV2),
513            WifiEnums.SSID_KEY: self.ent_network_2g[WifiEnums.SSID_KEY],
514            Ent.DOM_SUFFIX_MATCH: self.domain_suffix_match,
515        }
516        config = dict(self.config_ttls)
517        config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value
518
519        self._test_connect_to_wifi_network_reboot_config_store(
520            [config], self.ent_network_2g)
521
522    @test_tracker_info(uuid="554b5861-22d0-4922-a5f4-712b4cf564eb")
523    def test_fail_to_connect_to_wpa_psk_5g_when_not_approved(self):
524        """
525        Adds a network suggestion and ensure that the device does not
526        connect to it until we approve the app.
527
528        Steps:
529        1. Send a network suggestion to the device with the app not approved.
530        2. Ensure the network is present in scan results, but we don't connect
531           to it.
532        3. Now approve the app.
533        4. Wait for the device to connect to it.
534        """
535        self.dut.log.info("Adding network suggestions")
536        asserts.assert_true(
537            self.dut.droid.wifiAddNetworkSuggestions([self.wpa_psk_5g]),
538            "Failed to add suggestions")
539
540        # Disable suggestions by the app.
541        self.set_approved(False)
542
543        # Ensure the app is not approved.
544        asserts.assert_false(
545            self.is_approved(),
546            "Suggestions should be disabled")
547
548        # Start a new scan to trigger auto-join.
549        wutils.start_wifi_connection_scan_and_ensure_network_found(
550            self.dut, self.wpa_psk_5g[WifiEnums.SSID_KEY])
551
552        # Ensure we don't connect to the network.
553        asserts.assert_false(
554            wutils.wait_for_connect(
555                self.dut, self.wpa_psk_5g[WifiEnums.SSID_KEY], assert_on_fail=False),
556            "Should not connect to network suggestions from unapproved app")
557
558        self.dut.log.info("Enabling suggestions from test")
559        # Now Enable suggestions by the app & ensure we connect to the network.
560        self.set_approved(True)
561
562        # Ensure the app is approved.
563        asserts.assert_true(
564            self.is_approved(),
565            "Suggestions should be enabled")
566
567        # Start a new scan to trigger auto-join.
568        wutils.start_wifi_connection_scan_and_ensure_network_found(
569            self.dut, self.wpa_psk_5g[WifiEnums.SSID_KEY])
570
571        wutils.wait_for_connect(self.dut, self.wpa_psk_5g[WifiEnums.SSID_KEY])
572
573    @test_tracker_info(uuid="98400dea-776e-4a0a-9024-18845b27331c")
574    def test_fail_to_connect_to_wpa_psk_2g_after_user_forgot_network(self):
575        """
576        Adds a network suggestion and ensures that the device does not
577        connect to it after the user forgot the network previously.
578
579        Steps:
580        1. Send a network suggestion to the device with
581           isAppInteractionRequired set.
582        2. Wait for the device to connect to it.
583        3. Ensure that we did receive the post connection broadcast
584           (isAppInteractionRequired = True).
585        4. Simulate user forgetting the network and the device does not
586           connecting back even though the suggestion is active from the app.
587        """
588        network_suggestion = self.wpa_psk_2g
589        network_suggestion[WifiEnums.IS_APP_INTERACTION_REQUIRED] = True
590        self.add_suggestions_and_ensure_connection(
591            [network_suggestion], self.wpa_psk_2g[WifiEnums.SSID_KEY],
592            True)
593
594        # Simulate user disconnect the network.
595        self.dut.droid.wifiUserDisconnectNetwork(
596            self.wpa_psk_2g[WifiEnums.SSID_KEY])
597        wutils.wait_for_disconnect(self.dut)
598        self.dut.log.info("Disconnected from network %s", self.wpa_psk_2g)
599        self.dut.ed.clear_all_events()
600
601        # Now ensure that we don't connect back even though the suggestion
602        # is still active.
603        asserts.assert_false(
604            wutils.wait_for_connect(self.dut,
605                                    self.wpa_psk_2g[WifiEnums.SSID_KEY],
606                                    assert_on_fail=False),
607            "Device should not connect back")
608
609    @test_tracker_info(uuid="93c86b05-fa56-4d79-ad27-009a16f691b1")
610    def test_connect_to_hidden_network(self):
611        """
612        Adds a network suggestion with hidden SSID config, ensure device can scan
613        and connect to this network.
614
615        Steps:
616        1. Send a hidden network suggestion to the device.
617        2. Wait for the device to connect to it.
618        3. Ensure that we did not receive the post connection broadcast
619           (isAppInteractionRequired = False).
620        4. Remove the suggestions and ensure the device does not connect back.
621        """
622        asserts.skip_if(not hasattr(self, "hidden_networks"), "No hidden networks, skip this test")
623
624        network_suggestion = self.hidden_network
625        self.add_suggestions_and_ensure_connection(
626            [network_suggestion], network_suggestion[WifiEnums.SSID_KEY], False)
627        self.remove_suggestions_disconnect_and_ensure_no_connection_back(
628            [network_suggestion], network_suggestion[WifiEnums.SSID_KEY])
629
630    @test_tracker_info(uuid="806dff14-7543-482b-bd0a-598de59374b3")
631    def test_connect_to_passpoint_network_with_post_connection_broadcast(self):
632        """ Adds a passpoint network suggestion and ensure that the device connected.
633
634        Steps:
635        1. Send a network suggestion to the device.
636        2. Wait for the device to connect to it.
637        3. Ensure that we did receive the post connection broadcast
638               (isAppInteractionRequired = true).
639        4. Remove the suggestions and ensure the device does not connect back.
640        """
641        asserts.skip_if(not hasattr(self, "passpoint_networks"),
642                        "No passpoint networks, skip this test")
643        passpoint_config = self.passpoint_network
644        passpoint_config[WifiEnums.IS_APP_INTERACTION_REQUIRED] = True
645        if "carrierId" in passpoint_config:
646            self.set_carrier_approved(passpoint_config["carrierId"], True)
647        self.add_suggestions_and_ensure_connection([passpoint_config],
648                                                   passpoint_config[WifiEnums.SSID_KEY], True)
649        self.remove_suggestions_disconnect_and_ensure_no_connection_back(
650            [passpoint_config], passpoint_config[WifiEnums.SSID_KEY])
651        if "carrierId" in passpoint_config:
652            self.clear_carrier_approved(passpoint_config["carrierId"])
653
654    @test_tracker_info(uuid="159b8b8c-fb00-4d4e-a29f-606881dcbf44")
655    def test_connect_to_passpoint_network_reboot_config_store(self):
656        """
657        Adds a passpoint network suggestion and ensure that the device connects to it
658        after reboot.
659
660        Steps:
661        1. Send a network suggestion to the device.
662        2. Wait for the device to connect to it.
663        3. Ensure that we did not receive the post connection broadcast
664           (isAppInteractionRequired = False).
665        4. Reboot the device.
666        5. Wait for the device to connect to back to it.
667        6. Remove the suggestions and ensure the device does not connect back.
668        7. Reboot the device again, ensure user approval is kept
669        """
670        asserts.skip_if(not hasattr(self, "passpoint_networks"),
671                        "No passpoint networks, skip this test")
672        passpoint_config = self.passpoint_network
673        if "carrierId" in passpoint_config:
674            self.set_carrier_approved(passpoint_config["carrierId"], True)
675        self._test_connect_to_wifi_network_reboot_config_store([passpoint_config],
676                                                               passpoint_config)
677        if "carrierId" in passpoint_config:
678            self.clear_carrier_approved(passpoint_config["carrierId"])
679
680    @test_tracker_info(uuid="34f3d28a-bedf-43fe-a12d-2cfadf6bc6eb")
681    def test_fail_to_connect_to_passpoint_network_when_not_approved(self):
682        """
683        Adds a passpoint network suggestion and ensure that the device does not
684        connect to it until we approve the app.
685
686        Steps:
687        1. Send a network suggestion to the device with the app not approved.
688        2. Ensure the network is present in scan results, but we don't connect
689           to it.
690        3. Now approve the app.
691        4. Wait for the device to connect to it.
692        """
693        asserts.skip_if(not hasattr(self, "passpoint_networks"),
694                        "No passpoint networks, skip this test")
695        passpoint_config = self.passpoint_network
696        if "carrierId" in passpoint_config:
697            self.set_carrier_approved(passpoint_config["carrierId"], True)
698        self.dut.log.info("Adding network suggestions")
699        asserts.assert_true(
700            self.dut.droid.wifiAddNetworkSuggestions([passpoint_config]),
701            "Failed to add suggestions")
702
703        # Disable suggestions by the app.
704        self.set_approved(False)
705
706        # Ensure the app is not approved.
707        asserts.assert_false(
708            self.is_approved(),
709            "Suggestions should be disabled")
710
711        # Start a new scan to trigger auto-join.
712        wutils.start_wifi_connection_scan_and_ensure_network_found(
713            self.dut, passpoint_config[WifiEnums.SSID_KEY])
714
715        # Ensure we don't connect to the network.
716        asserts.assert_false(
717            wutils.wait_for_connect(
718                self.dut, passpoint_config[WifiEnums.SSID_KEY], assert_on_fail=False),
719            "Should not connect to network suggestions from unapproved app")
720
721        self.dut.log.info("Enabling suggestions from test")
722        # Now Enable suggestions by the app & ensure we connect to the network.
723        self.set_approved(True)
724
725        # Ensure the app is approved.
726        asserts.assert_true(
727            self.is_approved(),
728            "Suggestions should be enabled")
729
730        # Start a new scan to trigger auto-join.
731        wutils.start_wifi_connection_scan_and_ensure_network_found(
732            self.dut, passpoint_config[WifiEnums.SSID_KEY])
733        time.sleep(PASSPOINT_TIMEOUT)
734        wutils.wait_for_connect(self.dut, passpoint_config[WifiEnums.SSID_KEY])
735        if "carrierId" in passpoint_config:
736            self.clear_carrier_approved(passpoint_config["carrierId"])
737
738    @test_tracker_info(uuid="cf624cda-4d25-42f1-80eb-6c717fb08338")
739    def test_fail_to_connect_to_passpoint_network_when_imsi_protection_exemption_not_approved(self):
740        """
741        Adds a passpoint network suggestion using SIM credential without IMSI privacy protection.
742        Before user approves the exemption, ensure that the device does noconnect to it until we
743        approve the carrier exemption.
744
745        Steps:
746        1. Send a network suggestion to the device with IMSI protection exemption not approved.
747        2. Ensure the network is present in scan results, but we don't connect
748           to it.
749        3. Now approve the carrier.
750        4. Wait for the device to connect to it.
751        """
752        asserts.skip_if(not hasattr(self, "passpoint_networks"),
753                        "No passpoint networks, skip this test")
754        passpoint_config = self.passpoint_networks[ATT]
755        passpoint_config[WifiEnums.SSID_KEY] = self.passpoint_networks[
756                ATT][WifiEnums.SSID_KEY][0]
757        asserts.skip_if("carrierId" not in passpoint_config,
758                        "Not a SIM based passpoint network, skip this test")
759
760        # Ensure the carrier is not approved.
761        asserts.assert_false(
762            self.is_carrier_approved(passpoint_config["carrierId"]),
763            "Carrier shouldn't be approved")
764
765        self.dut.log.info("Adding network suggestions")
766        asserts.assert_true(
767            self.dut.droid.wifiAddNetworkSuggestions([passpoint_config]),
768            "Failed to add suggestions")
769
770        # Start a new scan to trigger auto-join.
771        wutils.start_wifi_connection_scan_and_ensure_network_found(
772            self.dut, passpoint_config[WifiEnums.SSID_KEY])
773
774        # Ensure we don't connect to the network.
775        asserts.assert_false(
776            wutils.wait_for_connect(
777                self.dut, passpoint_config[WifiEnums.SSID_KEY], assert_on_fail=False),
778            "Should not connect to network suggestions from unapproved app")
779
780        self.dut.log.info("Enabling suggestions from test")
781        # Now approve IMSI protection exemption by carrier & ensure we connect to the network.
782        self.set_carrier_approved(passpoint_config["carrierId"], True)
783
784        # Ensure the carrier is approved.
785        asserts.assert_true(
786            self.is_carrier_approved(passpoint_config["carrierId"]),
787            "Carrier should be approved")
788
789        # Start a new scan to trigger auto-join.
790        wutils.start_wifi_connection_scan_and_ensure_network_found(
791            self.dut, passpoint_config[WifiEnums.SSID_KEY])
792        time.sleep(PASSPOINT_TIMEOUT)
793        wutils.wait_for_connect(self.dut, passpoint_config[WifiEnums.SSID_KEY])
794        self.clear_carrier_approved(passpoint_config["carrierId"])
795
796    @test_tracker_info(uuid="e35f99c8-78a4-4b96-9258-f9834b6ddd33")
797    def test_initial_auto_join_on_network_suggestion(self):
798        """
799        Add a network suggestion with enableAutojoin bit set to false, ensure the device doesn't
800        auto connect to this network
801
802        Steps:
803        1. Create a network suggestion.
804        2. Set EnableAutojoin to false.
805        3. Add this suggestion
806        4. Ensure device doesn't connect to his network
807        """
808        network_suggestion = self.wpa_psk_5g
809        # Set suggestion auto join initial to false.
810        network_suggestion[AutoJoin] = False
811        self.dut.log.info("Adding network suggestions")
812        asserts.assert_true(
813            self.dut.droid.wifiAddNetworkSuggestions([network_suggestion]),
814            "Failed to add suggestions")
815        # Enable suggestions by the app.
816        self.dut.log.debug("Enabling suggestions from test")
817        self.set_approved(True)
818        wutils.start_wifi_connection_scan_and_return_status(self.dut)
819        asserts.assert_false(
820            wutils.wait_for_connect(self.dut, network_suggestion[WifiEnums.SSID_KEY],
821                                    assert_on_fail=False), "Device should not connect.")
822
823    @test_tracker_info(uuid="ff4e451f-a380-4ff5-a5c2-dd9b1633d5e5")
824    def test_user_override_auto_join_on_network_suggestion(self):
825        """
826        Add a network suggestion, user change the auto join to false, ensure the device doesn't
827        auto connect to this network
828
829        Steps:
830        1. Create a network suggestion.
831        2. Add this suggestion, and ensure we connect to this network
832        3. Simulate user change the auto join to false.
833        4. Toggle the Wifi off and on
834        4. Ensure device doesn't connect to his network
835        """
836        network_suggestion = self.wpa_psk_5g
837        self.add_suggestions_and_ensure_connection([network_suggestion],
838                                                   network_suggestion[WifiEnums.SSID_KEY], False)
839        wifi_info = self.dut.droid.wifiGetConnectionInfo()
840        self.dut.log.info(wifi_info)
841        network_id = wifi_info[WifiEnums.NETID_KEY]
842        # Simulate user disable auto join through Settings.
843        self.dut.log.info("Disable auto join on suggestion")
844        self.dut.droid.wifiEnableAutojoin(network_id, False)
845        wutils.wifi_toggle_state(self.dut, False)
846        wutils.wifi_toggle_state(self.dut, True)
847        asserts.assert_false(
848            wutils.wait_for_connect(self.dut, network_suggestion[WifiEnums.SSID_KEY],
849                                    assert_on_fail=False), "Device should not connect.")
850
851    @test_tracker_info(uuid="32201b1c-76a0-46dc-9983-2cd24312a783")
852    def test_untrusted_suggestion_without_untrusted_request(self):
853        """
854        Add an untrusted network suggestion, when no untrusted request, will not connect to it.
855        Steps:
856        1. Create a untrusted network suggestion.
857        2. Add this suggestion, and ensure device do not connect to this network
858        3. Request untrusted network and ensure device connect to this network
859        """
860        network_suggestion = self.open_5g
861        network_suggestion[Untrusted] = True
862        self.dut.log.info("Adding network suggestions")
863        asserts.assert_true(
864            self.dut.droid.wifiAddNetworkSuggestions([network_suggestion]),
865            "Failed to add suggestions")
866        # Start a new scan to trigger auto-join.
867        wutils.start_wifi_connection_scan_and_ensure_network_found(
868            self.dut, network_suggestion[WifiEnums.SSID_KEY])
869
870        # Ensure we don't connect to the network.
871        asserts.assert_false(
872            wutils.wait_for_connect(
873                self.dut, network_suggestion[WifiEnums.SSID_KEY], assert_on_fail=False),
874            "Should not connect to untrusted network suggestions with no request")
875        network_request = {ClearCapabilities: True, TransportType: 1}
876        req_key = self.dut.droid.connectivityRequestNetwork(network_request)
877
878        # Start a new scan to trigger auto-join.
879        wutils.start_wifi_connection_scan_and_ensure_network_found(
880            self.dut, network_suggestion[WifiEnums.SSID_KEY])
881
882        wutils.wait_for_connect(
883            self.dut, network_suggestion[WifiEnums.SSID_KEY], assert_on_fail=False)
884
885        self.dut.droid.connectivityUnregisterNetworkCallback(req_key)
886
887