#!/usr/bin/env python3.4
#
#   Copyright 2020 - Google
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
"""
    Test Script for 5G Voice scenarios
"""

import time

from acts import signals
from acts.utils import adb_shell_ping
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_ORIGINATED
from acts_contrib.test_utils.tel.tel_defines import DIRECTION_MOBILE_TERMINATED
from acts_contrib.test_utils.tel.tel_defines import GEN_5G
from acts_contrib.test_utils.tel.tel_defines import TOTAL_LONG_CALL_DURATION
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL_FOR_IMS
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_ONLY
from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown
from acts_contrib.test_utils.tel.tel_test_utils import \
    call_voicemail_erase_all_pending_voicemail
from acts_contrib.test_utils.tel.tel_test_utils import ensure_phones_idle
from acts_contrib.test_utils.tel.tel_test_utils import get_mobile_data_usage
from acts_contrib.test_utils.tel.tel_test_utils import hangup_call
from acts_contrib.test_utils.tel.tel_test_utils import is_phone_in_call_active
from acts_contrib.test_utils.tel.tel_test_utils import multithread_func
from acts_contrib.test_utils.tel.tel_test_utils import remove_mobile_data_usage_limit
from acts_contrib.test_utils.tel.tel_test_utils import set_mobile_data_usage_limit
from acts_contrib.test_utils.tel.tel_voice_utils import _test_call_long_duration
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_volte
from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_2g
from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import phone_idle_volte
from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_call_hold_unhold_test
from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_csfb
from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan
from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_2g
from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_3g
from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_voice_general
from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_leave_voice_mail
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_long_seq
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_short_seq
from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_nsa
from acts_contrib.test_utils.tel.tel_5g_utils import provision_both_devices_for_volte
from acts_contrib.test_utils.tel.tel_5g_utils import provision_device_for_5g
from acts_contrib.test_utils.tel.tel_5g_utils import set_preferred_mode_for_5g
from acts_contrib.test_utils.tel.tel_5g_utils import verify_5g_attach_for_both_devices
from acts_contrib.test_utils.tel.tel_5g_utils import disable_apm_mode_both_devices
from acts_contrib.test_utils.tel.tel_data_utils import call_epdg_to_epdg_wfc
from acts_contrib.test_utils.tel.tel_data_utils import test_call_setup_in_active_data_transfer
from acts_contrib.test_utils.tel.tel_data_utils import test_call_setup_in_active_youtube_video
from acts_contrib.test_utils.tel.tel_data_utils import wifi_cell_switching
from acts_contrib.test_utils.tel.tel_data_utils import test_wifi_cell_switching_in_call
CallResult = TelephonyVoiceTestResult.CallResult.Value


