blob: 26751cfa08b67eba236a4488916fb450061e315c [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2016 - Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import time
from queue import Empty
from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_EARPIECE
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_VIDEO_SESSION_EVENT
from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED
from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA
from acts_contrib.test_utils.tel.tel_defines import GEN_4G
from acts_contrib.test_utils.tel.tel_defines import RAT_IWLAN
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_AUDIO_ONLY
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL_PAUSED
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_RX_ENABLED
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_RX_PAUSED
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_TX_ENABLED
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_TX_PAUSED
from acts_contrib.test_utils.tel.tel_defines import VT_STATE_STATE_INVALID
from acts_contrib.test_utils.tel.tel_defines import VT_VIDEO_QUALITY_DEFAULT
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 WFC_MODE_DISABLED
from acts_contrib.test_utils.tel.tel_defines import EventTelecomVideoCallSessionModifyRequestReceived
from acts_contrib.test_utils.tel.tel_defines import EventTelecomVideoCallSessionModifyResponseReceived
from acts_contrib.test_utils.tel.tel_defines import EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED
from acts_contrib.test_utils.tel.tel_defines import EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED
from acts_contrib.test_utils.tel.tel_ims_utils import is_wfc_enabled
from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode_for_subscription
from acts_contrib.test_utils.tel.tel_ims_utils import wait_for_video_enabled
from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_network_generation
from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_iwlan_for_subscription
from acts_contrib.test_utils.tel.tel_phone_setup_utils import wait_for_network_generation
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_incoming_voice_sub_id
from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat
from acts_contrib.test_utils.tel.tel_voice_utils import call_setup_teardown_for_subscription
from acts_contrib.test_utils.tel.tel_voice_utils import initiate_call
from acts_contrib.test_utils.tel.tel_voice_utils import is_call_hd
from acts_contrib.test_utils.tel.tel_voice_utils import wait_and_answer_call_for_subscription
def phone_setup_video(
log,
ad,
wfc_mode=WFC_MODE_DISABLED,
is_airplane_mode=False,
wifi_ssid=None,
wifi_pwd=None):
"""Setup phone default sub_id to make video call
Args:
log: log object.
ad: android device object
wfc_mode: WFC mode to set to.
Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED.
Returns:
True if ad (default sub_id) is setup correctly and idle for video call.
"""
return phone_setup_video_for_subscription(log, ad,
get_outgoing_voice_sub_id(ad),
wfc_mode,
False,
wifi_ssid,
wifi_pwd)
def phone_setup_video_for_subscription(log,
ad,
sub_id,
wfc_mode=WFC_MODE_DISABLED,
is_airplane_mode=False,
wifi_ssid=None,
wifi_pwd=None):
"""Setup phone sub_id to make video call
Args:
log: log object.
ad: android device object
sub_id: ad's sub id.
wfc_mode: WFC mode to set to. Valid mode includes:
- WFC_MODE_WIFI_ONLY
- Wi-Fi will be connected if wifi_ssid is assigned.
- WFC_MODE_CELLULAR_PREFERRED
- Wi-Fi will be connected if wifi_ssid is assigned.
- WFC_MODE_WIFI_PREFERRED
- Wi-Fi will be connected if wifi_ssid is assigned.
- WFC_MODE_DISABLED
- Only WFC mode will be set to DISABLED.
- None
- Neither WFC mode nor Wi-Fi state will be changed.
is_airplane_mode:
- False: airplane mode disabled
- True: airplane mode enabled for ViWifi
wifi_ssid: SSID of Wi-Fi AP to connect for ViWifi
wifi_ssid: Password of Wi-Fi AP SSID for ViWifi
Returns:
True if ad (sub_id) is setup correctly and idle for video call.
"""
if not ensure_network_generation(
log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA):
log.error("{} voice not in LTE mode.".format(ad.serial))
return False
toggle_volte(log, ad, True)
if wfc_mode == WFC_MODE_DISABLED:
if not set_wfc_mode_for_subscription(ad, wfc_mode, sub_id):
log.error("{} WFC mode failed to be set to {}.".format(
ad.serial, wfc_mode))
return False
else:
if wfc_mode:
if not phone_setup_iwlan_for_subscription(log, ad, sub_id,
is_airplane_mode, wfc_mode, wifi_ssid, wifi_pwd):
log.error("Failed to set up phone on iwlan.")
return False
return phone_idle_video_for_subscription(log, ad, sub_id)
def phone_idle_video(log, ad):
"""Return if phone (default sub_id) is idle for video call.
Args:
log: log object.
ad: android device object
Returns:
True if ad is idle for video call.
"""
return phone_idle_video_for_subscription(log, ad,
get_outgoing_voice_sub_id(ad))
def phone_idle_video_for_subscription(log, ad, sub_id):
"""Return if phone (sub_id) is idle for video call.
Args:
log: log object.
ad: android device object
sub_id: ad's sub id
Returns:
True if ad (sub_id) is idle for video call.
"""
if not wait_for_network_generation(log, ad, GEN_4G):
log.error("{} voice not in LTE mode.".format(ad.serial))
return False
if not wait_for_video_enabled(log, ad, MAX_WAIT_TIME_VOLTE_ENABLED):
log.error(
"{} failed to <report video calling enabled> within {}s.".format(
ad.serial, MAX_WAIT_TIME_VOLTE_ENABLED))
return False
return True
def is_phone_in_call_video(log, ad):
"""Return if ad is in a video call (in expected video state).
Args:
log: log object.
ad: android device object
video_state: Expected Video call state.
This is optional, if it's None,
then TX_ENABLED/RX_ENABLED/BIDIRECTIONAL video call state will
return True.
Returns:
True if ad (for sub_id) is in a video call (in expected video state).
"""
return is_phone_in_call_video_for_subscription(
log, ad, get_outgoing_voice_sub_id(ad))
def is_phone_in_call_video_for_subscription(log, ad, sub_id, video_state=None):
"""Return if ad (for sub_id) is in a video call (in expected video state).
Args:
log: log object.
ad: android device object
sub_id: device sub_id
video_state: Expected Video call state.
This is optional, if it's None,
then TX_ENABLED/RX_ENABLED/BIDIRECTIONAL video call state will
return True.
Returns:
True if ad is in a video call (in expected video state).
"""
if video_state is None:
log.info("Verify if {}(subid {}) in video call.".format(
ad.serial, sub_id))
if not ad.droid.telecomIsInCall():
log.error("{} not in call.".format(ad.serial))
return False
call_list = ad.droid.telecomCallGetCallIds()
for call in call_list:
state = ad.droid.telecomCallVideoGetState(call)
if video_state is None:
if {
VT_STATE_AUDIO_ONLY: False,
VT_STATE_TX_ENABLED: True,
VT_STATE_TX_PAUSED: True,
VT_STATE_RX_ENABLED: True,
VT_STATE_RX_PAUSED: True,
VT_STATE_BIDIRECTIONAL: True,
VT_STATE_BIDIRECTIONAL_PAUSED: True,
VT_STATE_STATE_INVALID: False
}[state]:
return True
else:
if state == video_state:
return True
log.info("Non-Video-State: {}".format(state))
log.error("Phone not in video call. Call list: {}".format(call_list))
return False
def is_phone_in_call_viwifi_for_subscription(log, ad, sub_id,
video_state=None):
"""Return if ad (for sub_id) is in a viwifi call (in expected video state).
Args:
log: log object.
ad: android device object
sub_id: device sub_id
video_state: Expected Video call state.
This is optional, if it's None,
then TX_ENABLED/RX_ENABLED/BIDIRECTIONAL video call state will
return True.
Returns:
True if ad is in a video call (in expected video state).
"""
if video_state is None:
log.info("Verify if {}(subid {}) in video call.".format(
ad.serial, sub_id))
if not ad.droid.telecomIsInCall():
log.error("{} not in call.".format(ad.serial))
return False
nw_type = get_network_rat(log, ad, NETWORK_SERVICE_DATA)
if nw_type != RAT_IWLAN:
ad.log.error("Data rat on: %s. Expected: iwlan", nw_type)
return False
if not is_wfc_enabled(log, ad):
ad.log.error("WiFi Calling feature bit is False.")
return False
call_list = ad.droid.telecomCallGetCallIds()
for call in call_list:
state = ad.droid.telecomCallVideoGetState(call)
if video_state is None:
if {
VT_STATE_AUDIO_ONLY: False,
VT_STATE_TX_ENABLED: True,
VT_STATE_TX_PAUSED: True,
VT_STATE_RX_ENABLED: True,
VT_STATE_RX_PAUSED: True,
VT_STATE_BIDIRECTIONAL: True,
VT_STATE_BIDIRECTIONAL_PAUSED: True,
VT_STATE_STATE_INVALID: False
}[state]:
return True
else:
if state == video_state:
return True
ad.log.info("Non-Video-State: %s", state)
ad.log.error("Phone not in video call. Call list: %s", call_list)
return False
def is_phone_in_call_video_bidirectional(log, ad):
"""Return if phone in bi-directional video call.
Args:
log: log object.
ad: android device object
Returns:
True if phone in bi-directional video call.
"""
return is_phone_in_call_video_bidirectional_for_subscription(
log, ad, get_outgoing_voice_sub_id(ad))
def is_phone_in_call_video_bidirectional_for_subscription(log, ad, sub_id):
"""Return if phone in bi-directional video call for subscription id.
Args:
log: log object.
ad: android device object
sub_id: subscription id.
Returns:
True if phone in bi-directional video call.
"""
log.info("Verify if {}(subid {}) in bi-directional video call.".format(
ad.serial, sub_id))
return is_phone_in_call_video_for_subscription(log, ad, sub_id,
VT_STATE_BIDIRECTIONAL)
def is_phone_in_call_viwifi_bidirectional(log, ad):
"""Return if phone in bi-directional viwifi call.
Args:
log: log object.
ad: android device object
Returns:
True if phone in bi-directional viwifi call.
"""
return is_phone_in_call_viwifi_bidirectional_for_subscription(
log, ad, get_outgoing_voice_sub_id(ad))
def is_phone_in_call_viwifi_bidirectional_for_subscription(log, ad, sub_id):
"""Return if phone in bi-directional viwifi call for subscription id.
Args:
log: log object.
ad: android device object
sub_id: subscription id.
Returns:
True if phone in bi-directional viwifi call.
"""
ad.log.info("Verify if subid %s in bi-directional video call.", sub_id)
return is_phone_in_call_viwifi_for_subscription(log, ad, sub_id,
VT_STATE_BIDIRECTIONAL)
def is_phone_in_call_video_tx_enabled(log, ad):
"""Return if phone in tx_enabled video call.
Args:
log: log object.
ad: android device object
Returns:
True if phone in tx_enabled video call.
"""
return is_phone_in_call_video_tx_enabled_for_subscription(
log, ad, get_outgoing_voice_sub_id(ad))
def is_phone_in_call_video_tx_enabled_for_subscription(log, ad, sub_id):
"""Return if phone in tx_enabled video call for subscription id.
Args:
log: log object.
ad: android device object
sub_id: subscription id.
Returns:
True if phone in tx_enabled video call.
"""
log.info("Verify if {}(subid {}) in tx_enabled video call.".format(
ad.serial, sub_id))
return is_phone_in_call_video_for_subscription(log, ad, sub_id,
VT_STATE_TX_ENABLED)
def is_phone_in_call_video_rx_enabled(log, ad):
"""Return if phone in rx_enabled video call.
Args:
log: log object.
ad: android device object
Returns:
True if phone in rx_enabled video call.
"""
return is_phone_in_call_video_rx_enabled_for_subscription(
log, ad, get_outgoing_voice_sub_id(ad))
def is_phone_in_call_video_rx_enabled_for_subscription(log, ad, sub_id):
"""Return if phone in rx_enabled video call for subscription id.
Args:
log: log object.
ad: android device object
sub_id: subscription id.
Returns:
True if phone in rx_enabled video call.
"""
log.info("Verify if {}(subid {}) in rx_enabled video call.".format(
ad.serial, sub_id))
return is_phone_in_call_video_for_subscription(log, ad, sub_id,
VT_STATE_RX_ENABLED)
def is_phone_in_call_voice_hd(log, ad):
"""Return if phone in hd voice call.
Args:
log: log object.
ad: android device object
Returns:
True if phone in hd voice call.
"""
return is_phone_in_call_voice_hd_for_subscription(
log, ad, get_outgoing_voice_sub_id(ad))
def is_phone_in_call_voice_hd_for_subscription(log, ad, sub_id):
"""Return if phone in hd voice call for subscription id.
Args:
log: log object.
ad: android device object
sub_id: subscription id.
Returns:
True if phone in hd voice call.
"""
log.info("Verify if {}(subid {}) in hd voice call.".format(
ad.serial, sub_id))
if not ad.droid.telecomIsInCall():
log.error("{} not in call.".format(ad.serial))
return False
for call in ad.droid.telecomCallGetCallIds():
state = ad.droid.telecomCallVideoGetState(call)
if (state == VT_STATE_AUDIO_ONLY and is_call_hd(log, ad, call)):
return True
log.info("Non-HDAudio-State: {}, property: {}".format(
state, ad.droid.telecomCallGetProperties(call)))
return False
def initiate_video_call(log, ad_caller, callee_number):
"""Make phone call from caller to callee.
Args:
log: logging handle
ad_caller: Caller android device object.
callee_number: Callee phone number.
Returns:
result: if phone call is placed successfully.
"""
return initiate_call(log, ad_caller, callee_number, video=True)
def wait_and_answer_video_call(log,
ad,
incoming_number=None,
video_state=VT_STATE_BIDIRECTIONAL,
incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
"""Wait for an incoming call on default voice subscription and
accepts the call.
Args:
ad: android device object.
incoming_number: Expected incoming number.
Optional. Default is None
incall_ui_display: after answer the call, bring in-call UI to foreground or
background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
else, do nothing.
Returns:
True: if incoming call is received and answered successfully.
False: for errors
"""
return wait_and_answer_video_call_for_subscription(
log, ad, get_outgoing_voice_sub_id(ad), incoming_number, video_state,
incall_ui_display)
def wait_and_answer_video_call_for_subscription(
log,
ad,
sub_id,
incoming_number=None,
video_state=VT_STATE_BIDIRECTIONAL,
incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
"""Wait for an incoming call on specified subscription and
accepts the call.
Args:
ad: android device object.
sub_id: subscription ID
incoming_number: Expected incoming number.
Optional. Default is None
incall_ui_display: after answer the call, bring in-call UI to foreground or
background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
else, do nothing.
Returns:
True: if incoming call is received and answered successfully.
False: for errors
"""
return wait_and_answer_call_for_subscription(
log,
ad,
sub_id,
incoming_number=None,
incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
video_state=video_state)
def video_call_setup_teardown(log,
ad_caller,
ad_callee,
ad_hangup=None,
video_state=VT_STATE_BIDIRECTIONAL,
verify_caller_func=None,
verify_callee_func=None,
wait_time_in_call=WAIT_TIME_IN_CALL,
incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
""" Call process, including make a phone call from caller,
accept from callee, and hang up. The call is on default subscription
In call process, call from <droid_caller> to <droid_callee>,
accept the call, (optional)then hang up from <droid_hangup>.
Args:
ad_caller: Caller Android Device Object.
ad_callee: Callee Android Device Object.
ad_hangup: Android Device Object end the phone call.
Optional. Default value is None, and phone call will continue.
video_state: video state for VT call.
Optional. Default value is VT_STATE_BIDIRECTIONAL
verify_caller_func: func_ptr to verify caller in correct mode
Optional. Default is None
verify_callee_func: func_ptr to verify callee in correct mode
Optional. Default is None
wait_time_in_call: wait time during call.
Optional. Default is WAIT_TIME_IN_CALL.
incall_ui_display: after answer the call, bring in-call UI to foreground or
background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
else, do nothing.
Returns:
True if call process without any error.
False if error happened.
"""
return video_call_setup_teardown_for_subscription(
log, ad_caller, ad_callee, get_outgoing_voice_sub_id(ad_caller),
get_incoming_voice_sub_id(ad_callee), ad_hangup, video_state,
verify_caller_func, verify_callee_func, wait_time_in_call,
incall_ui_display)
def video_call_setup_teardown_for_subscription(
log,
ad_caller,
ad_callee,
subid_caller,
subid_callee,
ad_hangup=None,
video_state=VT_STATE_BIDIRECTIONAL,
verify_caller_func=None,
verify_callee_func=None,
wait_time_in_call=WAIT_TIME_IN_CALL,
incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
""" Call process, including make a phone call from caller,
accept from callee, and hang up. The call is on specified subscription
In call process, call from <droid_caller> to <droid_callee>,
accept the call, (optional)then hang up from <droid_hangup>.
Args:
ad_caller: Caller Android Device Object.
ad_callee: Callee Android Device Object.
subid_caller: Caller subscription ID
subid_callee: Callee subscription ID
ad_hangup: Android Device Object end the phone call.
Optional. Default value is None, and phone call will continue.
video_state: video state for VT call.
Optional. Default value is VT_STATE_BIDIRECTIONAL
verify_caller_func: func_ptr to verify caller in correct mode
Optional. Default is None
verify_callee_func: func_ptr to verify callee in correct mode
Optional. Default is None
wait_time_in_call: wait time during call.
Optional. Default is WAIT_TIME_IN_CALL.
incall_ui_display: after answer the call, bring in-call UI to foreground or
background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
else, do nothing.
Returns:
True if call process without any error.
False if error happened.
"""
return call_setup_teardown_for_subscription(
log,
ad_caller,
ad_callee,
subid_caller,
subid_callee,
ad_hangup=ad_hangup,
verify_caller_func=verify_caller_func,
verify_callee_func=verify_callee_func,
wait_time_in_call=wait_time_in_call,
incall_ui_display=incall_ui_display,
video_state=video_state)
def video_call_setup(log,
ad_caller,
ad_callee,
video_state=VT_STATE_BIDIRECTIONAL,
incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
""" Call process, including make a phone call from caller,
accept from callee, and hang up. The call is on default subscription
In call process, call from <droid_caller> to <droid_callee>,
accept the call, (optional)then hang up from <droid_hangup>.
Args:
ad_caller: Caller Android Device Object.
ad_callee: Callee Android Device Object.
incall_ui_display: after answer the call, bring in-call UI to foreground or
background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
else, do nothing.
Returns:
True if call process without any error.
False if error happened.
"""
return video_call_setup_for_subscription(
log, ad_caller, ad_callee, get_outgoing_voice_sub_id(ad_caller),
get_incoming_voice_sub_id(ad_callee), video_state, incall_ui_display)
def video_call_setup_for_subscription(
log,
ad_caller,
ad_callee,
subid_caller,
subid_callee,
video_state=VT_STATE_BIDIRECTIONAL,
incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
""" Call process, including make a phone call from caller,
accept from callee, and hang up. The call is on specified subscription
In call process, call from <droid_caller> to <droid_callee>,
accept the call, (optional)then hang up from <droid_hangup>.
Args:
ad_caller: Caller Android Device Object.
ad_callee: Callee Android Device Object.
subid_caller: Caller subscription ID
subid_callee: Callee subscription ID
ad_hangup: Android Device Object end the phone call.
Optional. Default value is None, and phone call will continue.
incall_ui_display: after answer the call, bring in-call UI to foreground or
background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
else, do nothing.
Returns:
True if call process without any error.
False if error happened.
"""
return call_setup_teardown_for_subscription(
log,
ad_caller,
ad_callee,
subid_caller,
subid_callee,
ad_hangup=None,
incall_ui_display=incall_ui_display,
video_state=video_state)
def video_call_modify_video(log,
ad_requester,
call_id_requester,
ad_responder,
call_id_responder,
video_state_request,
video_quality_request=VT_VIDEO_QUALITY_DEFAULT,
video_state_response=None,
video_quality_response=None,
verify_func_between_request_and_response=None):
"""Modifies an ongoing call to change the video_call state
Args:
log: logger object
ad_requester: android_device object of the requester
call_id_requester: the call_id of the call placing the modify request
ad_requester: android_device object of the responder
call_id_requester: the call_id of the call receiving the modify request
video_state_request: the requested video state
video_quality_request: the requested video quality, defaults to
QUALITY_DEFAULT
video_state_response: the responded video state or, or (default)
match the request if None
video_quality_response: the responded video quality, or (default)
match the request if None
Returns:
A call_id corresponding to the first call in the state, or None
"""
if not video_state_response:
video_state_response = video_state_request
if not video_quality_response:
video_quality_response = video_quality_request
cur_video_state = ad_requester.droid.telecomCallVideoGetState(
call_id_requester)
log.info("State change request from {} to {} requested".format(
cur_video_state, video_state_request))
if cur_video_state == video_state_request:
return True
ad_responder.ed.clear_events(
EventTelecomVideoCallSessionModifyRequestReceived)
ad_responder.droid.telecomCallVideoStartListeningForEvent(
call_id_responder, EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED)
ad_requester.droid.telecomCallVideoSendSessionModifyRequest(
call_id_requester, video_state_request, video_quality_request)
try:
request_event = ad_responder.ed.pop_event(
EventTelecomVideoCallSessionModifyRequestReceived,
MAX_WAIT_TIME_VIDEO_SESSION_EVENT)
log.info(request_event)
except Empty:
log.error("Failed to receive SessionModifyRequest!")
return False
finally:
ad_responder.droid.telecomCallVideoStopListeningForEvent(
call_id_responder, EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED)
if (verify_func_between_request_and_response
and not verify_func_between_request_and_response()):
log.error("verify_func_between_request_and_response failed.")
return False
# TODO: b/26291165 Replace with reducing the volume as we want
# to test route switching
ad_requester.droid.telecomCallSetAudioRoute(AUDIO_ROUTE_EARPIECE)
ad_requester.droid.telecomCallVideoStartListeningForEvent(
call_id_requester, EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED)
ad_responder.droid.telecomCallVideoSendSessionModifyResponse(
call_id_responder, video_state_response, video_quality_response)
try:
response_event = ad_requester.ed.pop_event(
EventTelecomVideoCallSessionModifyResponseReceived,
MAX_WAIT_TIME_VIDEO_SESSION_EVENT)
log.info(response_event)
except Empty:
log.error("Failed to receive SessionModifyResponse!")
return False
finally:
ad_requester.droid.telecomCallVideoStopListeningForEvent(
call_id_requester, EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED)
# TODO: b/26291165 Replace with reducing the volume as we want
# to test route switching
ad_responder.droid.telecomCallSetAudioRoute(AUDIO_ROUTE_EARPIECE)
return True
def is_call_id_in_video_state(log, ad, call_id, video_state):
"""Return is the call_id is in expected video_state
Args:
log: logger object
ad: android_device object
call_id: call id
video_state: valid VIDEO_STATE
Returns:
True is call_id in expected video_state; False if not.
"""
return video_state == ad.droid.telecomCallVideoGetState(call_id)
def get_call_id_in_video_state(log, ad, video_state):
"""Gets the first call reporting a given video_state
from among the active calls
Args:
log: logger object
ad: android_device object
video_state: valid VIDEO_STATE
Returns:
A call_id corresponding to the first call in the state, or None
"""
if not ad.droid.telecomIsInCall():
log.error("{} not in call.".format(ad.serial))
return None
for call in ad.droid.telecomCallGetCallIds():
if is_call_id_in_video_state(log, ad, call, video_state):
return call
return None
def video_call_downgrade(log,
ad_requester,
call_id_requester,
ad_responder,
call_id_responder,
video_state_request=None,
video_quality_request=VT_VIDEO_QUALITY_DEFAULT):
"""Downgrade Video call to video_state_request.
Send telecomCallVideoSendSessionModifyRequest from ad_requester.
Get video call state from ad_requester and ad_responder.
Verify video calls states are correct and downgrade succeed.
Args:
log: logger object
ad_requester: android_device object of the requester
call_id_requester: the call_id of the call placing the modify request
ad_requester: android_device object of the responder
call_id_requester: the call_id of the call receiving the modify request
video_state_request: the requested downgrade video state
This parameter is optional. If this parameter is None:
if call_id_requester current is bi-directional, will downgrade to RX_ENABLED
if call_id_requester current is RX_ENABLED, will downgrade to AUDIO_ONLY
video_quality_request: the requested video quality, defaults to
QUALITY_DEFAULT
Returns:
True if downgrade succeed.
"""
if (call_id_requester is None) or (call_id_responder is None):
log.error("call_id_requester: {}, call_id_responder: {}".format(
call_id_requester, call_id_responder))
return False
current_video_state_requester = ad_requester.droid.telecomCallVideoGetState(
call_id_requester)
if video_state_request is None:
if (current_video_state_requester == VT_STATE_BIDIRECTIONAL or
current_video_state_requester == VT_STATE_BIDIRECTIONAL_PAUSED
):
video_state_request = VT_STATE_RX_ENABLED
elif (current_video_state_requester == VT_STATE_TX_ENABLED
or current_video_state_requester == VT_STATE_TX_PAUSED):
video_state_request = VT_STATE_AUDIO_ONLY
else:
log.error("Can Not Downgrade. ad: {}, current state {}".format(
ad_requester.serial, current_video_state_requester))
return False
expected_video_state_responder = {
VT_STATE_AUDIO_ONLY: VT_STATE_AUDIO_ONLY,
VT_STATE_RX_ENABLED: VT_STATE_TX_ENABLED
}[video_state_request]
ad_requester.droid.telecomCallVideoStartListeningForEvent(
call_id_requester, EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED)
ad_requester.droid.telecomCallVideoSendSessionModifyRequest(
call_id_requester, video_state_request, video_quality_request)
try:
response_event = ad_requester.ed.pop_event(
EventTelecomVideoCallSessionModifyResponseReceived,
MAX_WAIT_TIME_VIDEO_SESSION_EVENT)
log.info(response_event)
except Empty:
log.error("Failed to receive SessionModifyResponse!")
return False
finally:
ad_requester.droid.telecomCallVideoStopListeningForEvent(
call_id_requester, EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED)
time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
# TODO: b/26291165 Replace with reducing the volume as we want
# to test route switching
ad_requester.droid.telecomCallSetAudioRoute(AUDIO_ROUTE_EARPIECE)
ad_responder.droid.telecomCallSetAudioRoute(AUDIO_ROUTE_EARPIECE)
time.sleep(WAIT_TIME_IN_CALL)
if video_state_request != ad_requester.droid.telecomCallVideoGetState(
call_id_requester):
log.error("requester not in correct state. expected:{}, current:{}"
.format(video_state_request,
ad_requester.droid.telecomCallVideoGetState(
call_id_requester)))
return False
if (expected_video_state_responder !=
ad_responder.droid.telecomCallVideoGetState(call_id_responder)):
log.error(
"responder not in correct state. expected:{}, current:{}".format(
expected_video_state_responder,
ad_responder.droid.telecomCallVideoGetState(
call_id_responder)))
return False
return True
def verify_video_call_in_expected_state(log, ad, call_id, call_video_state,
call_state):
"""Return True if video call is in expected video state and call state.
Args:
log: logger object
ad: android_device object
call_id: ad's call id
call_video_state: video state to validate.
call_state: call state to validate.
Returns:
True if video call is in expected video state and call state.
"""
if not is_call_id_in_video_state(log, ad, call_id, call_video_state):
log.error("Call is not in expected {} state. Current state {}".format(
call_video_state, ad.droid.telecomCallVideoGetState(call_id)))
return False
if ad.droid.telecomCallGetCallState(call_id) != call_state:
log.error("Call is not in expected {} state. Current state {}".format(
call_state, ad.droid.telecomCallGetCallState(call_id)))
return False
return True