#!/usr/bin/env python3
#
#   Copyright 2021 - 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.

import time
from acts import signals
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_VOLTE
from acts_contrib.test_utils.tel.tel_defines import CAPABILITY_WFC
from acts_contrib.test_utils.tel.tel_defines import CARRIER_FRE
from acts_contrib.test_utils.tel.tel_defines import CARRIER_TMO
from acts_contrib.test_utils.tel.tel_defines import GEN_2G
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 GEN_5G
from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_DROP
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_WFC_ENABLED
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE
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_GSM_UMTS
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_CDMA_EVDO
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_GSM_WCDMA
from acts_contrib.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY
from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT
from acts_contrib.test_utils.tel.tel_defines import RAT_5G
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_CDMA2000
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_LTE
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_GSM
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WCDMA
from acts_contrib.test_utils.tel.tel_defines import RAT_FAMILY_WLAN
from acts_contrib.test_utils.tel.tel_defines import RAT_UNKNOWN
from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_IDLE
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_1XRTT_VOICE_ATTACH
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_for_subscription
from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte_for_subscription
from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode_for_subscription
from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_enhanced_4g_lte_setting
from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_volte_enabled
from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_enabled
from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_wfc_disabled
from acts_contrib.test_utils.tel.tel_lookup_tables import network_preference_for_generation
from acts_contrib.test_utils.tel.tel_lookup_tables import rat_families_for_network_preference
from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_for_generation
from acts_contrib.test_utils.tel.tel_lookup_tables import rat_family_from_rat
from acts_contrib.test_utils.tel.tel_lookup_tables import rat_generation_from_rat
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id
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_default_data_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import _is_attached
from acts_contrib.test_utils.tel.tel_test_utils import _is_attached_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state
from acts_contrib.test_utils.tel.tel_test_utils import _wait_for_droid_in_state_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import get_capability_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import get_cell_data_roaming_state_by_adb
from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
from acts_contrib.test_utils.tel.tel_test_utils import get_telephony_signal_strength
from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_network_generation_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_rat_family_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import is_droid_in_rat_family_list_for_subscription
from acts_contrib.test_utils.tel.tel_test_utils import reset_preferred_network_type_to_allowable_range
from acts_contrib.test_utils.tel.tel_test_utils import set_cell_data_roaming_state_by_adb
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 toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
from acts_contrib.test_utils.tel.tel_test_utils import wait_for_data_attach_for_subscription
from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
from acts_contrib.test_utils.tel.tel_wifi_utils import set_wifi_to_default
from acts.libs.utils.multithread import multithread_func


def phone_setup_iwlan(log,
                      ad,
                      is_airplane_mode,
                      wfc_mode,
                      wifi_ssid=None,
                      wifi_pwd=None,
                      nw_gen=None):
    """Phone setup function for epdg call test.
    Set WFC mode according to wfc_mode.
    Set airplane mode according to is_airplane_mode.
    Make sure phone connect to WiFi. (If wifi_ssid is not None.)
    Wait for phone to be in iwlan data network type.
    Wait for phone to report wfc enabled flag to be true.
    Args:
        log: Log object.
        ad: Android device object.
        is_airplane_mode: True to turn on airplane mode. False to turn off airplane mode.
        wfc_mode: WFC mode to set to.
        wifi_ssid: WiFi network SSID. This is optional.
            If wifi_ssid is None, then phone_setup_iwlan will not attempt to connect to wifi.
        wifi_pwd: WiFi network password. This is optional.
        nw_gen: network type selection. This is optional.
            GEN_4G for 4G, GEN_5G for 5G or None for doing nothing.
    Returns:
        True if success. False if fail.
    """
    return phone_setup_iwlan_for_subscription(log, ad,
                                              get_outgoing_voice_sub_id(ad),
                                              is_airplane_mode, wfc_mode,
                                              wifi_ssid, wifi_pwd, nw_gen)


def phone_setup_iwlan_for_subscription(log,
                                       ad,
                                       sub_id,
                                       is_airplane_mode,
                                       wfc_mode,
                                       wifi_ssid=None,
                                       wifi_pwd=None,
                                       nw_gen=None,
                                       nr_type=None):
    """Phone setup function for epdg call test for subscription id.
    Set WFC mode according to wfc_mode.
    Set airplane mode according to is_airplane_mode.
    Make sure phone connect to WiFi. (If wifi_ssid is not None.)
    Wait for phone to be in iwlan data network type.
    Wait for phone to report wfc enabled flag to be true.
    Args:
        log: Log object.
        ad: Android device object.
        sub_id: subscription id.
        is_airplane_mode: True to turn on airplane mode. False to turn off airplane mode.
        wfc_mode: WFC mode to set to.
        wifi_ssid: WiFi network SSID. This is optional.
            If wifi_ssid is None, then phone_setup_iwlan will not attempt to connect to wifi.
        wifi_pwd: WiFi network password. This is optional.
        nw_gen: network type selection. This is optional.
            GEN_4G for 4G, GEN_5G for 5G or None for doing nothing.
        nr_type: NR network type
    Returns:
        True if success. False if fail.
    """
    if not get_capability_for_subscription(ad, CAPABILITY_WFC, sub_id):
        ad.log.error("WFC is not supported, abort test.")
        raise signals.TestSkip("WFC is not supported, abort test.")

    if nw_gen:
        if not ensure_network_generation_for_subscription(
                log, ad, sub_id, nw_gen, voice_or_data=NETWORK_SERVICE_DATA,
                nr_type=nr_type):
            ad.log.error("Failed to set to %s data.", nw_gen)
            return False
    toggle_airplane_mode(log, ad, is_airplane_mode, strict_checking=False)

    # Pause at least for 4 seconds is necessary after airplane mode was turned
    # on due to the mechanism of deferring Wi-Fi (b/191481736)
    if is_airplane_mode:
        time.sleep(5)

    # check if WFC supported phones
    if wfc_mode != WFC_MODE_DISABLED and not ad.droid.imsIsWfcEnabledByPlatform(
    ):
        ad.log.error("WFC is not enabled on this device by checking "
                     "ImsManager.isWfcEnabledByPlatform")
        return False
    if wifi_ssid is not None:
        if not ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd, apm=is_airplane_mode):
            ad.log.error("Fail to bring up WiFi connection on %s.", wifi_ssid)
            return False
    else:
        ad.log.info("WiFi network SSID not specified, available user "
                    "parameters are: wifi_network_ssid, wifi_network_ssid_2g, "
                    "wifi_network_ssid_5g")
    if not set_wfc_mode_for_subscription(ad, wfc_mode, sub_id):
        ad.log.error("Unable to set WFC mode to %s.", wfc_mode)
        return False

    if wfc_mode != WFC_MODE_DISABLED:
        if not wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED):
            ad.log.error("WFC is not enabled")
            return False

    return True