class Nsa5gVoiceTest(TelephonyBaseTest):
    def setup_class(self):
        super().setup_class()
        self.number_of_devices = 2
        self.message_lengths = (50, 160, 180)
        self.tel_logger = TelephonyMetricLogger.for_test_case()
        self.stress_test_number = self.get_stress_test_number()
        self.long_call_duration = self.user_params.get(
            "long_call_duration",
            TOTAL_LONG_CALL_DURATION)

    def setup_test(self):
        TelephonyBaseTest.setup_test(self)

    def teardown_test(self):
        ensure_phones_idle(self.log, self.android_devices)

    """ Tests Begin """

    @test_tracker_info(uuid="1bef3da1-4608-4b0e-8b78-f3f7be0115d5")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_to_volte(self):
        """ 5g nsa volte to volte call test

        1. Make sure PhoneA is in nsa5g mode (with volte).
        2. Make sure PhoneB is in nsa5g mode (with volte).
        3. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.
        5. Verify both PhoneA and PhoneB gets attached back to nsa5g

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices
        if not provision_both_devices_for_volte(self.log, ads):
            return False

        if not provision_device_for_5g(self.log, ads):
            return False

        # VoLTE calls
        result = two_phone_call_short_seq(
            self.log, ads[0], None, is_phone_in_call_volte, ads[1],
            None, is_phone_in_call_volte, None,
            WAIT_TIME_IN_CALL_FOR_IMS)
        if not result:
            self.log.error("Failure is volte call during 5g nsa")
            return False

        if not verify_5g_attach_for_both_devices(self.log, ads):
            return False

        self.log.info("PASS - volte test over 5g nsa validated")
        return True

    @test_tracker_info(uuid="3df252a4-308a-49c3-8e37-08e9c4e8efef")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_to_3g(self):
        """ 5g nsa volte to 3g call test

        1. Make sure PhoneA is in nsa5g mode (with volte).
        2. Make sure PhoneB is in 3g mode.
        3. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.
        5. Verify both PhoneA and PhoneB gets attached back to nsa5g

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices

        # LTE attach
        tasks = [(phone_setup_volte, (self.log, ads[0])),
                 (phone_setup_voice_3g, (self.log, ads[1]))]
        if not multithread_func(self.log, tasks):
            self.log.error("Phone failed to set up in volte/3g")
            return False

        if not provision_device_for_5g(self.log, ads[0]):
            return False

        # VoLTE to 3G
        result = two_phone_call_short_seq(
            self.log, ads[0], None, is_phone_in_call_volte, ads[1],
            None, is_phone_in_call_3g, None,
            WAIT_TIME_IN_CALL_FOR_IMS)
        if not result:
            self.log.error("Failure is volte to 3g call during 5g nsa")
            return False

        # Attach nsa5g
        if not is_current_network_5g_nsa(ads[0]):
            ads[0].log.error("Phone not attached on 5g nsa after call end.")
            return False

        self.log.info("PASS - VoLTE to 3g over 5g nsa validated")
        return True


    @test_tracker_info(uuid="3a8147d6-c136-42cb-92ca-2023b8eed85e")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_mo_hold_unhold(self):
        """ 5g nsa volte mo hold unhold test

        1. Make sure PhoneA is in nsa 5g (with volte)
        2. Make sure PhoneB is in nsa 5g (with volte)
        3. Call from PhoneA to PhoneB, accept on PhoneB
        4. Make sure PhoneA/B are in call
        5. Hold and unhold on PhoneA
        6. Verify both PhoneA and PhoneB gets attached back to nsa5g

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices
        if not provision_both_devices_for_volte(self.log, ads):
            return False

        if not provision_device_for_5g(self.log, ads):
            return False

        if not phone_setup_call_hold_unhold_test(self.log,
                                                 ads,
                                                 DIRECTION_MOBILE_ORIGINATED,
                                                 caller_func=is_phone_in_call_volte):
            return False

        if not verify_5g_attach_for_both_devices(self.log, ads):
            return False
        return True

    @test_tracker_info(uuid="1825f9d9-dcf1-4407-922d-3f218d5b8932")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_mt_hold_unhold(self):
        """ 5g nsa volte mt hold unhold test

        1. Make sure PhoneA is in nsa 5g (with volte)
        2. Make sure PhoneB is in nsa 5g (with volte)
        3. Call from PhoneB to PhoneA, accept on PhoneA
        4. Make sure PhoneA/B are in call
        5. Hold and unhold on PhoneA
        6. Verify both PhoneA and PhoneB gets attached back to nsa5g

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices
        if not provision_both_devices_for_volte(self.log, ads):
            return False

        if not provision_device_for_5g(self.log, ads):
            return False

        if not phone_setup_call_hold_unhold_test(self.log,
                                                 ads,
                                                 DIRECTION_MOBILE_TERMINATED,
                                                 callee_func=is_phone_in_call_volte):
            return False

        if not verify_5g_attach_for_both_devices(self.log, ads):
            return False
        return True


    @test_tracker_info(uuid="c082a9b0-fb66-4d3a-9fdd-1ce5710624be")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mo_volte_in_active_data_transfer(self):
        """Test call can be established during active data connection in 5G NSA.

        Turn off airplane mode, disable WiFi, enable Cellular Data.
        Make sure phone in 5G NSA.
        Starting downloading file from Internet.
        Initiate a MO voice call. Verify call can be established.
        Hangup Voice Call, verify file is downloaded successfully.
        Note: file download will be suspended when call is initiated if voice
              is using voice channel and voice channel and data channel are
              on different RATs.

        Returns:
            True if success.
            False if failed.
        """
        ads = self.android_devices
        if not phone_setup_volte(self.log, ads[0]):
            ads[0].log.error("failed to setup volte")
            return False
        return test_call_setup_in_active_data_transfer(self.log,
                                                       ads,
                                                       GEN_5G,
                                                       DIRECTION_MOBILE_ORIGINATED)


    @test_tracker_info(uuid="aaa98e51-0bde-472a-abc3-5dc180f56a08")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mt_volte_in_active_data_transfer(self):
        """Test call can be established during active data connection in 5G NSA.

        Turn off airplane mode, disable WiFi, enable Cellular Data.
        Make sure phone in 5G NSA.
        Starting downloading file from Internet.
        Initiate a MT voice call. Verify call can be established.
        Hangup Voice Call, verify file is downloaded successfully.
        Note: file download will be suspended when call is initiated if voice
              is using voice channel and voice channel and data channel are
              on different RATs.

        Returns:
            True if success.
            False if failed.
        """
        ads = self.android_devices
        if not phone_setup_volte(self.log, ads[0]):
            ads[0].log.error("failed to setup volte")
            return False
        return test_call_setup_in_active_data_transfer(self.log,
                                                       ads,
                                                       GEN_5G,
                                                       DIRECTION_MOBILE_TERMINATED)


    @test_tracker_info(uuid="3a607dee-7e92-4567-8ca0-05099590b773")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_volte_in_call_wifi_toggling(self):
        """ Test data connection network switching during VoLTE call in 5G NSA.

        1. Make Sure PhoneA in VoLTE.
        2. Make Sure PhoneB in VoLTE.
        3. Make sure Phones are in 5G NSA
        4. Call from PhoneA to PhoneB.
        5. Toggling Wifi connection in call.
        6. Verify call is active.
        7. Hung up the call on PhoneA
        8. Make sure Phones are in 5G NSA

        Returns:
            True if pass; False if fail.
        """
        ads = self.android_devices
        result = True
        if not provision_both_devices_for_volte(self.log, ads):
            return False

        time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)

        if not provision_device_for_5g(self.log, ads):
            return False

        if not verify_5g_attach_for_both_devices(self.log, ads):
            self.log.error("Phone not attached on 5G NSA before call.")
            return False

        if not call_setup_teardown(self.log, ads[0], ads[1], None, None, None,
                                   5):
            self.log.error("Call setup failed")
            return False
        else:
            self.log.info("Call setup succeed")

        if not wifi_cell_switching(self.log, ads[0], None, self.wifi_network_ssid,
                                   self.wifi_network_pass):
            ads[0].log.error("Failed to do WIFI and Cell switch in call")
            result = False

        if not is_phone_in_call_active(ads[0]):
            return False
        else:
            if not ads[0].droid.telecomCallGetAudioState():
                ads[0].log.error("Audio is not on call")
                result = False
            else:
                ads[0].log.info("Audio is on call")
            hangup_call(self.log, ads[0])

            time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)

            if not verify_5g_attach_for_both_devices(self.log, ads):
                self.log.error("Phone not attached on 5G NSA after call.")
                return False
            return result


    @test_tracker_info(uuid="96b7d8c9-d32a-4abf-8326-6b060d116ac2")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_epdg_to_epdg_wfc_wifi_preferred(self):
        """ WiFi Preferred, WiFi calling to WiFi Calling test on 5G NSA

        1. Setup PhoneA WFC mode: WIFI_PREFERRED, APM off.
        2. Setup PhoneB WFC mode: WIFI_PREFERRED, APM off .
        3. Set PhoneA/PhoneB on 5G NSA
        4. Make sure PhoneA/PhoneB on 5G NSA before testing
        5. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        6. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.
        7. Make sure PhoneA/PhoneB on 5G NSA after testing

        Returns:
            True if pass; False if fail.
        """
        return call_epdg_to_epdg_wfc(self.log,
                                     self.android_devices,
                                     False,
                                     WFC_MODE_WIFI_PREFERRED,
                                     self.wifi_network_ssid,
                                     self.wifi_network_pass,
                                     GEN_5G)


    @test_tracker_info(uuid="29fa7f44-8d6a-4948-8178-33c9a9aab334")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mo_volte_in_active_youtube(self):
        """Test call can be established during active youtube video on 5G NSA.

        1. Enable VoLTE on PhoneA.
        2. Set up PhoneA on 5G NSA.
        3. Make sure phoneA is on 5G NSA.
        4. Starting an youtube video.
        5. Initiate a MO voice call. Verify call can be established.
        6. Make sure phoneA is on 5G NSA.

        Returns:
            True if success.
            False if failed.
        """
        ads = self.android_devices
        if not phone_setup_volte(self.log, ads[0]):
            ads[0].log.error("Failed to setup VoLTE")
            return False
        return test_call_setup_in_active_youtube_video(self.log,
                                                       ads,
                                                       GEN_5G,
                                                       DIRECTION_MOBILE_ORIGINATED)

    @test_tracker_info(uuid="4e138477-3536-48bd-ab8a-7fb7c228b3e6")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mt_volte_in_active_youtube(self):
        """Test call can be established during active youtube video on 5G NSA.

        1. Enable VoLTE on PhoneA.
        2. Set up PhoneA on 5G NSA.
        3. Make sure phoneA is on 5G NSA.
        4. Starting an youtube video.
        5. Initiate a MT voice call. Verify call can be established.
        6. Make sure phoneA is on 5G NSA.

        Returns:
            True if success.
            False if failed.
        """
        ads = self.android_devices
        if not phone_setup_volte(self.log, ads[0]):
            ads[0].log.error("Failed to setup VoLTE")
            return False
        return test_call_setup_in_active_youtube_video(self.log,
                                                       ads,
                                                       GEN_5G,
                                                       DIRECTION_MOBILE_TERMINATED)


    @test_tracker_info(uuid="0d477f6f-3464-4b32-a5e5-0fd134f2753d")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mo_vowifi_in_active_data_transfer(self):
        """Test MO voice wifi call can be established during active data connection on 5G NSA.

        1. Turn off airplane mode, turn on wfc and wifi on phoneA.
        2. Set PhoneA on 5G NSA
        3. Make sure PhoneA on 5G NSA before testing
        4. Starting downloading file from Internet.
        5. Initiate a MO voice call. Verify call can be established.
        6. Hangup Voice Call, verify file is downloaded successfully.
        7. Make sure PhoneA on 5G NSA after testing

        Returns:
            True if success.
            False if failed.
        """
        ads = self.android_devices
        if not phone_setup_iwlan(self.log, ads[0], False,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            ads[0].log.error(
                "Failed to setup iwlan with APM off and WIFI and WFC on")
            return False

        return test_call_setup_in_active_data_transfer(self.log,
                                                       ads,
                                                       GEN_5G,
                                                       DIRECTION_MOBILE_ORIGINATED)


    @test_tracker_info(uuid="4d1d7dd9-b373-4361-8301-8517ef77b57b")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mt_vowifi_in_active_data_transfer(self):
        """Test MT voice wifi call can be established during active data connection on 5G NSA.

        1. Turn off airplane mode, turn on wfc and wifi on phoneA.
        2. Set PhoneA on 5G NSA
        3. Make sure PhoneA on 5G NSA before testing
        4. Starting downloading file from Internet.
        5. Initiate a MT voice call. Verify call can be established.
        6. Hangup Voice Call, verify file is downloaded successfully.
        7. Make sure PhoneA on 5G NSA after testing

        Returns:
            True if success.
            False if failed.
        """
        ads = self.android_devices
        if not phone_setup_iwlan(self.log, ads[0], False,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            ads[0].log.error(
                "Failed to setup iwlan with APM off and WIFI and WFC on")
            return False

        return test_call_setup_in_active_data_transfer(self.log,
                                                       ads,
                                                       GEN_5G,
                                                       DIRECTION_MOBILE_TERMINATED)


    @test_tracker_info(uuid="e360bc3a-96b3-4fdf-9bf3-fe3aa08b1af5")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_epdg_mo_hold_unhold_wfc_wifi_preferred(self):
        """ WiFi Preferred, WiFi calling MO call hold/unhold test on 5G NSA

        1. Setup PhoneA WFC mode: WIFI_PREFERRED.
        2. Set preferred network of phoneA on 5G NSA
        3. Verify phoneA is on 5G NSA.
        4. Call from PhoneA to PhoneB, accept on PhoneB.
        5. Hold and unhold on PhoneA.
        6. Verify phoneA is on 5G NSA.

        Returns:
            True if pass; False if fail.
        """
        ads = self.android_devices
        if not phone_setup_iwlan(self.log, ads[0], False,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            ads[0].log.error(
                "Failed to setup iwlan with APM off and WIFI and WFC on")
            return False

        if not provision_device_for_5g(self.log, ads[0]):
            return False

        if not phone_setup_call_hold_unhold_test(self.log,
                                                 ads,
                                                 DIRECTION_MOBILE_ORIGINATED,
                                                 caller_func=is_phone_in_call_iwlan):
            return False

        if not is_current_network_5g_nsa(ads[0]):
            ads[0].log.error("Phone not attached on 5G NSA after call.")
            return False
        return True


    @test_tracker_info(uuid="d2335c83-87ec-4a0e-97a8-b53f769b0d21")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_epdg_mt_hold_unhold_wfc_wifi_preferred(self):
        """ WiFi Preferred, WiFi calling MT call hold/unhold test on 5G NSA

        1. Setup PhoneA WFC mode: WIFI_PREFERRED.
        2. Set preferred network of phoneA on 5G NSA
        3. Verify if phoneA is on 5G NSA.
        4. Call from PhoneB to PhoneA, accept on PhoneA.
        5. Hold and unhold on PhoneA.
        6. Verify if phoneA is on 5G NSA.

        Returns:
            True if pass; False if fail.
        """
        ads = self.android_devices
        if not phone_setup_iwlan(self.log, ads[0], False,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            ads[0].log.error(
                "Failed to setup iwlan with APM off and WIFI and WFC on")
            return False

        if not provision_device_for_5g(self.log, ads[0]):
            return False

        if not phone_setup_call_hold_unhold_test(self.log,
                                                 ads,
                                                 DIRECTION_MOBILE_TERMINATED,
                                                 callee_func=is_phone_in_call_iwlan):
            return False

        if not is_current_network_5g_nsa(ads[0]):
            ads[0].log.error("Phone not attached on 5G NSA after call.")
            return False
        return True


    @test_tracker_info(uuid="03dc3296-5f2f-4141-b2e5-bb0d8ea6ffec")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_to_csfb_3g(self):
        """ VoLTE nsa 5G to CSFB 3G call test

        1. Make Sure PhoneA is in nsa 5G mode (with VoLTE).
        2. Make Sure PhoneB is in CSFB mode (without VoLTE).
        3. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices

        tasks = [(phone_setup_volte, (self.log, ads[0])), (phone_setup_csfb,
                                                           (self.log, ads[1]))]
        if not multithread_func(self.log, tasks):
            self.log.error("Phone failed to set up in VoLTE/CSFB")
            return False

        if not provision_device_for_5g(self.log, ads[0]):
            return False

        result = two_phone_call_short_seq(
            self.log, ads[0], None, is_phone_in_call_volte, ads[1],
            phone_idle_csfb, is_phone_in_call_csfb, None)
        self.tel_logger.set_result(result.result_value)
        if not result:
            raise signals.TestFailure("Failed",
                extras={"fail_reason": str(result.result_value)})


    @test_tracker_info(uuid="1955604b-5b81-4b06-b846-ba55b46ea997")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_to_2g(self):
        """ nsa 5G to 2G call test (with VoLTE)

        1. Make Sure PhoneA is in nsa 5G mode (with VoLTE).
        2. Make Sure PhoneB is in 2G mode.
        3. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices

        tasks = [(phone_setup_volte, (self.log, ads[0])),
                 (phone_setup_voice_2g, (self.log, ads[1]))]
        if not multithread_func(self.log, tasks):
            self.log.error("Phone failed to set up in VoLTE/2G")
            return False

        if not provision_device_for_5g(self.log, ads[0]):
            return False

        result = two_phone_call_short_seq(
            self.log, ads[0], None, is_phone_in_call_volte, ads[1],
            phone_idle_2g, is_phone_in_call_2g, None)
        self.tel_logger.set_result(result.result_value)
        if not result:
            raise signals.TestFailure("Failed",
                extras={"fail_reason": str(result.result_value)})


    @test_tracker_info(uuid="547d0b7e-8130-4166-bd57-af8257d5d0c4")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_epdg_to_volte_wfc_wifi_preferred(self):
        """ WiFi Preferred, WiFi calling to nsa5g VoLTE test

        1. Setup PhoneA WFC mode: WIFI_PREFERRED.
        2. Make Sure PhoneB is in nsa5G mode (with VoLTE enabled).
        3. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices
        tasks = [(phone_setup_iwlan,
                  (self.log, ads[0], False, WFC_MODE_WIFI_PREFERRED,
                   self.wifi_network_ssid, self.wifi_network_pass)),
                 (phone_setup_volte, (self.log, ads[1]))]

        if not multithread_func(self.log, tasks):
            self.log.error("Phone failed to set up in VoLTE")
            return False

        if not provision_device_for_5g(self.log, ads[1]):
            return False

        result = two_phone_call_short_seq(
            self.log, ads[0], phone_idle_iwlan, is_phone_in_call_iwlan, ads[1],
            None, is_phone_in_call_volte, None,
            WAIT_TIME_IN_CALL_FOR_IMS)
        self.tel_logger.set_result(result.result_value)
        if not result:
            raise signals.TestFailure("Failed",
                extras={"fail_reason": str(result.result_value)})


    @test_tracker_info(uuid="119b54f8-fe4f-4158-baa3-c869a7ce12b9")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_epdg_to_volte_apm_wfc_wifi_only(self):
        """ Airplane + WiFi Only, WiFi calling to nsa5g VoLTE test

        1. Setup PhoneA in airplane mode, WFC mode: WIFI_ONLY.
        2. Make Sure PhoneB is in nsa 5G mode (with VoLTE enabled).
        3. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices
        tasks = [(phone_setup_iwlan,
                  (self.log, ads[0], True, WFC_MODE_WIFI_ONLY,
                   self.wifi_network_ssid, self.wifi_network_pass)),
                 (phone_setup_volte, (self.log, ads[1]))]

        if not multithread_func(self.log, tasks):
            self.log.error("Phone failed to set up in VoLTE")
            return False

        if not provision_device_for_5g(self.log, ads[1]):
            return False

        result = two_phone_call_short_seq(
            self.log, ads[0], phone_idle_iwlan, is_phone_in_call_iwlan, ads[1],
            None, is_phone_in_call_volte, None,
            WAIT_TIME_IN_CALL_FOR_IMS)
        self.tel_logger.set_result(result.result_value)
        if not result:
            raise signals.TestFailure("Failed",
                extras={"fail_reason": str(result.result_value)})


    @test_tracker_info(uuid="cb2eac2b-fc48-409d-bff2-a06849d6cd1a")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_epdg_to_volte_apm_wfc_wifi_preferred(self):
        """ Airplane + WiFi Preferred, WiFi calling to nsa5g VoLTE test

        1. Setup PhoneA in airplane mode, WFC mode: WIFI_PREFERRED.
        2. Make Sure PhoneB is in nsa 5G mode (with VoLTE enabled).
        3. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices
        tasks = [(phone_setup_iwlan,
                  (self.log, ads[0], True, WFC_MODE_WIFI_PREFERRED,
                   self.wifi_network_ssid, self.wifi_network_pass)),
                 (phone_setup_volte, (self.log, ads[1]))]

        if not multithread_func(self.log, tasks):
            self.log.error("Phone failed to set up in VoLTE")
            return False

        if not provision_device_for_5g(self.log, ads[1]):
            return False

        result = two_phone_call_short_seq(
            self.log, ads[0], phone_idle_iwlan, is_phone_in_call_iwlan, ads[1],
            None, is_phone_in_call_volte, None,
            WAIT_TIME_IN_CALL_FOR_IMS)
        self.tel_logger.set_result(result.result_value)
        if not result:
            raise signals.TestFailure("Failed",
                extras={"fail_reason": str(result.result_value)})


    @test_tracker_info(uuid="c06d6c81-ce26-474d-b41e-fcfe1ec6e761")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_to_volte_long(self):
        """ VoLTE to nsa 5G VoLTE call test

        1. Make Sure PhoneA is in LTE mode (with VoLTE).
        2. Make Sure PhoneB is in nsa 5G mode (with VoLTE).
        3. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.
        5. Call from PhoneB to PhoneA, accept on PhoneA, hang up on PhoneB.
        6. Call from PhoneB to PhoneA, accept on PhoneA, hang up on PhoneA.

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices
        if not provision_both_devices_for_volte(self.log, ads):
            return False

        if not provision_device_for_5g(self.log, ads[1]):
            return False

        result = two_phone_call_long_seq(
            self.log, ads[0], phone_idle_volte, is_phone_in_call_volte, ads[1],
            None, is_phone_in_call_volte, None,
            WAIT_TIME_IN_CALL_FOR_IMS)
        self.tel_logger.set_result(result.result_value)
        if not result:
            raise signals.TestFailure("Failed",
                extras={"fail_reason": str(result.result_value)})


    @test_tracker_info(uuid="3c45ab10-9e8c-4804-9f32-c775baa3d5e7")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_to_volte_loop(self):
        """ Stress test: VoLTE to nsa 5g VoLTE call test

        1. Make Sure PhoneA is in LTE mode (with VoLTE).
        2. Make Sure PhoneB is in nsa 5G mode (with VoLTE).
        3. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.
        5. Call from PhoneB to PhoneA, accept on PhoneA, hang up on PhoneB.
        6. Call from PhoneB to PhoneA, accept on PhoneA, hang up on PhoneA.
        7. Repeat step 3~6.

        Returns:
            True if pass; False if fail.
        """

        MINIMUM_SUCCESS_RATE = .95
        ads = self.android_devices

        if not provision_both_devices_for_volte(self.log, ads):
            return False

        if not provision_device_for_5g(self.log, ads[1]):
            return False

        success_count = 0
        fail_count = 0

        for i in range(1, self.stress_test_number + 1):

            if two_phone_call_long_seq(
                    self.log, ads[0], phone_idle_volte, is_phone_in_call_volte,
                    ads[1], None, is_phone_in_call_volte, None,
                    WAIT_TIME_IN_CALL_FOR_IMS):
                success_count += 1
                result_str = "Succeeded"

            else:
                fail_count += 1
                result_str = "Failed"

            self.log.info("Iteration %s %s. Current: %s / %s passed.", i,
                          result_str, success_count, self.stress_test_number)

        self.log.info("Final Count - Success: %s, Failure: %s - %s%",
                      success_count, fail_count,
                      str(100 * success_count / (success_count + fail_count)))
        if success_count / (
                success_count + fail_count) >= MINIMUM_SUCCESS_RATE:
            return True
        else:
            return False


    @test_tracker_info(uuid="875292c8-14f8-43aa-8770-3d0099da9c53")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_voicemail_indicator_volte(self):
        """Test Voice Mail notification in nsa 5G (VoLTE enabled).
        This script currently only works for TMO now.

        1. Make sure DUT (ads[0]) in nsa 5g VoLTE mode. Both PhoneB and DUT idle.
        2. Make call from PhoneB to DUT, reject on DUT.
        3. On PhoneB, leave a voice mail to DUT.
        4. Verify DUT receive voice mail notification.

        Returns:
            True if pass; False if fail.
        """
        ads = self.android_devices

        tasks = [(phone_setup_voice_general, (self.log, ads[1])),
                 (phone_setup_volte, (self.log, ads[0]))]
        if not multithread_func(self.log, tasks):
            self.log.error("Phone Failed to Set Up Properly.")
            return False

        if not provision_device_for_5g(self.log, ads[0]):
            return False

        if not call_voicemail_erase_all_pending_voicemail(self.log, ads[0]):
            self.log.error("Failed to clear voice mail.")
            return False

        return two_phone_call_leave_voice_mail(self.log, ads[1], None, None,
                                               ads[0], phone_idle_volte)


    @test_tracker_info(uuid="b866dcfa-f133-424d-bb5d-f381a1f63602")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_long_duration_volte(self):
        """ Test call drop rate for nsa 5g VoLTE long duration call.

        Steps:
        1. Setup nsa 5g VoLTE for DUT.
        2. Make nsa 5g VoLTE call from DUT to PhoneB.
        3. For <total_duration> time, check if DUT drop call or not.

        Expected Results:
        DUT should not drop call.

        Returns:
        False if DUT call dropped during test.
        Otherwise True.
        """
        ads = self.android_devices

        tasks = [(phone_setup_volte, (self.log, ads[0])),
                 (phone_setup_voice_general, (self.log, ads[1]))]
        if not multithread_func(self.log, tasks):
            self.log.error("Phone Failed to Set Up Properly.")
            return False

        if not provision_device_for_5g(self.log, ads[0]):
            return False

        return _test_call_long_duration(self.log, ads,
            is_phone_in_call_volte, self.long_call_duration)


    @test_tracker_info(uuid="527e6676-25c7-4adc-94e7-bb6d3b8f6c24")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_after_mobile_data_usage_limit_reached(self):
        """ VoLTE to VoLTE call test after mobile data usage limit reached

        1. Set the data limit to the current usage
        2. Make Sure PhoneA is in nsa 5G mode (with VoLTE).
        3. Make Sure PhoneB is in nsa 5G mode (with VoLTE).
        4. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneA.
        5. Call from PhoneA to PhoneB, accept on PhoneB, hang up on PhoneB.

        Raises:
            TestFailure if not success.
        """
        ads = self.android_devices
        try:
            subscriber_id = ads[0].droid.telephonyGetSubscriberId()
            data_usage = get_mobile_data_usage(ads[0], subscriber_id)
            set_mobile_data_usage_limit(ads[0], data_usage, subscriber_id)

            if not provision_device_for_5g(self.log, ads):
                self.log.error("Phone Failed to Set Up Properly.")
                self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
                raise signals.TestFailure("Failed",
                    extras={"fail_reason": "Phone Failed to Set Up Properly."})

            result = two_phone_call_short_seq(
                self.log, ads[0], None, is_phone_in_call_volte,
                ads[1], None, is_phone_in_call_volte, None,
                WAIT_TIME_IN_CALL_FOR_IMS)
            self.tel_logger.set_result(result.result_value)

            if not result:
                raise signals.TestFailure("Failed",
                    extras={"fail_reason": str(result.result_value)})
        finally:
            remove_mobile_data_usage_limit(ads[0], subscriber_id)


    @test_tracker_info(uuid="2c28a974-dc31-4f01-b555-d3e0a8374f37")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_volte_in_call_wifi_toggling(self):
        """ General voice to voice call.

        1. Make Sure PhoneA in nsa5G.
        2. Make Sure PhoneB in nsa5G.
        3. Call from PhoneA to PhoneB.
        4. Toggling Wifi connnection in call.
        5. Verify call is active.
        6. Hung up the call on PhoneA

        Returns:
            True if pass; False if fail.
        """
        ads = self.android_devices
        result = True

        if not provision_device_for_5g(self.log, ads):
                self.log.error("Phone Failed to Set Up Properly.")
                self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
                raise signals.TestFailure("Failed",
                    extras={"fail_reason": "Phone Failed to Set Up Properly."})

        if not call_setup_teardown(self.log, ads[0], ads[1], None, None, None,
                                   5):
            self.log.error("Call setup failed")
            return False
        else:
            self.log.info("Call setup succeed")

        if not wifi_cell_switching(self.log, ads[0], GEN_5G, self.wifi_network_ssid,
                                   self.wifi_network_pass):
            ads[0].log.error("Failed to do WIFI and Cell switch in call")
            result = False

        if not is_phone_in_call_active(ads[0]):
            return False
        else:
            if not ads[0].droid.telecomCallGetAudioState():
                ads[0].log.error("Audio is not on call")
                result = False
            else:
                ads[0].log.info("Audio is on call")
            hangup_call(self.log, ads[0])
            return result

    @test_tracker_info(uuid="95802175-06d5-4774-8ce8-fdf7922eca20")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mo_vowifi_in_active_youtube(self):
        """Test call can be established during active youtube video on 5G NSA.

        Turn off airplane mode, turn on wfc and wifi.
        Starting youtube video.
        Initiate a MO voice call. Verify call can be established.

        Returns:
            True if success.
            False if failed.
        """
        if not phone_setup_iwlan(self.log, self.android_devices[0], False,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            self.android_devices[0].log.error(
                "Failed to setup IWLAN with NON-APM WIFI WFC on")
            return False
        return test_call_setup_in_active_youtube_video(self.log,
                                                       self.android_devices,
                                                       GEN_5G,
                                                       DIRECTION_MOBILE_ORIGINATED)

    @test_tracker_info(uuid="f827a8b5-039c-4cc1-b030-78a09119acfc")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mt_vowifi_in_active_youtube(self):
        """Test call can be established during active youtube_video on 5G NSA.

        Turn off airplane mode, turn on wfc and wifi.
        Starting an youtube video.
        Initiate a MT voice call. Verify call can be established.

        Returns:
            True if success.
            False if failed.
        """
        if not phone_setup_iwlan(self.log, self.android_devices[0], False,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            self.android_devices[0].log.error(
                "Failed to setup iwlan with APM off and WIFI and WFC on")
            return False
        return test_call_setup_in_active_youtube_video(self.log,
                                                       self.android_devices,
                                                       GEN_5G,
                                                       DIRECTION_MOBILE_TERMINATED)

    @test_tracker_info(uuid="af3254d0-a84a-47c8-8ebc-11517b7b4944")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mo_vowifi_apm_in_active_data_transfer(self):
        """Test call can be established during active data connection on 5G NSA.

        Turn on wifi-calling, airplane mode and wifi.
        Starting downloading file from Internet.
        Initiate a MO voice call. Verify call can be established.
        Hangup Voice Call, verify file is downloaded successfully.

        Returns:
            True if success.
            False if failed.
        """
        if not provision_device_for_5g(self.log, self.android_devices[0]):
            self.android_devices[0].log.error("Phone not attached on 5G NSA before call.")
            return False

        if not phone_setup_iwlan(self.log, self.android_devices[0], True,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            self.android_devices[0].log.error(
                "Failed to setup iwlan with APM, WIFI and WFC on")
            return False
        return test_call_setup_in_active_data_transfer(self.log,
                                                       self.android_devices,
                                                       None,
                                                       DIRECTION_MOBILE_ORIGINATED)

    @test_tracker_info(uuid="5c58af94-8c24-481b-a555-bdbf36db5f6e")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mt_vowifi_apm_in_active_data_transfer(self):
        """Test call can be established during active data connection on 5G NSA.

        Turn on wifi-calling, airplane mode and wifi.
        Starting downloading file from Internet.
        Initiate a MT voice call. Verify call can be established.
        Hangup Voice Call, verify file is downloaded successfully.

        Returns:
            True if success.
            False if failed.
        """
        if not provision_device_for_5g(self.log, self.android_devices[0]):
            self.android_devices[0].log.error("Phone not attached on 5G NSA before call.")
            return False

        if not phone_setup_iwlan(self.log, self.android_devices[0], True,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            self.android_devices[0].log.error(
                "Failed to setup iwlan with APM, WIFI and WFC on")
            return False
        return test_call_setup_in_active_data_transfer(self.log,
                                                       self.android_devices,
                                                       None,
                                                       DIRECTION_MOBILE_TERMINATED)

    @test_tracker_info(uuid="bcd874ae-58e1-4954-88af-bb3dd54d4abf")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mo_vowifi_apm_in_active_youtube(self):
        """Test call can be established during active youtube video on 5G NSA.

        Turn on wifi-calling, airplane mode and wifi.
        Starting an youtube video.
        Initiate a MO voice call. Verify call can be established.

        Returns:
            True if success.
            False if failed.
        """
        if not provision_device_for_5g(self.log, self.android_devices[0]):
            self.android_devices[0].log.error("Phone not attached on 5G NSA before call.")
            return False

        if not phone_setup_iwlan(self.log, self.android_devices[0], True,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            self.android_devices[0].log.error(
                "Failed to setup iwlan with APM, WIFI and WFC on")
            return False
        return test_call_setup_in_active_youtube_video(self.log,
                                                       self.android_devices,
                                                       None,
                                                       DIRECTION_MOBILE_ORIGINATED)

    @test_tracker_info(uuid="ad96f1cf-0d17-4a39-86cf-cacb5f4cc81c")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_mt_vowifi_apm_in_active_youtube(self):
        """Test call can be established during active youtube video on 5G NSA.

        Turn on wifi-calling, airplane mode and wifi.
        Starting youtube video.
        Initiate a MT voice call. Verify call can be established.

        Returns:
            True if success.
            False if failed.
        """
        if not provision_device_for_5g(self.log, self.android_devices[0]):
            self.android_devices[0].log.error("Phone not attached on 5G NSA before call.")
            return False

        if not phone_setup_iwlan(self.log, self.android_devices[0], True,
                                 WFC_MODE_WIFI_PREFERRED,
                                 self.wifi_network_ssid,
                                 self.wifi_network_pass):
            self.android_devices[0].log.error(
                "Failed to setup iwlan with APM, WIFI and WFC on")
            return False
        return test_call_setup_in_active_youtube_video(self.log,
                                                       self.android_devices,
                                                       None,
                                                       DIRECTION_MOBILE_TERMINATED)

    @test_tracker_info(uuid="9d1121c1-aae4-428b-9167-09d4efdb7e37")
    @TelephonyBaseTest.tel_test_wrap
    def test_5g_nsa_call_wfc_in_call_wifi_toggling(self):
        """ General voice to voice call on 5G NSA. TMO Only Test

        1. Make Sure PhoneA in wfc with APM off.
        2. Make Sure PhoneB in Voice Capable.
        3. Call from PhoneA to PhoneB.
        4. Toggling Wifi connection in call.
        5. Verify call is active.
        6. Hung up the call on PhoneA

        Returns:
            True if pass; False if fail.
        """

        ads = self.android_devices

        if not provision_device_for_5g(self.log, ads):
            return False
        tasks = [(phone_setup_iwlan,
                  (self.log, ads[0], False, WFC_MODE_WIFI_PREFERRED,
                   self.wifi_network_ssid, self.wifi_network_pass)),
                 (phone_setup_voice_general, (self.log, ads[1]))]

        if not multithread_func(self.log, tasks):
            self.log.error("Phone Failed to Set Up Properly.")
            return False
        return test_wifi_cell_switching_in_call(self.log,
                                                ads,
                                                self.wifi_network_ssid,
                                                self.wifi_network_pass)

    """ Tests End """
