def video_call_setup(log,
                     ad_caller,
                     ad_callee,
                     video_state=VT_STATE_BIDIRECTIONAL,
                     incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
    """ Call process, including make a phone call from caller,
    accept from callee, and hang up. The call is on default subscription

    In call process, call from <droid_caller> to <droid_callee>,
    accept the call, (optional)then hang up from <droid_hangup>.

    Args:
        ad_caller: Caller Android Device Object.
        ad_callee: Callee Android Device Object.
        incall_ui_display: after answer the call, bring in-call UI to foreground or
            background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
            if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
            if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
            else, do nothing.

    Returns:
        True if call process without any error.
        False if error happened.

    """
    return video_call_setup_for_subscription(
        log, ad_caller, ad_callee, get_outgoing_voice_sub_id(ad_caller),
        get_incoming_voice_sub_id(ad_callee), video_state, incall_ui_display)
    def setup_class(self):
        TelephonyBaseTest.setup_class(self)
        self.dut = self.android_devices[0]
        self.number_of_devices = 1
        self.skip_reset_between_cases = False
        subid = get_outgoing_voice_sub_id(self.dut)
        self.carrier_configs = dumpsys_carrier_config(self.dut)[subid]
        self.dut_capabilities = self.dut.telephony["subscription"][
            subid].get("capabilities", [])
        self.dut.log.info("DUT capabilities: %s", self.dut_capabilities)
        if CAPABILITY_VOLTE not in self.dut_capabilities:
            raise signals.TestAbortClass("VoLTE is not supported")
        if CAPABILITY_WFC not in self.dut_capabilities:
            raise signals.TestAbortClass("WFC is not supported")

        self.default_volte = (CAPABILITY_VOLTE in self.dut_capabilities) and (
            self.carrier_configs[CarrierConfigs.
                                 ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL])
        self.default_wfc_enabled = (
            CAPABILITY_WFC in self.dut_capabilities
        ) and (
            self.carrier_configs[CarrierConfigs.DEFAULT_WFC_IMS_ENABLED_BOOL])
        self.default_wfc_mode = self.carrier_configs.get(
            CarrierConfigs.DEFAULT_WFC_IMS_MODE_INT, None)
        self.dut_wfc_modes = self.dut.telephony[
            "subscription"][subid].get("wfc_modes", [])
Ejemplo n.º 3
0
def phone_setup_iwlan(log,
                      ad,
                      is_airplane_mode,
                      wfc_mode,
                      wifi_ssid=None,
                      wifi_pwd=None):
    """Phone setup function for epdg call test.
    Set WFC mode according to wfc_mode.
    Set airplane mode according to is_airplane_mode.
    Make sure phone connect to WiFi. (If wifi_ssid is not None.)
    Wait for phone to be in iwlan data network type.
    Wait for phone to report wfc enabled flag to be true.

    Args:
        log: Log object.
        ad: Android device object.
        is_airplane_mode: True to turn on airplane mode. False to turn off airplane mode.
        wfc_mode: WFC mode to set to.
        wifi_ssid: WiFi network SSID. This is optional.
            If wifi_ssid is None, then phone_setup_iwlan will not attempt to connect to wifi.
        wifi_pwd: WiFi network password. This is optional.

    Returns:
        True if success. False if fail.
    """
    #TODO: get per sub_id carrier_config for multi-sim purpose
    if CAPABILITY_WFC not in ad.telephony.get("capabilities", []):
        ad.log.error("WFC is not supported, abort test.")
        raise signals.TestSkip("WFC is not supported, abort test.")
    return phone_setup_iwlan_for_subscription(log, ad,
                                              get_outgoing_voice_sub_id(ad),
                                              is_airplane_mode, wfc_mode,
                                              wifi_ssid, wifi_pwd)
Ejemplo n.º 4
0
def phone_setup_iwlan(log,
                      ad,
                      is_airplane_mode,
                      wfc_mode,
                      wifi_ssid=None,
                      wifi_pwd=None):
    """Phone setup function for epdg call test.
    Set WFC mode according to wfc_mode.
    Set airplane mode according to is_airplane_mode.
    Make sure phone connect to WiFi. (If wifi_ssid is not None.)
    Wait for phone to be in iwlan data network type.
    Wait for phone to report wfc enabled flag to be true.

    Args:
        log: Log object.
        ad: Android device object.
        is_airplane_mode: True to turn on airplane mode. False to turn off airplane mode.
        wfc_mode: WFC mode to set to.
        wifi_ssid: WiFi network SSID. This is optional.
            If wifi_ssid is None, then phone_setup_iwlan will not attempt to connect to wifi.
        wifi_pwd: WiFi network password. This is optional.

    Returns:
        True if success. False if fail.
    """
    return phone_setup_iwlan_for_subscription(log, ad,
                                              get_outgoing_voice_sub_id(ad),
                                              is_airplane_mode, wfc_mode,
                                              wifi_ssid, wifi_pwd)
def wait_and_answer_video_call(log,
                               ad,
                               incoming_number=None,
                               video_state=VT_STATE_BIDIRECTIONAL,
                               incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
    """Wait for an incoming call on default voice subscription and
       accepts the call.

    Args:
        ad: android device object.
        incoming_number: Expected incoming number.
            Optional. Default is None
        incall_ui_display: after answer the call, bring in-call UI to foreground or
            background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
            if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
            if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
            else, do nothing.

    Returns:
        True: if incoming call is received and answered successfully.
        False: for errors
    """
    return wait_and_answer_video_call_for_subscription(
        log, ad, get_outgoing_voice_sub_id(ad), incoming_number, video_state,
        incall_ui_display)
Ejemplo n.º 6
0
def get_current_voice_rat(log, ad):
    """Return current Voice RAT

    Args:
        ad: Android device object.
    """
    return get_current_voice_rat_for_subscription(
        log, ad, get_outgoing_voice_sub_id(ad))
Ejemplo n.º 7
0
def is_phone_in_call_3g(log, ad):
    """Return if phone is in 3G call.

    Args:
        ad: Android device object.
    """
    return is_phone_in_call_3g_for_subscription(log, ad,
                                                get_outgoing_voice_sub_id(ad))
Ejemplo n.º 8
0
def phone_idle_2g(log, ad):
    """Return if phone is idle for 2G call test.

    Args:
        ad: Android device object.
    """
    return phone_idle_2g_for_subscription(log, ad,
                                          get_outgoing_voice_sub_id(ad))
Ejemplo n.º 9
0
def phone_idle_not_iwlan(log, ad):
    """Return if phone is idle for non WiFi calling call test.

    Args:
        ad: Android device object.
    """
    return phone_idle_not_iwlan_for_subscription(log, ad,
                                                 get_outgoing_voice_sub_id(ad))
def phone_idle_video(log, ad):
    """Return if phone (default sub_id) is idle for video call.

    Args:
        log: log object.
        ad: android device object

    Returns:
        True if ad is idle for video call.
    """
    return phone_idle_video_for_subscription(log, ad,
                                             get_outgoing_voice_sub_id(ad))
def is_phone_in_call_video_bidirectional(log, ad):
    """Return if phone in bi-directional video call.

    Args:
        log: log object.
        ad: android device object

    Returns:
        True if phone in bi-directional video call.
    """
    return is_phone_in_call_video_bidirectional_for_subscription(
        log, ad, get_outgoing_voice_sub_id(ad))
def is_phone_in_call_voice_hd(log, ad):
    """Return if phone in hd voice call.

    Args:
        log: log object.
        ad: android device object

    Returns:
        True if phone in hd voice call.
    """
    return is_phone_in_call_voice_hd_for_subscription(
        log, ad, get_outgoing_voice_sub_id(ad))
Ejemplo n.º 13
0
def phone_setup_voice_2g(log, ad):
    """Setup phone voice to 2G.

    Args:
        log: log object
        ad: Android device object.

    Returns:
        True if setup successfully.
        False for errors.
    """
    return phone_setup_voice_2g_for_subscription(log, ad,
                                                 get_outgoing_voice_sub_id(ad))
Ejemplo n.º 14
0
def phone_setup_volte(log, ad):
    """Setup VoLTE enable.

    Args:
        log: log object
        ad: android device object.

    Returns:
        True: if VoLTE is enabled successfully.
        False: for errors
    """
    return phone_setup_volte_for_subscription(log, ad,
                                              get_outgoing_voice_sub_id(ad))
Ejemplo n.º 15
0
def phone_setup_video(log, ad, wfc_mode=WFC_MODE_DISABLED):
    """Setup phone default sub_id to make video call

    Args:
        log: log object.
        ad: android device object
        wfc_mode: WFC mode to set to.
            Valid mode includes: WFC_MODE_WIFI_ONLY, WFC_MODE_CELLULAR_PREFERRED,
            WFC_MODE_WIFI_PREFERRED, WFC_MODE_DISABLED.

    Returns:
        True if ad (default sub_id) is setup correctly and idle for video call.
    """
    return phone_setup_video_for_subscription(log, ad, get_outgoing_voice_sub_id(ad), wfc_mode)
Ejemplo n.º 16
0
def phone_setup_voice_general(log, ad):
    """Setup phone for voice general call test.

    Make sure phone attached to voice.
    Make necessary delay.

    Args:
        ad: Android device object.

    Returns:
        True if setup successfully.
        False for errors.
    """
    return phone_setup_voice_general_for_subscription(
        log, ad, get_outgoing_voice_sub_id(ad))
Ejemplo n.º 17
0
def phone_setup_csfb(log, ad):
    """Setup phone for CSFB call test.

    Setup Phone to be in 4G mode.
    Disabled VoLTE.

    Args:
        log: log object
        ad: Android device object.

    Returns:
        True if setup successfully.
        False for errors.
    """
    return phone_setup_csfb_for_subscription(log, ad,
                                             get_outgoing_voice_sub_id(ad))
def is_phone_in_call_video(log, ad):
    """Return if ad is in a video call (in expected video state).

    Args:
        log: log object.
        ad: android device object
        video_state: Expected Video call state.
            This is optional, if it's None,
            then TX_ENABLED/RX_ENABLED/BIDIRECTIONAL video call state will
            return True.

    Returns:
        True if ad (for sub_id) is in a video call (in expected video state).
    """
    return is_phone_in_call_video_for_subscription(
        log, ad, get_outgoing_voice_sub_id(ad))
Ejemplo n.º 19
0
def phone_setup_volte(log, ad):
    """Setup VoLTE enable.

    Args:
        log: log object
        ad: android device object.

    Returns:
        True: if VoLTE is enabled successfully.
        False: for errors
    """
    #TODO: get per sub_id carrier_config for multi-sim purpose
    if CAPABILITY_VOLTE not in ad.telephony.get("capabilities", []):
        ad.log.error("VoLTE is not supported, abort test.")
        raise signals.TestSkip("VoLTE is not supported, abort test.")
    return phone_setup_volte_for_subscription(log, ad,
                                              get_outgoing_voice_sub_id(ad))
def video_call_setup_teardown(log,
                              ad_caller,
                              ad_callee,
                              ad_hangup=None,
                              video_state=VT_STATE_BIDIRECTIONAL,
                              verify_caller_func=None,
                              verify_callee_func=None,
                              wait_time_in_call=WAIT_TIME_IN_CALL,
                              incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND):
    """ Call process, including make a phone call from caller,
    accept from callee, and hang up. The call is on default subscription

    In call process, call from <droid_caller> to <droid_callee>,
    accept the call, (optional)then hang up from <droid_hangup>.

    Args:
        ad_caller: Caller Android Device Object.
        ad_callee: Callee Android Device Object.
        ad_hangup: Android Device Object end the phone call.
            Optional. Default value is None, and phone call will continue.
        video_state: video state for VT call.
            Optional. Default value is VT_STATE_BIDIRECTIONAL
        verify_caller_func: func_ptr to verify caller in correct mode
            Optional. Default is None
        verify_callee_func: func_ptr to verify callee in correct mode
            Optional. Default is None
        wait_time_in_call: wait time during call.
            Optional. Default is WAIT_TIME_IN_CALL.
        incall_ui_display: after answer the call, bring in-call UI to foreground or
            background. Optional, default value is INCALL_UI_DISPLAY_FOREGROUND.
            if = INCALL_UI_DISPLAY_FOREGROUND, bring in-call UI to foreground.
            if = INCALL_UI_DISPLAY_BACKGROUND, bring in-call UI to background.
            else, do nothing.

    Returns:
        True if call process without any error.
        False if error happened.

    """
    return video_call_setup_teardown_for_subscription(
        log, ad_caller, ad_callee, get_outgoing_voice_sub_id(ad_caller),
        get_incoming_voice_sub_id(ad_callee), ad_hangup, video_state,
        verify_caller_func, verify_callee_func, wait_time_in_call,
        incall_ui_display)
    def _test_msim_call_voice(self,
                              mo_slot,
                              mt_slot,
                              dds_slot,
                              mo_rat=["", ""],
                              mt_rat=["", ""],
                              call_direction="mo"):
        """Make MO/MT voice call at specific slot in specific RAT with DDS at
        specific slot.

        Test step:
        1. Get sub IDs of specific slots of both MO and MT devices.
        2. Switch DDS to specific slot.
        3. Check HTTP connection after DDS switch.
        4. Set up phones in desired RAT.
        5. Make voice call.

        Args:
            mo_slot: Slot making MO call (0 or 1)
            mt_slot: Slot receiving MT call (0 or 1)
            dds_slot: Preferred data slot
            mo_rat: RAT for both slots of MO device
            mt_rat: RAT for both slots of MT device
            call_direction: "mo" or "mt"

        Returns:
            TestFailure if failed.
        """
        ads = self.android_devices

        if call_direction == "mo":
            ad_mo = ads[0]
            ad_mt = ads[1]
        else:
            ad_mo = ads[1]
            ad_mt = ads[0]

        if mo_slot is not None:
            mo_sub_id = get_subid_from_slot_index(self.log, ad_mo, mo_slot)
            if mo_sub_id == INVALID_SUB_ID:
                ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
                return False
            mo_other_sub_id = get_subid_from_slot_index(
                self.log, ad_mo, 1 - mo_slot)
            set_incoming_voice_sub_id(ad_mo, mo_sub_id)
        else:
            _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
            if mo_sub_id == INVALID_SUB_ID:
                ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
                return False
            mo_slot = "auto"
            set_incoming_voice_sub_id(ad_mo, mo_sub_id)
        ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", mo_slot,
                       get_outgoing_voice_sub_id(ad_mo))

        if mt_slot is not None:
            mt_sub_id = get_subid_from_slot_index(self.log, ad_mt, mt_slot)
            if mt_sub_id == INVALID_SUB_ID:
                ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
                return False
            mt_other_sub_id = get_subid_from_slot_index(
                self.log, ad_mt, 1 - mt_slot)
            set_incoming_voice_sub_id(ad_mt, mt_sub_id)
        else:
            _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
            if mt_sub_id == INVALID_SUB_ID:
                ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
                return False
            mt_slot = "auto"
            set_incoming_voice_sub_id(ad_mt, mt_sub_id)
        ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot,
                       get_incoming_voice_sub_id(ad_mt))

        self.log.info("Step 1: Switch DDS.")
        if dds_slot:
            if not set_dds_on_slot_1(ads[0]):
                ads[0].log.warning("Failed to set DDS at eSIM.")
                return False
        else:
            if not set_dds_on_slot_0(ads[0]):
                ads[0].log.warning("Failed to set DDS at pSIM.")
                return False

        self.log.info("Step 2: Check HTTP connection after DDS switch.")
        if not verify_http_connection(self.log,
                                      ads[0],
                                      url="https://www.google.com",
                                      retry=5,
                                      retry_interval=15,
                                      expected_state=True):

            self.log.error("Failed to verify http connection.")
            return False
        else:
            self.log.info("Verify http connection successfully.")

        if mo_rat[0] == "volte":
            mo_slot0_phone_setup_func = phone_setup_volte
            is_mo_slot0_in_call = is_phone_in_call_volte
        elif mo_rat[0] == "csfb":
            mo_slot0_phone_setup_func = phone_setup_csfb
            is_mo_slot0_in_call = is_phone_in_call_csfb
        elif mo_rat[0] == "3g":
            mo_slot0_phone_setup_func = phone_setup_voice_3g
            is_mo_slot0_in_call = is_phone_in_call_3g
        elif not mo_rat[0] or mo_rat[0] == "general":
            mo_slot0_phone_setup_func = phone_setup_voice_general
            is_mo_slot0_in_call = None

        if mo_rat[1] == "volte":
            mo_slot1_phone_setup_func = phone_setup_volte
            is_mo_slot1_in_call = is_phone_in_call_volte
        elif mo_rat[1] == "csfb":
            mo_slot1_phone_setup_func = phone_setup_csfb
            is_mo_slot1_in_call = is_phone_in_call_csfb
        elif mo_rat[1] == "3g":
            mo_slot1_phone_setup_func = phone_setup_voice_3g
            is_mo_slot1_in_call = is_phone_in_call_3g
        elif not mo_rat[1] or mo_rat[1] == "general":
            mo_slot1_phone_setup_func = phone_setup_voice_general
            is_mo_slot1_in_call = None

        if mt_rat[0] == "volte":
            mt_slot0_phone_setup_func = phone_setup_volte
            is_mt_slot0_in_call = is_phone_in_call_volte
        elif mt_rat[0] == "csfb":
            mt_slot0_phone_setup_func = phone_setup_csfb
            is_mt_slot0_in_call = is_phone_in_call_csfb
        elif mt_rat[0] == "3g":
            mt_slot0_phone_setup_func = phone_setup_voice_3g
            is_mt_slot0_in_call = is_phone_in_call_3g
        elif not mt_rat[0] or mt_rat[0] == "general":
            mt_slot0_phone_setup_func = phone_setup_voice_general
            is_mt_slot0_in_call = None

        if mt_rat[1] == "volte":
            mt_slot1_phone_setup_func = phone_setup_volte
            is_mt_slot1_in_call = is_phone_in_call_volte
        elif mt_rat[1] == "csfb":
            mt_slot1_phone_setup_func = phone_setup_csfb
            is_mt_slot1_in_call = is_phone_in_call_csfb
        elif mt_rat[1] == "3g":
            mt_slot1_phone_setup_func = phone_setup_voice_3g
            is_mt_slot1_in_call = is_phone_in_call_3g
        elif not mt_rat[1] or mt_rat[1] == "general":
            mt_slot1_phone_setup_func = phone_setup_voice_general
            is_mt_slot1_in_call = None

        if mo_slot == 1:
            mo_phone_setup_func = mo_slot1_phone_setup_func
            is_mo_in_call = is_mo_slot1_in_call
            if mo_rat[0] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mo,
                                                   mo_other_sub_id)
            elif mo_rat[0] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mo,
                                                  mo_other_sub_id)
            elif mo_rat[0] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mo,
                                                      mo_other_sub_id)
            elif not mo_rat[0] or mo_rat[0] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mo, mo_other_sub_id)
        elif mo_slot == 0:
            mo_phone_setup_func = mo_slot0_phone_setup_func
            is_mo_in_call = is_mo_slot0_in_call
            if mo_rat[1] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mo,
                                                   mo_other_sub_id)
            elif mo_rat[1] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mo,
                                                  mo_other_sub_id)
            elif mo_rat[1] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mo,
                                                      mo_other_sub_id)
            elif not mo_rat[1] or mo_rat[1] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mo, mo_other_sub_id)
        else:
            mo_phone_setup_func = phone_setup_voice_general
            is_mo_in_call = None

        if mt_slot == 1:
            mt_phone_setup_func = mt_slot1_phone_setup_func
            is_mt_in_call = is_mt_slot1_in_call
            if mt_rat[0] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mt,
                                                   mt_other_sub_id)
            elif mt_rat[0] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mt,
                                                  mt_other_sub_id)
            elif mt_rat[0] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mt,
                                                      mt_other_sub_id)
            elif not mt_rat[0] or mt_rat[0] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mt, mt_other_sub_id)
        elif mt_slot == 0:
            mt_phone_setup_func = mt_slot0_phone_setup_func
            is_mt_in_call = is_mt_slot0_in_call
            if mt_rat[1] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mt,
                                                   mt_other_sub_id)
            elif mt_rat[1] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mt,
                                                  mt_other_sub_id)
            elif mt_rat[1] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mt,
                                                      mt_other_sub_id)
            elif not mt_rat[1] or mt_rat[1] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mt, mt_other_sub_id)
        else:
            mt_phone_setup_func = phone_setup_voice_general
            is_mt_in_call = None

        self.log.info("Step 3: Set up phones in desired RAT.")
        tasks = [(mo_phone_setup_func, (self.log, ad_mo)),
                 (mt_phone_setup_func, (self.log, ad_mt))]
        if not multithread_func(self.log, tasks):
            self.log.error("Phone Failed to Set Up Properly.")
            self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
            raise signals.TestFailure(
                "Failed",
                extras={"fail_reason": "Phone Failed to Set Up Properly."})

        self.log.info("Step 4: Make voice call.")
        result = two_phone_call_msim_for_slot(
            self.log, ad_mo,
            get_slot_index_from_subid(self.log, ad_mo,
                                      mo_sub_id), None, is_mo_in_call, ad_mt,
            get_slot_index_from_subid(self.log, ad_mt, mt_sub_id), None,
            is_mt_in_call)
        self.tel_logger.set_result(result.result_value)

        if not result:
            self.log.error(
                "Failed to make MO call from %s slot %s to %s slot %s",
                ad_mo.serial, mo_slot, ad_mt.serial, mt_slot)
            raise signals.TestFailure(
                "Failed", extras={"fail_reason": str(result.result_value)})
    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