def phone_setup_iwlan_cellular_preferred(log,
                                         ad,
                                         wifi_ssid=None,
                                         wifi_pwd=None):
    """Phone setup function for iwlan Non-APM CELLULAR_PREFERRED test.
    Set WFC mode according to CELLULAR_PREFERRED.
    Set airplane mode according to False.
    Make sure phone connect to WiFi. (If wifi_ssid is not None.)
    Make sure phone don't report iwlan data network type.
    Make sure phone don't report wfc enabled flag to be true.

    Args:
        log: Log object.
        ad: Android device object.
        wifi_ssid: WiFi network SSID. This is optional.
            If wifi_ssid is None, then phone_setup_iwlan will not attempt to connect to wifi.
        wifi_pwd: WiFi network password. This is optional.

    Returns:
        True if success. False if fail.
    """
    toggle_airplane_mode(log, ad, False, strict_checking=False)
    try:
        toggle_volte(log, ad, True)
        if not wait_for_network_generation(
                log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
            if not ensure_network_generation(
                    log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
                ad.log.error("Fail to ensure data in 4G")
                return False
    except Exception as e:
        ad.log.error(e)
        ad.droid.telephonyToggleDataConnection(True)
    if wifi_ssid is not None:
        if not ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd):
            ad.log.error("Connect to WiFi failed.")
            return False
    if not set_wfc_mode(log, ad, WFC_MODE_CELLULAR_PREFERRED):
        ad.log.error("Set WFC mode failed.")
        return False
    if not wait_for_not_network_rat(
            log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
        ad.log.error("Data rat in iwlan mode.")
        return False
    elif not wait_for_wfc_disabled(log, ad, MAX_WAIT_TIME_WFC_ENABLED):
        ad.log.error("Should report wifi calling disabled within %s.",
                     MAX_WAIT_TIME_WFC_ENABLED)
        return False
    return True


def phone_setup_data_for_subscription(log, ad, sub_id, network_generation,
                                        nr_type=None):
    """Setup Phone <sub_id> Data to <network_generation>

    Args:
        log: log object
        ad: android device object
        sub_id: subscription id
        network_generation: network generation, e.g. GEN_2G, GEN_3G, GEN_4G, GEN_5G
        nr_type: NR network type e.g. NSA, SA, MMWAVE

    Returns:
        True if success, False if fail.
    """
    toggle_airplane_mode(log, ad, False, strict_checking=False)
    set_wifi_to_default(log, ad)
    if not set_wfc_mode(log, ad, WFC_MODE_DISABLED):
        ad.log.error("Disable WFC failed.")
        return False
    if not ensure_network_generation_for_subscription(
            log,
            ad,
            sub_id,
            network_generation,
            voice_or_data=NETWORK_SERVICE_DATA,
            nr_type=nr_type):
        get_telephony_signal_strength(ad)
        return False
    return True


def phone_setup_5g(log, ad, nr_type=None):
    """Setup Phone default data sub_id data to 5G.

    Args:
        log: log object
        ad: android device object

    Returns:
        True if success, False if fail.
    """
    return phone_setup_5g_for_subscription(log, ad,
                                           get_default_data_sub_id(ad), nr_type=nr_type)


def phone_setup_5g_for_subscription(log, ad, sub_id, nr_type=None):
    """Setup Phone <sub_id> Data to 5G.

    Args:
        log: log object
        ad: android device object
        sub_id: subscription id
        nr_type: NR network type e.g. NSA, SA, MMWAVE

    Returns:
        True if success, False if fail.
    """
    return phone_setup_data_for_subscription(log, ad, sub_id, GEN_5G,
                                        nr_type=nr_type)


def phone_setup_4g(log, ad):
    """Setup Phone default data sub_id data to 4G.

    Args:
        log: log object
        ad: android device object

    Returns:
        True if success, False if fail.
    """
    return phone_setup_4g_for_subscription(log, ad,
                                           get_default_data_sub_id(ad))


def phone_setup_4g_for_subscription(log, ad, sub_id):
    """Setup Phone <sub_id> Data to 4G.

    Args:
        log: log object
        ad: android device object
        sub_id: subscription id

    Returns:
        True if success, False if fail.
    """
    return phone_setup_data_for_subscription(log, ad, sub_id, GEN_4G)


def phone_setup_3g(log, ad):
    """Setup Phone default data sub_id data to 3G.

    Args:
        log: log object
        ad: android device object

    Returns:
        True if success, False if fail.
    """
    return phone_setup_3g_for_subscription(log, ad,
                                           get_default_data_sub_id(ad))


def phone_setup_3g_for_subscription(log, ad, sub_id):
    """Setup Phone <sub_id> Data to 3G.

    Args:
        log: log object
        ad: android device object
        sub_id: subscription id

    Returns:
        True if success, False if fail.
    """
    return phone_setup_data_for_subscription(log, ad, sub_id, GEN_3G)


def phone_setup_2g(log, ad):
    """Setup Phone default data sub_id data to 2G.

    Args:
        log: log object
        ad: android device object

    Returns:
        True if success, False if fail.
    """
    return phone_setup_2g_for_subscription(log, ad,
                                           get_default_data_sub_id(ad))


def phone_setup_2g_for_subscription(log, ad, sub_id):
    """Setup Phone <sub_id> Data to 3G.

    Args:
        log: log object
        ad: android device object
        sub_id: subscription id

    Returns:
        True if success, False if fail.
    """
    return phone_setup_data_for_subscription(log, ad, sub_id, GEN_2G)


def phone_setup_csfb(log, ad, nw_gen=GEN_4G, nr_type=None):
    """Setup phone for CSFB call test.

    Setup Phone to be in 4G mode.
    Disabled VoLTE.

    Args:
        log: log object
        ad: Android device object.
        nw_gen: GEN_4G or GEN_5G

    Returns:
        True if setup successfully.
        False for errors.
    """
    return phone_setup_csfb_for_subscription(log, ad,
                                        get_outgoing_voice_sub_id(ad), nw_gen, nr_type=nr_type)


def phone_setup_csfb_for_subscription(log, ad, sub_id, nw_gen=GEN_4G, nr_type=None):
    """Setup phone for CSFB call test for subscription id.

    Setup Phone to be in 4G mode.
    Disabled VoLTE.

    Args:
        log: log object
        ad: Android device object.
        sub_id: subscription id.
        nw_gen: GEN_4G or GEN_5G
        nr_type: NR network type e.g. NSA, SA, MMWAVE

    Returns:
        True if setup successfully.
        False for errors.
    """
    capabilities = ad.telephony["subscription"][sub_id].get("capabilities", [])
    if capabilities:
        if "hide_enhanced_4g_lte" in capabilities:
            show_enhanced_4g_lte_mode = getattr(ad, "show_enhanced_4g_lte_mode", False)
            if show_enhanced_4g_lte_mode in ["false", "False", False]:
                ad.log.warning("'VoLTE' option is hidden. Test will be skipped.")
                raise signals.TestSkip("'VoLTE' option is hidden. Test will be skipped.")

    if nw_gen == GEN_4G:
        if not phone_setup_4g_for_subscription(log, ad, sub_id):
            ad.log.error("Failed to set to 4G data.")
            return False
    elif nw_gen == GEN_5G:
        if not phone_setup_5g_for_subscription(log, ad, sub_id, nr_type=nr_type):
            ad.log.error("Failed to set to 5G data.")
            return False

    if not toggle_volte_for_subscription(log, ad, sub_id, False):
        return False

    if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
                                                  MAX_WAIT_TIME_NW_SELECTION):
        return False

    return phone_idle_csfb_for_subscription(log, ad, sub_id, nw_gen)


def phone_setup_volte(log, ad, nw_gen=GEN_4G, nr_type=None):
    """Setup VoLTE enable.

    Args:
        log: log object
        ad: android device object.
        nw_gen: GEN_4G or GEN_5G

    Returns:
        True: if VoLTE is enabled successfully.
        False: for errors
    """
    if not get_capability_for_subscription(ad, CAPABILITY_VOLTE,
        get_outgoing_voice_sub_id(ad)):
        ad.log.error("VoLTE is not supported, abort test.")
        raise signals.TestSkip("VoLTE is not supported, abort test.")
    return phone_setup_volte_for_subscription(log, ad,
                        get_outgoing_voice_sub_id(ad), nw_gen, nr_type= nr_type)


def phone_setup_volte_for_subscription(log, ad, sub_id, nw_gen=GEN_4G,
                                        nr_type=None):
    """Setup VoLTE enable for subscription id.
    Args:
        log: log object
        ad: android device object.
        sub_id: subscription id.
        nw_gen: GEN_4G or GEN_5G.
        nr_type: NR network type.

    Returns:
        True: if VoLTE is enabled successfully.
        False: for errors
    """
    if not get_capability_for_subscription(ad, CAPABILITY_VOLTE,
        get_outgoing_voice_sub_id(ad)):
        ad.log.error("VoLTE is not supported, abort test.")
        raise signals.TestSkip("VoLTE is not supported, abort test.")

    if nw_gen == GEN_4G:
        if not phone_setup_4g_for_subscription(log, ad, sub_id):
            ad.log.error("Failed to set to 4G data.")
            return False
    elif nw_gen == GEN_5G:
        if not phone_setup_5g_for_subscription(log, ad, sub_id,
                                        nr_type=nr_type):
            ad.log.error("Failed to set to 5G data.")
            return False
    operator_name = get_operator_name(log, ad, sub_id)
    if operator_name == CARRIER_TMO:
        return True
    else:
        if not wait_for_enhanced_4g_lte_setting(log, ad, sub_id):
            ad.log.error("Enhanced 4G LTE setting is not available")
            return False
        toggle_volte_for_subscription(log, ad, sub_id, True)
    return phone_idle_volte_for_subscription(log, ad, sub_id, nw_gen,
                                        nr_type=nr_type)


def phone_setup_voice_3g(log, ad):
    """Setup phone voice to 3G.

    Args:
        log: log object
        ad: Android device object.

    Returns:
        True if setup successfully.
        False for errors.
    """
    return phone_setup_voice_3g_for_subscription(log, ad,
                                                 get_outgoing_voice_sub_id(ad))


def phone_setup_voice_3g_for_subscription(log, ad, sub_id):
    """Setup phone voice to 3G for subscription id.

    Args:
        log: log object
        ad: Android device object.
        sub_id: subscription id.

    Returns:
        True if setup successfully.
        False for errors.
    """
    if not phone_setup_3g_for_subscription(log, ad, sub_id):
        ad.log.error("Failed to set to 3G data.")
        return False
    if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
                                                  MAX_WAIT_TIME_NW_SELECTION):
        return False
    return phone_idle_3g_for_subscription(log, ad, sub_id)


