def _sms_test_dsds(self, ads):
        """Test SMS between two phones on multiple sub_id

        Returns:
            True if success.
            False if failed.
        """
        for slot in range(self.sim_config["number_of_sims"]):
            set_subid_for_message(
                ads[0], get_subid_from_slot_index(self.log, ads[0], slot))
            set_subid_for_message(
                ads[1], get_subid_from_slot_index(self.log, ads[1], slot))
            for length in self.message_lengths:
                message_array = [rand_ascii_str(length)]
                ads[0].log.info("SMS Test - length %s from slot %s to slot %s",
                                length, slot, slot)
                if not sms_send_receive_verify(
                        self.log, ads[0], ads[1], message_array,
                        slot_id_rx=slot):
                    ads[0].log.warning(
                        "SMS of length %s test failed from slot %s to slot %s",
                        length, slot, slot)
                    return False
                ads[0].log.info("SMS Test - length %s from slot %s to slot %s",
                                length, slot, 1 - slot)
                if not sms_send_receive_verify(self.log,
                                               ads[0],
                                               ads[1],
                                               message_array,
                                               slot_id_rx=1 - slot):
                    ads[0].log.warning(
                        "SMS of length %s test failed from slot %s to slot %s",
                        length, slot, 1 - slot)
                    return False
                else:
                    ads[0].log.info("SMS of length %s test succeeded", length)
            self.log.info("SMS test of length %s characters succeeded.",
                          self.message_lengths)
        return True
