1#!/usr/bin/env python3 2# 3# Copyright 2016 - Google 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import time 18from queue import Empty 19from acts_contrib.test_utils.tel.tel_defines import AUDIO_ROUTE_EARPIECE 20from acts_contrib.test_utils.tel.tel_defines import CALL_STATE_RINGING 21from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND 22from acts_contrib.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_FOREGROUND 23from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT 24from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALL_INITIATION 25from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_CALLEE_RINGING 26from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION 27from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_TELECOM_RINGING 28from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VIDEO_SESSION_EVENT 29from acts_contrib.test_utils.tel.tel_defines import MAX_WAIT_TIME_VOLTE_ENABLED 30from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA 31from acts_contrib.test_utils.tel.tel_defines import NETWORK_SERVICE_VOICE 32from acts_contrib.test_utils.tel.tel_defines import GEN_4G 33from acts_contrib.test_utils.tel.tel_defines import RAT_1XRTT 34from acts_contrib.test_utils.tel.tel_defines import RAT_IWLAN 35from acts_contrib.test_utils.tel.tel_defines import RAT_LTE 36from acts_contrib.test_utils.tel.tel_defines import RAT_UMTS 37from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_OFFHOOK 38from acts_contrib.test_utils.tel.tel_defines import TELEPHONY_STATE_RINGING 39from acts_contrib.test_utils.tel.tel_defines import VT_STATE_AUDIO_ONLY 40from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL 41from acts_contrib.test_utils.tel.tel_defines import VT_STATE_BIDIRECTIONAL_PAUSED 42from acts_contrib.test_utils.tel.tel_defines import VT_STATE_RX_ENABLED 43from acts_contrib.test_utils.tel.tel_defines import VT_STATE_RX_PAUSED 44from acts_contrib.test_utils.tel.tel_defines import VT_STATE_TX_ENABLED 45from acts_contrib.test_utils.tel.tel_defines import VT_STATE_TX_PAUSED 46from acts_contrib.test_utils.tel.tel_defines import VT_STATE_STATE_INVALID 47from acts_contrib.test_utils.tel.tel_defines import VT_VIDEO_QUALITY_DEFAULT 48from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ACCEPT_VIDEO_CALL_TO_CHECK_STATE 49from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING 50from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL 51from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED 52from acts_contrib.test_utils.tel.tel_defines import EventCallStateChanged 53from acts_contrib.test_utils.tel.tel_defines import EventTelecomVideoCallSessionModifyRequestReceived 54from acts_contrib.test_utils.tel.tel_defines import EventTelecomVideoCallSessionModifyResponseReceived 55from acts_contrib.test_utils.tel.tel_defines import EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED 56from acts_contrib.test_utils.tel.tel_defines import EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED 57from acts_contrib.test_utils.tel.tel_defines import CallStateContainer 58from acts_contrib.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id 59from acts_contrib.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id 60from acts_contrib.test_utils.tel.tel_test_utils import call_setup_teardown_for_subscription 61from acts_contrib.test_utils.tel.tel_test_utils import ensure_network_generation 62from acts_contrib.test_utils.tel.tel_test_utils import is_event_match 63from acts_contrib.test_utils.tel.tel_test_utils import hangup_call 64from acts_contrib.test_utils.tel.tel_test_utils import initiate_call 65from acts_contrib.test_utils.tel.tel_test_utils import set_wfc_mode_for_subscription 66from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode 67from acts_contrib.test_utils.tel.tel_test_utils import toggle_volte 68from acts_contrib.test_utils.tel.tel_test_utils import verify_incall_state 69from acts_contrib.test_utils.tel.tel_test_utils import wait_and_answer_call_for_subscription 70from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_generation 71from acts_contrib.test_utils.tel.tel_test_utils import wait_for_network_rat_for_subscription 72from acts_contrib.test_utils.tel.tel_test_utils import wait_for_ringing_call 73from acts_contrib.test_utils.tel.tel_test_utils import wait_for_telecom_ringing 74from acts_contrib.test_utils.tel.tel_test_utils import wait_for_video_enabled 75from acts_contrib.test_utils.tel.tel_test_utils import get_network_rat 76from acts_contrib.test_utils.tel.tel_test_utils import is_wfc_enabled 77from acts_contrib.test_utils.tel.tel_voice_utils import is_call_hd 78from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_iwlan_for_subscription 79 80 81def phone_setup_video( 82 log, 83 ad, 84 wfc_mode=WFC_MODE_DISABLED, 85 is_airplane_mode=False, 86 wifi_ssid=None, 87 wifi_pwd=None): 88 """Setup phone default sub_id to make video call 89 90 Args: 91 log: log object. 92 ad: android device object 93 wfc_mode: WFC mode to set to. 94 Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED, 95 WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED. 96 97 Returns: 98 True if ad (default sub_id) is setup correctly and idle for video call. 99 """ 100 return phone_setup_video_for_subscription(log, ad, 101 get_outgoing_voice_sub_id(ad), 102 wfc_mode, 103 False, 104 wifi_ssid, 105 wifi_pwd) 106 107 108def phone_setup_video_for_subscription(log, 109 ad, 110 sub_id, 111 wfc_mode=WFC_MODE_DISABLED, 112 is_airplane_mode=False, 113 wifi_ssid=None, 114 wifi_pwd=None): 115 """Setup phone sub_id to make video call 116 117 Args: 118 log: log object. 119 ad: android device object 120 sub_id: ad's sub id. 121 wfc_mode: WFC mode to set to. Valid mode includes: 122 - WFC_MODE_WIFI_ONLY 123 - Wi-Fi will be connected if wifi_ssid is assigned. 124 - WFC_MODE_CELLULAR_PREFERRED 125 - Wi-Fi will be connected if wifi_ssid is assigned. 126 - WFC_MODE_WIFI_PREFERRED 127 - Wi-Fi will be connected if wifi_ssid is assigned. 128 - WFC_MODE_DISABLED 129 - Only WFC mode will be set to DISABLED. 130 - None 131 - Neither WFC mode nor Wi-Fi state will be changed. 132 is_airplane_mode: 133 - False: airplane mode disabled 134 - True: airplane mode enabled for ViWifi 135 wifi_ssid: SSID of Wi-Fi AP to connect for ViWifi 136 wifi_ssid: Password of Wi-Fi AP SSID for ViWifi 137 138 Returns: 139 True if ad (sub_id) is setup correctly and idle for video call. 140 """ 141 if not ensure_network_generation( 142 log, ad, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA): 143 log.error("{} voice not in LTE mode.".format(ad.serial)) 144 return False 145 146 toggle_volte(log, ad, True) 147 148 if wfc_mode == WFC_MODE_DISABLED: 149 if not set_wfc_mode_for_subscription(ad, wfc_mode, sub_id): 150 log.error("{} WFC mode failed to be set to {}.".format( 151 ad.serial, wfc_mode)) 152 return False 153 else: 154 if wfc_mode: 155 if not phone_setup_iwlan_for_subscription(log, ad, sub_id, 156 is_airplane_mode, wfc_mode, wifi_ssid, wifi_pwd): 157 log.error("Failed to set up phone on iwlan.") 158 return False 159 160 return phone_idle_video_for_subscription(log, ad, sub_id) 161 162 163def phone_idle_video(log, ad): 164 """Return if phone (default sub_id) is idle for video call. 165 166 Args: 167 log: log object. 168 ad: android device object 169 170 Returns: 171 True if ad is idle for video call. 172 """ 173 return phone_idle_video_for_subscription(log, ad, 174 get_outgoing_voice_sub_id(ad)) 175 176 177def phone_idle_video_for_subscription(log, ad, sub_id): 178 """Return if phone (sub_id) is idle for video call. 179 180 Args: 181 log: log object. 182 ad: android device object 183 sub_id: ad's sub id 184 185 Returns: 186 True if ad (sub_id) is idle for video call. 187 """ 188 189 if not wait_for_network_generation(log, ad, GEN_4G): 190 log.error("{} voice not in LTE mode.".format(ad.serial)) 191 return False 192 193 if not wait_for_video_enabled(log, ad, MAX_WAIT_TIME_VOLTE_ENABLED): 194 log.error( 195 "{} failed to <report video calling enabled> within {}s.".format( 196 ad.serial, MAX_WAIT_TIME_VOLTE_ENABLED)) 197 return False 198 return True 199 200 201def is_phone_in_call_video(log, ad): 202 """Return if ad is in a video call (in expected video state). 203 204 Args: 205 log: log object. 206 ad: android device object 207 video_state: Expected Video call state. 208 This is optional, if it's None, 209 then TX_ENABLED/RX_ENABLED/BIDIRECTIONAL video call state will 210 return True. 211 212 Returns: 213 True if ad (for sub_id) is in a video call (in expected video state). 214 """ 215 return is_phone_in_call_video_for_subscription( 216 log, ad, get_outgoing_voice_sub_id(ad)) 217 218 219def is_phone_in_call_video_for_subscription(log, ad, sub_id, video_state=None): 220 """Return if ad (for sub_id) is in a video call (in expected video state). 221 Args: 222 log: log object. 223 ad: android device object 224 sub_id: device sub_id 225 video_state: Expected Video call state. 226 This is optional, if it's None, 227 then TX_ENABLED/RX_ENABLED/BIDIRECTIONAL video call state will 228 return True. 229 230 Returns: 231 True if ad is in a video call (in expected video state). 232 """ 233 234 if video_state is None: 235 log.info("Verify if {}(subid {}) in video call.".format( 236 ad.serial, sub_id)) 237 if not ad.droid.telecomIsInCall(): 238 log.error("{} not in call.".format(ad.serial)) 239 return False 240 call_list = ad.droid.telecomCallGetCallIds() 241 for call in call_list: 242 state = ad.droid.telecomCallVideoGetState(call) 243 if video_state is None: 244 if { 245 VT_STATE_AUDIO_ONLY: False, 246 VT_STATE_TX_ENABLED: True, 247 VT_STATE_TX_PAUSED: True, 248 VT_STATE_RX_ENABLED: True, 249 VT_STATE_RX_PAUSED: True, 250 VT_STATE_BIDIRECTIONAL: True, 251 VT_STATE_BIDIRECTIONAL_PAUSED: True, 252 VT_STATE_STATE_INVALID: False 253 }[state]: 254 return True 255 else: 256 if state == video_state: 257 return True 258 log.info("Non-Video-State: {}".format(state)) 259 log.error("Phone not in video call. Call list: {}".format(call_list)) 260 return False 261 262 263def is_phone_in_call_viwifi_for_subscription(log, ad, sub_id, 264 video_state=None): 265 """Return if ad (for sub_id) is in a viwifi call (in expected video state). 266 Args: 267 log: log object. 268 ad: android device object 269 sub_id: device sub_id 270 video_state: Expected Video call state. 271 This is optional, if it's None, 272 then TX_ENABLED/RX_ENABLED/BIDIRECTIONAL video call state will 273 return True. 274 275 Returns: 276 True if ad is in a video call (in expected video state). 277 """ 278 279 if video_state is None: 280 log.info("Verify if {}(subid {}) in video call.".format( 281 ad.serial, sub_id)) 282 if not ad.droid.telecomIsInCall(): 283 log.error("{} not in call.".format(ad.serial)) 284 return False 285 nw_type = get_network_rat(log, ad, NETWORK_SERVICE_DATA) 286 if nw_type != RAT_IWLAN: 287 ad.log.error("Data rat on: %s. Expected: iwlan", nw_type) 288 return False 289 if not is_wfc_enabled(log, ad): 290 ad.log.error("WiFi Calling feature bit is False.") 291 return False 292 call_list = ad.droid.telecomCallGetCallIds() 293 for call in call_list: 294 state = ad.droid.telecomCallVideoGetState(call) 295 if video_state is None: 296 if { 297 VT_STATE_AUDIO_ONLY: False, 298 VT_STATE_TX_ENABLED: True, 299 VT_STATE_TX_PAUSED: True, 300 VT_STATE_RX_ENABLED: True, 301 VT_STATE_RX_PAUSED: True, 302 VT_STATE_BIDIRECTIONAL: True, 303 VT_STATE_BIDIRECTIONAL_PAUSED: True, 304 VT_STATE_STATE_INVALID: False 305 }[state]: 306 return True 307 else: 308 if state == video_state: 309 return True 310 ad.log.info("Non-Video-State: %s", state) 311 ad.log.error("Phone not in video call. Call list: %s", call_list) 312 return False 313 314 315def is_phone_in_call_video_bidirectional(log, ad): 316 """Return if phone in bi-directional video call. 317 318 Args: 319 log: log object. 320 ad: android device object 321 322 Returns: 323 True if phone in bi-directional video call. 324 """ 325 return is_phone_in_call_video_bidirectional_for_subscription( 326 log, ad, get_outgoing_voice_sub_id(ad)) 327 328 329def is_phone_in_call_video_bidirectional_for_subscription(log, ad, sub_id): 330 """Return if phone in bi-directional video call for subscription id. 331 332 Args: 333 log: log object. 334 ad: android device object 335 sub_id: subscription id. 336 337 Returns: 338 True if phone in bi-directional video call. 339 """ 340 log.info("Verify if {}(subid {}) in bi-directional video call.".format( 341 ad.serial, sub_id)) 342 return is_phone_in_call_video_for_subscription(log, ad, sub_id, 343 VT_STATE_BIDIRECTIONAL) 344 345 346def is_phone_in_call_viwifi_bidirectional(log, ad): 347 """Return if phone in bi-directional viwifi call. 348 349 Args: 350 log: log object. 351 ad: android device object 352 353 Returns: 354 True if phone in bi-directional viwifi call. 355 """ 356 return is_phone_in_call_viwifi_bidirectional_for_subscription( 357 log, ad, get_outgoing_voice_sub_id(ad)) 358 359 360def is_phone_in_call_viwifi_bidirectional_for_subscription(log, ad, sub_id): 361 """Return if phone in bi-directional viwifi call for subscription id. 362 363 Args: 364 log: log object. 365 ad: android device object 366 sub_id: subscription id. 367 368 Returns: 369 True if phone in bi-directional viwifi call. 370 """ 371 ad.log.info("Verify if subid %s in bi-directional video call.", sub_id) 372 return is_phone_in_call_viwifi_for_subscription(log, ad, sub_id, 373 VT_STATE_BIDIRECTIONAL) 374 375 376def is_phone_in_call_video_tx_enabled(log, ad): 377 """Return if phone in tx_enabled video call. 378 379 Args: 380 log: log object. 381 ad: android device object 382 383 Returns: 384 True if phone in tx_enabled video call. 385 """ 386 return is_phone_in_call_video_tx_enabled_for_subscription( 387 log, ad, get_outgoing_voice_sub_id(ad)) 388 389 390def is_phone_in_call_video_tx_enabled_for_subscription(log, ad, sub_id): 391 """Return if phone in tx_enabled video call for subscription id. 392 393 Args: 394 log: log object. 395 ad: android device object 396 sub_id: subscription id. 397 398 Returns: 399 True if phone in tx_enabled video call. 400 """ 401 log.info("Verify if {}(subid {}) in tx_enabled video call.".format( 402 ad.serial, sub_id)) 403 return is_phone_in_call_video_for_subscription(log, ad, sub_id, 404 VT_STATE_TX_ENABLED) 405 406 407def is_phone_in_call_video_rx_enabled(log, ad): 408 """Return if phone in rx_enabled video call. 409 410 Args: 411 log: log object. 412 ad: android device object 413 414 Returns: 415 True if phone in rx_enabled video call. 416 """ 417 return is_phone_in_call_video_rx_enabled_for_subscription( 418 log, ad, get_outgoing_voice_sub_id(ad)) 419 420 421def is_phone_in_call_video_rx_enabled_for_subscription(log, ad, sub_id): 422 """Return if phone in rx_enabled video call for subscription id. 423 424 Args: 425 log: log object. 426 ad: android device object 427 sub_id: subscription id. 428 429 Returns: 430 True if phone in rx_enabled video call. 431 """ 432 log.info("Verify if {}(subid {}) in rx_enabled video call.".format( 433 ad.serial, sub_id)) 434 return is_phone_in_call_video_for_subscription(log, ad, sub_id, 435 VT_STATE_RX_ENABLED) 436 437 438def is_phone_in_call_voice_hd(log, ad): 439 """Return if phone in hd voice call. 440 441 Args: 442 log: log object. 443 ad: android device object 444 445 Returns: 446 True if phone in hd voice call. 447 """ 448 return is_phone_in_call_voice_hd_for_subscription( 449 log, ad, get_outgoing_voice_sub_id(ad)) 450 451 452def is_phone_in_call_voice_hd_for_subscription(log, ad, sub_id): 453 """Return if phone in hd voice call for subscription id. 454 455 Args: 456 log: log object. 457 ad: android device object 458 sub_id: subscription id. 459 460 Returns: 461 True if phone in hd voice call. 462 """ 463 log.info("Verify if {}(subid {}) in hd voice call.".format( 464 ad.serial, sub_id)) 465 if not ad.droid.telecomIsInCall(): 466 log.error("{} not in call.".format(ad.serial)) 467 return False 468 for call in ad.droid.telecomCallGetCallIds(): 469 state = ad.droid.telecomCallVideoGetState(call) 470 if (state == VT_STATE_AUDIO_ONLY and is_call_hd(log, ad, call)): 471 return True 472 log.info("Non-HDAudio-State: {}, property: {}".format( 473 state, ad.droid.telecomCallGetProperties(call))) 474 return False 475 476 477def initiate_video_call(log, ad_caller, callee_number): 478 """Make phone call from caller to callee. 479 480 Args: 481 log: logging handle 482 ad_caller: Caller android device object. 483 callee_number: Callee phone number. 484 485 Returns: 486 result: if phone call is placed successfully. 487 """ 488 return initiate_call(log, ad_caller, callee_number, video=True) 489 490 491def wait_and_answer_video_call(log, 492 ad, 493 incoming_number=None, 494 video_state=VT_STATE_BIDIRECTIONAL, 495 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 496 """Wait for an incoming call on default voice subscription and 497 accepts the call. 498 499 Args: 500 ad: android device object. 501 incoming_number: Expected incoming number. 502 Optional. Default is None 503 incall_ui_display: after answer the call, bring in-call UI to foreground or 504 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 505 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 506 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 507 else, do nothing. 508 509 Returns: 510 True: if incoming call is received and answered successfully. 511 False: for errors 512 """ 513 return wait_and_answer_video_call_for_subscription( 514 log, ad, get_outgoing_voice_sub_id(ad), incoming_number, video_state, 515 incall_ui_display) 516 517 518def wait_and_answer_video_call_for_subscription( 519 log, 520 ad, 521 sub_id, 522 incoming_number=None, 523 video_state=VT_STATE_BIDIRECTIONAL, 524 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 525 """Wait for an incoming call on specified subscription and 526 accepts the call. 527 528 Args: 529 ad: android device object. 530 sub_id: subscription ID 531 incoming_number: Expected incoming number. 532 Optional. Default is None 533 incall_ui_display: after answer the call, bring in-call UI to foreground or 534 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 535 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 536 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 537 else, do nothing. 538 539 Returns: 540 True: if incoming call is received and answered successfully. 541 False: for errors 542 """ 543 return wait_and_answer_call_for_subscription( 544 log, 545 ad, 546 sub_id, 547 incoming_number=None, 548 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND, 549 video_state=video_state) 550 551 552def video_call_setup_teardown(log, 553 ad_caller, 554 ad_callee, 555 ad_hangup=None, 556 video_state=VT_STATE_BIDIRECTIONAL, 557 verify_caller_func=None, 558 verify_callee_func=None, 559 wait_time_in_call=WAIT_TIME_IN_CALL, 560 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 561 """ Call process, including make a phone call from caller, 562 accept from callee, and hang up. The call is on default subscription 563 564 In call process, call from <droid_caller> to <droid_callee>, 565 accept the call, (optional)then hang up from <droid_hangup>. 566 567 Args: 568 ad_caller: Caller Android Device Object. 569 ad_callee: Callee Android Device Object. 570 ad_hangup: Android Device Object end the phone call. 571 Optional. Default value is None, and phone call will continue. 572 video_state: video state for VT call. 573 Optional. Default value is VT_STATE_BIDIRECTIONAL 574 verify_caller_func: func_ptr to verify caller in correct mode 575 Optional. Default is None 576 verify_callee_func: func_ptr to verify callee in correct mode 577 Optional. Default is None 578 wait_time_in_call: wait time during call. 579 Optional. Default is WAIT_TIME_IN_CALL. 580 incall_ui_display: after answer the call, bring in-call UI to foreground or 581 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 582 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 583 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 584 else, do nothing. 585 586 Returns: 587 True if call process without any error. 588 False if error happened. 589 590 """ 591 return video_call_setup_teardown_for_subscription( 592 log, ad_caller, ad_callee, get_outgoing_voice_sub_id(ad_caller), 593 get_incoming_voice_sub_id(ad_callee), ad_hangup, video_state, 594 verify_caller_func, verify_callee_func, wait_time_in_call, 595 incall_ui_display) 596 597 598def video_call_setup_teardown_for_subscription( 599 log, 600 ad_caller, 601 ad_callee, 602 subid_caller, 603 subid_callee, 604 ad_hangup=None, 605 video_state=VT_STATE_BIDIRECTIONAL, 606 verify_caller_func=None, 607 verify_callee_func=None, 608 wait_time_in_call=WAIT_TIME_IN_CALL, 609 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 610 """ Call process, including make a phone call from caller, 611 accept from callee, and hang up. The call is on specified subscription 612 613 In call process, call from <droid_caller> to <droid_callee>, 614 accept the call, (optional)then hang up from <droid_hangup>. 615 616 Args: 617 ad_caller: Caller Android Device Object. 618 ad_callee: Callee Android Device Object. 619 subid_caller: Caller subscription ID 620 subid_callee: Callee subscription ID 621 ad_hangup: Android Device Object end the phone call. 622 Optional. Default value is None, and phone call will continue. 623 video_state: video state for VT call. 624 Optional. Default value is VT_STATE_BIDIRECTIONAL 625 verify_caller_func: func_ptr to verify caller in correct mode 626 Optional. Default is None 627 verify_callee_func: func_ptr to verify callee in correct mode 628 Optional. Default is None 629 wait_time_in_call: wait time during call. 630 Optional. Default is WAIT_TIME_IN_CALL. 631 incall_ui_display: after answer the call, bring in-call UI to foreground or 632 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 633 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 634 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 635 else, do nothing. 636 637 Returns: 638 True if call process without any error. 639 False if error happened. 640 641 """ 642 return call_setup_teardown_for_subscription( 643 log, 644 ad_caller, 645 ad_callee, 646 subid_caller, 647 subid_callee, 648 ad_hangup=ad_hangup, 649 verify_caller_func=verify_caller_func, 650 verify_callee_func=verify_callee_func, 651 wait_time_in_call=wait_time_in_call, 652 incall_ui_display=incall_ui_display, 653 video_state=video_state) 654 655 656def video_call_setup(log, 657 ad_caller, 658 ad_callee, 659 video_state=VT_STATE_BIDIRECTIONAL, 660 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 661 """ Call process, including make a phone call from caller, 662 accept from callee, and hang up. The call is on default subscription 663 664 In call process, call from <droid_caller> to <droid_callee>, 665 accept the call, (optional)then hang up from <droid_hangup>. 666 667 Args: 668 ad_caller: Caller Android Device Object. 669 ad_callee: Callee Android Device Object. 670 incall_ui_display: after answer the call, bring in-call UI to foreground or 671 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 672 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 673 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 674 else, do nothing. 675 676 Returns: 677 True if call process without any error. 678 False if error happened. 679 680 """ 681 return video_call_setup_for_subscription( 682 log, ad_caller, ad_callee, get_outgoing_voice_sub_id(ad_caller), 683 get_incoming_voice_sub_id(ad_callee), video_state, incall_ui_display) 684 685 686def video_call_setup_for_subscription( 687 log, 688 ad_caller, 689 ad_callee, 690 subid_caller, 691 subid_callee, 692 video_state=VT_STATE_BIDIRECTIONAL, 693 incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND): 694 """ Call process, including make a phone call from caller, 695 accept from callee, and hang up. The call is on specified subscription 696 697 In call process, call from <droid_caller> to <droid_callee>, 698 accept the call, (optional)then hang up from <droid_hangup>. 699 700 Args: 701 ad_caller: Caller Android Device Object. 702 ad_callee: Callee Android Device Object. 703 subid_caller: Caller subscription ID 704 subid_callee: Callee subscription ID 705 ad_hangup: Android Device Object end the phone call. 706 Optional. Default value is None, and phone call will continue. 707 incall_ui_display: after answer the call, bring in-call UI to foreground or 708 background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND. 709 if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground. 710 if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background. 711 else, do nothing. 712 713 Returns: 714 True if call process without any error. 715 False if error happened. 716 717 """ 718 return call_setup_teardown_for_subscription( 719 log, 720 ad_caller, 721 ad_callee, 722 subid_caller, 723 subid_callee, 724 ad_hangup=None, 725 incall_ui_display=incall_ui_display, 726 video_state=video_state) 727 728 729def video_call_modify_video(log, 730 ad_requester, 731 call_id_requester, 732 ad_responder, 733 call_id_responder, 734 video_state_request, 735 video_quality_request=VT_VIDEO_QUALITY_DEFAULT, 736 video_state_response=None, 737 video_quality_response=None, 738 verify_func_between_request_and_response=None): 739 """Modifies an ongoing call to change the video_call state 740 741 Args: 742 log: logger object 743 ad_requester: android_device object of the requester 744 call_id_requester: the call_id of the call placing the modify request 745 ad_requester: android_device object of the responder 746 call_id_requester: the call_id of the call receiving the modify request 747 video_state_request: the requested video state 748 video_quality_request: the requested video quality, defaults to 749 QUALITY_DEFAULT 750 video_state_response: the responded video state or, or (default) 751 match the request if None 752 video_quality_response: the responded video quality, or (default) 753 match the request if None 754 755 Returns: 756 A call_id corresponding to the first call in the state, or None 757 """ 758 759 if not video_state_response: 760 video_state_response = video_state_request 761 if not video_quality_response: 762 video_quality_response = video_quality_request 763 764 cur_video_state = ad_requester.droid.telecomCallVideoGetState( 765 call_id_requester) 766 767 log.info("State change request from {} to {} requested".format( 768 cur_video_state, video_state_request)) 769 770 if cur_video_state == video_state_request: 771 return True 772 773 ad_responder.ed.clear_events( 774 EventTelecomVideoCallSessionModifyRequestReceived) 775 776 ad_responder.droid.telecomCallVideoStartListeningForEvent( 777 call_id_responder, EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED) 778 779 ad_requester.droid.telecomCallVideoSendSessionModifyRequest( 780 call_id_requester, video_state_request, video_quality_request) 781 782 try: 783 request_event = ad_responder.ed.pop_event( 784 EventTelecomVideoCallSessionModifyRequestReceived, 785 MAX_WAIT_TIME_VIDEO_SESSION_EVENT) 786 log.info(request_event) 787 except Empty: 788 log.error("Failed to receive SessionModifyRequest!") 789 return False 790 finally: 791 ad_responder.droid.telecomCallVideoStopListeningForEvent( 792 call_id_responder, EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED) 793 794 if (verify_func_between_request_and_response 795 and not verify_func_between_request_and_response()): 796 log.error("verify_func_between_request_and_response failed.") 797 return False 798 799 # TODO: b/26291165 Replace with reducing the volume as we want 800 # to test route switching 801 ad_requester.droid.telecomCallSetAudioRoute(AUDIO_ROUTE_EARPIECE) 802 803 ad_requester.droid.telecomCallVideoStartListeningForEvent( 804 call_id_requester, EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED) 805 806 ad_responder.droid.telecomCallVideoSendSessionModifyResponse( 807 call_id_responder, video_state_response, video_quality_response) 808 809 try: 810 response_event = ad_requester.ed.pop_event( 811 EventTelecomVideoCallSessionModifyResponseReceived, 812 MAX_WAIT_TIME_VIDEO_SESSION_EVENT) 813 log.info(response_event) 814 except Empty: 815 log.error("Failed to receive SessionModifyResponse!") 816 return False 817 finally: 818 ad_requester.droid.telecomCallVideoStopListeningForEvent( 819 call_id_requester, EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED) 820 821 # TODO: b/26291165 Replace with reducing the volume as we want 822 # to test route switching 823 ad_responder.droid.telecomCallSetAudioRoute(AUDIO_ROUTE_EARPIECE) 824 825 return True 826 827 828def is_call_id_in_video_state(log, ad, call_id, video_state): 829 """Return is the call_id is in expected video_state 830 831 Args: 832 log: logger object 833 ad: android_device object 834 call_id: call id 835 video_state: valid VIDEO_STATE 836 837 Returns: 838 True is call_id in expected video_state; False if not. 839 """ 840 return video_state == ad.droid.telecomCallVideoGetState(call_id) 841 842 843def get_call_id_in_video_state(log, ad, video_state): 844 """Gets the first call reporting a given video_state 845 from among the active calls 846 847 Args: 848 log: logger object 849 ad: android_device object 850 video_state: valid VIDEO_STATE 851 852 Returns: 853 A call_id corresponding to the first call in the state, or None 854 """ 855 856 if not ad.droid.telecomIsInCall(): 857 log.error("{} not in call.".format(ad.serial)) 858 return None 859 for call in ad.droid.telecomCallGetCallIds(): 860 if is_call_id_in_video_state(log, ad, call, video_state): 861 return call 862 return None 863 864 865def video_call_downgrade(log, 866 ad_requester, 867 call_id_requester, 868 ad_responder, 869 call_id_responder, 870 video_state_request=None, 871 video_quality_request=VT_VIDEO_QUALITY_DEFAULT): 872 """Downgrade Video call to video_state_request. 873 Send telecomCallVideoSendSessionModifyRequest from ad_requester. 874 Get video call state from ad_requester and ad_responder. 875 Verify video calls states are correct and downgrade succeed. 876 877 Args: 878 log: logger object 879 ad_requester: android_device object of the requester 880 call_id_requester: the call_id of the call placing the modify request 881 ad_requester: android_device object of the responder 882 call_id_requester: the call_id of the call receiving the modify request 883 video_state_request: the requested downgrade video state 884 This parameter is optional. If this parameter is None: 885 if call_id_requester current is bi-directional, will downgrade to RX_ENABLED 886 if call_id_requester current is RX_ENABLED, will downgrade to AUDIO_ONLY 887 video_quality_request: the requested video quality, defaults to 888 QUALITY_DEFAULT 889 Returns: 890 True if downgrade succeed. 891 """ 892 if (call_id_requester is None) or (call_id_responder is None): 893 log.error("call_id_requester: {}, call_id_responder: {}".format( 894 call_id_requester, call_id_responder)) 895 return False 896 current_video_state_requester = ad_requester.droid.telecomCallVideoGetState( 897 call_id_requester) 898 if video_state_request is None: 899 if (current_video_state_requester == VT_STATE_BIDIRECTIONAL or 900 current_video_state_requester == VT_STATE_BIDIRECTIONAL_PAUSED 901 ): 902 video_state_request = VT_STATE_RX_ENABLED 903 elif (current_video_state_requester == VT_STATE_TX_ENABLED 904 or current_video_state_requester == VT_STATE_TX_PAUSED): 905 video_state_request = VT_STATE_AUDIO_ONLY 906 else: 907 log.error("Can Not Downgrade. ad: {}, current state {}".format( 908 ad_requester.serial, current_video_state_requester)) 909 return False 910 expected_video_state_responder = { 911 VT_STATE_AUDIO_ONLY: VT_STATE_AUDIO_ONLY, 912 VT_STATE_RX_ENABLED: VT_STATE_TX_ENABLED 913 }[video_state_request] 914 915 ad_requester.droid.telecomCallVideoStartListeningForEvent( 916 call_id_requester, EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED) 917 918 ad_requester.droid.telecomCallVideoSendSessionModifyRequest( 919 call_id_requester, video_state_request, video_quality_request) 920 921 try: 922 response_event = ad_requester.ed.pop_event( 923 EventTelecomVideoCallSessionModifyResponseReceived, 924 MAX_WAIT_TIME_VIDEO_SESSION_EVENT) 925 log.info(response_event) 926 except Empty: 927 log.error("Failed to receive SessionModifyResponse!") 928 return False 929 finally: 930 ad_requester.droid.telecomCallVideoStopListeningForEvent( 931 call_id_requester, EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED) 932 933 time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) 934 # TODO: b/26291165 Replace with reducing the volume as we want 935 # to test route switching 936 ad_requester.droid.telecomCallSetAudioRoute(AUDIO_ROUTE_EARPIECE) 937 ad_responder.droid.telecomCallSetAudioRoute(AUDIO_ROUTE_EARPIECE) 938 939 time.sleep(WAIT_TIME_IN_CALL) 940 if video_state_request != ad_requester.droid.telecomCallVideoGetState( 941 call_id_requester): 942 log.error("requester not in correct state. expected:{}, current:{}" 943 .format(video_state_request, 944 ad_requester.droid.telecomCallVideoGetState( 945 call_id_requester))) 946 return False 947 if (expected_video_state_responder != 948 ad_responder.droid.telecomCallVideoGetState(call_id_responder)): 949 log.error( 950 "responder not in correct state. expected:{}, current:{}".format( 951 expected_video_state_responder, 952 ad_responder.droid.telecomCallVideoGetState( 953 call_id_responder))) 954 return False 955 956 return True 957 958 959def verify_video_call_in_expected_state(log, ad, call_id, call_video_state, 960 call_state): 961 """Return True if video call is in expected video state and call state. 962 963 Args: 964 log: logger object 965 ad: android_device object 966 call_id: ad's call id 967 call_video_state: video state to validate. 968 call_state: call state to validate. 969 970 Returns: 971 True if video call is in expected video state and call state. 972 """ 973 if not is_call_id_in_video_state(log, ad, call_id, call_video_state): 974 log.error("Call is not in expected {} state. Current state {}".format( 975 call_video_state, ad.droid.telecomCallVideoGetState(call_id))) 976 return False 977 if ad.droid.telecomCallGetCallState(call_id) != call_state: 978 log.error("Call is not in expected {} state. Current state {}".format( 979 call_state, ad.droid.telecomCallGetCallState(call_id))) 980 return False 981 return True 982