def phone_setup_voice_2g(log, ad):
    """Setup phone voice to 2G.

    Args:
        log: log object
        ad: Android device object.

    Returns:
        True if setup successfully.
        False for errors.
    """
    return phone_setup_voice_2g_for_subscription(log, ad,
                                                 get_outgoing_voice_sub_id(ad))


def phone_setup_voice_2g_for_subscription(log, ad, sub_id):
    """Setup phone voice to 2G for subscription id.

    Args:
        log: log object
        ad: Android device object.
        sub_id: subscription id.

    Returns:
        True if setup successfully.
        False for errors.
    """
    if not phone_setup_2g_for_subscription(log, ad, sub_id):
        ad.log.error("Failed to set to 2G data.")
        return False
    if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
                                                  MAX_WAIT_TIME_NW_SELECTION):
        return False
    return phone_idle_2g_for_subscription(log, ad, sub_id)


def phone_setup_voice_general(log, ad):
    """Setup phone for voice general call test.

    Make sure phone attached to voice.
    Make necessary delay.

    Args:
        ad: Android device object.

    Returns:
        True if setup successfully.
        False for errors.
    """
    return phone_setup_voice_general_for_subscription(
        log, ad, get_outgoing_voice_sub_id(ad))


def phone_setup_voice_general_for_slot(log,ad,slot_id):
    return phone_setup_voice_general_for_subscription(
        log, ad, get_subid_from_slot_index(log,ad,slot_id))


def phone_setup_voice_general_for_subscription(log, ad, sub_id):
    """Setup phone for voice general call test for subscription id.

    Make sure phone attached to voice.
    Make necessary delay.

    Args:
        ad: Android device object.
        sub_id: subscription id.

    Returns:
        True if setup successfully.
        False for errors.
    """
    toggle_airplane_mode(log, ad, False, strict_checking=False)
    if not wait_for_voice_attach_for_subscription(log, ad, sub_id,
                                                  MAX_WAIT_TIME_NW_SELECTION):
        # if phone can not attach voice, try phone_setup_voice_3g
        return phone_setup_voice_3g_for_subscription(log, ad, sub_id)
    return True


def phone_setup_data_general(log, ad):
    """Setup phone for data general test.

    Make sure phone attached to data.
    Make necessary delay.

    Args:
        ad: Android device object.

    Returns:
        True if setup successfully.
        False for errors.
    """
    return phone_setup_data_general_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultDataSubId())


def phone_setup_data_general_for_subscription(log, ad, sub_id):
    """Setup phone for data general test for subscription id.

    Make sure phone attached to data.
    Make necessary delay.

    Args:
        ad: Android device object.
        sub_id: subscription id.

    Returns:
        True if setup successfully.
        False for errors.
    """
    toggle_airplane_mode(log, ad, False, strict_checking=False)
    if not wait_for_data_attach_for_subscription(log, ad, sub_id,
                                                 MAX_WAIT_TIME_NW_SELECTION):
        # if phone can not attach data, try reset network preference settings
        reset_preferred_network_type_to_allowable_range(log, ad)

    return wait_for_data_attach_for_subscription(log, ad, sub_id,
                                                 MAX_WAIT_TIME_NW_SELECTION)


