1#!/usr/bin/env python3.4
2
3import time
4
5import acts.base_test
6import acts_contrib.test_utils.tel.tel_wifi_utils
7import acts_contrib.test_utils.wifi.wifi_test_utils as wifi_utils
8import acts_contrib.test_utils.tel.tel_test_utils as tele_utils
9import acts_contrib.test_utils.tel.tel_mms_utils as mms_utils
10import acts.utils
11
12from acts import asserts
13from acts import signals
14from acts.test_decorators import test_tracker_info
15from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
16from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
17from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
18from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
19from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
20from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
21from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_short_seq
22from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
23from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
24from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
25from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
26from acts_contrib.test_utils.tel.tel_defines import GEN_4G
27from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
28from acts_contrib.test_utils.net import net_test_utils as nutil
29
30WifiEnums = wifi_utils.WifiEnums
31
32ATTENUATORS = "attenuators"
33WIFI_SSID = "wifi_network_ssid"
34WIFI_PWD = "wifi_network_pass"
35STRESS_COUNT = "stress_iteration"
36DEFAULT_TIMEOUT = 10
37
38
39class WifiTeleCoexTest(TelephonyBaseTest):
40    """Tests for WiFi, Celular Co-existance."""
41
42    def setup_class(self):
43        TelephonyBaseTest.setup_class(self)
44
45        self.dut = self.android_devices[0]
46        wifi_utils.wifi_test_device_init(self.dut)
47        # Set attenuation to 0 on all channels.
48        if getattr(self, ATTENUATORS, []):
49            for a in self.attenuators:
50                a.set_atten(0)
51        self.ads = self.android_devices
52        self.dut = self.android_devices[0]
53        self.wifi_network_ssid = self.user_params.get(WIFI_SSID)
54        self.wifi_network_pass = self.user_params.get(WIFI_PWD)
55        self.network = {
56            WifiEnums.SSID_KEY: self.wifi_network_ssid,
57            WifiEnums.PWD_KEY: self.wifi_network_pass
58        }
59        self.stress_count = self.user_params.get(STRESS_COUNT)
60
61    def setup_test(self):
62        """ Setup test make sure the DUT is wake and screen unlock"""
63        for ad in self.android_devices:
64            ad.droid.wakeLockAcquireBright()
65            ad.droid.wakeUpNow()
66            ad.droid.telephonyToggleDataConnection(True)
67        wifi_utils.wifi_toggle_state(self.dut, True)
68
69    def teardown_test(self):
70        """ End test make sure the DUT return idle"""
71        for ad in self.android_devices:
72            wifi_utils.reset_wifi(ad)
73            ad.droid.telephonyToggleDataConnection(False)
74        ensure_phones_idle(self.log, self.android_devices)
75        nutil.stop_usb_tethering(self.dut)
76
77    """Helper Functions"""
78
79    def connect_to_wifi(self, ad, network):
80        """Connection logic for open and psk wifi networks.
81
82        Args:
83            ad: Android device object.
84            network: A JSON dict of the WiFi network configuration.
85
86        """
87        ad.ed.clear_all_events()
88        wifi_utils.start_wifi_connection_scan(ad)
89        scan_results = ad.droid.wifiGetScanResults()
90        wifi_utils.assert_network_in_list(
91            {WifiEnums.SSID_KEY: self.wifi_network_ssid}, scan_results)
92        wifi_utils.wifi_connect(ad, network)
93        self.log.debug("Connected to %s network on %s device" %
94                       (network[WifiEnums.SSID_KEY], ad.serial))
95
96    def stress_toggle_wifi(self, stress_count):
97        """Toggle WiFi in a loop.
98
99        Args:
100            stress_count: Number of times to toggle WiFi OFF and ON.
101
102        """
103        for count in range(stress_count):
104            self.log.debug("stress_toggle_wifi: Iteration %d" % count)
105            wifi_utils.toggle_wifi_off_and_on(self.dut)
106
107        if not self.dut.droid.wifiGetisWifiEnabled():
108            raise signals.TestFailure("WiFi did not turn on after toggling it"
109                                      " %d times" % self.stress_count)
110
111    def stress_toggle_airplane(self, stress_count):
112        """Toggle Airplane mode in a loop.
113
114        Args:
115            stress_count: Number of times to toggle Airplane mode OFF and ON.
116
117        """
118        for count in range(stress_count):
119            self.log.debug("stress_toggle_airplane: Iteration %d" % count)
120            wifi_utils.toggle_airplane_mode_on_and_off(self.dut)
121
122        if not self.dut.droid.wifiGetisWifiEnabled():
123            raise signals.TestFailure("WiFi did not turn on after toggling it"
124                                      " %d times" % self.stress_count)
125
126    def stress_toggle_airplane_and_wifi(self, stress_count):
127        """Toggle Airplane and WiFi modes in a loop.
128
129        Args:
130            stress_count: Number of times to perform Airplane mode ON, WiFi ON,
131                          Airplane mode OFF, in a sequence.
132
133        """
134        for count in range(stress_count):
135            self.log.debug("stress_toggle_airplane_and_wifi: Iteration %d" %
136                           count)
137            self.log.debug("Toggling Airplane mode ON")
138            asserts.assert_true(
139                acts.utils.force_airplane_mode(self.dut, True),
140                "Can not turn on airplane mode on: %s" % self.dut.serial)
141            # Sleep for atleast 500ms so that, call to enable wifi is not deferred.
142            time.sleep(1)
143            self.log.debug("Toggling wifi ON")
144            wifi_utils.wifi_toggle_state(self.dut, True)
145            # Sleep for 1s before getting new WiFi state.
146            time.sleep(1)
147            if not self.dut.droid.wifiGetisWifiEnabled():
148                raise signals.TestFailure(
149                    "WiFi did not turn on after turning ON"
150                    " Airplane mode")
151            asserts.assert_true(
152                acts.utils.force_airplane_mode(self.dut, False),
153                "Can not turn on airplane mode on: %s" % self.dut.serial)
154
155        if not self.dut.droid.wifiGetisWifiEnabled():
156            raise signals.TestFailure("WiFi did not turn on after toggling it"
157                                      " %d times" % self.stress_count)
158
159    def setup_cellular_voice_calling(self):
160        """Setup phone for voice general calling and make sure phone is
161           attached to voice."""
162        # Make sure Phone A and B are attached to voice network.
163        for ad in self.ads:
164            if not phone_setup_voice_general(self.log, ad):
165                raise signals.TestFailure("Phone failed to setup for voice"
166                                          " calling serial:%s" % ad.serial)
167        self.log.debug("Finished setting up phones for voice calling")
168
169    def validate_cellular_and_wifi(self):
170        """Validate WiFi, make some cellular calls.
171
172        Steps:
173            1. Check if device is still connected to the WiFi network.
174            2. If WiFi looks good, check if deivce is attached to voice.
175            3. Make a short sequence voice call between Phone A and B.
176
177        """
178        # Sleep for 30s before getting new WiFi state.
179        time.sleep(30)
180        wifi_info = self.dut.droid.wifiGetConnectionInfo()
181        if wifi_info[WifiEnums.SSID_KEY] != self.wifi_network_ssid:
182            raise signals.TestFailure(
183                "Phone failed to connect to %s network on"
184                " %s" % (self.wifi_network_ssid, self.dut.serial))
185
186        # Make short call sequence between Phone A and Phone B.
187        two_phone_call_short_seq(self.log, self.ads[0], None, None,
188                                 self.ads[1], None, None)
189
190    def _phone_idle_iwlan(self):
191        return phone_idle_iwlan(self.log, self.android_devices[0])
192
193    def _wfc_phone_setup_apm_wifi_preferred(self):
194        return self._wfc_phone_setup(True, WFC_MODE_WIFI_PREFERRED)
195
196    def _wfc_phone_setup(self, is_airplane_mode, wfc_mode, volte_mode=True):
197        """Enables WiFi calling by turning off Airplane Mode and setting up volte
198
199        Args:
200          is_airplane_mode: boolean, True/False to turn on/off Airplane Mode.
201          wfc_mode: str, String stating what WFC Mode is used.
202          volte_mode: boolean, True/False to turn on/off VoLTE Mode.
203
204        Returns:
205          False, when 4G fails or wrong wfc_mode or WiFi does not connect,
206          (failure is logged) True otherwise.
207
208        """
209        tele_utils.toggle_airplane_mode(self.log, self.android_devices[0],
210                                        False)
211        toggle_volte(self.log, self.android_devices[0], volte_mode)
212        if not ensure_network_generation(self.log,
213                                         self.android_devices[0],
214                                         GEN_4G,
215                                         voice_or_data=NETWORK_SERVICE_DATA):
216            return False
217        if not set_wfc_mode(self.log, self.android_devices[0], wfc_mode):
218            self.log.error("{} set WFC mode failed.".format(
219                self.android_devices[0].serial))
220            return False
221        tele_utils.toggle_airplane_mode(self.log, self.android_devices[0],
222                                        is_airplane_mode)
223        if not tel_wifi_utils.ensure_wifi_connected(
224                self.log, self.android_devices[0], self.wifi_network_ssid,
225                self.wifi_network_pass):
226            self.log.error("{} connect WiFI failed".format(
227                self.android_devices[0].serial))
228            return False
229        return True
230
231    """Tests"""
232
233    @test_tracker_info(uuid="8b9b6fb9-964b-43e7-b75f-675774ee346f")
234    @TelephonyBaseTest.tel_test_wrap
235    def test_toggle_wifi_call(self):
236        """Test to toggle WiFi and then perform WiFi connection and
237           cellular calls.
238
239        Steps:
240            1. Attach device to voice subscription network.
241            2. Connect to a WiFi network.
242            3. Toggle WiFi OFF and ON.
243            4. Verify device auto-connects to the WiFi network.
244            5. Verify device is attached to voice network.
245            6. Make short sequence voice calls.
246
247        """
248        self.setup_cellular_voice_calling()
249        self.connect_to_wifi(self.dut, self.network)
250        wifi_utils.toggle_wifi_off_and_on(self.dut)
251        self.validate_cellular_and_wifi()
252        return True
253
254    @test_tracker_info(uuid="caf22447-6354-4a2e-99e5-0ff235fc8f20")
255    @TelephonyBaseTest.tel_test_wrap
256    def test_toggle_airplane_call(self):
257        """Test to toggle Airplane mode and perform WiFi connection and
258           cellular calls.
259
260        Steps:
261            1. Attach device to voice subscription network.
262            2. Connect to a WiFi network.
263            3. Toggle Airplane mode OFF and ON.
264            4. Verify device auto-connects to the WiFi network.
265            5. Verify device is attached to voice network.
266            6. Make short sequence voice calls.
267
268        """
269        self.setup_cellular_voice_calling()
270        self.connect_to_wifi(self.dut, self.network)
271        wifi_utils.toggle_airplane_mode_on_and_off(self.dut)
272        self.validate_cellular_and_wifi()
273        return True
274
275    @test_tracker_info(uuid="dd888b35-f820-409a-89af-4b0f6551e4d6")
276    @TelephonyBaseTest.tel_test_wrap
277    def test_toggle_airplane_and_wifi_call(self):
278        """Test to toggle WiFi in a loop and perform WiFi connection and
279           cellular calls.
280
281        Steps:
282            1. Attach device to voice subscription network.
283            2. Connect to a WiFi network.
284            3. Toggle Airplane mode ON.
285            4. Turn WiFi ON.
286            5. Toggle Airplane mode OFF.
287            3. Verify device auto-connects to the WiFi network.
288            4. Verify device is attached to voice network.
289            5. Make short sequence voice calls.
290
291        """
292        self.setup_cellular_voice_calling()
293        self.connect_to_wifi(self.dut, self.network)
294        self.stress_toggle_airplane_and_wifi(1)
295        self.validate_cellular_and_wifi()
296        return True
297
298    @test_tracker_info(uuid="15db5b7e-827e-4bc8-8e77-7fcce343a323")
299    @TelephonyBaseTest.tel_test_wrap
300    def test_stress_toggle_wifi_call(self):
301        """Stress test to toggle WiFi in a loop, then perform WiFi connection
302           and cellular calls.
303
304        Steps:
305            1. Attach device to voice subscription network.
306            2. Connect to a WiFi network.
307            3. Toggle WiFi OFF and ON in a loop.
308            4. Verify device auto-connects to the WiFi network.
309            5. Verify device is attached to voice network.
310            6. Make short sequence voice calls.
311
312        """
313        self.setup_cellular_voice_calling()
314        self.connect_to_wifi(self.dut, self.network)
315        self.stress_toggle_wifi(self.stress_count)
316        self.validate_cellular_and_wifi()
317        return True
318
319    @test_tracker_info(uuid="80a2f1bf-5e41-453a-9b8e-be3b41d4d313")
320    @TelephonyBaseTest.tel_test_wrap
321    def test_stress_toggle_airplane_call(self):
322        """Stress test to toggle Airplane mode in a loop, then perform WiFi and
323           cellular calls.
324
325        Steps:
326            1. Attach device to voice subscription network.
327            2. Connect to a WiFi network.
328            3. Toggle Airplane mode OFF and ON in a loop.
329            4. Verify device auto-connects to the WiFi network.
330            5. Verify device is attached to voice network.
331            6. Make short sequence voice calls.
332
333        """
334        self.setup_cellular_voice_calling()
335        self.connect_to_wifi(self.dut, self.network)
336        self.stress_toggle_airplane(self.stress_count)
337        self.validate_cellular_and_wifi()
338        return True
339
340    @test_tracker_info(uuid="b88ad3e7-6462-4280-ad57-22d0ac91fdd8")
341    @TelephonyBaseTest.tel_test_wrap
342    def test_stress_toggle_airplane_and_wifi_call(self):
343        """Stress test to toggle Airplane and WiFi mode in a loop, then perform
344           WiFi connection and cellular calls.
345
346        Steps:
347            1. Attach device to voice subscription network.
348            2. Connect to a WiFi network.
349            3. Toggle Airplane mode ON.
350            4. Turn WiFi ON.
351            5. Toggle Airplane mode OFF.
352            6. Repeat 3, 4 & 5, in a loop.
353            7. Verify device auto-connects to the WiFi network.
354            8. Verify device is attached to voice network.
355            9. Make short sequence voice calls.
356
357        """
358        self.setup_cellular_voice_calling()
359        self.connect_to_wifi(self.dut, self.network)
360        self.stress_toggle_airplane_and_wifi(self.stress_count)
361        self.validate_cellular_and_wifi()
362        return True
363
364    @test_tracker_info(uuid="7cd9698c-7cde-4c99-b73a-67a2246ca4ec")
365    @TelephonyBaseTest.tel_test_wrap
366    def test_toggle_WFC_call(self):
367        """Test to toggle WiFi and then perform WiFi connection and
368           cellular calls.
369
370        Raises:
371          signals.TestFailure:The Wifi calling test is failed.
372
373        Steps:
374            1. Attach device to voice subscription network.
375            2. Connect to a WiFi network.
376            3. Turn on airplane mode
377            4. Toggle WiFi OFF and ON.
378            5. Make WiFi calling
379            6. Verify device is in WiFi calling
380            5. Hang up the call
381
382        Verification:
383            The device is using WiFi calling to call out.
384
385        """
386        mo_mt = []
387        if mo_mt == DIRECTION_MOBILE_ORIGINATED:
388            ad_caller = self.ads[0]
389            ad_callee = self.ads[1]
390        else:
391            ad_caller = self.ads[1]
392            ad_callee = self.ads[0]
393        caller_number = tele_utils.get_phone_number(self.log, ad_caller)
394        callee_number = tele_utils.get_phone_number(self.log, ad_callee)
395        self._wfc_phone_setup_apm_wifi_preferred()
396
397        self.connect_to_wifi(self.dut, self.network)
398        asserts.assert_true(
399            acts.utils.force_airplane_mode(self.dut, True),
400            "Can not turn on airplane mode on: %s" % self.dut.serial)
401        time.sleep(1)
402        self.log.info("Toggling wifi ON")
403        wifi_utils.wifi_toggle_state(self.dut, True)
404        time.sleep(10)
405        tele_utils.initiate_call(self.log, ad_caller, callee_number)
406        tele_utils.wait_and_answer_call(self.log, ad_callee, caller_number)
407        if not self._phone_idle_iwlan():
408            self.log.error("no in wifi calling")
409            raise signals.TestFailure("The Wifi calling test is failed."
410                                      "WiFi State = %d" %
411                                      self.dut.droid.wifiCheckState())
412        tele_utils.hangup_call(self.log, self.ads[0])
413
414    @test_tracker_info(uuid="c1f0e0a7-b651-4d6c-a4a5-f946cabf56ef")
415    @TelephonyBaseTest.tel_test_wrap
416    def test_back_to_back_of_the_modem_restart(self):
417        """Make sure DUT can connect to AP after modem restart
418
419        Raises:
420          signals.TestFailure: The Wifi connect failed after modem restart.
421
422        From b/171275893:
423          b/170702695 has modem back to back restart,
424          it causes WIFi failure and only reboot device can recover.
425          Currently modem team has this test case but they only check modem status.
426          Therefore, we need to add the same test case and the criteria is to check
427          if WiFi works well after back to back modem restart.
428          For the interval setting between 2 restarts, we suggest to use 20s.
429          We can change to different interval if necessary.
430
431        Steps:
432            1.Restart the modem once
433            2.Waiting for 20s
434            3.Restart the modem again
435            4.Go to Settings ->Network & internet ->Wi-Fi
436            5.To check the DUT can find WiFi AP then connect it
437        Verification:
438            DUT can connect to AP successfully
439            DUT can access the Internet after connect to AP.
440
441        """
442        self.dut = self.android_devices[0]
443        try:
444            tele_utils.trigger_modem_crash_by_modem(self.dut)
445            time.sleep(20)
446            tele_utils.trigger_modem_crash_by_modem(self.dut)
447            time.sleep(20)
448            self.connect_to_wifi(self.dut, self.network)
449        except:
450            raise signals.TestFailure(
451                "The Wifi connect failed after modem restart."
452                "WiFi State = %d" % self.dut.droid.wifiCheckState())
453
454    @test_tracker_info(uuid="a72ff9da-3855-4c21-b447-b80f43227961")
455    @TelephonyBaseTest.tel_test_wrap
456    def test_internet_accessing_over_wifi_and_mms_test(self):
457        """Verify when MMS is working WLAN connection can work normally as well.
458
459        Raises:
460          signals.TestFailure: Internet_connection is stop
461
462        Steps:
463            1. Connect to WiFi
464            2. Prepare two DUT for testing (DUT1 and DUT2)
465            3. Send 5 MMS from DUT1 to DUT2
466
467        Verification:
468            The internet cannot be impacted by MMS delivery.
469            MMS can be sent / received successfully and content is correct.
470        """
471        self.dut1 = self.android_devices[0]
472        self.dut2 = self.android_devices[1]
473        self.connect_to_wifi(self.dut1, self.network)
474        wifi_utils.wifi_toggle_state(self.dut2, True)
475        self.connect_to_wifi(self.dut2, self.network)
476        mms = 5
477        for count in range(mms):
478            mms_utils._mms_test(self.log, self.ads)
479            if not tele_utils.verify_internet_connection(
480                    self.dut2.log, self.dut2):
481                raise signals.TestFailure("The internet connection is stop."
482                                          "Current WiFi state is %d" %
483                                          self.dut2.droid.wifiCheckState())
484            time.sleep(30)
485
486    @test_tracker_info(uuid="a7d774e4-ead3-465c-b4a6-f39a6397dfe3")
487    @TelephonyBaseTest.tel_test_wrap
488    def test_internet_accessing_wifi_and_data_test(self):
489        """Verify interwork between Wi-Fi and data.
490
491        Raises:
492          signals.TestFailure: Internet_connection is stop for WiFi off or
493          Data off
494
495        Steps:
496            1. Connect to WiFi
497            2. To Wi-Fi and data switched for 5 times,
498            3. DUT is kept awake during testing.
499        Verification:
500            The internet cannot be impacted after data path switched
501
502        """
503        self.dut = self.android_devices[0]
504        self.connect_to_wifi(self.dut, self.network)
505        data_count = 5
506        for count in range(data_count):
507            wifi_utils.wifi_toggle_state(self.dut, False)
508            time.sleep(60)
509            if not tele_utils.verify_internet_connection(
510                    self.dut.log, self.dut):
511                raise signals.TestFailure(
512                    "The internet connection is stop"
513                    "for WiFi off. Current WiFi state is %d" %
514                    self.dut.droid.wifiCheckState())
515            wifi_utils.wifi_toggle_state(self.dut, True)
516            time.sleep(DEFAULT_TIMEOUT)
517            self.dut.log.info("DUT data is disable")
518            self.dut.droid.telephonyToggleDataConnection(False)
519            time.sleep(30)
520            if not tele_utils.verify_internet_connection(
521                    self.dut.log, self.dut):
522                raise signals.TestFailure(
523                    "The internet connection is stop"
524                    "for Data off. Current WiFi state is %d" %
525                    self.dut.droid.wifiCheckState())
526            self.dut.log.info("DUT data is enable")
527            self.dut.droid.telephonyToggleDataConnection(True)
528            time.sleep(DEFAULT_TIMEOUT)
529
530    @test_tracker_info(uuid="e53adef6-d537-4098-a354-1e63457ab444")
531    @TelephonyBaseTest.tel_test_wrap
532    def test_internet_accessing_wifi_and_usb_tethering(self):
533        """Verify interwork between Wi-Fi and USB_TETHERED.
534
535        Raises:
536          signals.TestFailure: Internet_connection is stop for enable or
537          disable USB tethering
538
539        Steps:
540            1.Connect to WiFi
541            2. enable/disable USB tethering for 5 cycles,
542
543        Verification:
544            The Internet cannot be impacted after enable/disable USB tethering
545
546        """
547        self.dut = self.android_devices[0]
548        nutil.verify_lte_data_and_tethering_supported(self.dut)
549        self.connect_to_wifi(self.dut, self.network)
550        usb_count = 5
551        for count in range(usb_count):
552            time.sleep(DEFAULT_TIMEOUT)
553            nutil.start_usb_tethering(self.dut)
554            time.sleep(DEFAULT_TIMEOUT)
555            if not tele_utils.verify_internet_connection(
556                    self.dut.log, self.dut):
557                raise signals.TestFailure(
558                    "The internet connection is stop"
559                    "for tethering enable. Current WiFi state is %d" %
560                    self.dut.droid.wifiCheckState())
561            nutil.stop_usb_tethering(self.dut)
562            time.sleep(DEFAULT_TIMEOUT)
563            if not tele_utils.verify_internet_connection(
564                    self.dut.log, self.dut):
565                raise signals.TestFailure(
566                    "The internet connection is stop"
567                    "for tethering disable. Current WiFi state is %d" %
568                    self.dut.droid.wifiCheckState())
569