blob: 0a93e8fe767d5d6db24bf2f769419259fdb98ab9 [file] [log] [blame]
#!/usr/bin/env python3
#
# 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.
import re
import time
from datetime import datetime, timedelta
from acts import signals
from acts.utils import rand_ascii_str
from acts.libs.utils.multithread import multithread_func
from acts_contrib.test_utils.tel.loggers.protos.telephony_metric_pb2 import TelephonyVoiceTestResult
from acts_contrib.test_utils.tel.tel_defines import INVALID_SUB_ID
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
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_CELLULAR_PREFERRED
from acts_contrib.test_utils.tel.tel_defines import YOUTUBE_PACKAGE_NAME
from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
from acts_contrib.test_utils.tel.tel_data_utils import start_youtube_video
from acts_contrib.test_utils.tel.tel_message_utils import log_messaging_screen_shot
from acts_contrib.test_utils.tel.tel_message_utils import mms_send_receive_verify
from acts_contrib.test_utils.tel.tel_message_utils import sms_send_receive_verify_for_subscription
from acts_contrib.test_utils.tel.tel_ss_utils import erase_call_forwarding_by_mmi
from acts_contrib.test_utils.tel.tel_ss_utils import set_call_forwarding_by_mmi
from acts_contrib.test_utils.tel.tel_ss_utils import set_call_waiting
from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc_for_subscription
from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode_for_subscription
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_voice_general
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_on_rat
from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_idle
from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_forwarding_short_seq
from acts_contrib.test_utils.tel.tel_ss_utils import three_phone_call_waiting_short_seq
from acts_contrib.test_utils.tel.tel_subscription_utils import get_default_data_sub_id
from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id
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_slot_index_from_subid
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_subid_on_same_network_of_host_ad
from acts_contrib.test_utils.tel.tel_subscription_utils import set_dds_on_slot
from acts_contrib.test_utils.tel.tel_subscription_utils import set_message_subid
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_voice_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import get_operator_name
from acts_contrib.test_utils.tel.tel_test_utils import num_active_calls
from acts_contrib.test_utils.tel.tel_test_utils import power_off_sim
from acts_contrib.test_utils.tel.tel_test_utils import power_on_sim
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state
from acts_contrib.test_utils.tel.tel_test_utils import verify_http_connection
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_ims_conference_merge_drop_second_call_from_participant
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _test_wcdma_conference_merge_drop
from acts_contrib.test_utils.tel.tel_voice_conf_utils import _three_phone_call_mo_add_mt
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 initiate_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_phone_in_call_on_rat
from acts_contrib.test_utils.tel.tel_voice_utils import swap_calls
from acts_contrib.test_utils.tel.tel_voice_utils import two_phone_call_msim_for_slot
from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_reject_call_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 wifi_toggle_state
CallResult = TelephonyVoiceTestResult.CallResult.Value
def dsds_voice_call_test(
log,
tel_logger,
ads,
mo_slot,
mt_slot,
dds,
mo_rat=["", ""],
mt_rat=["", ""],
call_direction="mo",
is_airplane_mode=False,
wfc_mode=[
WFC_MODE_CELLULAR_PREFERRED,
WFC_MODE_CELLULAR_PREFERRED],
wifi_network_ssid=None,
wifi_network_pass=None,
turn_off_wifi_in_the_end=False,
turn_off_airplane_mode_in_the_end=False):
"""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.
6. Turn off airplane mode if necessary.
7. Turn off Wi-Fi if necessary.
8. Verify RAT and HTTP connection.
Args:
log: logger object
tel_logger: logger object for telephony proto
ads: list of android devices
mo_slot: Slot making MO call (0 or 1)
mt_slot: Slot receiving MT call (0 or 1)
dds: 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"
is_airplane_mode: True or False for WFC setup
wfc_mode: Cellular preferred or Wi-Fi preferred.
wifi_network_ssid: SSID of Wi-Fi AP
wifi_network_pass: Password of Wi-Fi AP SSID
turn_off_wifi_in_the_end: True to turn off Wi-Fi and False not to turn
off Wi-Fi in the end of the function.
turn_off_airplane_mode_in_the_end: True to turn off airplane mode and
False not to turn off airplane mode in the end of the function.
Returns:
TestFailure if failed.
"""
if not toggle_airplane_mode(log, ads[0], False):
ads[0].log.error("Failed to disable airplane mode.")
return False
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(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(
log, ad_mo, 1-mo_slot)
set_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_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(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(
log, ad_mt, 1-mt_slot)
set_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_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))
log.info("Step 1: Switch DDS.")
if not set_dds_on_slot(ads[0], dds):
log.error(
"Failed to set DDS at slot %s on %s",(dds, ads[0].serial))
return False
log.info("Step 2: Check HTTP connection after DDS switch.")
if not verify_http_connection(log, ads[0]):
log.error("Failed to verify http connection.")
return False
else:
log.info("Verify http connection successfully.")
log.info("Step 3: Set up phones in desired RAT.")
if mo_slot == 0 or mo_slot == 1:
phone_setup_on_rat(
log,
ad_mo,
mo_rat[1-mo_slot],
mo_other_sub_id,
is_airplane_mode,
wfc_mode[1-mo_slot],
wifi_network_ssid,
wifi_network_pass)
mo_phone_setup_func_argv = (
log,
ad_mo,
mo_rat[mo_slot],
mo_sub_id,
is_airplane_mode,
wfc_mode[mo_slot],
wifi_network_ssid,
wifi_network_pass)
is_mo_in_call = is_phone_in_call_on_rat(
log, ad_mo, mo_rat[mo_slot], only_return_fn=True)
else:
mo_phone_setup_func_argv = (log, ad_mo, 'general')
is_mo_in_call = is_phone_in_call_on_rat(
log, ad_mo, 'general', only_return_fn=True)
if mt_slot == 0 or mt_slot == 1:
phone_setup_on_rat(
log,
ad_mt,
mt_rat[1-mt_slot],
mt_other_sub_id,
is_airplane_mode,
wfc_mode[1-mt_slot],
wifi_network_ssid,
wifi_network_pass)
mt_phone_setup_func_argv = (
log,
ad_mt,
mt_rat[mt_slot],
mt_sub_id,
is_airplane_mode,
wfc_mode[mt_slot],
wifi_network_ssid,
wifi_network_pass)
is_mt_in_call = is_phone_in_call_on_rat(
log, ad_mt, mt_rat[mt_slot], only_return_fn=True)
else:
mt_phone_setup_func_argv = (log, ad_mt, 'general')
is_mt_in_call = is_phone_in_call_on_rat(
log, ad_mt, 'general', only_return_fn=True)
tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
(phone_setup_on_rat, mt_phone_setup_func_argv)]
if not multithread_func(log, tasks):
log.error("Phone Failed to Set Up Properly.")
tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure("Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
log.info("Step 4: Make voice call.")
result = two_phone_call_msim_for_slot(
log,
ad_mo,
get_slot_index_from_subid(ad_mo, mo_sub_id),
None,
is_mo_in_call,
ad_mt,
get_slot_index_from_subid(ad_mt, mt_sub_id),
None,
is_mt_in_call)
tel_logger.set_result(result.result_value)
if not result:
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)})
log.info("Step 5: Verify RAT and HTTP connection.")
if call_direction == "mo":
rat_list = [mo_rat[mo_slot], mo_rat[1-mo_slot]]
sub_id_list = [mo_sub_id, mo_other_sub_id]
else:
rat_list = [mt_rat[mt_slot], mt_rat[1-mt_slot]]
sub_id_list = [mt_sub_id, mt_other_sub_id]
# For the tese cases related to WFC in which airplane mode will be turned
# off in the end.
if turn_off_airplane_mode_in_the_end:
log.info("Step 5-1: Turning off airplane mode......")
if not toggle_airplane_mode(log, ads[0], False):
ads[0].log.error('Failed to toggle off airplane mode.')
# For the tese cases related to WFC in which Wi-Fi will be turned off in the
# end.
if turn_off_wifi_in_the_end:
log.info("Step 5-2: Turning off Wi-Fi......")
if not wifi_toggle_state(log, ads[0], False):
ads[0].log.error('Failed to toggle off Wi-Fi.')
return False
for index, value in enumerate(rat_list):
if value == '5g_wfc':
rat_list[index] = '5g'
elif value == 'wfc':
rat_list[index] = '4g'
for rat, sub_id in zip(rat_list, sub_id_list):
if not wait_for_network_idle(log, ads[0], rat, sub_id):
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Idle state of sub ID %s does not match the "
"given RAT %s." % (sub_id, rat)})
def dsds_message_test(
log,
ads,
mo_slot,
mt_slot,
dds_slot,
msg="SMS",
mo_rat=["", ""],
mt_rat=["", ""],
direction="mo",
streaming=False,
expected_result=True):
"""Make MO/MT SMS/MMS 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. Send SMS/MMS.
Args:
mo_slot: Slot sending MO SMS (0 or 1)
mt_slot: Slot receiving MT SMS (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
direction: "mo" or "mt"
streaming: True for playing Youtube before send/receive SMS/MMS and
False on the contrary.
expected_result: True or False
Returns:
TestFailure if failed.
"""
if 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(log, ad_mo, mo_slot)
if mo_sub_id == INVALID_SUB_ID:
ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
return False
mo_other_sub_id = get_subid_from_slot_index(
log, ad_mo, 1-mo_slot)
set_message_subid(ad_mo, mo_sub_id)
else:
_, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
ads, type="sms")
if mo_sub_id == INVALID_SUB_ID:
ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
return False
mo_slot = "auto"
set_message_subid(ad_mo, mo_sub_id)
if msg == "MMS":
set_subid_for_data(ad_mo, mo_sub_id)
ad_mo.droid.telephonyToggleDataConnection(True)
ad_mo.log.info("Sub ID for outgoing %s at slot %s: %s", msg, mo_slot,
get_outgoing_message_sub_id(ad_mo))
if mt_slot is not None:
mt_sub_id = get_subid_from_slot_index(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(log, ad_mt, 1-mt_slot)
set_message_subid(ad_mt, mt_sub_id)
else:
_, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
ads, type="sms")
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_message_subid(ad_mt, mt_sub_id)
if msg == "MMS":
set_subid_for_data(ad_mt, mt_sub_id)
ad_mt.droid.telephonyToggleDataConnection(True)
ad_mt.log.info("Sub ID for incoming %s at slot %s: %s", msg, mt_slot,
get_outgoing_message_sub_id(ad_mt))
log.info("Step 1: Switch DDS.")
if not set_dds_on_slot(ads[0], dds_slot):
log.error(
"Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
return False
log.info("Step 2: Check HTTP connection after DDS switch.")
if not verify_http_connection(log, ads[0]):
log.error("Failed to verify http connection.")
return False
else:
log.info("Verify http connection successfully.")
if mo_slot == 0 or mo_slot == 1:
phone_setup_on_rat(log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id)
mo_phone_setup_func_argv = (log, ad_mo, mo_rat[mo_slot], mo_sub_id)
else:
mo_phone_setup_func_argv = (log, ad_mo, 'general', mo_sub_id)
if mt_slot == 0 or mt_slot == 1:
phone_setup_on_rat(log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id)
mt_phone_setup_func_argv = (log, ad_mt, mt_rat[mt_slot], mt_sub_id)
else:
mt_phone_setup_func_argv = (log, ad_mt, 'general', mt_sub_id)
log.info("Step 3: Set up phones in desired RAT.")
tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
(phone_setup_on_rat, mt_phone_setup_func_argv)]
if not multithread_func(log, tasks):
log.error("Phone Failed to Set Up Properly.")
return False
time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
if streaming:
log.info("Step 4: Start Youtube streaming.")
if not start_youtube_video(ads[0]):
log.warning("Fail to bring up youtube video")
time.sleep(10)
else:
log.info("Step 4: Skip Youtube streaming.")
log.info("Step 5: Send %s.", msg)
if msg == "MMS":
for ad, current_data_sub_id, current_msg_sub_id in [
[ ads[0],
get_default_data_sub_id(ads[0]),
get_outgoing_message_sub_id(ads[0]) ],
[ ads[1],
get_default_data_sub_id(ads[1]),
get_outgoing_message_sub_id(ads[1]) ]]:
if current_data_sub_id != current_msg_sub_id:
ad.log.warning(
"Current data sub ID (%s) does not match message"
" sub ID (%s). MMS should NOT be sent.",
current_data_sub_id,
current_msg_sub_id)
expected_result = False
result = msim_message_test(log, ad_mo, ad_mt, mo_sub_id, mt_sub_id,
msg=msg, expected_result=expected_result)
if not result:
log_messaging_screen_shot(ad_mo, test_name="%s_tx" % msg)
log_messaging_screen_shot(ad_mt, test_name="%s_rx" % msg)
if streaming:
ads[0].force_stop_apk(YOUTUBE_PACKAGE_NAME)
return result
def dds_switch_during_data_transfer_test(
log,
tel_logger,
ads,
nw_rat=["volte", "volte"],
call_slot=0,
call_direction=None,
call_or_sms_or_mms="call",
streaming=True,
is_airplane_mode=False,
wfc_mode=[WFC_MODE_CELLULAR_PREFERRED, WFC_MODE_CELLULAR_PREFERRED],
wifi_network_ssid=None,
wifi_network_pass=None):
"""Switch DDS and make voice call(VoLTE/WFC/CS call)/SMS/MMS together with
Youtube playing after each DDS switch at specific slot in specific RAT.
Test step:
1. Get sub ID of each slot of the primary device.
2. Set up phones in desired RAT.
3. Switch DDS to slot 0.
4. Check HTTP connection after DDS switch.
5. Play Youtube.
6. Make voice call (VoLTE/WFC/CS call)/SMS/MMS
7. Switch DDS to slot 1 and repeat step 4-6.
8. Switch DDS to slot 0 again and repeat step 4-6.
Args:
log: logger object
tel_logger: logger object for telephony proto
ads: list of android devices
nw_rat: RAT for both slots of the primary device
call_slot: Slot for making voice call
call_direction: "mo" or "mt" or None to stoping making call.
call_or_sms_or_mms: Voice call or SMS or MMS
streaming: True for playing Youtube after DDS switch and False on the contrary.
is_airplane_mode: True or False for WFC setup
wfc_mode: Cellular preferred or Wi-Fi preferred.
wifi_network_ssid: SSID of Wi-Fi AP
wifi_network_pass: Password of Wi-Fi AP SSID
Returns:
TestFailure if failed.
"""
ad = ads[0]
slot_0_subid = get_subid_from_slot_index(log, ad, 0)
slot_1_subid = get_subid_from_slot_index(log, ad, 1)
if slot_0_subid == INVALID_SUB_ID or slot_1_subid == INVALID_SUB_ID:
ad.log.error("Not all slots have valid sub ID.")
raise signals.TestFailure("Failed",
extras={"fail_reason": "Not all slots have valid sub ID"})
ad.log.info(
"Step 0: Set up phone in desired RAT (slot 0: %s, slot 1: %s)",
nw_rat[0], nw_rat[1])
if not phone_setup_on_rat(
log,
ad,
nw_rat[0],
slot_0_subid,
is_airplane_mode,
wfc_mode[0],
wifi_network_ssid,
wifi_network_pass):
log.error("Phone Failed to Set Up Properly.")
tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure("Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
if not phone_setup_on_rat(
log,
ad,
nw_rat[1],
slot_1_subid,
is_airplane_mode,
wfc_mode[1],
wifi_network_ssid,
wifi_network_pass):
log.error("Phone Failed to Set Up Properly.")
tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure("Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
is_slot0_in_call = is_phone_in_call_on_rat(
log, ad, nw_rat[0], True)
is_slot1_in_call = is_phone_in_call_on_rat(
log, ad, nw_rat[1], True)
for attempt in range(3):
if attempt != 0:
ad.log.info("Repeat step 1 to 4.")
ad.log.info("Step 1: Switch DDS.")
if attempt % 2 == 0:
set_dds_on_slot(ad, 0)
else:
set_dds_on_slot(ad, 1)
ad.log.info("Step 2: Check HTTP connection after DDS switch.")
if not verify_http_connection(log, ad):
ad.log.error("Failed to verify http connection.")
return False
else:
ad.log.info("Verify http connection successfully.")
if streaming:
ad.log.info("Step 3: Start Youtube streaming.")
if not start_youtube_video(ad):
ad.log.warning("Fail to bring up youtube video")
time.sleep(10)
else:
ad.log.info("Step 3: Skip Youtube streaming.")
if not call_direction:
return True
else:
expected_result = True
if call_direction == "mo":
ad_mo = ads[0]
ad_mt = ads[1]
phone_setup_on_rat(log, ad_mt, 'general')
mo_sub_id = get_subid_from_slot_index(log, ad, call_slot)
if call_or_sms_or_mms == "call":
set_voice_sub_id(ad_mo, mo_sub_id)
_, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
ads)
if call_slot == 0:
is_mo_in_call = is_slot0_in_call
elif call_slot == 1:
is_mo_in_call = is_slot1_in_call
is_mt_in_call = None
elif call_or_sms_or_mms == "sms":
set_message_subid(ad_mo, mo_sub_id)
_, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
ads, type="sms")
set_message_subid(ad_mt, mt_sub_id)
elif call_or_sms_or_mms == "mms":
current_data_sub_id = get_default_data_sub_id(ad_mo)
if mo_sub_id != current_data_sub_id:
ad_mo.log.warning(
"Current data sub ID (%s) does not match"
" message sub ID (%s). MMS should NOT be sent.",
current_data_sub_id, mo_sub_id)
expected_result = False
set_message_subid(ad_mo, mo_sub_id)
_, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(
ads, type="sms")
set_message_subid(ad_mt, mt_sub_id)
set_subid_for_data(ad_mt, mt_sub_id)
ad_mt.droid.telephonyToggleDataConnection(True)
elif call_direction == "mt":
ad_mo = ads[1]
ad_mt = ads[0]
phone_setup_on_rat(log, ad_mo, 'general')
mt_sub_id = get_subid_from_slot_index(log, ad, call_slot)
if call_or_sms_or_mms == "call":
set_voice_sub_id(ad_mt, mt_sub_id)
_, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
ads)
if call_slot == 0:
is_mt_in_call = is_slot0_in_call
elif call_slot == 1:
is_mt_in_call = is_slot1_in_call
is_mo_in_call = None
elif call_or_sms_or_mms == "sms":
set_message_subid(ad_mt, mt_sub_id)
_, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
ads, type="sms")
set_message_subid(ad_mo, mo_sub_id)
elif call_or_sms_or_mms == "mms":
current_data_sub_id = get_default_data_sub_id(ad_mt)
if mt_sub_id != current_data_sub_id:
ad_mt.log.warning(
"Current data sub ID (%s) does not match"
" message sub ID (%s). MMS should NOT be"
" received.", current_data_sub_id, mt_sub_id)
expected_result = False
set_message_subid(ad_mt, mt_sub_id)
_, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(
ads, type="sms")
set_message_subid(ad_mo, mo_sub_id)
set_subid_for_data(ad_mo, mo_sub_id)
ad_mo.droid.telephonyToggleDataConnection(True)
if call_or_sms_or_mms == "call":
log.info("Step 4: Make voice call.")
mo_slot = get_slot_index_from_subid(ad_mo, mo_sub_id)
mt_slot = get_slot_index_from_subid(ad_mt, mt_sub_id)
result = two_phone_call_msim_for_slot(
log,
ad_mo,
mo_slot,
None,
is_mo_in_call,
ad_mt,
mt_slot,
None,
is_mt_in_call)
tel_logger.set_result(result.result_value)
if not result:
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)})
else:
log.info("Step 4: Send %s.", call_or_sms_or_mms)
if call_or_sms_or_mms == "sms":
result = msim_message_test(
ad_mo,
ad_mt,
mo_sub_id,
mt_sub_id,
msg=call_or_sms_or_mms.upper())
elif call_or_sms_or_mms == "mms":
result = msim_message_test(
ad_mo,
ad_mt,
mo_sub_id,
mt_sub_id,
msg=call_or_sms_or_mms.upper(),
expected_result=expected_result)
if not result:
log_messaging_screen_shot(
ad_mo, test_name="%s_tx" % call_or_sms_or_mms)
log_messaging_screen_shot(
ad_mt, test_name="%s_rx" % call_or_sms_or_mms)
return False
if streaming:
ad.force_stop_apk(YOUTUBE_PACKAGE_NAME)
return True
def enable_slot_after_voice_call_test(
log,
tel_logger,
ads,
mo_slot,
mt_slot,
disabled_slot,
mo_rat=["", ""],
mt_rat=["", ""],
call_direction="mo"):
"""Disable/enable pSIM or eSIM with voice call
Test step:
1. Get sub IDs of specific slots of both MO and MT devices.
2. Set up phones in desired RAT.
3. Disable assigned slot.
4. Switch DDS to the other slot.
5. Verify RAT and HTTP connection after DDS switch.
6. Make voice call.
7. Enable assigned slot.
8. Switch DDS to the assigned slot.
9. Verify RAT and HTTP connection after DDS switch.
Args:
log: logger object
tel_logger: logger object for telephony proto
ads: list of android devices
mo_slot: Slot making MO call (0 or 1)
mt_slot: Slot receiving MT call (0 or 1)
disabled_slot: slot to be disabled/enabled
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.
"""
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(log, ad_mo, mo_slot)
if mo_sub_id == INVALID_SUB_ID:
ad_mo.log.warning("Failed to get sub ID at slot %s.", mo_slot)
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Failed to get sub ID at slot %s." % mo_slot})
mo_other_sub_id = get_subid_from_slot_index(
log, ad_mo, 1-mo_slot)
set_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 at slot %s.", mo_slot)
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Failed to get sub ID at slot %s." % mo_slot})
mo_slot = "auto"
set_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(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)
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Failed to get sub ID at slot %s." % mt_slot})
mt_other_sub_id = get_subid_from_slot_index(
log, ad_mt, 1-mt_slot)
set_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)
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Failed to get sub ID at slot %s." % mt_slot})
mt_slot = "auto"
set_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))
if mo_slot == 0 or mo_slot == 1:
phone_setup_on_rat(log, ad_mo, mo_rat[1-mo_slot], mo_other_sub_id)
mo_phone_setup_func_argv = (log, ad_mo, mo_rat[mo_slot], mo_sub_id)
is_mo_in_call = is_phone_in_call_on_rat(
log, ad_mo, mo_rat[mo_slot], only_return_fn=True)
else:
mo_phone_setup_func_argv = (log, ad_mo, 'general')
is_mo_in_call = is_phone_in_call_on_rat(
log, ad_mo, 'general', only_return_fn=True)
if mt_slot == 0 or mt_slot == 1:
phone_setup_on_rat(log, ad_mt, mt_rat[1-mt_slot], mt_other_sub_id)
mt_phone_setup_func_argv = (log, ad_mt, mt_rat[mt_slot], mt_sub_id)
is_mt_in_call = is_phone_in_call_on_rat(
log, ad_mt, mt_rat[mt_slot], only_return_fn=True)
else:
mt_phone_setup_func_argv = (log, ad_mt, 'general')
is_mt_in_call = is_phone_in_call_on_rat(
log, ad_mt, 'general', only_return_fn=True)
log.info("Step 1: Set up phones in desired RAT.")
tasks = [(phone_setup_on_rat, mo_phone_setup_func_argv),
(phone_setup_on_rat, mt_phone_setup_func_argv)]
if not multithread_func(log, tasks):
log.error("Phone Failed to Set Up Properly.")
tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
log.info("Step 2: Disable slot %s.", disabled_slot)
if not power_off_sim(ads[0], disabled_slot):
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Failed to disable slot %s." % disabled_slot})
log.info("Step 3: Switch DDS.")
if not set_dds_on_slot(ads[0], 1-disabled_slot):
log.error(
"Failed to set DDS at slot %s on %s.",
(1-disabled_slot, ads[0].serial))
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to set DDS at slot %s on %s." % (
1-disabled_slot, ads[0].serial)})
log.info("Step 4: Verify RAT and HTTP connection after DDS switch.")
if mo_slot == 0 or mo_slot == 1:
if not wait_for_network_idle(
log, ad_mo, mo_rat[1-disabled_slot], mo_sub_id):
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Idle state does not match the given "
"RAT %s." % mo_rat[1-disabled_slot]})
if mt_slot == 0 or mt_slot == 1:
if not wait_for_network_idle(
log, ad_mt, mt_rat[1-disabled_slot], mt_sub_id):
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Idle state does not match the given "
"RAT %s." % mt_rat[1-disabled_slot]})
if not verify_http_connection(log, ads[0]):
log.error("Failed to verify http connection.")
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to verify http connection."})
else:
log.info("Verify http connection successfully.")
log.info("Step 5: Make voice call.")
result = two_phone_call_msim_for_slot(
log,
ad_mo,
get_slot_index_from_subid(ad_mo, mo_sub_id),
None,
is_mo_in_call,
ad_mt,
get_slot_index_from_subid(ad_mt, mt_sub_id),
None,
is_mt_in_call)
tel_logger.set_result(result.result_value)
if not result:
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)})
log.info("Step 6: Enable slot %s.", disabled_slot)
if not power_on_sim(ads[0], disabled_slot):
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to enable slot %s." % disabled_slot})
log.info("Step 7: Switch DDS to slot %s.", disabled_slot)
if not set_dds_on_slot(ads[0], disabled_slot):
log.error(
"Failed to set DDS at slot %s on %s.",(disabled_slot, ads[0].serial))
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to set DDS at slot %s on %s." % (
disabled_slot, ads[0].serial)})
log.info("Step 8: Verify RAT and HTTP connection after DDS switch.")
if mo_slot == 0 or mo_slot == 1:
if not wait_for_network_idle(
log, ad_mo, mo_rat[disabled_slot], mo_other_sub_id):
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Idle state does not match the given "
"RAT %s." % mo_rat[mo_slot]})
if mt_slot == 0 or mt_slot == 1:
if not wait_for_network_idle(
log, ad_mt, mt_rat[disabled_slot], mt_other_sub_id):
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Idle state does not match the given "
"RAT %s." % mt_rat[mt_slot]})
if not verify_http_connection(log, ads[0]):
log.error("Failed to verify http connection.")
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to verify http connection."})
else:
log.info("Verify http connection successfully.")
def enable_slot_after_data_call_test(
log,
ad,
disabled_slot,
rat=["", ""]):
"""Disable/enable pSIM or eSIM with data call
Test step:
1. Get sub IDs of specific slots of both MO and MT devices.
2. Set up phones in desired RAT.
3. Disable assigned slot.
4. Switch DDS to the other slot.
5. Verify RAT and HTTP connection after DDS switch.
6. Make a data call by http download.
7. Enable assigned slot.
8. Switch DDS to the assigned slot.
9. Verify RAT and HTTP connection after DDS switch.
Args:
log: logger object
ads: list of android devices
disabled_slot: slot to be disabled/enabled
mo_rat: RAT for both slots of MO device
mt_rat: RAT for both slots of MT device
Returns:
TestFailure if failed.
"""
data_sub_id = get_subid_from_slot_index(log, ad, 1-disabled_slot)
if data_sub_id == INVALID_SUB_ID:
ad.log.warning("Failed to get sub ID at slot %s.", 1-disabled_slot)
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Failed to get sub ID at slot %s." % (
1-disabled_slot)})
other_sub_id = get_subid_from_slot_index(log, ad, disabled_slot)
log.info("Step 1: Set up phones in desired RAT.")
if not phone_setup_on_rat(log, ad, rat[1-disabled_slot], data_sub_id):
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
if not phone_setup_on_rat(log, ad, rat[disabled_slot], other_sub_id):
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
log.info("Step 2: Disable slot %s.", disabled_slot)
if not power_off_sim(ad, disabled_slot):
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to disable slot %s." % disabled_slot})
log.info("Step 3: Switch DDS.")
if not set_dds_on_slot(ad, 1-disabled_slot):
log.error(
"Failed to set DDS at slot %s on %s.",(1-disabled_slot, ad.serial))
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to set DDS at slot %s on %s." % (
1-disabled_slot, ad.serial)})
log.info("Step 4: Verify RAT and HTTP connection after DDS switch.")
if not wait_for_network_idle(log, ad, rat[1-disabled_slot], data_sub_id):
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Idle state does not match the given "
"RAT %s." % rat[1-disabled_slot]})
if not verify_http_connection(log, ad):
log.error("Failed to verify http connection.")
raise signals.TestFailure("Failed",
extras={"fail_reason": "Failed to verify http connection."})
else:
log.info("Verify http connection successfully.")
duration = 30
start_time = datetime.now()
while datetime.now() - start_time <= timedelta(seconds=duration):
if not active_file_download_test(
log, ad, file_name='20MB', method='sl4a'):
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to download by sl4a."})
log.info("Step 6: Enable slot %s.", disabled_slot)
if not power_on_sim(ad, disabled_slot):
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to enable slot %s." % disabled_slot})
log.info("Step 7: Switch DDS to slot %s.", disabled_slot)
if not set_dds_on_slot(ad, disabled_slot):
log.error(
"Failed to set DDS at slot %s on %s.",(disabled_slot, ad.serial))
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to set DDS at slot %s on %s." % (
disabled_slot, ad.serial)})
log.info("Step 8: Verify RAT and HTTP connection after DDS switch.")
if not wait_for_network_idle(log, ad, rat[disabled_slot], other_sub_id):
raise signals.TestFailure(
"Failed",
extras={
"fail_reason": "Idle state does not match the given "
"RAT %s." % rat[disabled_slot]})
if not verify_http_connection(log, ad):
log.error("Failed to verify http connection.")
raise signals.TestFailure(
"Failed",
extras={"fail_reason": "Failed to verify http connection."})
else:
log.info("Verify http connection successfully.")
def erase_call_forwarding(log, ad):
slot0_sub_id = get_subid_from_slot_index(log, ad, 0)
slot1_sub_id = get_subid_from_slot_index(log, ad, 1)
current_voice_sub_id = get_incoming_voice_sub_id(ad)
for sub_id in (slot0_sub_id, slot1_sub_id):
set_voice_sub_id(ad, sub_id)
get_operator_name(log, ad, sub_id)
erase_call_forwarding_by_mmi(log, ad)
set_voice_sub_id(ad, current_voice_sub_id)
def three_way_calling_mo_and_mt_with_hangup_once(
log,
ads,
phone_setups,
verify_funcs,
reject_once=False):
"""Use 3 phones to make MO call and MT call.
Call from PhoneA to PhoneB, accept on PhoneB.
Call from PhoneC to PhoneA, accept on PhoneA.
Args:
ads: list of ad object.
The list should have three objects.
phone_setups: list of phone setup functions.
The list should have three objects.
verify_funcs: list of phone call verify functions.
The list should have three objects.
Returns:
If success, return 'call_AB' id in PhoneA.
if fail, return None.
"""
class _CallException(Exception):
pass
try:
verify_func_a, verify_func_b, verify_func_c = verify_funcs
tasks = []
for ad, setup_func in zip(ads, phone_setups):
if setup_func is not None:
tasks.append((setup_func, (log, ad, get_incoming_voice_sub_id(ad))))
if tasks != [] and not multithread_func(log, tasks):
log.error("Phone Failed to Set Up Properly.")
raise _CallException("Setup failed.")
for ad in ads:
ad.droid.telecomCallClearCallList()
if num_active_calls(log, ad) != 0:
ad.log.error("Phone Call List is not empty.")
raise _CallException("Clear call list failed.")
log.info("Step1: Call From PhoneA to PhoneB.")
if not call_setup_teardown(
log,
ads[0],
ads[1],
ad_hangup=None,
verify_caller_func=verify_func_a,
verify_callee_func=verify_func_b):
raise _CallException("PhoneA call PhoneB failed.")
calls = ads[0].droid.telecomCallGetCallIds()
ads[0].log.info("Calls in PhoneA %s", calls)
if num_active_calls(log, ads[0]) != 1:
raise _CallException("Call list verify failed.")
call_ab_id = calls[0]
log.info("Step2: Call From PhoneC to PhoneA.")
if reject_once:
log.info("Step2-1: Reject incoming call once.")
if not initiate_call(
log,
ads[2],
ads[0].telephony['subscription'][get_incoming_voice_sub_id(
ads[0])]['phone_num']):
ads[2].log.error("Initiate call failed.")
raise _CallException("Failed to initiate call.")
if not wait_and_reject_call_for_subscription(
log,
ads[0],
get_incoming_voice_sub_id(ads[0]),
incoming_number= \
ads[2].telephony['subscription'][
get_incoming_voice_sub_id(
ads[2])]['phone_num']):
ads[0].log.error("Reject call fail.")
raise _CallException("Failed to reject call.")
hangup_call(log, ads[2])
time.sleep(15)
if not call_setup_teardown(
log,
ads[2],
ads[0],
ad_hangup=None,
verify_caller_func=verify_func_c,
verify_callee_func=verify_func_a):
raise _CallException("PhoneA call PhoneC failed.")
if not verify_incall_state(log, [ads[0], ads[1], ads[2]],
True):
raise _CallException("Not All phones are in-call.")
except Exception as e:
setattr(ads[0], "exception", e)
return None
return call_ab_id
def msim_message_test(
log,
ad_mo,
ad_mt,
mo_sub_id,
mt_sub_id, msg="SMS",
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
expected_result=True):
"""Make MO/MT SMS/MMS at specific slot.
Args:
ad_mo: Android object of the device sending SMS/MMS
ad_mt: Android object of the device receiving SMS/MMS
mo_sub_id: Sub ID of MO device
mt_sub_id: Sub ID of MT device
max_wait_time: Max wait time before SMS/MMS is received.
expected_result: True for successful sending/receiving and False on
the contrary
Returns:
True if the result matches expected_result and False on the
contrary.
"""
message_lengths = (50, 160, 180)
if msg == "SMS":
for length in message_lengths:
message_array = [rand_ascii_str(length)]
if not sms_send_receive_verify_for_subscription(
log,
ad_mo,
ad_mt,
mo_sub_id,
mt_sub_id,
message_array,
max_wait_time):
ad_mo.log.warning(
"%s of length %s test failed", msg, length)
return False
else:
ad_mo.log.info(
"%s of length %s test succeeded", msg, length)
log.info("%s test of length %s characters succeeded.",
msg, message_lengths)
elif msg == "MMS":
for length in message_lengths:
message_array = [("Test Message", rand_ascii_str(length), None)]
if not mms_send_receive_verify(
log,
ad_mo,
ad_mt,
message_array,
max_wait_time,
expected_result):
log.warning("%s of body length %s test failed",
msg, length)
return False
else:
log.info(
"%s of body length %s test succeeded", msg, length)
log.info("%s test of body lengths %s succeeded",
msg, message_lengths)
return True
def msim_call_forwarding(
log,
tel_logger,
ads,
caller_slot,
callee_slot,
forwarded_callee_slot,
dds_slot,
caller_rat=["", ""],
callee_rat=["", ""],
forwarded_callee_rat=["", ""],
call_forwarding_type="unconditional"):
"""Make MO voice call to the primary device at specific slot in specific
RAT with DDS at specific slot, and then forwarded to 3rd device with
specific call forwarding type.
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. Register and enable call forwarding with specifc type.
5. Make voice call to the primary device and wait for being forwarded
to 3rd device.
Args:
log: logger object
tel_logger: logger object for telephony proto
ads: list of android devices
caller_slot: Slot of 2nd device making MO call (0 or 1)
callee_slot: Slot of primary device receiving and forwarding MT call
(0 or 1)
forwarded_callee_slot: Slot of 3rd device receiving forwarded call.
dds_slot: Preferred data slot
caller_rat: RAT for both slots of the 2nd device
callee_rat: RAT for both slots of the primary device
forwarded_callee_rat: RAT for both slots of the 3rd device
call_forwarding_type:
"unconditional"
"busy"
"not_answered"
"not_reachable"
Returns:
True or False
"""
ad_caller = ads[1]
ad_callee = ads[0]
ad_forwarded_callee = ads[2]
if callee_slot is not None:
callee_sub_id = get_subid_from_slot_index(
log, ad_callee, callee_slot)
if callee_sub_id == INVALID_SUB_ID:
ad_callee.log.warning(
"Failed to get sub ID at slot %s.", callee_slot)
return False
callee_other_sub_id = get_subid_from_slot_index(
log, ad_callee, 1-callee_slot)
set_voice_sub_id(ad_callee, callee_sub_id)
else:
callee_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads)
if callee_sub_id == INVALID_SUB_ID:
ad_callee.log.warning(
"Failed to get sub ID at slot %s.", callee_slot)
return False
callee_slot = "auto"
set_voice_sub_id(ad_callee, callee_sub_id)
ad_callee.log.info(
"Sub ID for incoming call at slot %s: %s",
callee_slot, get_incoming_voice_sub_id(ad_callee))
if caller_slot is not None:
caller_sub_id = get_subid_from_slot_index(
log, ad_caller, caller_slot)
if caller_sub_id == INVALID_SUB_ID:
ad_caller.log.warning(
"Failed to get sub ID at slot %s.", caller_slot)
return False
caller_other_sub_id = get_subid_from_slot_index(
log, ad_caller, 1-caller_slot)
set_voice_sub_id(ad_caller, caller_sub_id)
else:
_, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
if caller_sub_id == INVALID_SUB_ID:
ad_caller.log.warning(
"Failed to get sub ID at slot %s.", caller_slot)
return False
caller_slot = "auto"
set_voice_sub_id(ad_caller, caller_sub_id)
ad_caller.log.info(
"Sub ID for outgoing call at slot %s: %s",
caller_slot, get_outgoing_voice_sub_id(ad_caller))
if forwarded_callee_slot is not None:
forwarded_callee_sub_id = get_subid_from_slot_index(
log, ad_forwarded_callee, forwarded_callee_slot)
if forwarded_callee_sub_id == INVALID_SUB_ID:
ad_forwarded_callee.log.warning(
"Failed to get sub ID at slot %s.", forwarded_callee_slot)
return False
forwarded_callee_other_sub_id = get_subid_from_slot_index(
log, ad_forwarded_callee, 1-forwarded_callee_slot)
set_voice_sub_id(
ad_forwarded_callee, forwarded_callee_sub_id)
else:
_, _, forwarded_callee_sub_id = \
get_subid_on_same_network_of_host_ad(ads)
if forwarded_callee_sub_id == INVALID_SUB_ID:
ad_forwarded_callee.log.warning(
"Failed to get sub ID at slot %s.", forwarded_callee_slot)
return False
forwarded_callee_slot = "auto"
set_voice_sub_id(
ad_forwarded_callee, forwarded_callee_sub_id)
ad_forwarded_callee.log.info(
"Sub ID for incoming call at slot %s: %s",
forwarded_callee_slot,
get_incoming_voice_sub_id(ad_forwarded_callee))
log.info("Step 1: Switch DDS.")
if not set_dds_on_slot(ads[0], dds_slot):
log.error(
"Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
return False
log.info("Step 2: Check HTTP connection after DDS switch.")
if not verify_http_connection(log, ads[0]):
log.error("Failed to verify http connection.")
return False
else:
log.info("Verify http connection successfully.")
if caller_slot == 1:
phone_setup_on_rat(
log,
ad_caller,
caller_rat[0],
caller_other_sub_id)
elif caller_slot == 0:
phone_setup_on_rat(
log,
ad_caller,
caller_rat[1],
caller_other_sub_id)
else:
phone_setup_on_rat(
log,
ad_caller,
'general')
if callee_slot == 1:
phone_setup_on_rat(
log,
ad_callee,
callee_rat[0],
callee_other_sub_id)
elif callee_slot == 0:
phone_setup_on_rat(
log,
ad_callee,
callee_rat[1],
callee_other_sub_id)
else:
phone_setup_on_rat(
log,
ad_callee,
'general')
if forwarded_callee_slot == 1:
phone_setup_on_rat(
log,
ad_forwarded_callee,
forwarded_callee_rat[0],
forwarded_callee_other_sub_id)
elif forwarded_callee_slot == 0:
phone_setup_on_rat(
log,
ad_forwarded_callee,
forwarded_callee_rat[1],
forwarded_callee_other_sub_id)
else:
phone_setup_on_rat(
log,
ad_forwarded_callee,
'general')
if caller_slot == 0 or caller_slot == 1:
caller_phone_setup_func_argv = (log, ad_caller, caller_rat[caller_slot], caller_sub_id)
else:
caller_phone_setup_func_argv = (log, ad_caller, 'general')
callee_phone_setup_func_argv = (log, ad_callee, callee_rat[callee_slot], callee_sub_id)
if forwarded_callee_slot == 0 or forwarded_callee_slot == 1:
forwarded_callee_phone_setup_func_argv = (
log,
ad_forwarded_callee,
forwarded_callee_rat[forwarded_callee_slot],
forwarded_callee_sub_id)
else:
forwarded_callee_phone_setup_func_argv = (
log,
ad_forwarded_callee,
'general')
log.info("Step 3: Set up phones in desired RAT.")
tasks = [(phone_setup_on_rat, caller_phone_setup_func_argv),
(phone_setup_on_rat, callee_phone_setup_func_argv),
(phone_setup_on_rat,
forwarded_callee_phone_setup_func_argv)]
if not multithread_func(log, tasks):
log.error("Phone Failed to Set Up Properly.")
tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure("Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
is_callee_in_call = is_phone_in_call_on_rat(
log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
is_call_waiting = re.search(
"call_waiting (True (\d)|False)", call_forwarding_type, re.I)
if is_call_waiting:
if is_call_waiting.group(1) == "False":
call_waiting = False
scenario = None
else:
call_waiting = True
scenario = int(is_call_waiting.group(2))
log.info(
"Step 4: Make voice call with call waiting enabled = %s.",
call_waiting)
result = three_phone_call_waiting_short_seq(
log,
ads[0],
None,
is_callee_in_call,
ads[1],
ads[2],
call_waiting=call_waiting, scenario=scenario)
else:
log.info(
"Step 4: Make voice call with call forwarding %s.",
call_forwarding_type)
result = three_phone_call_forwarding_short_seq(
log,
ads[0],
None,
is_callee_in_call,
ads[1],
ads[2],
call_forwarding_type=call_forwarding_type)
if not result:
if is_call_waiting:
pass
else:
log.error(
"Failed to make MO call from %s slot %s to %s slot %s"
" and forward to %s slot %s",
ad_caller.serial,
caller_slot,
ad_callee.serial,
callee_slot,
ad_forwarded_callee.serial,
forwarded_callee_slot)
return result
def msim_call_voice_conf(
log,
tel_logger,
ads,
host_slot,
p1_slot,
p2_slot,
dds_slot,
host_rat=["volte", "volte"],
p1_rat="",
p2_rat="",
merge=True,
disable_cw=False):
"""Make a voice conference 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 and make 3-way voice call.
5. Swap calls.
6. Merge calls.
Args:
log: logger object
tel_logger: logger object for telephony proto
ads: list of android devices
host_slot: Slot on the primary device to host the comference call.
0 or 1 (0 for pSIM or 1 for eSIM)
p1_slot: Slot on the participant device for the call
p2_slot: Slot on another participant device for the call
dds_slot: Preferred data slot
host_rat: RAT for both slots of the primary device
p1_rat: RAT for both slots of the participant device
p2_rat: RAT for both slots of another participant device
merge: True for merging 2 calls into the conference call. False for
not merging 2 separated call.
disable_cw: True for disabling call waiting and False on the
contrary.
Returns:
True or False
"""
ad_host = ads[0]
ad_p1 = ads[1]
ad_p2 = ads[2]
if host_slot is not None:
host_sub_id = get_subid_from_slot_index(
log, ad_host, host_slot)
if host_sub_id == INVALID_SUB_ID:
ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
return False
host_other_sub_id = get_subid_from_slot_index(
log, ad_host, 1-host_slot)
set_voice_sub_id(ad_host, host_sub_id)
else:
host_sub_id, _, _ = get_subid_on_same_network_of_host_ad(ads)
if host_sub_id == INVALID_SUB_ID:
ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
return False
host_slot = "auto"
set_voice_sub_id(ad_host, host_sub_id)
ad_host.log.info("Sub ID for outgoing call at slot %s: %s",
host_slot, get_outgoing_voice_sub_id(ad_host))
if p1_slot is not None:
p1_sub_id = get_subid_from_slot_index(log, ad_p1, p1_slot)
if p1_sub_id == INVALID_SUB_ID:
ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot)
return False
set_voice_sub_id(ad_p1, p1_sub_id)
else:
_, p1_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
if p1_sub_id == INVALID_SUB_ID:
ad_p1.log.warning("Failed to get sub ID at slot %s.", p1_slot)
return False
p1_slot = "auto"
set_voice_sub_id(ad_p1, p1_sub_id)
ad_p1.log.info("Sub ID for incoming call at slot %s: %s",
p1_slot, get_incoming_voice_sub_id(ad_p1))
if p2_slot is not None:
p2_sub_id = get_subid_from_slot_index(log, ad_p2, p2_slot)
if p2_sub_id == INVALID_SUB_ID:
ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot)
return False
set_voice_sub_id(ad_p2, p2_sub_id)
else:
_, _, p2_sub_id = get_subid_on_same_network_of_host_ad(ads)
if p2_sub_id == INVALID_SUB_ID:
ad_p2.log.warning("Failed to get sub ID at slot %s.", p2_slot)
return False
p2_slot = "auto"
set_voice_sub_id(ad_p2, p2_sub_id)
ad_p2.log.info("Sub ID for incoming call at slot %s: %s",
p2_slot, get_incoming_voice_sub_id(ad_p2))
log.info("Step 1: Switch DDS.")
if not set_dds_on_slot(ads[0], dds_slot):
log.error(
"Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
return False
log.info("Step 2: Check HTTP connection after DDS switch.")
if not verify_http_connection(log, ads[0]):
log.error("Failed to verify http connection.")
return False
else:
log.info("Verify http connection successfully.")
if disable_cw:
if not set_call_waiting(log, ad_host, enable=0):
return False
else:
if not set_call_waiting(log, ad_host, enable=1):
return False
if host_slot == 1:
phone_setup_on_rat(
log,
ad_host,
host_rat[0],
host_other_sub_id)
elif host_slot == 0:
phone_setup_on_rat(
log,
ad_host,
host_rat[1],
host_other_sub_id)
if host_slot == 0 or host_slot == 1:
host_phone_setup_func_argv = (log, ad_host, host_rat[host_slot], host_sub_id)
is_host_in_call = is_phone_in_call_on_rat(
log, ad_host, host_rat[host_slot], only_return_fn=True)
else:
host_phone_setup_func_argv = (log, ad_host, 'general')
is_host_in_call = is_phone_in_call_on_rat(
log, ad_host, 'general', only_return_fn=True)
if p1_rat:
p1_phone_setup_func_argv = (log, ad_p1, p1_rat, p1_sub_id)
is_p1_in_call = is_phone_in_call_on_rat(
log, ad_p1, p1_rat, only_return_fn=True)
else:
p1_phone_setup_func_argv = (log, ad_p1, 'general')
is_p1_in_call = is_phone_in_call_on_rat(
log, ad_p1, 'general', only_return_fn=True)
if p2_rat:
p2_phone_setup_func_argv = (log, ad_p2, p2_rat, p2_sub_id)
is_p2_in_call = is_phone_in_call_on_rat(
log, ad_p2, p2_rat, only_return_fn=True)
else:
p2_phone_setup_func_argv = (log, ad_p2, 'general')
is_p2_in_call = is_phone_in_call_on_rat(
log, ad_p2, 'general', only_return_fn=True)
log.info("Step 3: Set up phone in desired RAT and make 3-way"
" voice call.")
tasks = [(phone_setup_on_rat, host_phone_setup_func_argv),
(phone_setup_on_rat, p1_phone_setup_func_argv),
(phone_setup_on_rat, p2_phone_setup_func_argv)]
if not multithread_func(log, tasks):
log.error("Phone Failed to Set Up Properly.")
tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure("Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
call_ab_id = three_way_calling_mo_and_mt_with_hangup_once(
log,
[ad_host, ad_p1, ad_p2],
[None, None, None], [
is_host_in_call, is_p1_in_call,
is_p2_in_call
])
if call_ab_id is None:
if disable_cw:
set_call_waiting(log, ad_host, enable=1)
if str(getattr(ad_host, "exception", None)) == \
"PhoneA call PhoneC failed.":
ads[0].log.info("PhoneA failed to call PhoneC due to call"
" waiting being disabled.")
delattr(ad_host, "exception")
return True
log.error("Failed to get call_ab_id")
return False
else:
if disable_cw:
return False
calls = ads[0].droid.telecomCallGetCallIds()
ads[0].log.info("Calls in PhoneA %s", calls)
if num_active_calls(log, ads[0]) != 2:
return False
if calls[0] == call_ab_id:
call_ac_id = calls[1]
else:
call_ac_id = calls[0]
if call_ac_id is None:
log.error("Failed to get call_ac_id")
return False
num_swaps = 2
log.info("Step 4: Begin Swap x%s test.", num_swaps)
if not swap_calls(log, ads, call_ab_id, call_ac_id,
num_swaps):
log.error("Swap test failed.")
return False
if not merge:
result = True
if not hangup_call(log, ads[1]):
result = False
if not hangup_call(log, ads[2]):
result = False
return result
else:
log.info("Step 5: Merge calls.")
if host_rat[host_slot] == "volte":
return _test_ims_conference_merge_drop_second_call_from_participant(
log, ads, call_ab_id, call_ac_id)
else:
return _test_wcdma_conference_merge_drop(
log, ads, call_ab_id, call_ac_id)
def msim_volte_wfc_call_forwarding(
log,
tel_logger,
ads,
callee_slot,
dds_slot,
callee_rat=["5g_wfc", "5g_wfc"],
call_forwarding_type="unconditional",
is_airplane_mode=False,
is_wifi_connected=False,
wfc_mode=[
WFC_MODE_CELLULAR_PREFERRED,
WFC_MODE_CELLULAR_PREFERRED],
wifi_network_ssid=None,
wifi_network_pass=None):
"""Make VoLTE/WFC call to the primary device at specific slot with DDS
at specific slot, and then forwarded to 3rd device with specific call
forwarding type.
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. Register and enable call forwarding with specifc type.
6. Make VoLTE/WFC call to the primary device and wait for being
forwarded to 3rd device.
Args:
log: logger object
tel_logger: logger object for telephony proto
ads: list of android devices
callee_slot: Slot of primary device receiving and forwarding MT call
(0 or 1)
dds_slot: Preferred data slot
callee_rat: RAT for both slots of the primary device
call_forwarding_type:
"unconditional"
"busy"
"not_answered"
"not_reachable"
is_airplane_mode: True or False for WFC setup
wfc_mode: Cellular preferred or Wi-Fi preferred.
wifi_network_ssid: SSID of Wi-Fi AP
wifi_network_pass: Password of Wi-Fi AP SSID
Returns:
True or False
"""
ad_caller = ads[1]
ad_callee = ads[0]
ad_forwarded_callee = ads[2]
if not toggle_airplane_mode(log, ad_callee, False):
ad_callee.log.error("Failed to disable airplane mode.")
return False
# Set up callee (primary device)
callee_sub_id = get_subid_from_slot_index(
log, ad_callee, callee_slot)
if callee_sub_id == INVALID_SUB_ID:
log.warning(
"Failed to get sub ID at slot %s.", callee_slot)
return
callee_other_sub_id = get_subid_from_slot_index(
log, ad_callee, 1-callee_slot)
set_voice_sub_id(ad_callee, callee_sub_id)
ad_callee.log.info(
"Sub ID for incoming call at slot %s: %s",
callee_slot, get_incoming_voice_sub_id(ad_callee))
# Set up caller
_, caller_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
if caller_sub_id == INVALID_SUB_ID:
ad_caller.log.warning("Failed to get proper sub ID of the caller")
return
set_voice_sub_id(ad_caller, caller_sub_id)
ad_caller.log.info(
"Sub ID for outgoing call of the caller: %s",
get_outgoing_voice_sub_id(ad_caller))
# Set up forwarded callee
_, _, forwarded_callee_sub_id = get_subid_on_same_network_of_host_ad(
ads)
if forwarded_callee_sub_id == INVALID_SUB_ID:
ad_forwarded_callee.log.warning(
"Failed to get proper sub ID of the forwarded callee.")
return
set_voice_sub_id(ad_forwarded_callee, forwarded_callee_sub_id)
ad_forwarded_callee.log.info(
"Sub ID for incoming call of the forwarded callee: %s",
get_incoming_voice_sub_id(ad_forwarded_callee))
log.info("Step 1: Switch DDS.")
if not set_dds_on_slot(ads[0], dds_slot):
log.error(
"Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
return False
log.info("Step 2: Check HTTP connection after DDS switch.")
if not verify_http_connection(log, ad_callee):
ad_callee.log.error("Failed to verify http connection.")
return False
else:
ad_callee.log.info("Verify http connection successfully.")
is_callee_in_call = is_phone_in_call_on_rat(
log, ad_callee, callee_rat[callee_slot], only_return_fn=True)
if is_airplane_mode:
set_call_forwarding_by_mmi(log, ad_callee, ad_forwarded_callee)
log.info("Step 3: Set up phones in desired RAT.")
if callee_slot == 1:
phone_setup_on_rat(
log,
ad_callee,
callee_rat[0],
callee_other_sub_id,
is_airplane_mode,
wfc_mode[0],
wifi_network_ssid,
wifi_network_pass)
elif callee_slot == 0:
phone_setup_on_rat(
log,
ad_callee,
callee_rat[1],
callee_other_sub_id,
is_airplane_mode,
wfc_mode[1],
wifi_network_ssid,
wifi_network_pass)
argv = (
log,
ad_callee,
callee_rat[callee_slot],
callee_sub_id,
is_airplane_mode,
wfc_mode[callee_slot],
wifi_network_ssid,
wifi_network_pass)
tasks = [(phone_setup_voice_general, (log, ad_caller)),
(phone_setup_on_rat, argv),
(phone_setup_voice_general, (log, ad_forwarded_callee))]
if not multithread_func(log, tasks):
log.error("Phone Failed to Set Up Properly.")
tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure("Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
if is_wifi_connected:
if not ensure_wifi_connected(
log,
ad_callee,
wifi_network_ssid,
wifi_network_pass,
apm=is_airplane_mode):
return False
time.sleep(5)
if "wfc" not in callee_rat[callee_slot]:
if not toggle_wfc_for_subscription(
log,
ad_callee,
new_state=True,
sub_id=callee_sub_id):
return False
if not set_wfc_mode_for_subscription(
ad_callee, wfc_mode[callee_slot], sub_id=callee_sub_id):
return False
log.info(
"Step 4: Make voice call with call forwarding %s.",
call_forwarding_type)
result = three_phone_call_forwarding_short_seq(
log,
ad_callee,
None,
is_callee_in_call,
ad_caller,
ad_forwarded_callee,
call_forwarding_type=call_forwarding_type)
if not result:
log.error(
"Failed to make MO call from %s to %s slot %s and forward"
" to %s.",
ad_caller.serial,
ad_callee.serial,
callee_slot,
ad_forwarded_callee.serial)
return result
def msim_volte_wfc_call_voice_conf(
log,
tel_logger,
ads,
host_slot,
dds_slot,
host_rat=["5g_wfc", "5g_wfc"],
merge=True,
disable_cw=False,
is_airplane_mode=False,
is_wifi_connected=False,
wfc_mode=[WFC_MODE_CELLULAR_PREFERRED, WFC_MODE_CELLULAR_PREFERRED],
reject_once=False,
wifi_network_ssid=None,
wifi_network_pass=None):
"""Make a VoLTE/WFC conference call at specific slot with DDS at
specific slot.
Test step:
1. Get sub IDs of specific slots of both MO and MT devices.
2. Set up phones in desired RAT
3. Enable VoLTE/WFC.
4. Switch DDS to specific slot.
5. Check HTTP connection after DDS switch.
6. Make 3-way VoLTE/WFC call.
7. Swap calls.
8. Merge calls.
Args:
log: logger object
tel_logger: logger object for telephony proto
ads: list of android devices
host_slot: Slot on the primary device to host the comference call.
0 or 1 (0 for pSIM or 1 for eSIM)call
dds_slot: Preferred data slot
host_rat: RAT for both slots of the primary devicevice
merge: True for merging 2 calls into the conference call. False for
not merging 2 separated call.
disable_cw: True for disabling call waiting and False on the
contrary.
enable_volte: True for enabling and False for disabling VoLTE for
each slot on the primary device
enable_wfc: True for enabling and False for disabling WFC for
each slot on the primary device
is_airplane_mode: True or False for WFC setup
wfc_mode: Cellular preferred or Wi-Fi preferred.
reject_once: True for rejecting the 2nd call once from the 3rd
device (Phone C) to the primary device (Phone A).
wifi_network_ssid: SSID of Wi-Fi AP
wifi_network_pass: Password of Wi-Fi AP SSID
Returns:
True or False
"""
ad_host = ads[0]
ad_p1 = ads[1]
ad_p2 = ads[2]
host_sub_id = get_subid_from_slot_index(log, ad_host, host_slot)
if host_sub_id == INVALID_SUB_ID:
ad_host.log.warning("Failed to get sub ID at slot.", host_slot)
return
host_other_sub_id = get_subid_from_slot_index(
log, ad_host, 1-host_slot)
set_voice_sub_id(ad_host, host_sub_id)
ad_host.log.info(
"Sub ID for outgoing call at slot %s: %s",
host_slot, get_outgoing_voice_sub_id(ad_host))
_, p1_sub_id, p2_sub_id = get_subid_on_same_network_of_host_ad(ads)
if p1_sub_id == INVALID_SUB_ID:
ad_p1.log.warning("Failed to get proper sub ID.")
return
set_voice_sub_id(ad_p1, p1_sub_id)
ad_p1.log.info(
"Sub ID for incoming call: %s",
get_incoming_voice_sub_id(ad_p1))
if p2_sub_id == INVALID_SUB_ID:
ad_p2.log.warning("Failed to get proper sub ID.")
return
set_voice_sub_id(ad_p2, p2_sub_id)
ad_p2.log.info(
"Sub ID for incoming call: %s", get_incoming_voice_sub_id(ad_p2))
log.info("Step 1: Switch DDS.")
if not set_dds_on_slot(ads[0], dds_slot):
log.error(
"Failed to set DDS at slot %s on %s",(dds_slot, ads[0].serial))
return False
log.info("Step 2: Check HTTP connection after DDS switch.")
if not verify_http_connection(log, ads[0]):
ad_host.log.error("Failed to verify http connection.")
return False
else:
ad_host.log.info("Verify http connection successfully.")
if disable_cw:
if not set_call_waiting(log, ad_host, enable=0):
return False
log.info("Step 3: Set up phones in desired RAT.")
if host_slot == 1:
phone_setup_on_rat(
log,
ad_host,
host_rat[0],
host_other_sub_id,
is_airplane_mode,
wfc_mode[0],
wifi_network_ssid,
wifi_network_pass)
elif host_slot == 0:
phone_setup_on_rat(
log,
ad_host,
host_rat[1],
host_other_sub_id,
is_airplane_mode,
wfc_mode[1],
wifi_network_ssid,
wifi_network_pass)
argv = (
log,
ad_host,
host_rat[host_slot],
host_sub_id,
is_airplane_mode,
wfc_mode[host_slot],
wifi_network_ssid,
wifi_network_pass)
tasks = [(phone_setup_voice_general, (log, ad_p1)),
(phone_setup_on_rat, argv),
(phone_setup_voice_general, (log, ad_p2))]
if not multithread_func(log, tasks):
log.error("Phone Failed to Set Up Properly.")
tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
raise signals.TestFailure("Failed",
extras={"fail_reason": "Phone Failed to Set Up Properly."})
if is_wifi_connected:
if not ensure_wifi_connected(
log,
ad_host,
wifi_network_ssid,
wifi_network_pass,
apm=is_airplane_mode):
return False
time.sleep(5)
if "wfc" not in host_rat[host_slot]:
if not toggle_wfc_for_subscription(
log,
ad_host,
new_state=True,
sub_id=host_sub_id):
return False
if not set_wfc_mode_for_subscription(
ad_host, wfc_mode[host_slot], sub_id=host_sub_id):
return False
log.info("Step 4: Make 3-way voice call.")
is_host_in_call = is_phone_in_call_on_rat(
log, ad_host, host_rat[host_slot], only_return_fn=True)
call_ab_id = _three_phone_call_mo_add_mt(
log,
[ad_host, ad_p1, ad_p2],
[None, None, None],
[is_host_in_call, None, None],
reject_once=reject_once)
if call_ab_id is None:
if disable_cw:
set_call_waiting(log, ad_host, enable=1)
if str(getattr(ad_host, "exception", None)) == \
"PhoneA call PhoneC failed.":
ads[0].log.info("PhoneA failed to call PhoneC due to call"
" waiting being disabled.")
delattr(ad_host, "exception")
return True
log.error("Failed to get call_ab_id")
return False
else:
if disable_cw:
set_call_waiting(log, ad_host, enable=0)
return False
calls = ads[0].droid.telecomCallGetCallIds()
ads[0].log.info("Calls in PhoneA %s", calls)
if num_active_calls(log, ads[0]) != 2:
return False
if calls[0] == call_ab_id:
call_ac_id = calls[1]
else:
call_ac_id = calls[0]
if call_ac_id is None:
log.error("Failed to get call_ac_id")
return False
num_swaps = 2
log.info("Step 5: Begin Swap x%s test.", num_swaps)
if not swap_calls(log, ads, call_ab_id, call_ac_id,
num_swaps):
ad_host.log.error("Swap test failed.")
return False
if not merge:
result = True
if not hangup_call(log, ads[1]):
result = False
if not hangup_call(log, ads[2]):
result = False
return result
else:
log.info("Step 6: Merge calls.")
if re.search('csfb|2g|3g', host_rat[host_slot].lower(), re.I):
return _test_wcdma_conference_merge_drop(
log, ads, call_ab_id, call_ac_id)
else:
return _test_ims_conference_merge_drop_second_call_from_participant(
log, ads, call_ab_id, call_ac_id)