def phone_setup_rat_for_subscription(log, ad, sub_id, network_preference,
                                     rat_family):
    toggle_airplane_mode(log, ad, False, strict_checking=False)
    set_wifi_to_default(log, ad)
    if not set_wfc_mode(log, ad, WFC_MODE_DISABLED):
        ad.log.error("Disable WFC failed.")
        return False
    return ensure_network_rat_for_subscription(log, ad, sub_id,
                                               network_preference, rat_family)


def phone_setup_lte_gsm_wcdma(log, ad):
    return phone_setup_lte_gsm_wcdma_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId())


def phone_setup_lte_gsm_wcdma_for_subscription(log, ad, sub_id):
    return phone_setup_rat_for_subscription(
        log, ad, sub_id, NETWORK_MODE_LTE_GSM_WCDMA, RAT_FAMILY_LTE)


def phone_setup_gsm_umts(log, ad):
    return phone_setup_gsm_umts_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId())


def phone_setup_gsm_umts_for_subscription(log, ad, sub_id):
    return phone_setup_rat_for_subscription(
        log, ad, sub_id, NETWORK_MODE_GSM_UMTS, RAT_FAMILY_WCDMA)


def phone_setup_gsm_only(log, ad):
    return phone_setup_gsm_only_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId())


def phone_setup_gsm_only_for_subscription(log, ad, sub_id):
    return phone_setup_rat_for_subscription(
        log, ad, sub_id, NETWORK_MODE_GSM_ONLY, RAT_FAMILY_GSM)


def phone_setup_lte_cdma_evdo(log, ad):
    return phone_setup_lte_cdma_evdo_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId())


def phone_setup_lte_cdma_evdo_for_subscription(log, ad, sub_id):
    return phone_setup_rat_for_subscription(
        log, ad, sub_id, NETWORK_MODE_LTE_CDMA_EVDO, RAT_FAMILY_LTE)


def phone_setup_cdma(log, ad):
    return phone_setup_cdma_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId())


def phone_setup_cdma_for_subscription(log, ad, sub_id):
    return phone_setup_rat_for_subscription(log, ad, sub_id, NETWORK_MODE_CDMA,
                                            RAT_FAMILY_CDMA2000)


def phone_idle_volte(log, ad):
    """Return if phone is idle for VoLTE call test.

    Args:
        ad: Android device object.
    """
    return phone_idle_volte_for_subscription(log, ad,
                                             get_outgoing_voice_sub_id(ad))


def phone_idle_volte_for_subscription(log, ad, sub_id, nw_gen=GEN_4G,
                                    nr_type=None):
    """Return if phone is idle for VoLTE call test for subscription id.
    Args:
        ad: Android device object.
        sub_id: subscription id.
        nw_gen: GEN_4G or GEN_5G.
        nr_type: NR network type e.g. NSA, SA, MMWAVE
    """
    if nw_gen == GEN_5G:
        if not is_current_network_5g_for_subscription(ad, sub_id=sub_id,
                                            nr_type=nr_type):
            ad.log.error("Not in 5G coverage.")
            return False
    else:
        if not wait_for_network_rat_for_subscription(
                log, ad, sub_id, RAT_FAMILY_LTE,
                voice_or_data=NETWORK_SERVICE_VOICE):
            ad.log.error("Voice rat not in LTE mode.")
            return False
    if not wait_for_volte_enabled(log, ad, MAX_WAIT_TIME_VOLTE_ENABLED, sub_id):
        ad.log.error(
            "Failed to <report volte enabled true> within %s seconds.",
            MAX_WAIT_TIME_VOLTE_ENABLED)
        return False
    return True


def phone_idle_iwlan(log, ad):
    """Return if phone is idle for WiFi calling call test.

    Args:
        ad: Android device object.
    """
    return phone_idle_iwlan_for_subscription(log, ad,
                                             get_outgoing_voice_sub_id(ad))


def phone_idle_iwlan_for_subscription(log, ad, sub_id):
    """Return if phone is idle for WiFi calling call test for subscription id.

    Args:
        ad: Android device object.
        sub_id: subscription id.
    """
    if not wait_for_wfc_enabled(log, ad, MAX_WAIT_TIME_WFC_ENABLED):
        ad.log.error("Failed to <report wfc enabled true> within %s seconds.",
                     MAX_WAIT_TIME_WFC_ENABLED)
        return False
    return True


def phone_idle_not_iwlan(log, ad):
    """Return if phone is idle for non WiFi calling call test.

    Args:
        ad: Android device object.
    """
    return phone_idle_not_iwlan_for_subscription(log, ad,
                                                 get_outgoing_voice_sub_id(ad))


def phone_idle_not_iwlan_for_subscription(log, ad, sub_id):
    """Return if phone is idle for non WiFi calling call test for sub id.

    Args:
        ad: Android device object.
        sub_id: subscription id.
    """
    if not wait_for_not_network_rat_for_subscription(
            log, ad, sub_id, RAT_FAMILY_WLAN,
            voice_or_data=NETWORK_SERVICE_DATA):
        log.error("{} data rat in iwlan mode.".format(ad.serial))
        return False
    return True


def phone_idle_csfb(log, ad):
    """Return if phone is idle for CSFB call test.

    Args:
        ad: Android device object.
    """
    return phone_idle_csfb_for_subscription(log, ad,
                                            get_outgoing_voice_sub_id(ad))


def phone_idle_csfb_for_subscription(log, ad, sub_id, nw_gen=GEN_4G, nr_type=None):
    """Return if phone is idle for CSFB call test for subscription id.

    Args:
        ad: Android device object.
        sub_id: subscription id.
        nw_gen: GEN_4G or GEN_5G
    """
    if nw_gen == GEN_5G:
        if not is_current_network_5g_for_subscription(ad, sub_id=sub_id, nr_type=nr_type):
            ad.log.error("Not in 5G coverage.")
            return False
    else:
        if not wait_for_network_rat_for_subscription(
                log, ad, sub_id, RAT_FAMILY_LTE,
                voice_or_data=NETWORK_SERVICE_DATA):
            ad.log.error("Data rat not in lte mode.")
            return False
    return True


def phone_idle_3g(log, ad):
    """Return if phone is idle for 3G call test.

    Args:
        ad: Android device object.
    """
    return phone_idle_3g_for_subscription(log, ad,
                                          get_outgoing_voice_sub_id(ad))


def phone_idle_3g_for_subscription(log, ad, sub_id):
    """Return if phone is idle for 3G call test for subscription id.

    Args:
        ad: Android device object.
        sub_id: subscription id.
    """
    return wait_for_network_generation_for_subscription(
        log, ad, sub_id, GEN_3G, voice_or_data=NETWORK_SERVICE_VOICE)