def change_data_sim_and_verify_data(log, ad, sim_slot):
    """Change Data SIM and verify Data attach and Internet access

    Args:
        log: log object.
        ad: android device object.
        sim_slot: SIM slot index.

    Returns:
        Data SIM changed successfully, data attached and Internet access is OK.
    """
    sub_id = get_subid_from_slot_index(log, ad, sim_slot)
    log.info("Change Data to subId: {}, SIM slot: {}".format(sub_id, sim_slot))
    set_subid_for_data(ad, sub_id)
    if not wait_for_data_attach_for_subscription(log, ad, sub_id,
                                                 MAX_WAIT_TIME_NW_SELECTION):
        log.error("Failed to attach data on subId:{}".format(sub_id))
        return False
    if not verify_http_connection(log, ad):
        log.error("No Internet access after changing Data SIM.")
        return False
    return True
    def _test_msim_call_voice(self,
                              mo_slot,
                              mt_slot,
                              dds_slot,
                              mo_rat=["", ""],
                              mt_rat=["", ""],
                              call_direction="mo"):
        """Make MO/MT voice call at specific slot in specific RAT with DDS at
        specific slot.

        Test step:
        1. Get sub IDs of specific slots of both MO and MT devices.
        2. Switch DDS to specific slot.
        3. Check HTTP connection after DDS switch.
        4. Set up phones in desired RAT.
        5. Make voice call.

        Args:
            mo_slot: Slot making MO call (0 or 1)
            mt_slot: Slot receiving MT call (0 or 1)
            dds_slot: Preferred data slot
            mo_rat: RAT for both slots of MO device
            mt_rat: RAT for both slots of MT device
            call_direction: "mo" or "mt"

        Returns:
            TestFailure if failed.
        """
        ads = self.android_devices

        if call_direction == "mo":
            ad_mo = ads[0]
            ad_mt = ads[1]
        else:
            ad_mo = ads[1]
            ad_mt = ads[0]

        if mo_slot is not None:
            mo_sub_id = get_subid_from_slot_index(self.log, ad_mo, mo_slot)
            if mo_sub_id == INVALID_SUB_ID:
                ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
                return False
            mo_other_sub_id = get_subid_from_slot_index(
                self.log, ad_mo, 1 - mo_slot)
            set_incoming_voice_sub_id(ad_mo, mo_sub_id)
        else:
            _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
            if mo_sub_id == INVALID_SUB_ID:
                ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
                return False
            mo_slot = "auto"
            set_incoming_voice_sub_id(ad_mo, mo_sub_id)
        ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", mo_slot,
                       get_outgoing_voice_sub_id(ad_mo))

        if mt_slot is not None:
            mt_sub_id = get_subid_from_slot_index(self.log, ad_mt, mt_slot)
            if mt_sub_id == INVALID_SUB_ID:
                ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
                return False
            mt_other_sub_id = get_subid_from_slot_index(
                self.log, ad_mt, 1 - mt_slot)
            set_incoming_voice_sub_id(ad_mt, mt_sub_id)
        else:
            _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
            if mt_sub_id == INVALID_SUB_ID:
                ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
                return False
            mt_slot = "auto"
            set_incoming_voice_sub_id(ad_mt, mt_sub_id)
        ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot,
                       get_incoming_voice_sub_id(ad_mt))

        self.log.info("Step 1: Switch DDS.")
        if dds_slot:
            if not set_dds_on_slot_1(ads[0]):
                ads[0].log.warning("Failed to set DDS at eSIM.")
                return False
        else:
            if not set_dds_on_slot_0(ads[0]):
                ads[0].log.warning("Failed to set DDS at pSIM.")
                return False

        self.log.info("Step 2: Check HTTP connection after DDS switch.")
        if not verify_http_connection(self.log,
                                      ads[0],
                                      url="https://www.google.com",
                                      retry=5,
                                      retry_interval=15,
                                      expected_state=True):

            self.log.error("Failed to verify http connection.")
            return False
        else:
            self.log.info("Verify http connection successfully.")

        if mo_rat[0] == "volte":
            mo_slot0_phone_setup_func = phone_setup_volte
            is_mo_slot0_in_call = is_phone_in_call_volte
        elif mo_rat[0] == "csfb":
            mo_slot0_phone_setup_func = phone_setup_csfb
            is_mo_slot0_in_call = is_phone_in_call_csfb
        elif mo_rat[0] == "3g":
            mo_slot0_phone_setup_func = phone_setup_voice_3g
            is_mo_slot0_in_call = is_phone_in_call_3g
        elif not mo_rat[0] or mo_rat[0] == "general":
            mo_slot0_phone_setup_func = phone_setup_voice_general
            is_mo_slot0_in_call = None

        if mo_rat[1] == "volte":
            mo_slot1_phone_setup_func = phone_setup_volte
            is_mo_slot1_in_call = is_phone_in_call_volte
        elif mo_rat[1] == "csfb":
            mo_slot1_phone_setup_func = phone_setup_csfb
            is_mo_slot1_in_call = is_phone_in_call_csfb
        elif mo_rat[1] == "3g":
            mo_slot1_phone_setup_func = phone_setup_voice_3g
            is_mo_slot1_in_call = is_phone_in_call_3g
        elif not mo_rat[1] or mo_rat[1] == "general":
            mo_slot1_phone_setup_func = phone_setup_voice_general
            is_mo_slot1_in_call = None

        if mt_rat[0] == "volte":
            mt_slot0_phone_setup_func = phone_setup_volte
            is_mt_slot0_in_call = is_phone_in_call_volte
        elif mt_rat[0] == "csfb":
            mt_slot0_phone_setup_func = phone_setup_csfb
            is_mt_slot0_in_call = is_phone_in_call_csfb
        elif mt_rat[0] == "3g":
            mt_slot0_phone_setup_func = phone_setup_voice_3g
            is_mt_slot0_in_call = is_phone_in_call_3g
        elif not mt_rat[0] or mt_rat[0] == "general":
            mt_slot0_phone_setup_func = phone_setup_voice_general
            is_mt_slot0_in_call = None

        if mt_rat[1] == "volte":
            mt_slot1_phone_setup_func = phone_setup_volte
            is_mt_slot1_in_call = is_phone_in_call_volte
        elif mt_rat[1] == "csfb":
            mt_slot1_phone_setup_func = phone_setup_csfb
            is_mt_slot1_in_call = is_phone_in_call_csfb
        elif mt_rat[1] == "3g":
            mt_slot1_phone_setup_func = phone_setup_voice_3g
            is_mt_slot1_in_call = is_phone_in_call_3g
        elif not mt_rat[1] or mt_rat[1] == "general":
            mt_slot1_phone_setup_func = phone_setup_voice_general
            is_mt_slot1_in_call = None

        if mo_slot == 1:
            mo_phone_setup_func = mo_slot1_phone_setup_func
            is_mo_in_call = is_mo_slot1_in_call
            if mo_rat[0] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mo,
                                                   mo_other_sub_id)
            elif mo_rat[0] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mo,
                                                  mo_other_sub_id)
            elif mo_rat[0] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mo,
                                                      mo_other_sub_id)
            elif not mo_rat[0] or mo_rat[0] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mo, mo_other_sub_id)
        elif mo_slot == 0:
            mo_phone_setup_func = mo_slot0_phone_setup_func
            is_mo_in_call = is_mo_slot0_in_call
            if mo_rat[1] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mo,
                                                   mo_other_sub_id)
            elif mo_rat[1] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mo,
                                                  mo_other_sub_id)
            elif mo_rat[1] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mo,
                                                      mo_other_sub_id)
            elif not mo_rat[1] or mo_rat[1] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mo, mo_other_sub_id)
        else:
            mo_phone_setup_func = phone_setup_voice_general
            is_mo_in_call = None

        if mt_slot == 1:
            mt_phone_setup_func = mt_slot1_phone_setup_func
            is_mt_in_call = is_mt_slot1_in_call
            if mt_rat[0] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mt,
                                                   mt_other_sub_id)
            elif mt_rat[0] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mt,
                                                  mt_other_sub_id)
            elif mt_rat[0] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mt,
                                                      mt_other_sub_id)
            elif not mt_rat[0] or mt_rat[0] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mt, mt_other_sub_id)
        elif mt_slot == 0:
            mt_phone_setup_func = mt_slot0_phone_setup_func
            is_mt_in_call = is_mt_slot0_in_call
            if mt_rat[1] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mt,
                                                   mt_other_sub_id)
            elif mt_rat[1] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mt,
                                                  mt_other_sub_id)
            elif mt_rat[1] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mt,
                                                      mt_other_sub_id)
            elif not mt_rat[1] or mt_rat[1] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mt, mt_other_sub_id)
        else:
            mt_phone_setup_func = phone_setup_voice_general
            is_mt_in_call = None

        self.log.info("Step 3: Set up phones in desired RAT.")
        tasks = [(mo_phone_setup_func, (self.log, ad_mo)),
                 (mt_phone_setup_func, (self.log, ad_mt))]
        if not multithread_func(self.log, tasks):
            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."})

        self.log.info("Step 4: Make voice call.")
        result = two_phone_call_msim_for_slot(
            self.log, ad_mo,
            get_slot_index_from_subid(self.log, ad_mo,
                                      mo_sub_id), None, is_mo_in_call, ad_mt,
            get_slot_index_from_subid(self.log, ad_mt, mt_sub_id), None,
            is_mt_in_call)
        self.tel_logger.set_result(result.result_value)

        if not result:
            self.log.error(
                "Failed to make MO call from %s slot %s to %s slot %s",
                ad_mo.serial, mo_slot, ad_mt.serial, mt_slot)
            raise signals.TestFailure(
                "Failed", extras={"fail_reason": str(result.result_value)})
    def _setup_device(self, ad, sim_conf_file, qxdm_log_mask_cfg=None):
        ad.qxdm_log = getattr(ad, "qxdm_log", self.qxdm_log)
        ad.sdm_log = getattr(ad, "sdm_log", self.sdm_log)
        if self.user_params.get("enable_connectivity_metrics", False):
            enable_connectivity_metrics(ad)
        if self.user_params.get("build_id_override", False):
            build_postfix = self.user_params.get("build_id_postfix",
                                                 "LAB_TEST")
            build_id_override(
                ad,
                new_build_id=self.user_params.get("build_id_override_with",
                                                  None),
                postfix=build_postfix)
        if self.enable_radio_log_on:
            enable_radio_log_on(ad)
        list_of_models = ["sdm", "msm", "kon", "lit"]
        if any(model in ad.model for model in list_of_models):
            phone_mode = "ssss"
            if hasattr(ad, "mtp_dsds"):
                phone_mode = "dsds"
            if ad.adb.getprop("persist.radio.multisim.config") != phone_mode:
                ad.adb.shell("setprop persist.radio.multisim.config %s" \
                             % phone_mode)
                reboot_device(ad)

        stop_qxdm_logger(ad)
        if ad.qxdm_log:
            qxdm_log_mask = getattr(ad, "qxdm_log_mask", None)
            if qxdm_log_mask_cfg:
                qxdm_mask_path = self.user_params.get("qxdm_log_path",
                                                      DEFAULT_QXDM_LOG_PATH)
                ad.adb.shell("mkdir %s" % qxdm_mask_path)
                ad.log.info("Push %s to %s", qxdm_log_mask_cfg, qxdm_mask_path)
                ad.adb.push("%s %s" % (qxdm_log_mask_cfg, qxdm_mask_path))
                mask_file_name = os.path.split(qxdm_log_mask_cfg)[-1]
                qxdm_log_mask = os.path.join(qxdm_mask_path, mask_file_name)
            set_qxdm_logger_command(ad, mask=qxdm_log_mask)
            start_qxdm_logger(ad, utils.get_current_epoch_time())
        elif ad.sdm_log:
            start_sdm_logger(ad)
        else:
            disable_qxdm_logger(ad)
        if not unlock_sim(ad):
            raise signals.TestAbortClass("unable to unlock the SIM")

        # eSIM enablement
        if hasattr(ad, "fi_esim"):
            if not ensure_wifi_connected(self.log, ad, self.wifi_network_ssid,
                                         self.wifi_network_pass):
                ad.log.error("Failed to connect to wifi")
            if check_google_fi_activated(ad):
                ad.log.info("Google Fi is already Activated")
            else:
                install_googleaccountutil_apk(ad, self.account_util)
                add_google_account(ad)
                install_googlefi_apk(ad, self.fi_util)
                if not activate_google_fi_account(ad):
                    ad.log.error("Failed to activate Fi")
                check_google_fi_activated(ad)
        if hasattr(ad, "dsds"):
            sim_mode = ad.droid.telephonyGetPhoneCount()
            if sim_mode == 1:
                ad.log.info("Phone in Single SIM Mode")
                if not phone_switch_to_msim_mode(ad):
                    ad.log.error("Failed to switch to Dual SIM Mode")
                    return False
            elif sim_mode == 2:
                ad.log.info("Phone already in Dual SIM Mode")
        if get_sim_state(ad) in (SIM_STATE_ABSENT, SIM_STATE_UNKNOWN):
            ad.log.info("Device has no or unknown SIM in it")
            # eSIM needs activation
            activate_esim_using_suw(ad)
            ensure_phone_idle(self.log, ad)
        elif self.user_params.get("Attenuator"):
            ad.log.info("Device in chamber room")
            ensure_phone_idle(self.log, ad)
            setup_droid_properties(self.log, ad, sim_conf_file)
        else:
            self.wait_for_sim_ready(ad)
            ensure_phone_default_state(self.log, ad)
            setup_droid_properties(self.log, ad, sim_conf_file)

        default_slot = getattr(ad, "default_slot", 0)
        if get_subid_from_slot_index(ad.log, ad, default_slot) != INVALID_SUB_ID:
            ad.log.info("Slot %s is the default slot.", default_slot)
            set_default_sub_for_all_services(ad, default_slot)
        else:
            ad.log.warning("Slot %s is NOT a valid slot. Slot %s will be used by default.",
                default_slot, 1-default_slot)
            set_default_sub_for_all_services(ad, 1-default_slot)

        # Activate WFC on Verizon, AT&T and Canada operators as per # b/33187374 &
        # b/122327716
        activate_wfc_on_device(self.log, ad)

        # Sub ID setup
        initial_set_up_for_subid_infomation(self.log, ad)

        # If device is setup already, skip the following setup procedures
        if getattr(ad, "telephony_test_setup", None):
            return True

        try:
            ad.droid.wifiEnableVerboseLogging(WIFI_VERBOSE_LOGGING_ENABLED)
        except Exception:
            pass

        # Disable Emergency alerts
        # Set chrome browser start with no-first-run verification and
        # disable-fre. Give permission to read from and write to storage.
        for cmd in ("pm disable com.android.cellbroadcastreceiver",
                    "pm grant com.android.chrome "
                    "android.permission.READ_EXTERNAL_STORAGE",
                    "pm grant com.android.chrome "
                    "android.permission.WRITE_EXTERNAL_STORAGE",
                    "rm /data/local/chrome-command-line",
                    "am set-debug-app --persistent com.android.chrome",
                    'echo "chrome --no-default-browser-check --no-first-run '
                    '--disable-fre" > /data/local/tmp/chrome-command-line'):
            ad.adb.shell(cmd, ignore_status=True)

        # Curl for 2016/7 devices
        if not getattr(ad, "curl_capable", False):
            try:
                out = ad.adb.shell("/data/curl --version")
                if not out or "not found" in out:
                    if int(ad.adb.getprop("ro.product.first_api_level")) >= 25:
                        tel_data = self.user_params.get("tel_data", "tel_data")
                        if isinstance(tel_data, list):
                            tel_data = tel_data[0]
                        curl_file_path = os.path.join(tel_data, "curl")
                        if not os.path.isfile(curl_file_path):
                            curl_file_path = os.path.join(
                                self.user_params[Config.key_config_path.value],
                                curl_file_path)
                        if os.path.isfile(curl_file_path):
                            ad.log.info("Pushing Curl to /data dir")
                            ad.adb.push("%s /data" % (curl_file_path))
                            ad.adb.shell(
                                "chmod 777 /data/curl", ignore_status=True)
                else:
                    setattr(ad, "curl_capable", True)
            except Exception:
                ad.log.info("Failed to push curl on this device")

        # Ensure that a test class starts from a consistent state that
        # improves chances of valid network selection and facilitates
        # logging.
        try:
            if not set_phone_screen_on(self.log, ad):
                self.log.error("Failed to set phone screen-on time.")
                return False
            if not set_phone_silent_mode(self.log, ad):
                self.log.error("Failed to set phone silent mode.")
                return False
            ad.droid.telephonyAdjustPreciseCallStateListenLevel(
                PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND, True)
            ad.droid.telephonyAdjustPreciseCallStateListenLevel(
                PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING, True)
            ad.droid.telephonyAdjustPreciseCallStateListenLevel(
                PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND, True)
        except Exception as e:
            self.log.error("Failure with %s", e)
        setattr(ad, "telephony_test_setup", True)
        return True