1"""Functions to interact with modem log. 2 3Different modem logging profile can be found here: 4cs/vendor/google/apps/PixelLogger/log_profile/GFT_Call_Performance.xml 5""" 6import enum 7import logging 8import time 9 10from mobly.controllers import android_device # type: ignore 11 12_LOG = logging.getLogger(__name__) 13 14 15class ModemLogAction(enum.Enum): 16 """All possible valid PILOT logging actions.""" 17 18 START = 'ACTION_START_LOGGING' 19 STOP = 'ACTION_STOP_LOGGING' 20 CLEAR = 'ACTION_CLEAR_LOG' 21 22 23class ModemLogProfile(enum.Enum): 24 """All possible modem logging profiles.""" 25 26 LASSEN_AUDIO_TCP_DSP = 'Call_Performance.xml' 27 LASSEN_TCP_DSP = 'Data_Performance.xml' 28 29 30_MODEM_PILOT_ENABLE_PROP_NAME = 'vendor.pixellogger.pilot.logging_enable' 31 32_MODEM_LOG_PATH = '/sdcard/Android/data/com.android.pixellogger/files/logs' 33 34_ADB_SET_LOG_PROFILE_TEMPLATE = ( 35 'am broadcast ' 36 '-a com.android.pixellogger.experiment.ACTION_LOAD_PROFILE ' 37 '-n com.android.pixellogger/.receiver.ExperimentLoggingReceiver ' 38 '--es name "{log_profile_name}"' 39) 40 41_ADB_LOG_ACTION = ( 42 'am broadcast ' 43 '-a com.android.pixellogger.experiment.{log_action} ' 44 '-n com.android.pixellogger/.receiver.ExperimentLoggingReceiver' 45) 46 47_MODEM_LOGGING_PROFILE_PROP_NAME = ( 48 'persist.vendor.pixellogger.pilot.profile_name' 49) 50 51 52def start_modem_logging( 53 dut: android_device.AndroidDevice, 54 timeout: int = 20, 55 polling_interval: int = 1, 56) -> bool: 57 """Starts modem PILOT logging. 58 59 Args: 60 dut: A mobly AndroidDevice controller object. 61 timeout: Seconds to try to confirm logging before giving up. 62 polling_interval: Seconds to wait between confirmation attempts. 63 64 Raises: 65 RuntimeError: If unable to enable PILOT modem logging within timeout. 66 """ 67 dut.adb.root() 68 cmd = _ADB_LOG_ACTION.format(log_action=ModemLogAction.START.value) 69 dut.adb.shell(cmd) 70 end_time = time.time() + timeout 71 while time.time() < end_time: 72 time.sleep(polling_interval) 73 res = dut.adb.getprop(_MODEM_PILOT_ENABLE_PROP_NAME).strip() 74 _LOG.debug('PILOT modem logging enable: %s', res) 75 if res == 'true': 76 return 77 raise RuntimeError('Fail to start modem logging in PILOT mode.') 78 79 80def stop_modem_logging( 81 dut: android_device.AndroidDevice, 82 timeout: int = 20, 83 polling_interval: int = 1, 84) -> bool: 85 """Stops modem PILOT logging. 86 87 Args: 88 dut: A mobly AndroidDevice controller object. 89 timeout: An integer of time in second to wait for modem log to stop. 90 polling_interval: Interval in second to check if modem logging stopped. 91 92 Raises: 93 RuntimeError: If unable to disable PILOT modem logging within timeout. 94 """ 95 dut.adb.root() 96 cmd = _ADB_LOG_ACTION.format(log_action=ModemLogAction.STOP.value) 97 dut.adb.shell(cmd) 98 end_time = time.time() + timeout 99 while time.time() < end_time: 100 time.sleep(polling_interval) 101 res = dut.adb.getprop(_MODEM_PILOT_ENABLE_PROP_NAME).strip() 102 _LOG.debug('PILOT modem logging enable: %s', res) 103 if res == 'false' or not res: 104 return 105 raise RuntimeError('Fail to stop modem logging in PILOT mode.') 106 107 108def clear_modem_logging(dut: android_device.AndroidDevice) -> None: 109 """Stops modem PILOT logging. 110 111 Args: 112 dut: A mobly AndroidDevice controller object. 113 """ 114 dut.adb.root() 115 cmd = _ADB_LOG_ACTION.format(log_action=ModemLogAction.CLEAR.value) 116 dut.adb.shell(cmd) 117 _LOG.debug('Cleared modem logs.') 118 119 120def set_modem_log_profle( 121 dut: android_device.AndroidDevice, 122 profile: ModemLogProfile, 123 timeout: int = 10, 124 polling_interval: int = 1, 125) -> bool: 126 """Set modem log profile. 127 128 Args: 129 dut: An mobly AndroidDevice controller object. 130 profile: An ModemLogProfile enum represent modem logging profile. 131 timeout: Time waiting for modem log profile to be set. 132 polling_interval: Interval in second to check if log profile change. 133 134 Returns: 135 True if successfully set modem log profile within timeout. Fail otherwise. 136 """ 137 dut.adb.root() 138 cmd = _ADB_SET_LOG_PROFILE_TEMPLATE.format(log_profile_name=profile.value) 139 dut.adb.shell(cmd) 140 end_time = time.time() + timeout 141 while time.time() < end_time: 142 time.sleep(polling_interval) 143 if profile.value in get_modem_log_profile(dut): 144 return True 145 return False 146 147 148def get_modem_log_profile(dut: android_device.AndroidDevice) -> str: 149 """Get modem log profile. 150 151 Args: 152 dut: An mobly AndroidDevice controller object. 153 154 Returns: 155 String value of modem logging profile name. 156 157 Raises: 158 RuntimeError: If get empty response from adb shell. 159 """ 160 dut.adb.root() 161 res = dut.adb.getprop(_MODEM_LOGGING_PROFILE_PROP_NAME) 162 if not res: 163 raise RuntimeError('Fail to get modem logging profile from device.') 164 return res 165 166 167def pull_logs(dut: android_device.AndroidDevice, out_path: str, pull_timeout = 300) -> None: 168 """Pulls logs on device. 169 170 Args: 171 dut: An mobly AndroidDevice controller object. 172 out_path: A path to extract logs to. 173 pull_timeout: Seconds to wait for pulling complete. 174 """ 175 dut.adb.root() 176 dut.adb.pull( 177 "%s %s" % (_MODEM_LOG_PATH, out_path), timeout=pull_timeout) 178 _LOG.debug('Modem logs exported to %s', out_path)