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