def initiate_call_when_a2dp_streaming_on(self): """Initiates HFP call when a2dp is streaming, then check for call is present or not. Disconnect a2dp profile and then connect HFP profile and answer the call from reference device. Returns: True if successful, False otherwise. """ if not self.play_music_and_connect_wifi(): return False if not initiate_call(self.log, self.pri_ad, self.re_phone_number): self.log.error("Failed to initiate call") return False if wait_for_dialing(self.log, self.pri_ad): self.pri_ad.droid.bluetoothDisconnectConnectedProfile( self.audio_receiver.mac_address, [BtEnum.BluetoothProfile.A2DP.value]) if not connect_dev_to_headset( self.pri_ad, self.audio_receiver.mac_address, [BtEnum.BluetoothProfile.HEADSET.value]): return False if not wait_and_answer_call(self.log, self.sec_ad): self.log.error("Failed to answer call in second device") return False time.sleep(self.iperf["duration"]) if not hangup_call(self.log, self.pri_ad): self.log.error("Failed to hangup call") return False return True
def setup_multi_call(self, caller0, caller1, callee): outgoing_num = get_phone_number(self.log, callee) if not initiate_call(self.log, caller0, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, callee): self.log.error("Failed to answer call.") return False time.sleep(self.short_timeout) if not initiate_call(self.log, caller1, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, callee): self.log.error("Failed to answer call.") return False return True
def test_call_transfer_disconnect_connect(self): """ Tests that after we connect when an active call is in progress, we show the call. Precondition: 1. AG & HF are disconnected but paired. Steps: 1. Make a call from AG role (since disconnected) 2. Accept from RE role and transition the call to Active 3. Connect AG & HF 4. HF should transition into Active call state. Returns: Pass if True Fail if False Priority: 1 """ # make a call on AG if not initiate_call(self.log, self.ag, self.re_phone_number): self.ag.log.error("Failed to initiate call from ag.") return False if not wait_and_answer_call(self.log, self.re): self.re.log.error("Failed to accept call on re.") return False # Wait for AG, RE to go into an Active state. if not car_telecom_utils.wait_for_active(self.log, self.ag): self.ag.log.error("AG not in Active state.") return False if not car_telecom_utils.wait_for_active(self.log, self.re): self.re.log.error("RE not in Active state.") return False # Now connect the devices. if not bt_test_utils.connect_pri_to_sec( self.hf, self.ag, set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])): self.log.error("Could not connect HF and AG {} {}".format( self.hf.serial, self.ag.serial)) return False # Check that HF is in active state if not car_telecom_utils.wait_for_active(self.log, self.hf): self.hf.log.error("HF not in Active state.") return False # Hangup the call and check all devices are clean self.hf.droid.telecomEndCall() ret = True ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.hf) ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.ag) ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.re) return ret
def initiate_disconnect_call_dut(pri_ad, sec_ad, duration, callee_number): """Initiates call and disconnect call on primary device. Steps: 1. Initiate call from DUT. 2. Wait for dialing state at DUT and wait for ringing at secondary device. 3. Accepts call from secondary device. 4. Wait for call active state at primary and secondary device. 5. Sleeps until given duration. 6. Disconnect call from primary device. 7. Wait for call is not present state. Args: pri_ad: An android device to disconnect call. sec_ad: An android device accepting call. duration: Duration of call in seconds. callee_number: Secondary device's phone number. Returns: True if successful, False otherwise. """ if not initiate_call(logging, pri_ad, callee_number): pri_ad.log.error("Failed to initiate call") return False time.sleep(2) flag = True flag &= wait_for_dialing(logging, pri_ad) flag &= wait_for_ringing(logging, sec_ad) if not flag: pri_ad.log.error("Outgoing call did not get established") return False if not wait_and_answer_call(logging, sec_ad): pri_ad.log.error("Failed to answer call in second device.") return False # Wait for AG, RE to go into an Active state. if not wait_for_active(logging, pri_ad): pri_ad.log.error("AG not in Active state.") return False if not wait_for_active(logging, sec_ad): pri_ad.log.error("RE not in Active state.") return False time.sleep(duration) if not hangup_call(logging, pri_ad): pri_ad.log.error("Failed to hangup call.") return False flag = True flag &= wait_for_not_in_call(logging, pri_ad) flag &= wait_for_not_in_call(logging, sec_ad) return flag
def outgoing_multi_call_join_conference_call(self, pri_dut, sec_dut, ter_dut): self.log.info( "Test 2 outgoing calls scenario from phone then join the calls.") input("Press enter to execute this testcase...") outgoing_num = get_phone_number(self.log, sec_dut) if not initiate_call(self.log, pri_dut, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, sec_dut): self.log.error("Failed to answer call.") return False time.sleep(self.short_timeout) outgoing_num = get_phone_number(self.log, ter_dut) if not initiate_call(self.log, pri_dut, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, ter_dut): self.log.error("Failed to answer call.") return False input("Press enter to join active calls...") calls = pri_dut.droid.telecomCallGetCallIds() pri_dut.droid.telecomCallJoinCallsInConf(calls[0], calls[1]) time.sleep(WAIT_TIME_IN_CALL) if num_active_calls(self.log, pri_dut) != 4: self.log.error("Total number of call ids in {} is not 4.".format( pri_dut.serial)) return False input("Press enter to hangup call 1...") if not hangup_call(self.log, sec_dut): self.log.error("Failed to hangup call") return False input("Press enter to hangup call 2...") if not hangup_call(self.log, ter_dut): self.log.error("Failed to hangup call") return False return True
def initiate_disconnect_from_hf(audio_receiver, pri_ad, sec_ad, duration): """Initiates call and disconnect call on primary device. Steps: 1. Initiate call from HF. 2. Wait for dialing state at DUT and wait for ringing at secondary device. 3. Accepts call from secondary device. 4. Wait for call active state at primary and secondary device. 5. Sleeps until given duration. 6. Disconnect call from primary device. 7. Wait for call is not present state. Args: audio_receiver: An relay device object. pri_ad: An android device to disconnect call. sec_ad: An android device accepting call. duration: Duration of call in seconds. Returns: True if successful, False otherwise. """ audio_receiver.press_initiate_call() time.sleep(2) flag = True flag &= wait_for_dialing(logging, pri_ad) flag &= wait_for_ringing(logging, sec_ad) if not flag: pri_ad.log.error("Outgoing call did not get established") return False if not wait_and_answer_call(logging, sec_ad): pri_ad.log.error("Failed to answer call in second device.") return False if not wait_for_active(logging, pri_ad): pri_ad.log.error("AG not in Active state.") return False if not wait_for_active(logging, sec_ad): pri_ad.log.error("RE not in Active state.") return False time.sleep(duration) if not hangup_call(logging, pri_ad): pri_ad.log.error("Failed to hangup call.") return False flag = True flag &= wait_for_not_in_call(logging, pri_ad) flag &= wait_for_not_in_call(logging, sec_ad) return flag
def incomming_call_unknown_contact(self, pri_dut, ter_dut): self.log.info( "Test incomming call scenario to phone from unknown contact") input("Press enter to execute this testcase...") outgoing_num = get_phone_number(self.log, pri_dut) if not initiate_call(self.log, ter_dut, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, pri_dut): self.log.error("Failed to answer call.") return False time.sleep(self.short_timeout) input("Press enter to hangup call...") if not hangup_call(self.log, ter_dut): self.log.error("Failed to hangup call") return False return True
def outgoing_call_private_number(self, pri_dut, ter_dut): self.log.info( "Test outgoing call scenario from phone to private number") input("Press enter to execute this testcase...") outgoing_num = "*67" + get_phone_number(self.log, ter_dut) if not initiate_call(self.log, pri_dut, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, ter_dut): self.log.error("Failed to answer call.") return False time.sleep(self.short_timeout) input("Press enter to hangup call...") if not hangup_call(self.log, pri_dut): self.log.error("Failed to hangup call") return False return True
def call_audio_routes(self, pri_dut, sec_dut): self.log.info("Test various audio routes scenario from phone.") input("Press enter to execute this testcase...") outgoing_num = get_phone_number(self.log, sec_dut) if not initiate_call(self.log, pri_dut, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, sec_dut): self.log.error("Failed to answer call.") return False time.sleep(self.short_timeout) call_id = pri_dut.droid.telecomCallGetCallIds()[0] pri_dut.droid.telecomCallPlayDtmfTone(call_id, "9") input("Press enter to switch to speaker...") self.log.info("Switching to speaker.") set_audio_route(self.log, pri_dut, AUDIO_ROUTE_SPEAKER) time.sleep(self.short_timeout) if get_audio_route(self.log, pri_dut) != AUDIO_ROUTE_SPEAKER: self.log.error( "Audio Route not set to {}".format(AUDIO_ROUTE_SPEAKER)) return False input("Press enter to switch to earpiece...") self.log.info("Switching to earpiece.") set_audio_route(self.log, pri_dut, AUDIO_ROUTE_EARPIECE) time.sleep(self.short_timeout) if get_audio_route(self.log, pri_dut) != AUDIO_ROUTE_EARPIECE: self.log.error( "Audio Route not set to {}".format(AUDIO_ROUTE_EARPIECE)) return False input("Press enter to switch to Bluetooth...") self.log.info("Switching to Bluetooth...") set_audio_route(self.log, pri_dut, AUDIO_ROUTE_BLUETOOTH) time.sleep(self.short_timeout) if get_audio_route(self.log, pri_dut) != AUDIO_ROUTE_BLUETOOTH: self.log.error( "Audio Route not set to {}".format(AUDIO_ROUTE_BLUETOOTH)) return False input("Press enter to hangup call...") self.log.info("Hanging up call...") pri_dut.droid.telecomCallStopDtmfTone(call_id) if not hangup_call(self.log, pri_dut): self.log.error("Failed to hangup call") return False return True
def outgoing_call_multiple_iterations(self, pri_dut, sec_dut): iteration_count = 3 self.log.info( "Test outgoing call scenario from phone {} times from known contact" .format(iteration_count)) input("Press enter to execute this testcase...") outgoing_num = get_phone_number(self.log, sec_dut) for _ in range(iteration_count): if not initiate_call(self.log, pri_dut, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, sec_dut): self.log.error("Failed to answer call.") return False time.sleep(self.short_timeout) if not hangup_call(self.log, pri_dut): self.log.error("Failed to hangup call") return False return True
def sms_during_incomming_call(self, pri_dut, sec_dut): self.log.info( "Test incomming call scenario to phone from unknown contact") input("Press enter to execute this testcase...") outgoing_num = get_phone_number(self.log, pri_dut) if not initiate_call(self.log, sec_dut, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, pri_dut): self.log.error("Failed to answer call.") return False time.sleep(self.short_timeout) msg = [rand_ascii_str(10)] if not sms_send_receive_verify(self.log, sec_dut, pri_dut, msg): return False else: self.log.info("Successfully sent sms. Please verify on carkit.") input("Press enter to hangup call...") if not hangup_call(self.log, sec_dut): self.log.error("Failed to hangup call") return False return True
def outgoing_call_a2dp_play_before_and_after(self, pri_dut, sec_dut): self.log.info( "Test outgoing call scenario while playing music. Music should resume after call." ) pri_dut.adb.shell(KEYCODE_EVENT_PREVIOUS) input( "Press enter to execute this testcase when music is in a play state..." ) outgoing_num = get_phone_number(self.log, sec_dut) if not initiate_call(self.log, pri_dut, outgoing_num): self.log.error("Failed to initiate call") return False if not wait_and_answer_call(self.log, sec_dut): self.log.error("Failed to answer call.") return False time.sleep(self.short_timeout) input("Press enter to hangup call...") if not hangup_call(self.log, pri_dut): self.log.error("Failed to hangup call") return False input("Press enter when music continues to play.") self.log.info("Pausing Music...") pri_dut.adb.shell(KEYCODE_EVENT_PLAY_PAUSE) return True
def test_call_transfer_connect_disconnect_connect(self): """ Test that when we go from connect -> disconnect -> connect on an active call then the call is restored on HF. Precondition: 1. AG & HF are paired Steps: 0. Connect AG & HF 1. Make a call from HF role 2. Accept from RE role and transition the call to Active 3. Disconnect AG & HF 4. Verify that we don't have any calls on HF 5. Connect AG & HF 6. Verify that HF gets the call back. Returns: Pass if True Fail if False Priority: 1 """ # Now connect the devices. if not bt_test_utils.connect_pri_to_sec( self.hf, self.ag, set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])): self.log.error("Could not connect HF and AG {} {}".format( self.hf.serial, self.ag.serial)) return False # make a call on HF if not car_telecom_utils.dial_number(self.log, self.hf, self.re_phone_number): self.hf.log.error("HF not in dialing state.") return False # Wait for HF, AG to be dialing and RE to be ringing ret = True ret &= car_telecom_utils.wait_for_dialing(self.log, self.hf) #uncomment once sl4a code has been merged. ret &= car_telecom_utils.wait_for_dialing(self.log, self.ag) ret &= car_telecom_utils.wait_for_ringing(self.log, self.re) if not ret: self.log.error("Outgoing call did not get established") return False # Accept call on RE. if not wait_and_answer_call(self.log, self.re): self.re.log.error("Failed to accept call on re.") return False ret &= car_telecom_utils.wait_for_active(self.log, self.hf) ret &= car_telecom_utils.wait_for_active(self.log, self.ag) ret &= car_telecom_utils.wait_for_active(self.log, self.re) if not ret: self.log.error("Outgoing call did not transition to active") return False # Disconnect HF & AG self.hf.droid.bluetoothDisconnectConnected( self.ag.droid.bluetoothGetLocalAddress()) # We use the proxy of the Call going away as HF disconnected if not car_telecom_utils.wait_for_not_in_call(self.log, self.hf): self.hf.log.error("HF still in call after disconnection.") return False # Now connect the devices. if not bt_test_utils.connect_pri_to_sec( self.hf, self.ag, set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])): self.log.error("Could not connect HF and AG {} {}".format( self.hf.serial, self.ag.serial)) # Additional profile connection check for b/ if not bt_test_utils.is_hfp_client_device_connected( self.hf, self.ag.droid.bluetoothGetLocalAddress()): self.hf.log.info( "HFP Client connected even though connection state changed " + " event not found") return False # Check that HF is in active state if not car_telecom_utils.wait_for_active(self.log, self.hf): self.hf.log.error("HF not in Active state.") return False # Hangup the call and check all devices are clean self.hf.droid.telecomEndCall() ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.hf) ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.ag) ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.re) return ret
def test_call_transfer_off_on(self): """ Tests that after we turn adapter on when an active call is in progress, we show the call. Precondition: 1. AG & HF are disconnected but paired. 2. HF's adapter is OFF Steps: 1. Make a call from AG role (since disconnected) 2. Accept from RE role and transition the call to Active 3. Turn HF's adapter ON 4. HF should transition into Active call state. Returns: Pass if True Fail if False Priority: 1 """ # Connect HF & AG if not bt_test_utils.connect_pri_to_sec( self.hf, self.ag, set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])): self.log.error("Could not connect HF and AG {} {}".format( self.hf.serial, self.ag.serial)) return False # make a call on AG if not initiate_call(self.log, self.ag, self.re_phone_number): self.ag.log.error("Failed to initiate call from ag.") return False # Wait for all HF if not car_telecom_utils.wait_for_dialing(self.log, self.hf): self.hf.log.error("HF not in ringing state.") return False # Accept the call on RE if not wait_and_answer_call(self.log, self.re): self.re.log.error("Failed to accept call on re.") return False # Wait for all HF, AG, RE to go into an Active state. if not car_telecom_utils.wait_for_active(self.log, self.hf): self.hf.log.error("HF not in Active state.") return False if not car_telecom_utils.wait_for_active(self.log, self.ag): self.ag.log.error("AG not in Active state.") return False if not car_telecom_utils.wait_for_active(self.log, self.re): self.re.log.error("RE not in Active state.") return False # Turn the adapter OFF on HF if not bt_test_utils.disable_bluetooth(self.hf.droid): self.hf.log.error("Failed to turn BT off on HF.") return False # Turn adapter ON on HF if not bt_test_utils.enable_bluetooth(self.hf.droid, self.hf.ed): self.hf.log.error("Failed to turn BT ON after call on HF.") return False # Check that HF is in active state if not car_telecom_utils.wait_for_active(self.log, self.hf): self.hf.log.error("HF not in Active state.") return False # Hangup the call and check all devices are clean self.hf.droid.telecomEndCall() ret = True ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.hf) ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.ag) ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.re) return ret
def _telephony_monitor_test(self): """ Steps - 1. Reboot the phone 2. Start Telephony Monitor using adb/developer options 3. Verify if it is running 4. Phone Call from A to B 5. Answer on B 6. Trigger ModemSSR on B 7. There will be a call drop with Media Timeout/Server Unreachable 8. Parse logcat to confirm that Expected Results: UI Notification is received by User Returns: True is pass, False if fail. """ # Reboot ads = self.android_devices ads[0].adb.shell( "am start -n com.android.settings/.DevelopmentSettings", ignore_status=True) ads[0].log.info("reboot!") ads[0].reboot() ads[0].log.info("wait %d secs for radio up." % WAIT_TIME_AFTER_REBOOT) time.sleep(WAIT_TIME_AFTER_REBOOT) # Ensure apk is running if not ads[0].is_apk_running("com.google.telephonymonitor"): ads[0].log.info("TelephonyMonitor is not running, start it now") ads[0].adb.shell( 'am broadcast -a ' 'com.google.gservices.intent.action.GSERVICES_OVERRIDE -e ' '"ce.telephony_monitor_enable" "true"') # Setup Phone Call caller_number = ads[0].cfg['subscription'][get_outgoing_voice_sub_id( ads[0])]['phone_num'] callee_number = ads[1].cfg['subscription'][get_incoming_voice_sub_id( ads[1])]['phone_num'] tasks = [(phone_setup_voice_general, (self.log, ads[0])), (phone_setup_voice_general, (self.log, ads[1]))] if not multithread_func(self.log, tasks): self.log.error("Phone Failed to Set Up Properly.") return False if not initiate_call(ads[0].log, ads[0], callee_number): ads[0].log.error("Phone was unable to initate a call") return False if not wait_and_answer_call(self.log, ads[1], caller_number): ads[0].log.error("wait_and_answer_call failed") return False # Modem SSR time.sleep(5) ads[1].log.info("Triggering ModemSSR") ads[1].adb.shell("echo restart > /sys/kernel/debug/msm_subsys/modem", ignore_status=True) time.sleep(60) # Parse logcat for UI notification if ads[0].search_logcat("Bugreport notification title Call Drop:"): ads[0].log.info("User got the Call Drop Notification") else: ads[0].log.error("User didn't get Call Drop Notification in 1 min") return False return True
def _cbrs_call_sequence( self, ads, mo_mt, cbrs_phone_setup_func, verify_cbrs_initial_idle_func, verify_data_initial_func, verify_cbrs_in_call_state_func, verify_data_in_call_func, incall_cbrs_setting_check_func, verify_data_final_func, verify_cbrs_final_func, expected_result): """_cbrs_call_sequence Args: ads: list of android devices. This list should have 2 ad. mo_mt: indicating this call sequence is MO or MT. Valid input: DIRECTION_MOBILE_ORIGINATED and DIRECTION_MOBILE_TERMINATED. Returns: if expected_result is True, Return True if call sequence finish without exception. if expected_result is string, Return True if expected exception happened. Otherwise False. """ class _CBRSCallSequenceException(Exception): pass if (len(ads) != 2) or (mo_mt not in [ DIRECTION_MOBILE_ORIGINATED, DIRECTION_MOBILE_TERMINATED ]): self.log.error("Invalid parameters.") return False self.cbrs_subid, self.default_subid = get_cbrs_and_default_sub_id( ads[0]) if mo_mt == DIRECTION_MOBILE_ORIGINATED: ad_caller = ads[0] ad_callee = ads[1] caller_number = get_phone_number(self.log, ad_caller) callee_number = get_phone_number(self.log, ad_callee) mo_operator = get_operator_name(ads[0].log, ads[0]) mt_operator = get_operator_name(ads[1].log, ads[1]) else: ad_caller = ads[1] ad_callee = ads[0] caller_number = get_phone_number(self.log, ad_caller) callee_number = get_phone_number(self.log, ad_callee) mt_operator = get_operator_name(ads[0].log, ads[0]) mo_operator = get_operator_name(ads[1].log, ads[1]) self.log.info("-->Begin cbrs_call_sequence: %s to %s<--", caller_number, callee_number) self.log.info("--> %s to %s <--", mo_operator, mt_operator) try: # Setup if cbrs_phone_setup_func and not cbrs_phone_setup_func(): raise _CBRSCallSequenceException("cbrs_phone_setup_func fail.") if not phone_setup_voice_general(self.log, ads[1]): raise _CBRSCallSequenceException( "phone_setup_voice_general fail.") time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL) # Ensure idle status correct if verify_cbrs_initial_idle_func and not \ verify_cbrs_initial_idle_func(): raise _CBRSCallSequenceException( "verify_cbrs_initial_idle_func fail.") # Ensure data checks are performed if verify_data_initial_func and not \ verify_data_initial_func(): raise _CBRSCallSequenceException( "verify_data_initial_func fail.") # Make MO/MT call. if not initiate_call(self.log, ad_caller, callee_number): raise _CBRSCallSequenceException("initiate_call fail.") if not wait_and_answer_call(self.log, ad_callee, caller_number): raise _CBRSCallSequenceException("wait_and_answer_call fail.") time.sleep(WAIT_TIME_FOR_CBRS_DATA_SWITCH) # Check state, wait 30 seconds, check again. if (verify_cbrs_in_call_state_func and not verify_cbrs_in_call_state_func()): raise _CBRSCallSequenceException( "verify_cbrs_in_call_state_func fail.") if is_phone_not_in_call(self.log, ads[1]): raise _CBRSCallSequenceException("PhoneB not in call.") # Ensure data checks are performed if verify_data_in_call_func and not \ verify_data_in_call_func(): raise _CBRSCallSequenceException( "verify_data_in_call_func fail.") time.sleep(WAIT_TIME_IN_CALL) if (verify_cbrs_in_call_state_func and not verify_cbrs_in_call_state_func()): raise _CBRSCallSequenceException( "verify_cbrs_in_call_state_func fail after 30 seconds.") if is_phone_not_in_call(self.log, ads[1]): raise _CBRSCallSequenceException( "PhoneB not in call after 30 seconds.") # in call change setting and check if (incall_cbrs_setting_check_func and not incall_cbrs_setting_check_func()): raise _CBRSCallSequenceException( "incall_cbrs_setting_check_func fail.") # Hangup call if is_phone_in_call(self.log, ads[0]): if not hangup_call(self.log, ads[0]): raise _CBRSCallSequenceException("hangup_call fail.") else: if incall_cbrs_setting_check_func is None: raise _CBRSCallSequenceException("Unexpected call drop.") time.sleep(WAIT_TIME_FOR_CBRS_DATA_SWITCH) # Ensure data checks are performed if verify_data_final_func and not \ verify_data_final_func(): raise _CBRSCallSequenceException( "verify_data_final_func fail.") # Ensure data checks are performed if verify_cbrs_final_func and not \ verify_cbrs_final_func(): raise _CBRSCallSequenceException( "verify_cbrs_final_func fail.") except _CBRSCallSequenceException as e: if str(e) == expected_result: self.log.info("Expected exception: <%s>, return True.", e) return True else: self.log.info("Unexpected exception: <%s>, return False.", e) return False finally: for ad in ads: if ad.droid.telecomIsInCall(): hangup_call_by_adb(ad) self.log.info("cbrs_call_sequence finished, return %s", expected_result is True) return (expected_result is True)