#!/usr/bin/env python3.4
#
#   Copyright 2022 - 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 Telephony Stress Call Test
"""

import collections
import json
import os
import random
import time

from acts import context
from acts import signals
from acts.libs.proc import job
from acts.test_decorators import test_tracker_info
from acts_contrib.test_utils.tel.loggers.telephony_metric_logger import TelephonyMetricLogger
from acts_contrib.test_utils.tel.loggers.telephony_stress_metric_logger import TelephonyStressMetricLogger
from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
from acts_contrib.test_utils.tel.tel_defines import GEN_3G
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
from acts_contrib.test_utils.tel.tel_defines import GOOGLE_CBRS_CARRIER_ID
from acts_contrib.test_utils.tel.tel_defines import GOOGLE_FI_CARRIER_ID
from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_WCDMA_ONLY
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GLOBAL
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_CDMA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_GSM_ONLY
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_TDSCDMA_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_AFTER_MODE_CHANGE
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_WIFI_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_MESSAGE_SUB_ID
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_VOICE_SUB_ID
from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
from acts_contrib.test_utils.tel.tel_logging_utils import extract_test_log
from acts_contrib.test_utils.tel.tel_logging_utils import start_qxdm_loggers
from acts_contrib.test_utils.tel.tel_logging_utils import start_sdm_loggers
from acts_contrib.test_utils.tel.tel_logging_utils import start_adb_tcpdump
from acts_contrib.test_utils.tel.tel_lookup_tables import is_rat_svd_capable
from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify
from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation_for_subscription
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_csfb
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_3g
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_2g
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_iwlan
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_idle_volte
from acts_contrib.test_utils.tel.tel_subscription_utils import get_subid_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import get_operatorname_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import get_carrierid_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import get_isopportunistic_from_slot_index
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_data
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_message
from acts_contrib.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call
from acts_contrib.test_utils.tel.tel_subscription_utils import set_always_allow_mms_data
from acts_contrib.test_utils.tel.tel_test_utils import STORY_LINE
from acts_contrib.test_utils.tel.tel_test_utils import force_connectivity_metrics_upload
from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
from acts_contrib.test_utils.tel.tel_test_utils import synchronize_device_time
from acts_contrib.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection_by_ping
from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
from acts_contrib.test_utils.tel.tel_data_utils import wait_for_data_connection
from acts_contrib.test_utils.tel.tel_test_utils import is_current_data_on_cbrs
from acts_contrib.test_utils.tel.tel_test_utils import check_voice_network_type
from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown
from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call
from acts_contrib.test_utils.tel.tel_voice_utils import hangup_call_by_adb
from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call
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_2g
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 last_call_drop_reason
from acts_contrib.test_utils.tel.tel_voice_utils import get_current_voice_rat
from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_id_clearing
from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_in_call_active
from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
from acts.utils import get_current_epoch_time
from acts.utils import rand_ascii_str
from acts.libs.utils.multithread import run_multithread_func

EXCEPTION_TOLERANCE = 5
BINDER_LOGS = ["/sys/kernel/debug/binder"]
DEFAULT_FILE_DOWNLOADS = ["1MB", "5MB", "10MB", "20MB", "50MB"]
RESULTS_LIST = {-2: "UNAVAILABLE_NETWORK_TYPE",
                -1: "CALL_SETUP_FAILURE",
                 0: "SUCCESS",
                 1: "INITIATE_FAILED",
                 2: "NO_RING_EVENT_OR_ANSWER_FAILED",
                 3: "NO_CALL_ID_FOUND",
                 4: "CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT",
                 5: "AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT",
                 6: "AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED",
                 7: "CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT",
                 8: "CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED",
                 9: "CALL_HANGUP_FAIL",
                 10: "CALL_ID_CLEANUP_FAIL"}


class TelLiveStressTest(TelephonyBaseTest):
    def setup_class(self):
        super(TelLiveStressTest, self).setup_class()
        self.dut = self.android_devices[0]
        self.single_phone_test = self.user_params.get("single_phone_test",
                                                      False)
        # supported file download methods: chrome, sl4a, curl
        self.file_download_method = self.user_params.get(
            "file_download_method", "curl")
        self.get_binder_logs = self.user_params.get("get_binder_logs", False)
        if len(self.android_devices) == 1:
            self.single_phone_test = True
        if self.single_phone_test:
            self.android_devices = self.android_devices[:1]
            self.call_server_number = self.user_params.get(
                "call_server_number", STORY_LINE)
            if self.file_download_method == "sl4a":
                # with single device, do not use sl4a file download
                # due to stability issue
                self.file_download_method = "curl"
        else:
            self.android_devices = self.android_devices[:2]
        self.sdm_log = self.user_params.get("sdm_log", False)
        for ad in self.android_devices:
            setattr(ad, "sdm_log", self.sdm_log)
            ad.adb.shell("setprop nfc.debug_enable 1")
            if self.user_params.get("turn_on_tcpdump", False):
                start_adb_tcpdump(ad, interface="any", mask="all")
        self.user_params["telephony_auto_rerun"] = 0
        self.phone_call_iteration = int(
            self.user_params.get("phone_call_iteration", 500))
        self.max_phone_call_duration = int(
            self.user_params.get("max_phone_call_duration", 600))
        self.min_sleep_time = int(self.user_params.get("min_sleep_time", 30))
        self.max_sleep_time = int(self.user_params.get("max_sleep_time", 60))
        self.max_run_time = int(self.user_params.get("max_run_time", 14400))
        self.max_sms_length = int(self.user_params.get("max_sms_length", 1000))
        self.max_mms_length = int(self.user_params.get("max_mms_length", 160))
        self.min_sms_length = int(self.user_params.get("min_sms_length", 1))
        self.min_mms_length = int(self.user_params.get("min_mms_length", 1))
        self.min_phone_call_duration = int(
            self.user_params.get("min_phone_call_duration", 10))
        self.crash_check_interval = int(
            self.user_params.get("crash_check_interval", 300))
        self.cbrs_check_interval = int(
            self.user_params.get("cbrs_check_interval", 100))
        self.dut_incall = False
        self.dsds_esim = self.user_params.get("dsds_esim", False)
        self.cbrs_esim = self.user_params.get("cbrs_esim", False)
        telephony_info = getattr(self.dut, "telephony", {})
        self.dut_capabilities = telephony_info.get("capabilities", [])
        self.dut_wfc_modes = telephony_info.get("wfc_modes", [])
        self.gps_log_file = self.user_params.get("gps_log_file", None)
        self.file_name_list = self.user_params.get("file_downloads", DEFAULT_FILE_DOWNLOADS)
        self.tel_logger = TelephonyMetricLogger.for_test_case()
        self.tel_logger = TelephonyStressMetricLogger.for_test_case()
        self.result_collection = {"UNAVAILABLE_NETWORK_TYPE" : 0,
                                  "CALL_SETUP_FAILURE" : 0,
                                  "SUCCESS" : 0,
                                  "INITIATE_FAILED" : 0,
                                  "NO_RING_EVENT_OR_ANSWER_FAILED" : 0,
                                  "NO_CALL_ID_FOUND" : 0,
                                  "CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT" : 0,
                                  "AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT" : 0,
                                  "AUDIO_STATE_NOT_INCALL_AFTER_CONNECTED" : 0,
                                  "CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT" : 0,
                                  "CALL_DROP_OR_WRONG_STATE_AFTER_CONNECTED": 0,
                                  "CALL_HANGUP_FAIL": 0,
                                  "CALL_ID_CLEANUP_FAIL": 0 }
        self.call_stats_check = self.user_params.get("call_stats_check", False)
        self.nsa_5g_for_stress = self.user_params.get("nsa_5g_for_stress", False)
        self.nr_type = self.user_params.get("nr_type", 'nsa')
        return True

    def setup_test(self):
        super(TelLiveStressTest, self).setup_test()
        self.result_info = collections.defaultdict(int)
        self._init_perf_json()
        self.internet_connection_check_method = verify_internet_connection

    def on_fail(self, test_name, begin_time):
        pass

    def _take_bug_report(self, test_name, begin_time):
        if self._skip_bug_report(test_name):
            return
        src_dir = context.get_current_context().get_full_output_path()
        dst_dir = os.path.join(self.log_path, test_name)

        # Extract test_run_info.txt, test_run_debug.txt
        for file_name in ("test_run_info.txt", "test_run_debug.txt"):
            extract_test_log(self.log, os.path.join(src_dir, file_name),
                             os.path.join(dst_dir,
                                          "%s_%s" % (test_name, file_name)),
                             "\[Test Case\] %s " % test_name)
        super()._take_bug_report(test_name, begin_time)

    def _ad_take_extra_logs(self, ad, test_name, begin_time):
        src_file = os.path.join(ad.device_log_path,
                                'adblog_%s_debug.txt' % ad.serial)
        dst_file = os.path.join(ad.device_log_path, test_name,
                                "%s_%s.logcat" % (ad.serial, test_name))
        extract_test_log(self.log, src_file, dst_file, test_name)
        return super()._ad_take_extra_logs(ad, test_name, begin_time)

    def _setup_wfc(self):
        for ad in self.android_devices:
            if not ensure_wifi_connected(
                    self.log,
                    ad,
                    self.wifi_network_ssid,
                    self.wifi_network_pass,
                    retries=3):
                ad.log.error("Bringing up Wifi connection fails.")
                return False
            ad.log.info("Phone WIFI is connected successfully.")
            if not set_wfc_mode(self.log, ad, WFC_MODE_WIFI_PREFERRED):
                ad.log.error("Phone failed to enable Wifi-Calling.")
                return False
            ad.log.info("Phone is set in Wifi-Calling successfully.")
            if not phone_idle_iwlan(self.log, ad):
                ad.log.error("Phone is not in WFC enabled state.")
                return False
            ad.log.info("Phone is in WFC enabled state.")
        return True

    def _setup_wfc_apm(self):
        for ad in self.android_devices:
            if not phone_setup_iwlan(
                    self.log, ad, True, WFC_MODE_CELLULAR_PREFERRED,
                    self.wifi_network_ssid, self.wifi_network_pass):
                ad.log.error("Failed to setup WFC.")
                return False
        return True

    def _setup_lte_volte_enabled(self):
        for ad in self.android_devices:
            if not phone_setup_volte(self.log, ad):
                ad.log.error("Phone failed to enable VoLTE.")
                return False
            ad.log.info("Phone VOLTE is enabled successfully.")
            # TODO: b/186865335 Move 5G methods to NR directory
            if self.nsa_5g_for_stress:
                if not provision_device_for_5g(self.log, ad):
                    ad.log.error("Phone failed to attach 5G NSA.")
                    return False
                ad.log.info("Phone 5G NSA VOLTE is enabled successfully.")
        return True

    def _setup_lte_volte_disabled(self):
        for ad in self.android_devices:
            if not phone_setup_csfb(self.log, ad):
                ad.log.error("Phone failed to setup CSFB.")
                return False
            ad.log.info("Phone VOLTE is disabled successfully.")
        return True

    def _setup_3g(self):
        for ad in self.android_devices:
            if not phone_setup_voice_3g(self.log, ad):
                ad.log.error("Phone failed to setup 3g.")
                return False
            ad.log.info("Phone RAT 3G is enabled successfully.")
        return True

    def _setup_2g(self):
        for ad in self.android_devices:
            if not phone_setup_voice_2g(self.log, ad):
                ad.log.error("Phone failed to setup 2g.")
                return False
            ad.log.info("RAT 2G is enabled successfully.")
        return True

    def _get_network_rat(self, slot_id):
        rat = self.dut.adb.getprop("gsm.network.type")
        if "," in rat:
            if self.dsds_esim:
                rat = rat.split(',')[slot_id]
            else:
                (rat1, rat2) = rat.split(',')
                if rat1 == "Unknown":
                    rat = rat2
                else:
                    rat = rat1
        return rat

    def _send_message(self, max_wait_time=2 * MAX_WAIT_TIME_SMS_RECEIVE):
        slot_id_rx = None
        if self.single_phone_test:
            ads = [self.dut, self.dut]
        else:
            ads = self.android_devices[:]
            random.shuffle(ads)
        slot_id = random.randint(0,1)
        if self.dsds_esim:
            sub_id = get_subid_from_slot_index(self.log, ads[0], slot_id)
            ads[0].log.info("Message - MO - slot_Id %d", slot_id)
            set_subid_for_message(ads[0], sub_id)
            time.sleep(WAIT_TIME_CHANGE_MESSAGE_SUB_ID)
            slot_id_rx = random.randint(0,1)
            ads[1].log.info("Message - MT - slot_id %d", slot_id_rx)
        selection = random.randrange(0, 2)
        message_type_map = {0: "SMS", 1: "MMS"}
        max_length_map = {0: self.max_sms_length, 1: self.max_mms_length}
        min_length_map = {0: self.min_sms_length, 1: self.min_mms_length}
        length = random.randrange(min_length_map[selection],
                                  max_length_map[selection] + 1)
        message_func_map = {
            0: sms_send_receive_verify,
            1: mms_send_receive_verify
        }
        rat = self._get_network_rat(slot_id)
        self.dut.log.info("Network in RAT %s", rat)
        if self.dut_incall and not is_rat_svd_capable(rat.upper()):
            self.dut.log.info("In call data not supported, test SMS only")
            selection = 0
        message_type = message_type_map[selection]
        the_number = self.result_info["%s Total" % message_type] + 1
        begin_time = get_device_epoch_time(self.dut)
        test_name = "%s_No_%s_%s" % (self.test_name, the_number, message_type)
        if self.sdm_log:
            start_sdm_loggers(self.log, self.android_devices)
        else:
            start_qxdm_loggers(self.log, self.android_devices)
        log_msg = "[Test Case] %s" % test_name
        self.log.info("%s begin", log_msg)
        for ad in self.android_devices:
            if self.user_params.get("turn_on_tcpdump", False):
                start_adb_tcpdump(ad, interface="any", mask="all")
            if not getattr(ad, "messaging_droid", None):
                ad.messaging_droid, ad.messaging_ed = ad.get_droid()
                ad.messaging_ed.start()
            else:
                try:
                    if not ad.messaging_droid.is_live:
                        ad.messaging_droid, ad.messaging_ed = ad.get_droid()
                        ad.messaging_ed.start()
                    else:
                        ad.messaging_ed.clear_all_events()
                except Exception:
                    ad.log.info("Create new sl4a session for messaging")
                    ad.messaging_droid, ad.messaging_ed = ad.get_droid()
                    ad.messaging_ed.start()
            ad.messaging_droid.logI("[BEGIN]%s" % log_msg)

        text = "%s:" % test_name
        text_length = len(text)
        if length < text_length:
            text = text[:length]
        else:
            text += rand_ascii_str(length - text_length)
        message_content_map = {0: [text], 1: [(test_name, text, None)]}

        result = message_func_map[selection](self.log, ads[0], ads[1],
                                             message_content_map[selection],
                                             max_wait_time,
                                             slot_id_rx=slot_id_rx)
        self.log.info("%s end", log_msg)
        for ad in self.android_devices:
            ad.messaging_droid.logI("[END]%s" % log_msg)
        if not result:
            self.result_info["%s Total" % message_type] += 1
            if message_type == "SMS":
                self.log.error("%s fails", log_msg)
                self.result_info["%s Failure" % message_type] += 1
            else:
                rat = self._get_network_rat(slot_id)
                self.dut.log.info("Network in RAT %s", rat)
                if self.dut_incall and not is_rat_svd_capable(rat.upper()):
                    self.dut.log.info(
                        "In call data not supported, MMS failure expected")
                    self.result_info["Expected In-call MMS failure"] += 1
                    return True
                else:
                    self.log.error("%s fails", log_msg)
                    self.result_info["MMS Failure"] += 1
            try:
                self._take_bug_report(test_name, begin_time)
            except Exception as e:
                self.log.exception(e)
            return False
        else:
            self.result_info["%s Total" % message_type] += 1
            self.log.info("%s succeed", log_msg)
            self.result_info["%s Success" % message_type] += 1
            return True

    def _make_phone_call(self, call_verification_func=None, voice_stress_only = False):
        ads = self.android_devices[:]
        slot_id_callee = None
        if not voice_stress_only:
            if not self.single_phone_test:
                random.shuffle(ads)
        if self.dsds_esim:
            slot_id = random.randint(0,1)
            sub_id = get_subid_from_slot_index(self.log, ads[0], slot_id)
            ads[0].log.info("Voice - MO - slot_Id %d", slot_id)
            set_subid_for_outgoing_call(ads[0], sub_id)
            time.sleep(WAIT_TIME_CHANGE_VOICE_SUB_ID)
            slot_id_callee = random.randint(0,1)
            ads[1].log.info("Voice - MT - slot_id %d", slot_id_callee)
        the_number = self.result_info["Call Total"] + 1
        if voice_stress_only:
            duration = 30
        else:
            duration = random.randrange(self.min_phone_call_duration,
                                    self.max_phone_call_duration)
        result = True
        test_name = "%s_No_%s_phone_call" % (self.test_name, the_number)
        log_msg = "[Test Case] %s" % test_name
        self.log.info("%s for %s seconds begin", log_msg, duration)

        if self.call_stats_check:
            voice_type_init = check_voice_network_type(ads, voice_init=True)
        else:
            voice_type_init = None

        begin_time = get_device_epoch_time(ads[0])
        for ad in self.android_devices:
            if self.user_params.get("turn_on_tcpdump", False):
                start_adb_tcpdump(ad, interface="any", mask="all")
            if not getattr(ad, "droid", None):
                ad.droid, ad.ed = ad.get_droid()
                ad.ed.start()
            else:
                try:
                    if not ad.droid.is_live:
                        ad.droid, ad.ed = ad.get_droid()
                        ad.ed.start()
                    else:
                        ad.ed.clear_all_events()
                except Exception:
                    ad.log.info("Create new sl4a session for phone call")
                    ad.droid, ad.ed = ad.get_droid()
                    ad.ed.start()
            ad.droid.logI("[BEGIN]%s" % log_msg)
        if self.sdm_log:
            for ad in ads:
                ad.adb.shell("i2cset -fy 3 64 6 1 b", ignore_status=True)
                ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True)
            start_sdm_loggers(self.log, self.android_devices)
        else:
            start_qxdm_loggers(self.log, self.android_devices)
        if self.cbrs_esim:
            self._cbrs_data_check_test(begin_time, expected_cbrs=True,
                                       test_time="before")
        failure_reasons = set()
        self.dut_incall = True
        if self.single_phone_test:
            call_setup_result = initiate_call(
                self.log,
                self.dut,
                self.call_server_number,
                incall_ui_display=INCALL_UI_DISPLAY_BACKGROUND,
                call_stats_check=self.call_stats_check,
                voice_type_init=voice_type_init,
                result_info = self.result_info,
                nw_gen_5g=self.nsa_5g_for_stress,
                nr_type= self.nr_type
            ) and wait_for_in_call_active(self.dut, 60, 3)
        else:
            call_setup_result = call_setup_teardown(
                self.log,
                ads[0],
                ads[1],
                ad_hangup=None,
                verify_caller_func=call_verification_func,
                verify_callee_func=call_verification_func,
                wait_time_in_call=0,
                incall_ui_display=INCALL_UI_DISPLAY_BACKGROUND,
                slot_id_callee=slot_id_callee,
                call_stats_check=self.call_stats_check,
                voice_type_init=voice_type_init,
                result_info = self.result_info,
                nsa_5g_for_stress=self.nsa_5g_for_stress,
                nr_type= self.nr_type)
            self.result_collection[RESULTS_LIST[call_setup_result.result_value]] += 1

        if not call_setup_result:
            get_telephony_signal_strength(ads[0])
            if not self.single_phone_test:
                get_telephony_signal_strength(ads[1])
            call_logs = ads[0].search_logcat(
                "ActivityManager: START u0 {act=android.intent.action.CALL",
                begin_time)
            messaging_logs = ads[0].search_logcat(
                "com.google.android.apps.messaging/.ui.conversation.ConversationActivity",
                begin_time)
            if call_logs and messaging_logs:
                if (messaging_logs[-1]["datetime_obj"] -
                        call_logs[-1]["datetime_obj"]).seconds < 5:
                    ads[0].log.info(
                        "Call setup failure due to simultaneous activities")
                    self.result_info[
                        "Call Setup Failure With Simultaneous Activity"] += 1
                    return True
            self.log.error("%s: Setup Call failed.", log_msg)
            failure_reasons.add("Setup")
            result = False
        else:
            elapsed_time = 0
            check_interval = 5
            if self.sdm_log:
                for ad in ads:
                    ad.adb.shell("i2cset -fy 3 64 6 1 b", ignore_status=True)
                    ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True)
            if self.cbrs_esim:
                time.sleep(5)
                self._cbrs_data_check_test(begin_time, expected_cbrs=False,
                                           test_time="during")
            while (elapsed_time < duration):
                check_interval = min(check_interval, duration - elapsed_time)
                time.sleep(check_interval)
                elapsed_time += check_interval
                time_message = "at <%s>/<%s> second." % (elapsed_time,
                                                         duration)
                for ad in ads:
                    get_telephony_signal_strength(ad)
                    if not call_verification_func(self.log, ad):
                        ad.log.warning("Call is NOT in correct %s state at %s",
                                       call_verification_func.__name__,
                                       time_message)
                        if call_verification_func.__name__ == "is_phone_in_call_iwlan":
                            if is_phone_in_call(self.log, ad):
                                if getattr(ad, "data_rat_state_error_count",
                                           0) < 1:
                                    setattr(ad, "data_rat_state_error_count",
                                            1)
                                    continue
                        failure_reasons.add("Maintenance")
                        last_call_drop_reason(ad, begin_time)
                        hangup_call(self.log, ads[0])
                        result = False
                    else:
                        ad.log.info("Call is in correct %s state at %s",
                                    call_verification_func.__name__,
                                    time_message)
                if not result:
                    break
        if not hangup_call(self.log, ads[0]):
            failure_reasons.add("Teardown")
            result = False
        for ad in ads:
            if not wait_for_call_id_clearing(ad,
                                             []) or ad.droid.telecomIsInCall():
                ad.log.error("Fail to hang up call")
                failure_reasons.add("Teardown")
                result = False
        self.result_info["Call Total"] += 1
        for ad in self.android_devices:
            try:
                ad.droid.logI("[END]%s" % log_msg)
            except:
                pass
        self.log.info("%s end", log_msg)
        self.dut_incall = False
        if self.cbrs_esim:
            time.sleep(30)
            self._cbrs_data_check_test(begin_time, expected_cbrs=True,
                                       test_time="after")
        if not result:
            self.log.info("%s failed", log_msg)
            if self.gps_log_file:
                gps_info = job.run(
                    "tail %s" % self.gps_log_file, ignore_status=True)
                if gps_info.stdout:
                    gps_log_path = os.path.join(self.log_path, test_name)
                    os.makedirs(gps_log_path, exist_ok=True)
                    job.run(
                        "tail %s > %s" %
                        (self.gps_log_file,
                         os.path.join(gps_log_path, "gps_logs.txt")),
                        ignore_status=True)
                    self.log.info("gps log:\n%s", gps_info.stdout)
                else:
                    self.log.warning("Fail to get gps log %s",
                                     self.user_params["gps_log_file"])
            for reason in failure_reasons:
                self.result_info["Call %s Failure" % reason] += 1
            for ad in ads:
                log_path = os.path.join(self.log_path, test_name,
                                        "%s_binder_logs" % ad.serial)
                os.makedirs(log_path, exist_ok=True)
                ad.pull_files(BINDER_LOGS, log_path)
            try:
                self._take_bug_report(test_name, begin_time)
            except Exception as e:
                self.log.exception(e)
            for ad in ads:
                if ad.droid.telecomIsInCall():
                    hangup_call_by_adb(ad)
        else:
            self.log.info("%s test succeed", log_msg)
            self.result_info["Call Success"] += 1
            if self.result_info["Call Total"] % 50 == 0:
                for ad in ads:
                    synchronize_device_time(ad)
                    force_connectivity_metrics_upload(ad)
                    if self.get_binder_logs:
                        log_path = os.path.join(self.log_path, test_name,
                                                "%s_binder_logs" % ad.serial)
                        os.makedirs(log_path, exist_ok=True)
                        ad.pull_files(BINDER_LOGS, log_path)
        return result

    def _prefnetwork_mode_change(self, sub_id):
        # ModePref change to non-LTE
        begin_time = get_device_epoch_time(self.dut)
        if self.sdm_log:
            start_sdm_loggers(self.log, self.android_devices)
        else:
            start_qxdm_loggers(self.log, self.android_devices)
        self.result_info["Network Change Request Total"] += 1
        test_name = "%s_network_change_iter_%s" % (
            self.test_name, self.result_info["Network Change Request Total"])
        log_msg = "[Test Case] %s" % test_name
        self.log.info("%s begin", log_msg)
        self.dut.droid.logI("[BEGIN]%s" % log_msg)
        network_preference_list = [
            NETWORK_MODE_TDSCDMA_GSM_WCDMA, NETWORK_MODE_WCDMA_ONLY,
            NETWORK_MODE_GLOBAL, NETWORK_MODE_CDMA, NETWORK_MODE_GSM_ONLY
        ]
        network_preference = random.choice(network_preference_list)
        set_preferred_network_mode_pref(self.log, self.dut, sub_id,
                                        network_preference)
        time.sleep(WAIT_TIME_AFTER_MODE_CHANGE)
        self.dut.log.info("Current Voice RAT is %s",
                          get_current_voice_rat(self.log, self.dut))

        # ModePref change back to with LTE
        if not phone_setup_volte(self.log, self.dut):
            self.dut.log.error("Phone failed to enable VoLTE.")
            self.result_info["VoLTE Setup Failure"] += 1
            self.dut.droid.logI("%s end" % log_msg)
            self.dut.log.info("[END]%s", log_msg)
            try:
                self._ad_take_extra_logs(self.dut, test_name, begin_time)
                self._ad_take_bugreport(self.dut, test_name, begin_time)
            except Exception as e:
                self.log.exception(e)
            return False
        else:
            self.result_info["VoLTE Setup Success"] += 1
            return True

    def _mobile_data_toggling(self, setup="volte"):
        # ModePref change to non-LTE
        begin_time = get_device_epoch_time(self.dut)
        if self.sdm_log:
            start_sdm_loggers(self.log, self.android_devices)
        else:
            start_qxdm_loggers(self.log, self.android_devices)
        result = True
        self.result_info["Data Toggling Request Total"] += 1
        test_name = "%s_data_toggling_iter_%s" % (
            self.test_name, self.result_info["Data Toggling Request Total"])
        log_msg = "[Test Case] %s" % test_name
        self.log.info("%s begin", log_msg)
        self.dut.droid.logI("[BEGIN]%s" % log_msg)
        self.dut.adb.shell("svc data disable")
        time.sleep(WAIT_TIME_AFTER_MODE_CHANGE)
        self.dut.adb.shell("svc data enable")
        if not self._check_data():
            result = False
        elif setup == "volte" and not phone_idle_volte(self.log, self.dut):
            result = False
        self.dut.droid.logI("%s end" % log_msg)
        self.dut.log.info("[END]%s", log_msg)
        if not result:
            self.result_info["Data Toggling Failure"] += 1
            try:
                self._ad_take_extra_logs(self.dut, test_name, begin_time)
                self._ad_take_bugreport(self.dut, test_name, begin_time)
            except Exception as e:
                self.log.exception(e)
            return False
        else:
            self.result_info["Data Toggling Success"] += 1
            return True

    def _get_result_message(self):
        msg_list = [
            "%s: %s" % (count, self.result_info[count])
            for count in sorted(self.result_info.keys())
        ]
        return ", ".join(msg_list)

    def _write_perf_json(self):
        json_str = json.dumps(self.perf_data, indent=4, sort_keys=True)
        with open(self.perf_file, 'w') as f:
            f.write(json_str)

    def _init_perf_json(self):
        self.perf_file = os.path.join(self.log_path, "%s_perf_data_%s.json" %
                                      (self.test_name, self.begin_time))
        self.perf_data = self.dut.build_info.copy()
        self.perf_data["build_fingerprint"] = self.dut.adb.getprop(
            "ro.build.fingerprint")
        self.perf_data["model"] = self.dut.model
        self.perf_data["carrier"] = self.dut.adb.getprop(
            "gsm.sim.operator.alpha")
        self._write_perf_json()

    def _update_perf_json(self):
        for result_key, result_value in self.result_info.items():
            self.perf_data[result_key] = result_value
        self._write_perf_json()

    def crash_check_test(self):
        failure = 0
        while time.time() < self.finishing_time:
            try:
                self.log.info(dict(self.result_info))
                self._update_perf_json()
                begin_time = get_device_epoch_time(self.dut)
                run_time_in_seconds = (begin_time - self.begin_time) / 1000
                test_name = "%s_crash_%s_seconds_after_start" % (
                    self.test_name, run_time_in_seconds)
                time.sleep(self.crash_check_interval)
                for ad in self.android_devices:
                    crash_report = ad.check_crash_report(
                        test_name, begin_time, log_crash_report=True)
                    if crash_report:
                        ad.log.error("Find new crash reports %s", crash_report)
                        failure += 1
                        self.result_info["Crashes"] += len(crash_report)
                        for crash in crash_report:
                            if "ramdump_modem" in crash:
                                self.result_info["Crashes-Modem"] += 1
                        try:
                            ad.take_bug_report(test_name, begin_time)
                        except Exception as e:
                            self.log.exception(e)
            except Exception as e:
                self.log.error("Exception error %s", str(e))
                self.result_info["Exception Errors"] += 1
            self.log.info("Crashes found: %s", failure)
            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
                self.log.error("Too many exception errors, quit test")
                return False
        if failure:
            return False
        else:
            return True

    def _cbrs_data_check_test(self, begin_time, expected_cbrs=True,
                              test_time="before"):
        cbrs_fail_count = 0
        the_number = self.result_info["CBRS Total"] + 1
        test_name = "%s_cbrs_%s_call_No_%s" % (self.test_name,
                                               test_time, the_number)
        for ad in self.android_devices:
            current_state = is_current_data_on_cbrs(ad, ad.cbrs)
            if current_state == expected_cbrs:
                self.result_info["CBRS-Check-Pass"] += 1
            else:
                self.result_info["CBRS-Check-Fail"] += 1
                cbrs_fail_count += 1
                try:
                    self._ad_take_extra_logs(ad, test_name, begin_time)
                    self._ad_take_bugreport(ad, test_name, begin_time)
                except Exception as e:
                    self.log.warning(e)
        if cbrs_fail_count > 0:
            ad.log.error("Found %d checks failed, expected cbrs %s",
                         cbrs_fail_count, expected_cbrs)
            cbrs_fail_count += 1
        self.result_info["CBRS Total"] += 1
        return True

    def call_test(self, call_verification_func=None):
        while time.time() < self.finishing_time:
            time.sleep(
                random.randrange(self.min_sleep_time, self.max_sleep_time))
            try:
                self._make_phone_call(call_verification_func)
            except Exception as e:
                self.log.exception("Exception error %s", str(e))
                self.result_info["Exception Errors"] += 1
            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
                self.log.error("Too many exception errors, quit test")
                return False
            self.log.info("%s", dict(self.result_info))
        self.tel_logger.set_result(self.result_collection)
        if any([
                self.result_info["Call Setup Failure"],
                self.result_info["Call Maintenance Failure"],
                self.result_info["Call Teardown Failure"]
        ]):
            return False
        else:
            return True

    def message_test(self, max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
        while time.time() < self.finishing_time:
            try:
                self._send_message(max_wait_time=max_wait_time)
            except Exception as e:
                self.log.exception("Exception error %s", str(e))
                self.result_info["Exception Errors"] += 1
            self.log.info(dict(self.result_info))
            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
                self.log.error("Too many exception errors, quit test")
                return False
            time.sleep(
                random.randrange(self.min_sleep_time, self.max_sleep_time))
        if self.result_info["SMS Failure"] or (
                self.result_info["MMS Failure"] / self.result_info["MMS Total"]
                > 0.3):
            return False
        else:
            return True

    def _data_download(self, file_names=[]):
        begin_time = get_current_epoch_time()
        slot_id = random.randint(0,1)
        if self.dsds_esim:
            sub_id = get_subid_from_slot_index(self.log, self.dut, slot_id)
            self.dut.log.info("Data - slot_Id %d", slot_id)
            set_subid_for_data(self.dut, sub_id)
            self.dut.droid.telephonyToggleDataConnection(True)
        if self.sdm_log:
            start_sdm_loggers(self.log, self.android_devices)
        else:
            start_qxdm_loggers(self.log, self.android_devices)
        self.dut.log.info(dict(self.result_info))
        selection = random.randrange(0, len(file_names))
        file_name = file_names[selection]
        self.result_info["Internet Connection Check Total"] += 1

        rat = self._get_network_rat(slot_id)
        if not self.internet_connection_check_method(self.log, self.dut):
            self.dut.log.info("Network in RAT %s", rat)
            if self.dut_incall and not is_rat_svd_capable(rat.upper()):
                self.result_info[
                    "Expected Incall Internet Connection Check Failure"] += 1
                return True
            else:
                self.result_info["Internet Connection Check Failure"] += 1
                test_name = "%s_internet_connection_No_%s_failure" % (
                    self.test_name,
                    self.result_info["Internet Connection Check Failure"])
                try:
                    self._ad_take_extra_logs(self.dut, test_name, begin_time)
                    self._ad_take_bugreport(self.dut, test_name, begin_time)
                except Exception as e:
                    self.log.exception(e)
                return False
        else:
            self.result_info["Internet Connection Check Success"] += 1

        self.result_info["File Download Total"] += 1
        self.result_info["Data Download Total"] += int(file_name[:-2])
        if not active_file_download_test(
                self.log, self.dut, file_name,
                method=self.file_download_method):
            self.result_info["File Download Failure"] += 1
            self.result_info["Data Failure Total"] += int(file_name[:-2])
            if self.result_info["File Download Failure"] == 1:
                try:
                    self._ad_take_extra_logs(
                        self.dut, "%s_file_download_failure" % self.test_name,
                        begin_time)
                    self._ad_take_bugreport(
                        self.dut, "%s_file_download_failure" % self.test_name,
                        begin_time)
                except Exception as e:
                    self.log.exception(e)
            return False
        else:
            self.result_info["File Download Success"] += 1
            self.result_info["Data Success Total"] += int(file_name[:-2])
            return True

    def data_test(self):
        while time.time() < self.finishing_time:
            try:
                self._data_download(self.file_name_list)
            except Exception as e:
                self.log.error("Exception error %s", str(e))
                self.result_info["Exception Errors"] += 1
            self.log.info("%s", dict(self.result_info))
            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
                self.log.error("Too many exception errors, quit test")
                return False
            time.sleep(
                random.randrange(self.min_sleep_time, self.max_sleep_time))
        if self.result_info["Internet Connection Check Failure"]:
            return False
        else:
            return True

    def _check_data(self):
        self.result_info["Data Connection Check Total"] += 1
        if not wait_for_data_connection(self.log, self.dut, True):
            self.result_info["Data Connection Setup Failure"] += 1
            return False
        if not self.internet_connection_check_method(self.log, self.dut):
            rat = self.dut.adb.getprop("gsm.network.type")
            self.dut.log.info("Network in RAT %s", rat)
            self.result_info["Internet Connection Check Failure"] += 1
            return False
        return True

    def _data_call_test(self, sub_id, generation):
        self.dut.log.info(dict(self.result_info))
        begin_time = get_device_epoch_time(self.dut)
        if self.sdm_log:
            start_sdm_loggers(self.log, self.android_devices)
        else:
            start_qxdm_loggers(self.log, self.android_devices)
        self.result_info["Network Change Request Total"] += 1
        test_name = "%s_network_change_test_iter_%s" % (
            self.test_name, self.result_info["Network Change Request Total"])
        log_msg = "[Test Case] %s" % test_name
        self.log.info("%s begin", log_msg)
        self.dut.droid.logI("[BEGIN]%s" % log_msg)
        if not ensure_network_generation_for_subscription(
                self.log, self.dut, sub_id,
                generation) or not self._check_data():
            self.result_info["Network Change Failure"] += 1
            self.dut.droid.logI("%s end" % log_msg)
            self.dut.log.info("[END]%s", log_msg)
            try:
                self._ad_take_extra_logs(self.dut, test_name, begin_time)
                self._ad_take_bugreport(self.dut, test_name, begin_time)
            except Exception as e:
                self.log.warning(e)
            return False
        if not self._mobile_data_toggling(setup=None):
            return False
        return True

    def data_call_stress_test(self):
        result = True
        sub_id = self.dut.droid.subscriptionGetDefaultSubId()
        while time.time() < self.finishing_time:
            for generation in (GEN_4G, GEN_3G):
                try:
                    if not self._data_call_test(sub_id, generation):
                        result = False
                except Exception as e:
                    self.log.error("Exception error %s", str(e))
                    self.result_info["Exception Errors"] += 1
            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
                self.log.error("Too many exception errors, quit test")
                return False
        return result

    def check_incall_data(self):
        if verify_internet_connection_by_ping(self.log, self.dut):
            self.internet_connection_check_method = verify_internet_connection_by_ping
        elif verify_http_connection(self.log, self.dut):
            self.internet_connection_check_method = verify_http_connection
        else:
            self.dut.log.error("Data test failed")
            raise signals.TestFailure("Data check failed")
        if self.single_phone_test:
            if not initiate_call(
                    self.log, self.dut,
                    self.call_server_number) and wait_for_in_call_active(
                        self.dut, 60, 3):
                self._take_bug_report(self.test_name, self.begin_time)
                raise signals.TestFailure("Unable to make phone call")
        else:
            if not call_setup_teardown(
                    self.log, self.dut, self.android_devices[1],
                    ad_hangup=None):
                self._take_bug_report(self.test_name, self.begin_time)
                raise signals.TestFailure("Unable to make phone call")
        voice_rat = self.dut.droid.telephonyGetCurrentVoiceNetworkType()
        data_rat = self.dut.droid.telephonyGetCurrentDataNetworkType()
        self.dut.log.info("Voice in RAT %s, Data in RAT %s", voice_rat,
                          data_rat)
        try:
            if "wfc" in self.test_name or is_rat_svd_capable(
                    voice_rat.upper()) and is_rat_svd_capable(
                        data_rat.upper()):
                self.dut.log.info("Capable for simultaneous voice and data")

                if not self.internet_connection_check_method(
                        self.log, self.dut):
                    self.dut.log.error("Incall data check failed")
                    raise signals.TestFailure("Incall data check failed")
                else:
                    return True
            else:
                self.dut.log.info(
                    "Not capable for simultaneous voice and data")
                return False
            hangup_call(self.log, self.dut)
        finally:
            for ad in self.android_devices:
                if ad.droid.telecomIsInCall():
                    hangup_call(self.log, ad)

    def parallel_tests(self, setup_func=None, call_verification_func=None):
        self.log.info(self._get_result_message())
        if setup_func and not setup_func():
            msg = "%s setup %s failed" % (self.test_name, setup_func.__name__)
            self.log.error(msg)
            self._take_bug_report("%s%s" % (self.test_name,
                                            setup_func.__name__),
                                  self.begin_time)
            return False
        if not call_verification_func:
            call_verification_func = is_phone_in_call
        self.finishing_time = time.time() + self.max_run_time
        # CBRS setup
        if self.cbrs_esim:
            cbrs_sub_count = 0
            for ad in self.android_devices:
                if not getattr(ad, 'cbrs', {}):
                    setattr(ad, 'cbrs', None)
                for i in range(0, 2):
                    sub_id = get_subid_from_slot_index(ad.log, ad, i)
                    operator = get_operatorname_from_slot_index(ad, i)
                    carrier_id = get_carrierid_from_slot_index(ad, i)
                    is_opportunistic = get_isopportunistic_from_slot_index(ad, i)
                    ad.log.info("Slot %d - Sub %s - %s - %d", i, sub_id, operator, carrier_id)
                    if carrier_id == GOOGLE_CBRS_CARRIER_ID or (carrier_id == GOOGLE_FI_CARRIER_ID and is_opportunistic):
                        ad.cbrs = sub_id
                        cbrs_sub_count += 1
            if cbrs_sub_count != 2:
                self.log.error("Expecting - 2 CBRS subs, found - %d", cbrs_sub_count)
                raise signals.TestAbortClass("Cannot find all expected CBRS subs")
        # DSDS setup
        if self.dsds_esim:
            for ad in self.android_devices:
                for i in range(0, 2):
                    sub_id = get_subid_from_slot_index(ad.log, ad, i)
                    set_always_allow_mms_data(ad, sub_id)
                    operator = get_operatorname_from_slot_index(ad, i)
                    ad.log.info("Slot %d - Sub %s - %s", i, sub_id, operator)
        # Actual test trigger
        if not self.dsds_esim and self.check_incall_data():
            self.log.info(
                "==== Start parallel voice/message/data stress test ====")
            self.perf_data["testing method"] = "parallel"
            results = run_multithread_func(
                self.log, [(self.call_test, [call_verification_func]),
                           (self.message_test, []), (self.data_test, []),
                           (self.crash_check_test, [])])
        else:
            self.log.info(
                "==== Start sequential voice/message/data stress test ====")
            self.perf_data["testing method"] = "sequential"
            results = run_multithread_func(
                self.log, [(self.sequential_tests, [call_verification_func]),
                           (self.crash_check_test, [])])
        result_message = self._get_result_message()
        self.log.info(result_message)
        self._update_perf_json()
        self.result_detail = result_message
        return all(results)

    def sequential_tests(self, call_verification_func):
        funcs = [(self._make_phone_call, [call_verification_func]),
                 (self._send_message, []), (self._data_download, [["5MB"]])]
        while time.time() < self.finishing_time:
            selection = random.randrange(0, 3)
            try:
                funcs[selection][0](*funcs[selection][1])
            except Exception as e:
                self.log.error("Exception error %s", str(e))
                self.result_info["Exception Errors"] += 1
            self.log.info("%s", dict(self.result_info))
            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
                self.log.error("Too many exception errors, quit test")
                return False
            time.sleep(
                random.randrange(self.min_sleep_time, self.max_sleep_time))
        if any([
                self.result_info["Call Setup Failure"],
                self.result_info["Call Maintenance Failure"],
                self.result_info["Call Teardown Failure"],
                self.result_info["SMS Failure"],
                self.result_info["MMS Failure"],
                self.result_info["Internet Connection Check Failure"]
        ]):
            return False
        return True

    def volte_modechange_volte_test(self):
        sub_id = self.dut.droid.subscriptionGetDefaultSubId()
        result = True
        while time.time() < self.finishing_time:
            try:
                if self._prefnetwork_mode_change(sub_id):
                    run_multithread_func(
                        self.log,
                        [(self._data_download, [["5MB"]]),
                         (self._make_phone_call, [is_phone_in_call_volte]),
                         (self._send_message, [])])
                else:
                    result = False
                if self._mobile_data_toggling():
                    run_multithread_func(
                        self.log,
                        [(self._data_download, [["5MB"]]),
                         (self._make_phone_call, [is_phone_in_call_volte]),
                         (self._send_message, [])])
                else:
                    result = False
            except Exception as e:
                self.log.error("Exception error %s", str(e))
                self.result_info["Exception Errors"] += 1
            self.log.info(dict(self.result_info))
            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
                self.log.error("Too many exception errors, quit test")
                return False
        return result

    def parallel_with_network_change_tests(self, setup_func=None):
        if setup_func and not setup_func():
            self.log.error("Test setup %s failed", setup_func.__name__)
            return False
        self.finishing_time = time.time() + self.max_run_time
        results = run_multithread_func(self.log,
                                       [(self.volte_modechange_volte_test, []),
                                        (self.crash_check_test, [])])
        result_message = self._get_result_message()
        self.log.info(result_message)
        self._update_perf_json()
        self.result_detail = result_message
        return all(results)

    def connect_to_wifi(self):
        for ad in self.android_devices:
            if not ensure_wifi_connected(
                    self.log,
                    ad,
                    self.wifi_network_ssid,
                    self.wifi_network_pass,
                    retries=3):
                ad.log.error("Bringing up Wifi connection fails.")
                return False
        ad.log.info("Phone WIFI is connected successfully.")
        return True

    def performance_tests(self, setup_func=None, call_verification_func=None):
        self.log.info(self._get_result_message())
        if setup_func and not setup_func():
            msg = "%s setup %s failed" % (self.test_name, setup_func.__name__)
            self.log.error(msg)
            self._take_bug_report("%s%s" % (self.test_name,
                                            setup_func.__name__),
                                  self.begin_time)
            return False
        if not call_verification_func:
            call_verification_func = is_phone_in_call
        self.finishing_time = time.time() + self.max_run_time

        self.log.info(
            "==== Start voice stress test ====")
        self.perf_data["testing method"] = "parallel"
        results = self.call_performance_test(call_verification_func)

        result_message = self._get_result_message()
        self.log.info(result_message)
        self._update_perf_json()
        self.result_detail = result_message
        total_call = self.result_info["Call Total"]
        success_call = self.result_info["Call Success Total"]
        call_fail = total_call - success_call
        if call_fail != 0:
            call_fail_rate = ( call_fail / total_call ) * 100
        else:
            call_fail_rate = 0
        call_success_rate = (success_call / total_call) * 100

        self.log.info("Call Success Rate is %s", call_success_rate)
        self.log.info("Call Drop Rate is %s", call_success_rate)

        return results

    def _update_initiate_call_fail_count(self):
        self.result_info["Call Initiate Fail"] += 1

    def call_performance_test(self, call_verification_func=None):
        count = 0
        while count < self.phone_call_iteration:
            time.sleep(15)
            count += 1
            try:
                self._make_phone_call(call_verification_func, True)
            except Exception as e:
                self.log.exception("Exception error %s", str(e))
                self.result_info["Exception Errors"] += 1
            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
                self.log.error("Too many exception errors, quit test")
                return False
            self.log.info("%s", dict(self.result_info))
            self.result_info["Call Success Total"] += 1
        if any([
                self.result_info["Call Setup Failure"],
                self.result_info["Call Maintenance Failure"],
                self.result_info["Call Teardown Failure"]
        ]):
            return False
        else:
            return True

    """ Tests Begin """

    @test_tracker_info(uuid="d035e5b9-476a-4e3d-b4e9-6fd86c51a68d")
    @TelephonyBaseTest.tel_test_wrap
    def test_default_parallel_stress(self):
        """ Default state stress test"""
        return self.parallel_tests()

    @test_tracker_info(uuid="798a3c34-db75-4bcf-b8ef-e1116414a7fe")
    @TelephonyBaseTest.tel_test_wrap
    def test_default_parallel_stress_with_wifi(self):
        """ Default state stress test with Wifi enabled."""
        if self.connect_to_wifi():
            return self.parallel_tests()

    @test_tracker_info(uuid="c21e1f17-3282-4f0b-b527-19f048798098")
    @TelephonyBaseTest.tel_test_wrap
    def test_lte_volte_parallel_stress(self):
        """ VoLTE on stress test"""
        return self.parallel_tests(
            setup_func=self._setup_lte_volte_enabled,
            call_verification_func=is_phone_in_call_volte)

    @test_tracker_info(uuid="a317c23a-41e0-4ef8-af67-661451cfefcf")
    @TelephonyBaseTest.tel_test_wrap
    def test_csfb_parallel_stress(self):
        """ LTE non-VoLTE stress test"""
        return self.parallel_tests(
            setup_func=self._setup_lte_volte_disabled,
            call_verification_func=is_phone_in_call_csfb)

    @test_tracker_info(uuid="fdb791bf-c414-4333-9fa3-cc18c9b3b234")
    @TelephonyBaseTest.tel_test_wrap
    def test_wfc_parallel_stress(self):
        """ Wifi calling APM mode off stress test"""
        if WFC_MODE_WIFI_PREFERRED not in self.dut_wfc_modes:
            raise signals.TestSkip("WFC_MODE_WIFI_PREFERRED is not supported")
        return self.parallel_tests(
            setup_func=self._setup_wfc,
            call_verification_func=is_phone_in_call_iwlan)

    @test_tracker_info(uuid="e334c1b3-4378-49bb-bf57-1573fa1b23fa")
    @TelephonyBaseTest.tel_test_wrap
    def test_wfc_apm_parallel_stress(self):
        """ Wifi calling in APM mode on stress test"""
        return self.parallel_tests(
            setup_func=self._setup_wfc_apm,
            call_verification_func=is_phone_in_call_iwlan)

    @test_tracker_info(uuid="4566eef6-55de-4ac8-87ee-58f2ef41a3e8")
    @TelephonyBaseTest.tel_test_wrap
    def test_3g_parallel_stress(self):
        """ 3G stress test"""
        return self.parallel_tests(
            setup_func=self._setup_3g,
            call_verification_func=is_phone_in_call_3g)

    @test_tracker_info(uuid="f34f1a31-3948-4675-8698-372a83b8088d")
    @TelephonyBaseTest.tel_test_wrap
    def test_2g_parallel_stress(self):
        """ 2G call stress test"""
        return self.parallel_tests(
            setup_func=self._setup_2g,
            call_verification_func=is_phone_in_call_2g)

    @test_tracker_info(uuid="af580fca-fea6-4ca5-b981-b8c710302d37")
    @TelephonyBaseTest.tel_test_wrap
    def test_volte_modeprefchange_parallel_stress(self):
        """ VoLTE Mode Pref call stress test"""
        return self.parallel_with_network_change_tests(
            setup_func=self._setup_lte_volte_enabled)

    @test_tracker_info(uuid="10e34247-5fd3-4f87-81bf-3c17a6b71ab2")
    @TelephonyBaseTest.tel_test_wrap
    def test_data_call_stress(self):
        """ Default state stress test"""
        self.finishing_time = time.time() + self.max_run_time
        results = run_multithread_func(self.log,
                                       [(self.data_call_stress_test, []),
                                        (self.crash_check_test, [])])
        result_message = self._get_result_message()
        self.log.info(result_message)
        self._update_perf_json()
        self.result_detail = result_message
        return all(results)

    @test_tracker_info(uuid="4212d0e0-fb87-47e5-ba48-9df9a4a6bb9b")
    @TelephonyBaseTest.tel_test_wrap
    def test_voice_performance_stress(self):
        """ Vocie Performance stress test"""
        return self.performance_tests()

    """ Tests End """