def phone_idle_2g(log, ad):
    """Return if phone is idle for 2G call test.

    Args:
        ad: Android device object.
    """
    return phone_idle_2g_for_subscription(log, ad,
                                          get_outgoing_voice_sub_id(ad))


def phone_idle_2g_for_subscription(log, ad, sub_id):
    """Return if phone is idle for 2G call test for subscription id.

    Args:
        ad: Android device object.
        sub_id: subscription id.
    """
    return wait_for_network_generation_for_subscription(
        log, ad, sub_id, GEN_2G, voice_or_data=NETWORK_SERVICE_VOICE)


def phone_setup_on_rat(
    log,
    ad,
    rat='volte',
    sub_id=None,
    is_airplane_mode=False,
    wfc_mode=None,
    wifi_ssid=None,
    wifi_pwd=None,
    only_return_fn=None,
    sub_id_type='voice',
    nr_type='nsa'):

    if sub_id is None:
        if sub_id_type == 'sms':
            sub_id = get_outgoing_message_sub_id(ad)
        else:
            sub_id = get_outgoing_voice_sub_id(ad)

    if get_default_data_sub_id(ad) != sub_id and '5g' in rat.lower():
        ad.log.warning('Default data sub ID is NOT given sub ID %s.', sub_id)
        network_preference = network_preference_for_generation(
            GEN_5G,
            ad.telephony["subscription"][sub_id]["operator"],
            ad.telephony["subscription"][sub_id]["phone_type"])

        ad.log.info("Network preference for %s is %s", GEN_5G,
                    network_preference)

        if not set_preferred_network_mode_pref(log, ad, sub_id,
            network_preference):
            return False

        if not wait_for_network_generation_for_subscription(
            log,
            ad,
            sub_id,
            GEN_5G,
            max_wait_time=30,
            voice_or_data=NETWORK_SERVICE_DATA,
            nr_type=nr_type):

            ad.log.warning('Non-DDS slot (sub ID: %s) cannot attach 5G network.', sub_id)
            ad.log.info('Check if sub ID %s can attach LTE network.', sub_id)

            if not wait_for_network_generation_for_subscription(
                log,
                ad,
                sub_id,
                GEN_4G,
                voice_or_data=NETWORK_SERVICE_DATA):
                return False

            if "volte" in rat.lower():
                phone_setup_volte_for_subscription(log, ad, sub_id, None)
            elif "wfc" in rat.lower():
                return phone_setup_iwlan_for_subscription(
                    log,
                    ad,
                    sub_id,
                    is_airplane_mode,
                    wfc_mode,
                    wifi_ssid,
                    wifi_pwd)
            elif "csfb" in rat.lower():
                return phone_setup_csfb_for_subscription(log, ad, sub_id, None)
            return True

    if rat.lower() == '5g_volte':
        if only_return_fn:
            return phone_setup_volte_for_subscription
        else:
            return phone_setup_volte_for_subscription(log, ad, sub_id, GEN_5G, nr_type='nsa')

    elif rat.lower() == '5g_nsa_mmw_volte':
        if only_return_fn:
            return phone_setup_volte_for_subscription
        else:
            return phone_setup_volte_for_subscription(log, ad, sub_id, GEN_5G,
                                                    nr_type='mmwave')

    elif rat.lower() == '5g_csfb':
        if only_return_fn:
            return phone_setup_csfb_for_subscription
        else:
            return phone_setup_csfb_for_subscription(log, ad, sub_id, GEN_5G, nr_type='nsa')

    elif rat.lower() == '5g_wfc':
        if only_return_fn:
            return phone_setup_iwlan_for_subscription
        else:
            return phone_setup_iwlan_for_subscription(
                log,
                ad,
                sub_id,
                is_airplane_mode,
                wfc_mode,
                wifi_ssid,
                wifi_pwd,
                GEN_5G,
                nr_type='nsa')

    elif rat.lower() == '5g_nsa_mmw_wfc':
        if only_return_fn:
            return phone_setup_iwlan_for_subscription
        else:
            return phone_setup_iwlan_for_subscription(
                log,
                ad,
                sub_id,
                is_airplane_mode,
                wfc_mode,
                wifi_ssid,
                wifi_pwd,
                GEN_5G,
                nr_type='mmwave')

    elif rat.lower() == 'volte':
        if only_return_fn:
            return phone_setup_volte_for_subscription
        else:
            return phone_setup_volte_for_subscription(log, ad, sub_id)

    elif rat.lower() == 'csfb':
        if only_return_fn:
            return phone_setup_csfb_for_subscription
        else:
            return phone_setup_csfb_for_subscription(log, ad, sub_id)

    elif rat.lower() == '5g':
        if only_return_fn:
            return phone_setup_5g_for_subscription
        else:
            return phone_setup_5g_for_subscription(log, ad, sub_id, nr_type='nsa')

    elif rat.lower() == '5g_nsa_mmwave':
        if only_return_fn:
            return phone_setup_5g_for_subscription
        else:
            return phone_setup_5g_for_subscription(log, ad, sub_id,
                                            nr_type='mmwave')

    elif rat.lower() == '3g':
        if only_return_fn:
            return phone_setup_voice_3g_for_subscription
        else:
            return phone_setup_voice_3g_for_subscription(log, ad, sub_id)

    elif rat.lower() == '2g':
        if only_return_fn:
            return phone_setup_voice_2g_for_subscription
        else:
            return phone_setup_voice_2g_for_subscription(log, ad, sub_id)

    elif rat.lower() == 'wfc':
        if only_return_fn:
            return phone_setup_iwlan_for_subscription
        else:
            return phone_setup_iwlan_for_subscription(
                log,
                ad,
                sub_id,
                is_airplane_mode,
                wfc_mode,
                wifi_ssid,
                wifi_pwd)
    elif rat.lower() == 'default':
        if only_return_fn:
            return ensure_phone_default_state
        else:
            return ensure_phone_default_state(log, ad)
    else:
        if only_return_fn:
            return phone_setup_voice_general_for_subscription
        else:
            return phone_setup_voice_general_for_subscription(log, ad, sub_id)


