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