blob: 21c418f530819dd441412c88d292782c63127968 [file] [log] [blame]
#!/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 re
import time
from queue import Empty
from acts import signals
from acts.utils import rand_ascii_str
from acts.libs.utils.multithread import multithread_func
from acts.libs.utils.multithread import run_multithread_func
from acts_contrib.test_utils.tel.tel_defines import EventCallStateChanged
from acts_contrib.test_utils.tel.tel_defines import EventMmsSentFailure
from acts_contrib.test_utils.tel.tel_defines import EventMmsSentSuccess
from acts_contrib.test_utils.tel.tel_defines import EventMmsDownloaded
from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverFailure
from acts_contrib.test_utils.tel.tel_defines import EventSmsDeliverSuccess
from acts_contrib.test_utils.tel.tel_defines import EventSmsReceived
from acts_contrib.test_utils.tel.tel_defines import EventSmsSentFailure
from acts_contrib.test_utils.tel.tel_defines import EventSmsSentSuccess
from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION
from acts_contrib.test_utils.tel.tel_defines import SMS_OVER_WIFI_PROVIDERS
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_on_rat
from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_message_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_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_subid_for_message
from acts_contrib.test_utils.tel.tel_test_utils import CallResult
from acts_contrib.test_utils.tel.tel_test_utils import TelResultWrapper
from acts_contrib.test_utils.tel.tel_test_utils import check_phone_number_match
from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
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 is_phone_in_call
from acts_contrib.test_utils.tel.tel_voice_utils import last_call_drop_reason
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 wait_and_answer_call_for_subscription
from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_in_call_active
from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_end
from acts_contrib.test_utils.tel.tel_voice_utils import wait_for_call_offhook_for_subscription
from acts_contrib.test_utils.tel.tel_video_utils import is_phone_in_call_video_bidirectional
from acts_contrib.test_utils.tel.tel_video_utils import video_call_setup_teardown
from acts_contrib.test_utils.tel.tel_video_utils import phone_idle_video
from acts_contrib.test_utils.tel.tel_wifi_utils import ensure_wifi_connected
def send_message_with_random_message_body(
log, ad_mo, ad_mt, msg_type='sms', long_msg=False, mms_expected_result=True):
"""Test SMS/MMS between two phones.
Returns:
True if success.
False if failed.
"""
message_lengths = (50, 160, 180)
if long_msg:
message_lengths = (800, 1600)
message_lengths_of_jp_carriers = (800, 1530)
sender_message_sub_id = get_outgoing_message_sub_id(ad_mo)
sender_mcc = ad_mo.telephony["subscription"][sender_message_sub_id]["mcc"]
if str(sender_mcc) in ["440", "441"]:
message_lengths = message_lengths_of_jp_carriers
if msg_type == 'sms':
for length in message_lengths:
message_array = [rand_ascii_str(length)]
if not sms_send_receive_verify(log, ad_mo, ad_mt, message_array):
ad_mo.log.error("SMS of length %s test failed", length)
return False
else:
ad_mo.log.info("SMS of length %s test succeeded", length)
log.info("SMS test of length %s characters succeeded.",
message_lengths)
elif msg_type == 'mms':
is_roaming = False
for ad in [ad_mo, ad_mt]:
ad.sms_over_wifi = False
# verizon supports sms over wifi. will add more carriers later
for sub in ad.telephony["subscription"].values():
if sub["operator"] in SMS_OVER_WIFI_PROVIDERS:
ad.sms_over_wifi = True
if getattr(ad, 'roaming', False):
is_roaming = True
if is_roaming:
# roaming device does not allow message of length 180
message_lengths = (50, 160)
for length in message_lengths:
message_array = [("Test Message", rand_ascii_str(length), None)]
result = True
if not mms_send_receive_verify(
log,
ad_mo,
ad_mt,
message_array,
expected_result=mms_expected_result):
if mms_expected_result is True:
if ad_mo.droid.telecomIsInCall() or ad_mt.droid.telecomIsInCall():
if not mms_receive_verify_after_call_hangup(
log, ad_mo, ad_mt, message_array):
result = False
else:
result = False
if not result:
log.error("MMS of body length %s test failed", length)
return False
else:
log.info("MMS of body length %s test succeeded", length)
log.info("MMS test of body lengths %s succeeded", message_lengths)
return True
def message_test(
log,
ad_mo,
ad_mt,
mo_rat='general',
mt_rat='general',
msg_type='sms',
long_msg=False,
mms_expected_result=True,
msg_in_call=False,
video_or_voice='voice',
is_airplane_mode=False,
wfc_mode=None,
wifi_ssid=None,
wifi_pwd=None):
mo_phone_setup_argv = (
log, ad_mo, 'general', None, False, None, None, None, None, 'sms')
mt_phone_setup_argv = (
log, ad_mt, 'general', None, False, None, None, None, None, 'sms')
verify_caller_func = None
verify_callee_func = None
if mo_rat:
mo_phone_setup_argv = (
log,
ad_mo,
mo_rat,
None,
is_airplane_mode,
wfc_mode,
wifi_ssid,
wifi_pwd,
None,
'sms')
verify_caller_func = is_phone_in_call_on_rat(
log, ad_mo, rat=mo_rat, only_return_fn=True)
if mt_rat:
mt_phone_setup_argv = (
log,
ad_mt,
mt_rat,
None,
is_airplane_mode,
wfc_mode,
wifi_ssid,
wifi_pwd,
None,
'sms')
verify_callee_func = is_phone_in_call_on_rat(
log, ad_mo, rat=mt_rat, only_return_fn=True)
tasks = [(phone_setup_on_rat, mo_phone_setup_argv),
(phone_setup_on_rat, mt_phone_setup_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 wifi_ssid:
if not wfc_mode or wfc_mode == WFC_MODE_DISABLED:
tasks = [(ensure_wifi_connected, (log, ad_mo, wifi_ssid, wifi_pwd)),
(ensure_wifi_connected, (log, ad_mt, wifi_ssid, wifi_pwd))]
if not multithread_func(log, tasks):
log.error("Failed to connected to Wi-Fi.")
return False
if msg_in_call:
if video_or_voice == 'voice':
if not call_setup_teardown(
log,
ad_mo,
ad_mt,
ad_hangup=None,
verify_caller_func=verify_caller_func,
verify_callee_func=verify_callee_func):
log.error("Failed to setup a voice call")
return False
elif video_or_voice == 'video':
tasks = [
(phone_idle_video, (log, ad_mo)),
(phone_idle_video, (log, ad_mt))]
if not multithread_func(log, tasks):
log.error("Phone Failed to Set Up Properly.")
return False
time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
if not video_call_setup_teardown(
log,
ad_mo,
ad_mt,
None,
video_state=VT_STATE_BIDIRECTIONAL,
verify_caller_func=is_phone_in_call_video_bidirectional,
verify_callee_func=is_phone_in_call_video_bidirectional):
log.error("Failed to setup a video call")
return False
result = True
if not send_message_with_random_message_body(
log, ad_mo, ad_mt, msg_type, long_msg, mms_expected_result):
log.error("Test failed.")
result = False
if msg_in_call:
if not hangup_call(log, ad_mo):
ad_mo.log.info("Failed to hang up call!")
result = False
return result
def sms_send_receive_verify(log,
ad_tx,
ad_rx,
array_message,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
expected_result=True,
slot_id_rx=None):
"""Send SMS, receive SMS, and verify content and sender's number.
Send (several) SMS from droid_tx to droid_rx.
Verify SMS is sent, delivered and received.
Verify received content and sender's number are correct.
Args:
log: Log object.
ad_tx: Sender's Android Device Object
ad_rx: Receiver's Android Device Object
array_message: the array of message to send/receive
slot_id_rx: the slot on the Receiver's android device (0/1)
"""
subid_tx = get_outgoing_message_sub_id(ad_tx)
if slot_id_rx is None:
subid_rx = get_incoming_message_sub_id(ad_rx)
else:
subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
result = sms_send_receive_verify_for_subscription(
log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
if result != expected_result:
log_messaging_screen_shot(ad_tx, test_name="sms_tx")
log_messaging_screen_shot(ad_rx, test_name="sms_rx")
return result == expected_result
def sms_send_receive_verify_for_subscription(
log,
ad_tx,
ad_rx,
subid_tx,
subid_rx,
array_message,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
"""Send SMS, receive SMS, and verify content and sender's number.
Send (several) SMS from droid_tx to droid_rx.
Verify SMS is sent, delivered and received.
Verify received content and sender's number are correct.
Args:
log: Log object.
ad_tx: Sender's Android Device Object..
ad_rx: Receiver's Android Device Object.
subid_tx: Sender's subscription ID to be used for SMS
subid_rx: Receiver's subscription ID to be used for SMS
array_message: the array of message to send/receive
"""
phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
for ad in (ad_tx, ad_rx):
if not getattr(ad, "messaging_droid", None):
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
else:
try:
if not ad.messaging_droid.is_live:
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
else:
ad.messaging_ed.clear_all_events()
ad.messaging_droid.logI(
"Start sms_send_receive_verify_for_subscription test")
except Exception:
ad.log.info("Create new sl4a session for messaging")
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
for text in array_message:
length = len(text)
ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
phonenumber_tx, phonenumber_rx, length, text)
try:
ad_rx.messaging_ed.clear_events(EventSmsReceived)
ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
time.sleep(1) #sleep 100ms after starting event tracking
ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
ad_tx.messaging_droid.smsSendTextMessage(phonenumber_rx, text,
True)
try:
events = ad_tx.messaging_ed.pop_events(
"(%s|%s|%s|%s)" %
(EventSmsSentSuccess, EventSmsSentFailure,
EventSmsDeliverSuccess,
EventSmsDeliverFailure), max_wait_time)
for event in events:
ad_tx.log.info("Got event %s", event["name"])
if event["name"] == EventSmsSentFailure or event["name"] == EventSmsDeliverFailure:
if event.get("data") and event["data"].get("Reason"):
ad_tx.log.error("%s with reason: %s",
event["name"],
event["data"]["Reason"])
return False
elif event["name"] == EventSmsSentSuccess or event["name"] == EventSmsDeliverSuccess:
break
except Empty:
ad_tx.log.error("No %s or %s event for SMS of length %s.",
EventSmsSentSuccess, EventSmsSentFailure,
length)
return False
if not wait_for_matching_sms(
log,
ad_rx,
phonenumber_tx,
text,
max_wait_time,
allow_multi_part_long_sms=True):
ad_rx.log.error("No matching received SMS of length %s.",
length)
return False
except Exception as e:
log.error("Exception error %s", e)
raise
finally:
ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
return True
def sms_in_collision_send_receive_verify(
log,
ad_rx,
ad_rx2,
ad_tx,
ad_tx2,
array_message,
array_message2,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
"""Send 2 SMS', receive both SMS', and verify content and sender's number of
each SMS.
Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
be tested.
Verify both SMS' are sent, delivered and received.
Verify received content and sender's number of each SMS is correct.
Args:
log: Log object.
ad_tx: Sender's Android Device Object..
ad_rx: Receiver's Android Device Object.
ad_tx2: 2nd sender's Android Device Object..
ad_rx2: 2nd receiver's Android Device Object.
array_message: the array of message to send/receive from ad_tx to ad_rx
array_message2: the array of message to send/receive from ad_tx2 to
ad_rx2
max_wait_time: Max time to wait for reception of SMS
"""
rx_sub_id = get_outgoing_message_sub_id(ad_rx)
rx2_sub_id = get_outgoing_message_sub_id(ad_rx2)
_, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
[ad_rx, ad_tx, ad_tx2],
host_sub_id=rx_sub_id)
set_subid_for_message(ad_tx, tx_sub_id)
_, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
[ad_rx2, ad_tx, ad_tx2],
host_sub_id=rx2_sub_id)
set_subid_for_message(ad_tx2, tx2_sub_id)
if not sms_in_collision_send_receive_verify_for_subscription(
log,
ad_tx,
ad_tx2,
ad_rx,
ad_rx2,
tx_sub_id,
tx2_sub_id,
rx_sub_id,
rx_sub_id,
array_message,
array_message2,
max_wait_time):
log_messaging_screen_shot(
ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
log_messaging_screen_shot(
ad_rx2, test_name="sms rx2 subid: %s" % rx2_sub_id)
log_messaging_screen_shot(
ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
log_messaging_screen_shot(
ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
return False
return True
def sms_in_collision_send_receive_verify_for_subscription(
log,
ad_tx,
ad_tx2,
ad_rx,
ad_rx2,
subid_tx,
subid_tx2,
subid_rx,
subid_rx2,
array_message,
array_message2,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
"""Send 2 SMS', receive both SMS', and verify content and sender's number of
each SMS.
Send 2 SMS'. One from ad_tx to ad_rx and the other from ad_tx2 to ad_rx2.
When ad_rx is identical to ad_rx2, the scenario of SMS' in collision can
be tested.
Verify both SMS' are sent, delivered and received.
Verify received content and sender's number of each SMS is correct.
Args:
log: Log object.
ad_tx: Sender's Android Device Object..
ad_rx: Receiver's Android Device Object.
ad_tx2: 2nd sender's Android Device Object..
ad_rx2: 2nd receiver's Android Device Object.
subid_tx: Sub ID of ad_tx as default Sub ID for outgoing SMS
subid_tx2: Sub ID of ad_tx2 as default Sub ID for outgoing SMS
subid_rx: Sub ID of ad_rx as default Sub ID for incoming SMS
subid_rx2: Sub ID of ad_rx2 as default Sub ID for incoming SMS
array_message: the array of message to send/receive from ad_tx to ad_rx
array_message2: the array of message to send/receive from ad_tx2 to
ad_rx2
max_wait_time: Max time to wait for reception of SMS
"""
phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
phonenumber_rx2 = ad_rx2.telephony['subscription'][subid_rx2]['phone_num']
for ad in (ad_tx, ad_tx2, ad_rx, ad_rx2):
ad.send_keycode("BACK")
if not getattr(ad, "messaging_droid", None):
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
else:
try:
if not ad.messaging_droid.is_live:
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
else:
ad.messaging_ed.clear_all_events()
ad.messaging_droid.logI(
"Start sms_send_receive_verify_for_subscription test")
except Exception:
ad.log.info("Create new sl4a session for messaging")
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
for text, text2 in zip(array_message, array_message2):
length = len(text)
length2 = len(text2)
ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
phonenumber_tx, phonenumber_rx, length, text)
ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
phonenumber_tx2, phonenumber_rx2, length2, text2)
try:
ad_rx.messaging_ed.clear_events(EventSmsReceived)
ad_rx2.messaging_ed.clear_events(EventSmsReceived)
ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
if ad_rx2 != ad_rx:
ad_rx2.messaging_droid.smsStartTrackingIncomingSmsMessage()
time.sleep(1)
ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
ad_tx2.messaging_droid.logI("Sending SMS of length %s" % length2)
ad_rx.messaging_droid.logI(
"Expecting SMS of length %s from %s" % (length, ad_tx.serial))
ad_rx2.messaging_droid.logI(
"Expecting SMS of length %s from %s" % (length2, ad_tx2.serial))
tasks = [
(ad_tx.messaging_droid.smsSendTextMessage,
(phonenumber_rx, text, True)),
(ad_tx2.messaging_droid.smsSendTextMessage,
(phonenumber_rx2, text2, True))]
multithread_func(log, tasks)
try:
tasks = [
(ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
EventSmsSentSuccess,
EventSmsSentFailure,
EventSmsDeliverSuccess,
EventSmsDeliverFailure), max_wait_time)),
(ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
EventSmsSentSuccess,
EventSmsSentFailure,
EventSmsDeliverSuccess,
EventSmsDeliverFailure), max_wait_time))
]
results = run_multithread_func(log, tasks)
res = True
_ad = ad_tx
for ad, events in [(ad_tx, results[0]),(ad_tx2, results[1])]:
_ad = ad
for event in events:
ad.log.info("Got event %s", event["name"])
if event["name"] == EventSmsSentFailure or \
event["name"] == EventSmsDeliverFailure:
if event.get("data") and event["data"].get("Reason"):
ad.log.error("%s with reason: %s",
event["name"],
event["data"]["Reason"])
res = False
elif event["name"] == EventSmsSentSuccess or \
event["name"] == EventSmsDeliverSuccess:
break
if not res:
return False
except Empty:
_ad.log.error("No %s or %s event for SMS of length %s.",
EventSmsSentSuccess, EventSmsSentFailure,
length)
return False
if ad_rx == ad_rx2:
if not wait_for_matching_mt_sms_in_collision(
log,
ad_rx,
phonenumber_tx,
phonenumber_tx2,
text,
text2,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
ad_rx.log.error(
"No matching received SMS of length %s from %s.",
length,
ad_rx.serial)
return False
else:
if not wait_for_matching_mt_sms_in_collision_with_mo_sms(
log,
ad_rx,
ad_rx2,
phonenumber_tx,
phonenumber_tx2,
text,
text2,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
return False
except Exception as e:
log.error("Exception error %s", e)
raise
finally:
ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
ad_rx2.messaging_droid.smsStopTrackingIncomingSmsMessage()
return True
def sms_rx_power_off_multiple_send_receive_verify(
log,
ad_rx,
ad_tx,
ad_tx2,
array_message_length,
array_message2_length,
num_array_message,
num_array_message2,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
rx_sub_id = get_outgoing_message_sub_id(ad_rx)
_, tx_sub_id, _ = get_subid_on_same_network_of_host_ad(
[ad_rx, ad_tx, ad_tx2],
host_sub_id=rx_sub_id)
set_subid_for_message(ad_tx, tx_sub_id)
_, _, tx2_sub_id = get_subid_on_same_network_of_host_ad(
[ad_rx, ad_tx, ad_tx2],
host_sub_id=rx_sub_id)
set_subid_for_message(ad_tx2, tx2_sub_id)
if not sms_rx_power_off_multiple_send_receive_verify_for_subscription(
log,
ad_tx,
ad_tx2,
ad_rx,
tx_sub_id,
tx2_sub_id,
rx_sub_id,
rx_sub_id,
array_message_length,
array_message2_length,
num_array_message,
num_array_message2):
log_messaging_screen_shot(
ad_rx, test_name="sms rx subid: %s" % rx_sub_id)
log_messaging_screen_shot(
ad_tx, test_name="sms tx subid: %s" % tx_sub_id)
log_messaging_screen_shot(
ad_tx2, test_name="sms tx subid: %s" % tx2_sub_id)
return False
return True
def sms_rx_power_off_multiple_send_receive_verify_for_subscription(
log,
ad_tx,
ad_tx2,
ad_rx,
subid_tx,
subid_tx2,
subid_rx,
subid_rx2,
array_message_length,
array_message2_length,
num_array_message,
num_array_message2,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
phonenumber_tx2 = ad_tx2.telephony['subscription'][subid_tx2]['phone_num']
phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
phonenumber_rx2 = ad_rx.telephony['subscription'][subid_rx2]['phone_num']
if not toggle_airplane_mode(log, ad_rx, True):
ad_rx.log.error("Failed to enable Airplane Mode")
return False
ad_rx.stop_services()
ad_rx.log.info("Rebooting......")
ad_rx.adb.reboot()
message_dict = {phonenumber_tx: [], phonenumber_tx2: []}
for index in range(max(num_array_message, num_array_message2)):
array_message = [rand_ascii_str(array_message_length)]
array_message2 = [rand_ascii_str(array_message2_length)]
for text, text2 in zip(array_message, array_message2):
message_dict[phonenumber_tx].append(text)
message_dict[phonenumber_tx2].append(text2)
length = len(text)
length2 = len(text2)
ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
phonenumber_tx, phonenumber_rx, length, text)
ad_tx2.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
phonenumber_tx2, phonenumber_rx2, length2, text2)
try:
for ad in (ad_tx, ad_tx2):
ad.send_keycode("BACK")
if not getattr(ad, "messaging_droid", None):
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
else:
try:
if not ad.messaging_droid.is_live:
ad.messaging_droid, ad.messaging_ed = \
ad.get_droid()
ad.messaging_ed.start()
else:
ad.messaging_ed.clear_all_events()
ad.messaging_droid.logI(
"Start sms_send_receive_verify_for_subscription"
" test")
except Exception:
ad.log.info("Create new sl4a session for messaging")
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
ad_tx2.messaging_ed.clear_events(EventSmsSentSuccess)
ad_tx2.messaging_ed.clear_events(EventSmsSentFailure)
if index < num_array_message and index < num_array_message2:
ad_tx.messaging_droid.logI(
"Sending SMS of length %s" % length)
ad_tx2.messaging_droid.logI(
"Sending SMS of length %s" % length2)
tasks = [
(ad_tx.messaging_droid.smsSendTextMessage,
(phonenumber_rx, text, True)),
(ad_tx2.messaging_droid.smsSendTextMessage,
(phonenumber_rx2, text2, True))]
multithread_func(log, tasks)
else:
if index < num_array_message:
ad_tx.messaging_droid.logI(
"Sending SMS of length %s" % length)
ad_tx.messaging_droid.smsSendTextMessage(
phonenumber_rx, text, True)
if index < num_array_message2:
ad_tx2.messaging_droid.logI(
"Sending SMS of length %s" % length2)
ad_tx2.messaging_droid.smsSendTextMessage(
phonenumber_rx2, text2, True)
try:
if index < num_array_message and index < num_array_message2:
tasks = [
(ad_tx.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
EventSmsSentSuccess,
EventSmsSentFailure,
EventSmsDeliverSuccess,
EventSmsDeliverFailure),
max_wait_time)),
(ad_tx2.messaging_ed.pop_events, ("(%s|%s|%s|%s)" % (
EventSmsSentSuccess,
EventSmsSentFailure,
EventSmsDeliverSuccess,
EventSmsDeliverFailure),
max_wait_time))
]
results = run_multithread_func(log, tasks)
res = True
_ad = ad_tx
for ad, events in [
(ad_tx, results[0]), (ad_tx2, results[1])]:
_ad = ad
for event in events:
ad.log.info("Got event %s", event["name"])
if event["name"] == EventSmsSentFailure or \
event["name"] == EventSmsDeliverFailure:
if event.get("data") and \
event["data"].get("Reason"):
ad.log.error("%s with reason: %s",
event["name"],
event["data"]["Reason"])
res = False
elif event["name"] == EventSmsSentSuccess or \
event["name"] == EventSmsDeliverSuccess:
break
if not res:
return False
else:
if index < num_array_message:
result = ad_tx.messaging_ed.pop_events(
"(%s|%s|%s|%s)" % (
EventSmsSentSuccess,
EventSmsSentFailure,
EventSmsDeliverSuccess,
EventSmsDeliverFailure),
max_wait_time)
res = True
_ad = ad_tx
for ad, events in [(ad_tx, result)]:
_ad = ad
for event in events:
ad.log.info("Got event %s", event["name"])
if event["name"] == EventSmsSentFailure or \
event["name"] == EventSmsDeliverFailure:
if event.get("data") and \
event["data"].get("Reason"):
ad.log.error(
"%s with reason: %s",
event["name"],
event["data"]["Reason"])
res = False
elif event["name"] == EventSmsSentSuccess \
or event["name"] == EventSmsDeliverSuccess:
break
if not res:
return False
if index < num_array_message2:
result = ad_tx2.messaging_ed.pop_events(
"(%s|%s|%s|%s)" % (
EventSmsSentSuccess,
EventSmsSentFailure,
EventSmsDeliverSuccess,
EventSmsDeliverFailure),
max_wait_time)
res = True
_ad = ad_tx2
for ad, events in [(ad_tx2, result)]:
_ad = ad
for event in events:
ad.log.info("Got event %s", event["name"])
if event["name"] == EventSmsSentFailure or \
event["name"] == EventSmsDeliverFailure:
if event.get("data") and \
event["data"].get("Reason"):
ad.log.error(
"%s with reason: %s",
event["name"],
event["data"]["Reason"])
res = False
elif event["name"] == EventSmsSentSuccess \
or event["name"] == EventSmsDeliverSuccess:
break
if not res:
return False
except Empty:
_ad.log.error("No %s or %s event for SMS of length %s.",
EventSmsSentSuccess, EventSmsSentFailure,
length)
return False
except Exception as e:
log.error("Exception error %s", e)
raise
ad_rx.wait_for_boot_completion()
ad_rx.root_adb()
ad_rx.start_services(skip_setup_wizard=False)
output = ad_rx.adb.logcat("-t 1")
match = re.search(r"\d+-\d+\s\d+:\d+:\d+.\d+", output)
if match:
ad_rx.test_log_begin_time = match.group(0)
ad_rx.messaging_droid, ad_rx.messaging_ed = ad_rx.get_droid()
ad_rx.messaging_ed.start()
ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
time.sleep(1) #sleep 100ms after starting event tracking
if not toggle_airplane_mode(log, ad_rx, False):
ad_rx.log.error("Failed to disable Airplane Mode")
return False
res = True
try:
if not wait_for_matching_multiple_sms(log,
ad_rx,
phonenumber_tx,
phonenumber_tx2,
messages=message_dict,
max_wait_time=max_wait_time):
res = False
except Exception as e:
log.error("Exception error %s", e)
raise
finally:
ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
return res
def is_sms_match(event, phonenumber_tx, text):
"""Return True if 'text' equals to event['data']['Text']
and phone number match.
Args:
event: Event object to verify.
phonenumber_tx: phone number for sender.
text: text string to verify.
Returns:
Return True if 'text' equals to event['data']['Text']
and phone number match.
"""
return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
and event['data']['Text'].strip() == text)
def is_sms_partial_match(event, phonenumber_tx, text):
"""Return True if 'text' starts with event['data']['Text']
and phone number match.
Args:
event: Event object to verify.
phonenumber_tx: phone number for sender.
text: text string to verify.
Returns:
Return True if 'text' starts with event['data']['Text']
and phone number match.
"""
event_text = event['data']['Text'].strip()
if event_text.startswith("("):
event_text = event_text.split(")")[-1]
return (check_phone_number_match(event['data']['Sender'], phonenumber_tx)
and text.startswith(event_text))
def is_sms_in_collision_match(
event, phonenumber_tx, phonenumber_tx2, text, text2):
event_text = event['data']['Text'].strip()
if event_text.startswith("("):
event_text = event_text.split(")")[-1]
for phonenumber, txt in [[phonenumber_tx, text], [phonenumber_tx2, text2]]:
if check_phone_number_match(
event['data']['Sender'], phonenumber) and txt.startswith(event_text):
return True
return False
def is_sms_in_collision_partial_match(
event, phonenumber_tx, phonenumber_tx2, text, text2):
for phonenumber, txt in [[phonenumber_tx, text], [phonenumber_tx2, text2]]:
if check_phone_number_match(
event['data']['Sender'], phonenumber) and \
event['data']['Text'].strip() == txt:
return True
return False
def is_sms_match_among_multiple_sms(
event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]):
for txt in texts:
if check_phone_number_match(
event['data']['Sender'], phonenumber_tx) and \
event['data']['Text'].strip() == txt:
return True
for txt in texts2:
if check_phone_number_match(
event['data']['Sender'], phonenumber_tx2) and \
event['data']['Text'].strip() == txt:
return True
return False
def is_sms_partial_match_among_multiple_sms(
event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]):
event_text = event['data']['Text'].strip()
if event_text.startswith("("):
event_text = event_text.split(")")[-1]
for txt in texts:
if check_phone_number_match(
event['data']['Sender'], phonenumber_tx) and \
txt.startswith(event_text):
return True
for txt in texts2:
if check_phone_number_match(
event['data']['Sender'], phonenumber_tx2) and \
txt.startswith(event_text):
return True
return False
def wait_for_matching_sms(log,
ad_rx,
phonenumber_tx,
text,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
allow_multi_part_long_sms=True):
"""Wait for matching incoming SMS.
Args:
log: Log object.
ad_rx: Receiver's Android Device Object
phonenumber_tx: Sender's phone number.
text: SMS content string.
allow_multi_part_long_sms: is long SMS allowed to be received as
multiple short SMS. This is optional, default value is True.
Returns:
True if matching incoming SMS is received.
"""
if not allow_multi_part_long_sms:
try:
ad_rx.messaging_ed.wait_for_event(EventSmsReceived, is_sms_match,
max_wait_time, phonenumber_tx,
text)
ad_rx.log.info("Got event %s", EventSmsReceived)
return True
except Empty:
ad_rx.log.error("No matched SMS received event.")
return False
else:
try:
received_sms = ''
remaining_text = text
while (remaining_text != ''):
event = ad_rx.messaging_ed.wait_for_event(
EventSmsReceived, is_sms_partial_match, max_wait_time,
phonenumber_tx, remaining_text)
event_text = event['data']['Text'].split(")")[-1].strip()
event_text_length = len(event_text)
ad_rx.log.info("Got event %s of text length %s from %s",
EventSmsReceived, event_text_length,
phonenumber_tx)
remaining_text = remaining_text[event_text_length:]
received_sms += event_text
ad_rx.log.info("Received SMS of length %s", len(received_sms))
return True
except Empty:
ad_rx.log.error(
"Missing SMS received event of text length %s from %s",
len(remaining_text), phonenumber_tx)
if received_sms != '':
ad_rx.log.error(
"Only received partial matched SMS of length %s",
len(received_sms))
return False
def wait_for_matching_mt_sms_in_collision(log,
ad_rx,
phonenumber_tx,
phonenumber_tx2,
text,
text2,
allow_multi_part_long_sms=True,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
if not allow_multi_part_long_sms:
try:
ad_rx.messaging_ed.wait_for_event(
EventSmsReceived,
is_sms_in_collision_match,
max_wait_time,
phonenumber_tx,
phonenumber_tx2,
text,
text2)
ad_rx.log.info("Got event %s", EventSmsReceived)
return True
except Empty:
ad_rx.log.error("No matched SMS received event.")
return False
else:
try:
received_sms = ''
received_sms2 = ''
remaining_text = text
remaining_text2 = text2
while (remaining_text != '' or remaining_text2 != ''):
event = ad_rx.messaging_ed.wait_for_event(
EventSmsReceived,
is_sms_in_collision_partial_match,
max_wait_time,
phonenumber_tx,
phonenumber_tx2,
remaining_text,
remaining_text2)
event_text = event['data']['Text'].split(")")[-1].strip()
event_text_length = len(event_text)
if event_text in remaining_text:
ad_rx.log.info("Got event %s of text length %s from %s",
EventSmsReceived, event_text_length,
phonenumber_tx)
remaining_text = remaining_text[event_text_length:]
received_sms += event_text
elif event_text in remaining_text2:
ad_rx.log.info("Got event %s of text length %s from %s",
EventSmsReceived, event_text_length,
phonenumber_tx2)
remaining_text2 = remaining_text2[event_text_length:]
received_sms2 += event_text
ad_rx.log.info("Received SMS of length %s", len(received_sms))
ad_rx.log.info("Received SMS of length %s", len(received_sms2))
return True
except Empty:
ad_rx.log.error(
"Missing SMS received event.")
if received_sms != '':
ad_rx.log.error(
"Only received partial matched SMS of length %s from %s",
len(received_sms), phonenumber_tx)
if received_sms2 != '':
ad_rx.log.error(
"Only received partial matched SMS of length %s from %s",
len(received_sms2), phonenumber_tx2)
return False
def wait_for_matching_mt_sms_in_collision_with_mo_sms(log,
ad_rx,
ad_rx2,
phonenumber_tx,
phonenumber_tx2,
text,
text2,
allow_multi_part_long_sms=True,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION):
if not allow_multi_part_long_sms:
result = True
try:
ad_rx.messaging_ed.wait_for_call_offhook_event(
EventSmsReceived,
is_sms_match,
max_wait_time,
phonenumber_tx,
text)
ad_rx.log.info("Got event %s", EventSmsReceived)
except Empty:
ad_rx.log.error("No matched SMS received event.")
result = False
try:
ad_rx2.messaging_ed.wait_for_call_offhook_event(
EventSmsReceived,
is_sms_match,
max_wait_time,
phonenumber_tx2,
text2)
ad_rx2.log.info("Got event %s", EventSmsReceived)
except Empty:
ad_rx2.log.error("No matched SMS received event.")
result = False
return result
else:
result = True
try:
received_sms = ''
remaining_text = text
while remaining_text != '':
event = ad_rx.messaging_ed.wait_for_event(
EventSmsReceived, is_sms_partial_match, max_wait_time,
phonenumber_tx, remaining_text)
event_text = event['data']['Text'].split(")")[-1].strip()
event_text_length = len(event_text)
if event_text in remaining_text:
ad_rx.log.info("Got event %s of text length %s from %s",
EventSmsReceived, event_text_length,
phonenumber_tx)
remaining_text = remaining_text[event_text_length:]
received_sms += event_text
ad_rx.log.info("Received SMS of length %s", len(received_sms))
except Empty:
ad_rx.log.error(
"Missing SMS received event.")
if received_sms != '':
ad_rx.log.error(
"Only received partial matched SMS of length %s from %s",
len(received_sms), phonenumber_tx)
result = False
try:
received_sms2 = ''
remaining_text2 = text2
while remaining_text2 != '':
event2 = ad_rx2.messaging_ed.wait_for_event(
EventSmsReceived, is_sms_partial_match, max_wait_time,
phonenumber_tx2, remaining_text2)
event_text2 = event2['data']['Text'].split(")")[-1].strip()
event_text_length2 = len(event_text2)
if event_text2 in remaining_text2:
ad_rx2.log.info("Got event %s of text length %s from %s",
EventSmsReceived, event_text_length2,
phonenumber_tx2)
remaining_text2 = remaining_text2[event_text_length2:]
received_sms2 += event_text2
ad_rx2.log.info("Received SMS of length %s", len(received_sms2))
except Empty:
ad_rx2.log.error(
"Missing SMS received event.")
if received_sms2 != '':
ad_rx2.log.error(
"Only received partial matched SMS of length %s from %s",
len(received_sms2), phonenumber_tx2)
result = False
return result
def wait_for_matching_multiple_sms(log,
ad_rx,
phonenumber_tx,
phonenumber_tx2,
messages={},
allow_multi_part_long_sms=True,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
if not allow_multi_part_long_sms:
try:
ad_rx.messaging_ed.wait_for_event(
EventSmsReceived,
is_sms_match_among_multiple_sms,
max_wait_time,
phonenumber_tx,
phonenumber_tx2,
messages[phonenumber_tx],
messages[phonenumber_tx2])
ad_rx.log.info("Got event %s", EventSmsReceived)
return True
except Empty:
ad_rx.log.error("No matched SMS received event.")
return False
else:
all_msgs = []
for tx, msgs in messages.items():
for msg in msgs:
all_msgs.append([tx, msg, msg, ''])
all_msgs_copy = all_msgs.copy()
try:
while (all_msgs != []):
event = ad_rx.messaging_ed.wait_for_event(
EventSmsReceived,
is_sms_partial_match_among_multiple_sms,
max_wait_time,
phonenumber_tx,
phonenumber_tx2,
messages[phonenumber_tx],
messages[phonenumber_tx2])
event_text = event['data']['Text'].split(")")[-1].strip()
event_text_length = len(event_text)
for msg in all_msgs_copy:
if event_text in msg[2]:
ad_rx.log.info("Got event %s of text length %s from %s",
EventSmsReceived, event_text_length,
msg[0])
msg[2] = msg[2][event_text_length:]
msg[3] += event_text
if msg[2] == "":
all_msgs.remove(msg)
ad_rx.log.info("Received all SMS' sent when power-off.")
except Empty:
ad_rx.log.error(
"Missing SMS received event.")
for msg in all_msgs_copy:
if msg[3] != '':
ad_rx.log.error(
"Only received partial matched SMS of length %s from %s",
len(msg[3]), msg[0])
return False
return True
def wait_for_sending_sms(ad_tx, max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
try:
events = ad_tx.messaging_ed.pop_events(
"(%s|%s|%s|%s)" %
(EventSmsSentSuccess, EventSmsSentFailure,
EventSmsDeliverSuccess,
EventSmsDeliverFailure), max_wait_time)
for event in events:
ad_tx.log.info("Got event %s", event["name"])
if event["name"] == EventSmsSentFailure or \
event["name"] == EventSmsDeliverFailure:
if event.get("data") and event["data"].get("Reason"):
ad_tx.log.error("%s with reason: %s",
event["name"],
event["data"]["Reason"])
return False
elif event["name"] == EventSmsSentSuccess or \
event["name"] == EventSmsDeliverSuccess:
return True
except Empty:
ad_tx.log.error("No %s or %s event for SMS.",
EventSmsSentSuccess, EventSmsSentFailure)
return False
def voice_call_in_collision_with_mt_sms_msim(
log,
ad_primary,
ad_sms,
ad_voice,
sms_subid_ad_primary,
sms_subid_ad_sms,
voice_subid_ad_primary,
voice_subid_ad_voice,
array_message,
ad_hangup=None,
verify_caller_func=None,
verify_callee_func=None,
call_direction="mo",
wait_time_in_call=WAIT_TIME_IN_CALL,
incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
dialing_number_length=None,
video_state=None):
ad_tx = ad_sms
ad_rx = ad_primary
subid_tx = sms_subid_ad_sms
subid_rx = sms_subid_ad_primary
if call_direction == "mo":
ad_caller = ad_primary
ad_callee = ad_voice
subid_caller = voice_subid_ad_primary
subid_callee = voice_subid_ad_voice
elif call_direction == "mt":
ad_callee = ad_primary
ad_caller = ad_voice
subid_callee = voice_subid_ad_primary
subid_caller = voice_subid_ad_voice
phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
tel_result_wrapper = TelResultWrapper(CallResult('SUCCESS'))
for ad in (ad_tx, ad_rx):
ad.send_keycode("BACK")
if not getattr(ad, "messaging_droid", None):
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
else:
try:
if not ad.messaging_droid.is_live:
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
else:
ad.messaging_ed.clear_all_events()
except Exception:
ad.log.info("Create new sl4a session for messaging")
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
if not verify_caller_func:
verify_caller_func = is_phone_in_call
if not verify_callee_func:
verify_callee_func = is_phone_in_call
caller_number = ad_caller.telephony['subscription'][subid_caller][
'phone_num']
callee_number = ad_callee.telephony['subscription'][subid_callee][
'phone_num']
if dialing_number_length:
skip_test = False
trunc_position = 0 - int(dialing_number_length)
try:
caller_area_code = caller_number[:trunc_position]
callee_area_code = callee_number[:trunc_position]
callee_dial_number = callee_number[trunc_position:]
except:
skip_test = True
if caller_area_code != callee_area_code:
skip_test = True
if skip_test:
msg = "Cannot make call from %s to %s by %s digits" % (
caller_number, callee_number, dialing_number_length)
ad_caller.log.info(msg)
raise signals.TestSkip(msg)
else:
callee_number = callee_dial_number
msg = "Call from %s to %s" % (caller_number, callee_number)
if video_state:
msg = "Video %s" % msg
video = True
else:
video = False
if ad_hangup:
msg = "%s for duration of %s seconds" % (msg, wait_time_in_call)
ad_caller.log.info(msg)
for ad in (ad_caller, ad_callee):
call_ids = ad.droid.telecomCallGetCallIds()
setattr(ad, "call_ids", call_ids)
if call_ids:
ad.log.info("Pre-exist CallId %s before making call", call_ids)
ad_caller.ed.clear_events(EventCallStateChanged)
call_begin_time = get_device_epoch_time(ad)
ad_caller.droid.telephonyStartTrackingCallStateForSubscription(subid_caller)
for text in array_message:
length = len(text)
ad_tx.log.info("Sending SMS from %s to %s, len: %s, content: %s.",
phonenumber_tx, phonenumber_rx, length, text)
try:
ad_rx.messaging_ed.clear_events(EventSmsReceived)
ad_tx.messaging_ed.clear_events(EventSmsSentSuccess)
ad_tx.messaging_ed.clear_events(EventSmsSentFailure)
ad_rx.messaging_droid.smsStartTrackingIncomingSmsMessage()
time.sleep(1) #sleep 100ms after starting event tracking
ad_tx.messaging_droid.logI("Sending SMS of length %s" % length)
ad_rx.messaging_droid.logI("Expecting SMS of length %s" % length)
ad_caller.log.info("Make a phone call to %s", callee_number)
tasks = [
(ad_tx.messaging_droid.smsSendTextMessage,
(phonenumber_rx, text, True)),
(ad_caller.droid.telecomCallNumber,
(callee_number, video))]
run_multithread_func(log, tasks)
try:
# Verify OFFHOOK state
if not wait_for_call_offhook_for_subscription(
log,
ad_caller,
subid_caller,
event_tracking_started=True):
ad_caller.log.info(
"sub_id %s not in call offhook state", subid_caller)
last_call_drop_reason(ad_caller, begin_time=call_begin_time)
ad_caller.log.error("Initiate call failed.")
tel_result_wrapper.result_value = CallResult(
'INITIATE_FAILED')
return tel_result_wrapper
else:
ad_caller.log.info("Caller initate call successfully")
finally:
ad_caller.droid.telephonyStopTrackingCallStateChangeForSubscription(
subid_caller)
if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
ad_caller.droid.telecomShowInCallScreen()
elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
ad_caller.droid.showHomeScreen()
if not wait_and_answer_call_for_subscription(
log,
ad_callee,
subid_callee,
incoming_number=caller_number,
caller=ad_caller,
incall_ui_display=incall_ui_display,
video_state=video_state):
ad_callee.log.error("Answer call fail.")
tel_result_wrapper.result_value = CallResult(
'NO_RING_EVENT_OR_ANSWER_FAILED')
return tel_result_wrapper
else:
ad_callee.log.info("Callee answered the call successfully")
for ad, call_func in zip([ad_caller, ad_callee],
[verify_caller_func, verify_callee_func]):
call_ids = ad.droid.telecomCallGetCallIds()
new_call_ids = set(call_ids) - set(ad.call_ids)
if not new_call_ids:
ad.log.error(
"No new call ids are found after call establishment")
ad.log.error("telecomCallGetCallIds returns %s",
ad.droid.telecomCallGetCallIds())
tel_result_wrapper.result_value = CallResult(
'NO_CALL_ID_FOUND')
for new_call_id in new_call_ids:
if not wait_for_in_call_active(ad, call_id=new_call_id):
tel_result_wrapper.result_value = CallResult(
'CALL_STATE_NOT_ACTIVE_DURING_ESTABLISHMENT')
else:
ad.log.info(
"callProperties = %s",
ad.droid.telecomCallGetProperties(new_call_id))
if not ad.droid.telecomCallGetAudioState():
ad.log.error("Audio is not in call state")
tel_result_wrapper.result_value = CallResult(
'AUDIO_STATE_NOT_INCALL_DURING_ESTABLISHMENT')
if call_func(log, ad):
ad.log.info("Call is in %s state", call_func.__name__)
else:
ad.log.error("Call is not in %s state, voice in RAT %s",
call_func.__name__,
ad.droid.telephonyGetCurrentVoiceNetworkType())
tel_result_wrapper.result_value = CallResult(
'CALL_DROP_OR_WRONG_STATE_DURING_ESTABLISHMENT')
if not tel_result_wrapper:
return tel_result_wrapper
if not wait_for_sending_sms(
ad_tx,
max_wait_time=MAX_WAIT_TIME_SMS_SENT_SUCCESS_IN_COLLISION):
return False
tasks = [
(wait_for_matching_sms,
(log, ad_rx, phonenumber_tx, text,
MAX_WAIT_TIME_SMS_RECEIVE_IN_COLLISION, True)),
(wait_for_call_end,
(log, ad_caller, ad_callee, ad_hangup, verify_caller_func,
verify_callee_func, call_begin_time, 5, tel_result_wrapper,
WAIT_TIME_IN_CALL))]
results = run_multithread_func(log, tasks)
if not results[0]:
ad_rx.log.error("No matching received SMS of length %s.",
length)
return False
tel_result_wrapper = results[1]
except Exception as e:
log.error("Exception error %s", e)
raise
finally:
ad_rx.messaging_droid.smsStopTrackingIncomingSmsMessage()
return tel_result_wrapper
def is_mms_match(event, phonenumber_tx, text):
"""Return True if 'text' equals to event['data']['Text']
and phone number match.
Args:
event: Event object to verify.
phonenumber_tx: phone number for sender.
text: text string to verify.
Returns:
Return True if 'text' equals to event['data']['Text']
and phone number match.
"""
#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
return True
def wait_for_matching_mms(log,
ad_rx,
phonenumber_tx,
text,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
"""Wait for matching incoming SMS.
Args:
log: Log object.
ad_rx: Receiver's Android Device Object
phonenumber_tx: Sender's phone number.
text: SMS content string.
allow_multi_part_long_sms: is long SMS allowed to be received as
multiple short SMS. This is optional, default value is True.
Returns:
True if matching incoming SMS is received.
"""
try:
#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
ad_rx.messaging_ed.wait_for_event(EventMmsDownloaded, is_mms_match,
max_wait_time, phonenumber_tx, text)
ad_rx.log.info("Got event %s", EventMmsDownloaded)
return True
except Empty:
ad_rx.log.warning("No matched MMS downloaded event.")
return False
def mms_send_receive_verify(log,
ad_tx,
ad_rx,
array_message,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE,
expected_result=True,
slot_id_rx=None):
"""Send MMS, receive MMS, and verify content and sender's number.
Send (several) MMS from droid_tx to droid_rx.
Verify MMS is sent, delivered and received.
Verify received content and sender's number are correct.
Args:
log: Log object.
ad_tx: Sender's Android Device Object
ad_rx: Receiver's Android Device Object
array_message: the array of message to send/receive
"""
subid_tx = get_outgoing_message_sub_id(ad_tx)
if slot_id_rx is None:
subid_rx = get_incoming_message_sub_id(ad_rx)
else:
subid_rx = get_subid_from_slot_index(log, ad_rx, slot_id_rx)
result = mms_send_receive_verify_for_subscription(
log, ad_tx, ad_rx, subid_tx, subid_rx, array_message, max_wait_time)
if result != expected_result:
log_messaging_screen_shot(ad_tx, test_name="mms_tx")
log_messaging_screen_shot(ad_rx, test_name="mms_rx")
return result == expected_result
def sms_mms_send_logcat_check(ad, type, begin_time):
type = type.upper()
log_results = ad.search_logcat(
"%s Message sent successfully" % type, begin_time=begin_time)
if log_results:
ad.log.info("Found %s sent successful log message: %s", type,
log_results[-1]["log_message"])
return True
else:
log_results = ad.search_logcat(
"ProcessSentMessageAction: Done sending %s message" % type,
begin_time=begin_time)
if log_results:
for log_result in log_results:
if "status is SUCCEEDED" in log_result["log_message"]:
ad.log.info(
"Found BugleDataModel %s send succeed log message: %s",
type, log_result["log_message"])
return True
return False
def sms_mms_receive_logcat_check(ad, type, begin_time):
type = type.upper()
smshandle_logs = ad.search_logcat(
"InboundSmsHandler: No broadcast sent on processing EVENT_BROADCAST_SMS",
begin_time=begin_time)
if smshandle_logs:
ad.log.warning("Found %s", smshandle_logs[-1]["log_message"])
log_results = ad.search_logcat(
"New %s Received" % type, begin_time=begin_time) or \
ad.search_logcat("New %s Downloaded" % type, begin_time=begin_time)
if log_results:
ad.log.info("Found SL4A %s received log message: %s", type,
log_results[-1]["log_message"])
return True
else:
log_results = ad.search_logcat(
"Received %s message" % type, begin_time=begin_time)
if log_results:
ad.log.info("Found %s received log message: %s", type,
log_results[-1]["log_message"])
log_results = ad.search_logcat(
"ProcessDownloadedMmsAction", begin_time=begin_time)
for log_result in log_results:
ad.log.info("Found %s", log_result["log_message"])
if "status is SUCCEEDED" in log_result["log_message"]:
ad.log.info("Download succeed with ProcessDownloadedMmsAction")
return True
return False
#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
def mms_send_receive_verify_for_subscription(
log,
ad_tx,
ad_rx,
subid_tx,
subid_rx,
array_payload,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
"""Send MMS, receive MMS, and verify content and sender's number.
Send (several) MMS from droid_tx to droid_rx.
Verify MMS is sent, delivered and received.
Verify received content and sender's number are correct.
Args:
log: Log object.
ad_tx: Sender's Android Device Object..
ad_rx: Receiver's Android Device Object.
subid_tx: Sender's subscription ID to be used for SMS
subid_rx: Receiver's subscription ID to be used for SMS
array_message: the array of message to send/receive
"""
phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
toggle_enforce = False
for ad in (ad_tx, ad_rx):
if "Permissive" not in ad.adb.shell("su root getenforce"):
ad.adb.shell("su root setenforce 0")
toggle_enforce = True
if not getattr(ad, "messaging_droid", None):
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
else:
try:
if not ad.messaging_droid.is_live:
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
else:
ad.messaging_ed.clear_all_events()
ad.messaging_droid.logI(
"Start mms_send_receive_verify_for_subscription test")
except Exception:
ad.log.info("Create new sl4a session for messaging")
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
for subject, message, filename in array_payload:
ad_tx.messaging_ed.clear_events(EventMmsSentSuccess)
ad_tx.messaging_ed.clear_events(EventMmsSentFailure)
ad_rx.messaging_ed.clear_events(EventMmsDownloaded)
ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
ad_tx.log.info(
"Sending MMS from %s to %s, subject: %s, message: %s, file: %s.",
phonenumber_tx, phonenumber_rx, subject, message, filename)
try:
ad_tx.messaging_droid.smsSendMultimediaMessage(
phonenumber_rx, subject, message, phonenumber_tx, filename)
try:
events = ad_tx.messaging_ed.pop_events(
"(%s|%s)" % (EventMmsSentSuccess,
EventMmsSentFailure), max_wait_time)
for event in events:
ad_tx.log.info("Got event %s", event["name"])
if event["name"] == EventMmsSentFailure:
if event.get("data") and event["data"].get("Reason"):
ad_tx.log.error("%s with reason: %s",
event["name"],
event["data"]["Reason"])
return False
elif event["name"] == EventMmsSentSuccess:
break
except Empty:
ad_tx.log.warning("No %s or %s event.", EventMmsSentSuccess,
EventMmsSentFailure)
return False
if not wait_for_matching_mms(log, ad_rx, phonenumber_tx,
message, max_wait_time):
return False
except Exception as e:
log.error("Exception error %s", e)
raise
finally:
ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
for ad in (ad_tx, ad_rx):
if toggle_enforce:
ad.send_keycode("BACK")
ad.adb.shell("su root setenforce 1")
return True
def mms_receive_verify_after_call_hangup(
log, ad_tx, ad_rx, array_message,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
"""Verify the suspanded MMS during call will send out after call release.
Hangup call from droid_tx to droid_rx.
Verify MMS is sent, delivered and received.
Verify received content and sender's number are correct.
Args:
log: Log object.
ad_tx: Sender's Android Device Object
ad_rx: Receiver's Android Device Object
array_message: the array of message to send/receive
"""
return mms_receive_verify_after_call_hangup_for_subscription(
log, ad_tx, ad_rx, get_outgoing_message_sub_id(ad_tx),
get_incoming_message_sub_id(ad_rx), array_message, max_wait_time)
#TODO: add mms matching after mms message parser is added in sl4a. b/34276948
def mms_receive_verify_after_call_hangup_for_subscription(
log,
ad_tx,
ad_rx,
subid_tx,
subid_rx,
array_payload,
max_wait_time=MAX_WAIT_TIME_SMS_RECEIVE):
"""Verify the suspanded MMS during call will send out after call release.
Hangup call from droid_tx to droid_rx.
Verify MMS is sent, delivered and received.
Verify received content and sender's number are correct.
Args:
log: Log object.
ad_tx: Sender's Android Device Object..
ad_rx: Receiver's Android Device Object.
subid_tx: Sender's subscription ID to be used for SMS
subid_rx: Receiver's subscription ID to be used for SMS
array_message: the array of message to send/receive
"""
phonenumber_tx = ad_tx.telephony['subscription'][subid_tx]['phone_num']
phonenumber_rx = ad_rx.telephony['subscription'][subid_rx]['phone_num']
for ad in (ad_tx, ad_rx):
if not getattr(ad, "messaging_droid", None):
ad.messaging_droid, ad.messaging_ed = ad.get_droid()
ad.messaging_ed.start()
for subject, message, filename in array_payload:
ad_rx.log.info(
"Waiting MMS from %s to %s, subject: %s, message: %s, file: %s.",
phonenumber_tx, phonenumber_rx, subject, message, filename)
ad_rx.messaging_droid.smsStartTrackingIncomingMmsMessage()
time.sleep(5)
try:
hangup_call(log, ad_tx)
hangup_call(log, ad_rx)
try:
ad_tx.messaging_ed.pop_event(EventMmsSentSuccess,
max_wait_time)
ad_tx.log.info("Got event %s", EventMmsSentSuccess)
except Empty:
log.warning("No sent_success event.")
if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, message):
return False
finally:
ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage()
return True
def log_messaging_screen_shot(ad, test_name=""):
ad.ensure_screen_on()
ad.send_keycode("HOME")
ad.adb.shell("am start -n com.google.android.apps.messaging/.ui."
"ConversationListActivity")
time.sleep(3)
ad.screenshot(test_name)
ad.adb.shell("am start -n com.google.android.apps.messaging/com.google."
"android.apps.messaging.ui.conversation."
"LaunchConversationShimActivity -e conversation_id 1")
time.sleep(3)
ad.screenshot(test_name)
ad.send_keycode("HOME")