def wait_for_network_idle(
    log,
    ad,
    rat,
    sub_id,
    nr_type='nsa'):
    """Wait for attaching to network with assigned RAT and IMS/WFC registration

    This function can be used right after network service recovery after turning
    off airplane mode or switching DDS. It will ensure DUT has attached to the
    network with assigned RAT, and VoLTE/WFC has been ready.

    Args:
        log: log object
        ad: Android object
        rat: following RAT are supported:
            - 5g
            - 5g_volte
            - 5g_csfb
            - 5g_wfc
            - 4g (LTE)
            - volte (LTE)
            - csfb (LTE)
            - wfc (LTE)

    Returns:
        True or False
    """
    if get_default_data_sub_id(ad) != sub_id and '5g' in rat.lower():
        ad.log.warning('Default data sub ID is NOT given sub ID %s.', sub_id)
        network_preference = network_preference_for_generation(
            GEN_5G,
            ad.telephony["subscription"][sub_id]["operator"],
            ad.telephony["subscription"][sub_id]["phone_type"])

        ad.log.info("Network preference for %s is %s", GEN_5G,
                    network_preference)

        if not set_preferred_network_mode_pref(log, ad, sub_id,
            network_preference):
            return False

        if not wait_for_network_generation_for_subscription(
            log,
            ad,
            sub_id,
            GEN_5G,
            max_wait_time=30,
            voice_or_data=NETWORK_SERVICE_DATA,
            nr_type=nr_type):

            ad.log.warning('Non-DDS slot (sub ID: %s) cannot attach 5G network.', sub_id)
            ad.log.info('Check if sub ID %s can attach LTE network.', sub_id)

            if not wait_for_network_generation_for_subscription(
                log,
                ad,
                sub_id,
                GEN_4G,
                voice_or_data=NETWORK_SERVICE_DATA):
                return False

            if rat.lower() == '5g':
                rat = '4g'
            elif rat.lower() == '5g_volte':
                rat = 'volte'
            elif rat.lower() == '5g_wfc':
                rat = 'wfc'
            elif rat.lower() == '5g_csfb':
                rat = 'csfb'

    if rat.lower() == '5g_volte':
        if not phone_idle_volte_for_subscription(log, ad, sub_id, GEN_5G, nr_type=nr_type):
            return False
    elif rat.lower() == '5g_csfb':
        if not phone_idle_csfb_for_subscription(log, ad, sub_id, GEN_5G, nr_type=nr_type):
            return False
    elif rat.lower() == '5g_wfc':
        if not wait_for_network_generation_for_subscription(
            log,
            ad,
            sub_id,
            GEN_5G,
            voice_or_data=NETWORK_SERVICE_DATA,
            nr_type=nr_type):
            return False
        if not wait_for_wfc_enabled(log, ad):
            return False
    elif rat.lower() == '5g':
        if not wait_for_network_generation_for_subscription(
            log,
            ad,
            sub_id,
            GEN_5G,
            voice_or_data=NETWORK_SERVICE_DATA,
            nr_type=nr_type):
            return False
    elif rat.lower() == 'volte':
        if not phone_idle_volte_for_subscription(log, ad, sub_id, GEN_4G):
            return False
    elif rat.lower() == 'csfb':
        if not phone_idle_csfb_for_subscription(log, ad, sub_id, GEN_4G):
            return False
    elif rat.lower() == 'wfc':
        if not wait_for_network_generation_for_subscription(
            log,
            ad,
            sub_id,
            GEN_4G,
            voice_or_data=NETWORK_SERVICE_DATA):
            return False
        if not wait_for_wfc_enabled(log, ad):
            return False
    elif rat.lower() == '4g':
        if not wait_for_network_generation_for_subscription(
            log,
            ad,
            sub_id,
            GEN_4G,
            voice_or_data=NETWORK_SERVICE_DATA):
            return False
    return True


def ensure_preferred_network_type_for_subscription(
        ad,
        network_preference
        ):
    sub_id = ad.droid.subscriptionGetDefaultSubId()
    if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
            network_preference, sub_id):
        ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
                     sub_id, network_preference)
    return True


def ensure_network_rat(log,
                       ad,
                       network_preference,
                       rat_family,
                       voice_or_data=None,
                       max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
                       toggle_apm_after_setting=False):
    """Ensure ad's current network is in expected rat_family.
    """
    return ensure_network_rat_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
        rat_family, voice_or_data, max_wait_time, toggle_apm_after_setting)


def ensure_network_rat_for_subscription(
        log,
        ad,
        sub_id,
        network_preference,
        rat_family,
        voice_or_data=None,
        max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
        toggle_apm_after_setting=False):
    """Ensure ad's current network is in expected rat_family.
    """
    if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
            network_preference, sub_id):
        ad.log.error("Set sub_id %s Preferred Networks Type %s failed.",
                     sub_id, network_preference)
        return False
    if is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family,
                                               voice_or_data):
        ad.log.info("Sub_id %s in RAT %s for %s", sub_id, rat_family,
                    voice_or_data)
        return True

    if toggle_apm_after_setting:
        toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
        time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
        toggle_airplane_mode(log, ad, new_state=None, strict_checking=False)

    result = wait_for_network_rat_for_subscription(
        log, ad, sub_id, rat_family, max_wait_time, voice_or_data)

    log.info(
        "End of ensure_network_rat_for_subscription for %s. "
        "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
        "data: %s(family: %s)", ad.serial, network_preference, rat_family,
        voice_or_data,
        ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
        rat_family_from_rat(
            ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
                sub_id)),
        ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
        rat_family_from_rat(
            ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
                sub_id)))
    return result


def ensure_network_preference(log,
                              ad,
                              network_preference,
                              voice_or_data=None,
                              max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
                              toggle_apm_after_setting=False):
    """Ensure that current rat is within the device's preferred network rats.
    """
    return ensure_network_preference_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
        voice_or_data, max_wait_time, toggle_apm_after_setting)


def ensure_network_preference_for_subscription(
        log,
        ad,
        sub_id,
        network_preference,
        voice_or_data=None,
        max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
        toggle_apm_after_setting=False):
    """Ensure ad's network preference is <network_preference> for sub_id.
    """
    rat_family_list = rat_families_for_network_preference(network_preference)
    if not ad.droid.telephonySetPreferredNetworkTypesForSubscription(
            network_preference, sub_id):
        log.error("Set Preferred Networks failed.")
        return False
    if is_droid_in_rat_family_list_for_subscription(
            log, ad, sub_id, rat_family_list, voice_or_data):
        return True

    if toggle_apm_after_setting:
        toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
        time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
        toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)

    result = wait_for_preferred_network_for_subscription(
        log, ad, sub_id, network_preference, max_wait_time, voice_or_data)

    ad.log.info(
        "End of ensure_network_preference_for_subscription. "
        "Setting to %s, Expecting %s %s. Current: voice: %s(family: %s), "
        "data: %s(family: %s)", network_preference, rat_family_list,
        voice_or_data,
        ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
        rat_family_from_rat(
            ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
                sub_id)),
        ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
        rat_family_from_rat(
            ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
                sub_id)))
    return result


def ensure_network_generation(log,
                              ad,
                              generation,
                              max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
                              voice_or_data=None,
                              toggle_apm_after_setting=False,
                              nr_type=None):
    """Ensure ad's network is <network generation> for default subscription ID.

    Set preferred network generation to <generation>.
    Toggle ON/OFF airplane mode if necessary.
    Wait for ad in expected network type.
    """
    return ensure_network_generation_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
        max_wait_time, voice_or_data, toggle_apm_after_setting, nr_type=nr_type)


def ensure_network_generation_for_subscription(
        log,
        ad,
        sub_id,
        generation,
        max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
        voice_or_data=None,
        toggle_apm_after_setting=False,
        nr_type=None):
    """Ensure ad's network is <network generation> for specified subscription ID.

        Set preferred network generation to <generation>.
        Toggle ON/OFF airplane mode if necessary.
        Wait for ad in expected network type.

    Args:
        log: log object.
        ad: android device object.
        sub_id: subscription id.
        generation: network generation, e.g. GEN_2G, GEN_3G, GEN_4G, GEN_5G.
        max_wait_time: the time to wait for NW selection.
        voice_or_data: check voice network generation or data network generation
            This parameter is optional. If voice_or_data is None, then if
            either voice or data in expected generation, function will return True.
        toggle_apm_after_setting: Cycle airplane mode if True, otherwise do nothing.

    Returns:
        True if success, False if fail.
    """
    ad.log.info(
        "RAT network type voice: %s, data: %s",
        ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
        ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id))

    try:
        ad.log.info("Finding the network preference for generation %s for "
                    "operator %s phone type %s", generation,
                    ad.telephony["subscription"][sub_id]["operator"],
                    ad.telephony["subscription"][sub_id]["phone_type"])
        network_preference = network_preference_for_generation(
            generation, ad.telephony["subscription"][sub_id]["operator"],
            ad.telephony["subscription"][sub_id]["phone_type"])
        if ad.telephony["subscription"][sub_id]["operator"] == CARRIER_FRE \
            and generation == GEN_4G:
            network_preference = NETWORK_MODE_LTE_ONLY
        ad.log.info("Network preference for %s is %s", generation,
                    network_preference)
        rat_family = rat_family_for_generation(
            generation, ad.telephony["subscription"][sub_id]["operator"],
            ad.telephony["subscription"][sub_id]["phone_type"])
    except KeyError as e:
        ad.log.error("Failed to find a rat_family entry for generation %s"
                     " for subscriber id %s with error %s", generation,
                     sub_id, e)
        return False

    if not set_preferred_network_mode_pref(log, ad, sub_id,
                                           network_preference):
        return False

    if hasattr(ad, "dsds") and voice_or_data == "data" and sub_id != get_default_data_sub_id(ad):
        ad.log.info("MSIM - Non DDS, ignore data RAT")
        return True

    if (generation == GEN_5G) or (generation == RAT_5G):
        if is_current_network_5g_for_subscription(ad, sub_id=sub_id,
                                        nr_type=nr_type):
            ad.log.info("Current network type is 5G.")
            return True
        else:
            ad.log.error("Not in 5G coverage for Sub %s.", sub_id)
            return False

    if is_droid_in_network_generation_for_subscription(
            log, ad, sub_id, generation, voice_or_data):
        return True

    if toggle_apm_after_setting:
        toggle_airplane_mode(log, ad, new_state=True, strict_checking=False)
        time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
        toggle_airplane_mode(log, ad, new_state=False, strict_checking=False)

    result = wait_for_network_generation_for_subscription(
        log, ad, sub_id, generation, max_wait_time, voice_or_data)

    ad.log.info(
        "Ensure network %s %s %s. With network preference %s, "
        "current: voice: %s(family: %s), data: %s(family: %s)", generation,
        voice_or_data, result, network_preference,
        ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(sub_id),
        rat_generation_from_rat(
            ad.droid.telephonyGetCurrentVoiceNetworkTypeForSubscription(
                sub_id)),
        ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(sub_id),
        rat_generation_from_rat(
            ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
                sub_id)))
    if not result:
        get_telephony_signal_strength(ad)
    return result


def wait_for_network_rat(log,
                         ad,
                         rat_family,
                         max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
                         voice_or_data=None):
    return wait_for_network_rat_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
        max_wait_time, voice_or_data)


def wait_for_network_rat_for_subscription(
        log,
        ad,
        sub_id,
        rat_family,
        max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
        voice_or_data=None):
    return _wait_for_droid_in_state_for_subscription(
        log, ad, sub_id, max_wait_time,
        is_droid_in_rat_family_for_subscription, rat_family, voice_or_data)


def wait_for_not_network_rat(log,
                             ad,
                             rat_family,
                             max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
                             voice_or_data=None):
    return wait_for_not_network_rat_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId(), rat_family,
        max_wait_time, voice_or_data)


def wait_for_not_network_rat_for_subscription(
        log,
        ad,
        sub_id,
        rat_family,
        max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
        voice_or_data=None):
    return _wait_for_droid_in_state_for_subscription(
        log, ad, sub_id, max_wait_time,
        lambda log, ad, sub_id, *args, **kwargs: not is_droid_in_rat_family_for_subscription(log, ad, sub_id, rat_family, voice_or_data)
    )


def wait_for_preferred_network(log,
                               ad,
                               network_preference,
                               max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
                               voice_or_data=None):
    return wait_for_preferred_network_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId(), network_preference,
        max_wait_time, voice_or_data)


def wait_for_preferred_network_for_subscription(
        log,
        ad,
        sub_id,
        network_preference,
        max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
        voice_or_data=None):
    rat_family_list = rat_families_for_network_preference(network_preference)
    return _wait_for_droid_in_state_for_subscription(
        log, ad, sub_id, max_wait_time,
        is_droid_in_rat_family_list_for_subscription, rat_family_list,
        voice_or_data)


def wait_for_network_generation(log,
                                ad,
                                generation,
                                max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
                                voice_or_data=None):
    return wait_for_network_generation_for_subscription(
        log, ad, ad.droid.subscriptionGetDefaultSubId(), generation,
        max_wait_time, voice_or_data)


def wait_for_network_generation_for_subscription(
        log,
        ad,
        sub_id,
        generation,
        max_wait_time=MAX_WAIT_TIME_NW_SELECTION,
        voice_or_data=None,
        nr_type=None):

    if generation == GEN_5G:
        if is_current_network_5g_for_subscription(ad, sub_id=sub_id, nr_type=nr_type):
            ad.log.info("Current network type is 5G.")
            return True
        else:
            ad.log.error("Not in 5G coverage for Sub %s.", sub_id)
            return False

    return _wait_for_droid_in_state_for_subscription(
        log, ad, sub_id, max_wait_time,
        is_droid_in_network_generation_for_subscription, generation,
        voice_or_data)


def ensure_phones_idle(log, ads, max_time=MAX_WAIT_TIME_CALL_DROP):
    """Ensure ads idle (not in call).
    """
    result = True
    for ad in ads:
        if not ensure_phone_idle(log, ad, max_time=max_time):
            result = False
    return result


def ensure_phone_idle(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP, retry=2):
    """Ensure ad idle (not in call).
    """
    while ad.droid.telecomIsInCall() and retry > 0:
        ad.droid.telecomEndCall()
        time.sleep(3)
        retry -= 1
    if not wait_for_droid_not_in_call(log, ad, max_time=max_time):
        ad.log.error("Failed to end call")
        return False
    return True


def ensure_phone_subscription(log, ad):
    """Ensure Phone Subscription.
    """
    #check for sim and service
    duration = 0
    while duration < MAX_WAIT_TIME_NW_SELECTION:
        subInfo = ad.droid.subscriptionGetAllSubInfoList()
        if subInfo and len(subInfo) >= 1:
            ad.log.debug("Find valid subcription %s", subInfo)
            break
        else:
            ad.log.info("Did not find any subscription")
            time.sleep(5)
            duration += 5
    else:
        ad.log.error("Unable to find a valid subscription!")
        return False
    while duration < MAX_WAIT_TIME_NW_SELECTION:
        data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
        voice_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
        if data_sub_id > INVALID_SUB_ID or voice_sub_id > INVALID_SUB_ID:
            ad.log.debug("Find valid voice or data sub id")
            break
        else:
            ad.log.info("Did not find valid data or voice sub id")
            time.sleep(5)
            duration += 5
    else:
        ad.log.error("Unable to find valid data or voice sub id")
        return False
    while duration < MAX_WAIT_TIME_NW_SELECTION:
        data_sub_id = ad.droid.subscriptionGetDefaultDataSubId()
        if data_sub_id > INVALID_SUB_ID:
            data_rat = get_network_rat_for_subscription(
                log, ad, data_sub_id, NETWORK_SERVICE_DATA)
        else:
            data_rat = RAT_UNKNOWN
        if voice_sub_id > INVALID_SUB_ID:
            voice_rat = get_network_rat_for_subscription(
                log, ad, voice_sub_id, NETWORK_SERVICE_VOICE)
        else:
            voice_rat = RAT_UNKNOWN
        if data_rat != RAT_UNKNOWN or voice_rat != RAT_UNKNOWN:
            ad.log.info("Data sub_id %s in %s, voice sub_id %s in %s",
                        data_sub_id, data_rat, voice_sub_id, voice_rat)
            return True
        else:
            ad.log.info("Did not attach for data or voice service")
            time.sleep(5)
            duration += 5
    else:
        ad.log.error("Did not attach for voice or data service")
        return False


def ensure_phone_default_state(log, ad, check_subscription=True, retry=2):
    """Ensure ad in default state.
    Phone not in call.
    Phone have no stored WiFi network and WiFi disconnected.
    Phone not in airplane mode.
    """
    result = True
    if not toggle_airplane_mode(log, ad, False, False):
        ad.log.error("Fail to turn off airplane mode")
        result = False
    try:
        set_wifi_to_default(log, ad)
        while ad.droid.telecomIsInCall() and retry > 0:
            ad.droid.telecomEndCall()
            time.sleep(3)
            retry -= 1
        if not wait_for_droid_not_in_call(log, ad):
            ad.log.error("Failed to end call")
        #ad.droid.telephonyFactoryReset()
        data_roaming = getattr(ad, 'roaming', False)
        if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
            set_cell_data_roaming_state_by_adb(ad, data_roaming)
        #remove_mobile_data_usage_limit(ad)
        if not wait_for_not_network_rat(
                log, ad, RAT_FAMILY_WLAN, voice_or_data=NETWORK_SERVICE_DATA):
            ad.log.error("%s still in %s", NETWORK_SERVICE_DATA,
                         RAT_FAMILY_WLAN)
            result = False

        if check_subscription and not ensure_phone_subscription(log, ad):
            ad.log.error("Unable to find a valid subscription!")
            result = False
    except Exception as e:
        ad.log.error("%s failure, toggle APM instead", e)
        toggle_airplane_mode_by_adb(log, ad, True)
        toggle_airplane_mode_by_adb(log, ad, False)
        ad.send_keycode("ENDCALL")
        ad.adb.shell("settings put global wfc_ims_enabled 0")
        ad.adb.shell("settings put global mobile_data 1")

    return result


def ensure_phones_default_state(log, ads, check_subscription=True):
    """Ensure ads in default state.
    Phone not in call.
    Phone have no stored WiFi network and WiFi disconnected.
    Phone not in airplane mode.

    Returns:
        True if all steps of restoring default state succeed.
        False if any of the steps to restore default state fails.
    """
    tasks = []
    for ad in ads:
        tasks.append((ensure_phone_default_state, (log, ad,
                                                   check_subscription)))
    if not multithread_func(log, tasks):
        log.error("Ensure_phones_default_state Fail.")
        return False
    return True


def is_phone_not_in_call(log, ad):
    """Return True if phone not in call.

    Args:
        log: log object.
        ad:  android device.
    """
    in_call = ad.droid.telecomIsInCall()
    call_state = ad.droid.telephonyGetCallState()
    if in_call:
        ad.log.info("Device is In Call")
    if call_state != TELEPHONY_STATE_IDLE:
        ad.log.info("Call_state is %s, not %s", call_state,
                    TELEPHONY_STATE_IDLE)
    return ((not in_call) and (call_state == TELEPHONY_STATE_IDLE))


def wait_for_droid_not_in_call(log, ad, max_time=MAX_WAIT_TIME_CALL_DROP):
    """Wait for android to be not in call state.

    Args:
        log: log object.
        ad:  android device.
        max_time: maximal wait time.

    Returns:
        If phone become not in call state within max_time, return True.
        Return False if timeout.
    """
    return _wait_for_droid_in_state(log, ad, max_time, is_phone_not_in_call)


def wait_for_voice_attach(log, ad, max_time=MAX_WAIT_TIME_NW_SELECTION):
    """Wait for android device to attach on voice.

    Args:
        log: log object.
        ad:  android device.
        max_time: maximal wait time.

    Returns:
        Return True if device attach voice within max_time.
        Return False if timeout.
    """
    return _wait_for_droid_in_state(log, ad, max_time, _is_attached,
                                    NETWORK_SERVICE_VOICE)


def wait_for_voice_attach_for_subscription(
        log, ad, sub_id, max_time=MAX_WAIT_TIME_NW_SELECTION):
    """Wait for android device to attach on voice in subscription id.

    Args:
        log: log object.
        ad:  android device.
        sub_id: subscription id.
        max_time: maximal wait time.

    Returns:
        Return True if device attach voice within max_time.
        Return False if timeout.
    """
    if not _wait_for_droid_in_state_for_subscription(
            log, ad, sub_id, max_time, _is_attached_for_subscription,
            NETWORK_SERVICE_VOICE):
        return False

    # TODO: b/26295983 if pone attach to 1xrtt from unknown, phone may not
    # receive incoming call immediately.
    if ad.droid.telephonyGetCurrentVoiceNetworkType() == RAT_1XRTT:
        time.sleep(WAIT_TIME_1XRTT_VOICE_ATTACH)
    return True