1#!/usr/bin/env python3 2# 3# Copyright 2019 - The Android Open Source Project 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 os 18import time 19import errno 20 21 22DEVICE_CFG_FOLDER = "/data/vendor/radio/diag_logs/cfg/" 23DEVICE_DIAGMDLOG_FOLDER = "/data/vendor/radio/diag_logs/logs/" 24MDLOG_SETTLING_TIME = 2 25MDLOG_PROCESS_KILL_TIME = 3 26NOHUP_CMD = "nohup diag_mdlog -f {} -o {} -s 100 -c &> /dev/null &" 27DEVICE_GPSLOG_FOLDER = '/sdcard/Android/data/com.android.gpstool/files/' 28DEVICE_PIXEL_LOGGER_FOLDER = '/sdcard/Android/data/com.android.pixellogger/files/logs/gps/' 29 30 31def find_device_qxdm_log_mask(ad, maskfile): 32 """Finds device's diagmd mask file 33 34 Args: 35 ad: the target android device, AndroidDevice object 36 maskfile: Device's mask file name 37 38 Return: 39 exists, if cfg file is present 40 41 Raises: 42 FileNotFoundError if maskfile is not present 43 """ 44 45 if ".cfg" not in maskfile: 46 # errno.ENOENT - No such file or directory 47 raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), 48 maskfile) 49 else: 50 cfg_path = os.path.join(DEVICE_CFG_FOLDER, maskfile) 51 device_mask_file = ad.adb.shell('test -e %s && echo exists' % cfg_path) 52 return device_mask_file 53 54 55def set_diagmdlog_command(ad, maskfile): 56 """Sets diagmdlog command to run in background 57 58 Args: 59 ad: the target android device, AndroidDevice object 60 maskfile: mask file name 61 62 """ 63 cfg_path = os.path.join(DEVICE_CFG_FOLDER, maskfile) 64 ad.adb.shell(NOHUP_CMD.format(cfg_path, DEVICE_DIAGMDLOG_FOLDER)) 65 ad.log.info("Running diag_mdlog in the background") 66 time.sleep(MDLOG_SETTLING_TIME) 67 68 69def verify_diagmd_folder_exists(ad): 70 """Verify diagmd folder existence in device 71 72 Args: 73 ad: the target android device, AndroidDevice object 74 75 """ 76 mask_folder_exists = ad.adb.shell( 77 'test -d %s && echo exists' % DEVICE_CFG_FOLDER) 78 diag_folder_exists = ad.adb.shell( 79 'test -d %s && echo exists' % DEVICE_DIAGMDLOG_FOLDER) 80 if not mask_folder_exists and diag_folder_exists: 81 ad.adb.shell("mkdir " + DEVICE_CFG_FOLDER) 82 ad.adb.shell("mkdir " + DEVICE_DIAGMDLOG_FOLDER) 83 84 85def start_diagmdlog_background(ad, maskfile="default.cfg", is_local=True): 86 """Runs diagmd_log in background 87 88 Args: 89 ad: the target android device, AndroidDevice object 90 maskfile: Local Mask file path or Device's mask file name 91 is_local: False, take cfgfile from config. 92 True, find cfgfile in device and run diagmdlog 93 94 Raises: 95 FileNotFoundError if maskfile is not present 96 ProcessLookupError if diagmdlog process not present 97 """ 98 if is_local: 99 find_device_qxdm_log_mask(ad, maskfile) 100 set_diagmdlog_command(ad, maskfile) 101 else: 102 if not os.path.isfile(maskfile): 103 # errno.ENOENT - No such file or directory 104 raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), 105 maskfile) 106 else: 107 cfgfilename = os.path.basename(maskfile) 108 verify_diagmd_folder_exists(ad) 109 ad.adb.push("{} {}".format(maskfile, DEVICE_CFG_FOLDER)) 110 set_diagmdlog_command(ad, cfgfilename) 111 output = ad.adb.shell("pgrep diag_mdlog") 112 ad.log.info("Checking diag_mdlog in process") 113 if not output: 114 # errno.ESRCH - No such process 115 raise ProcessLookupError(errno.ESRCH, os.strerror(errno.ESRCH), 116 "diag_mdlog") 117 118 119def stop_background_diagmdlog(ad, local_logpath, keep_logs=True): 120 """Stop diagmdlog and pulls diag_mdlog from android device 121 122 Args: 123 ad: the target android device, AndroidDevice object 124 local_logpath: Local file path to pull the diag_mdlog logs 125 keep_logs: False, delete log files from the diag_mdlog path 126 127 Raises: 128 ProcessLookupError if diagmdlog process not present 129 """ 130 ps_output = ad.adb.shell("pgrep diag_mdlog") 131 ad.log.info("Checking diag_mdlog in process") 132 if ps_output: 133 output = ad.adb.shell("diag_mdlog -k") 134 time.sleep(MDLOG_PROCESS_KILL_TIME) 135 if "stopping" in output: 136 ad.log.debug("Stopping diag_mdlog") 137 ad.adb.pull("{} {}".format(DEVICE_DIAGMDLOG_FOLDER, local_logpath)) 138 ad.log.debug("Pulling diag_logs from the device to local") 139 if not keep_logs: 140 ad.adb.shell("rm -rf " + DEVICE_DIAGMDLOG_FOLDER + "*.*") 141 ad.log.debug("diagmd logs are deleted from device") 142 else: 143 ad.log.debug("diagmd logs are not deleted from device") 144 else: 145 output = ad.adb.shell("pidof diag_mdlog") 146 if output: 147 ad.adb.shell("kill -9 {}".format(output)) 148 ad.log.debug("Kill the existing qxdm process") 149 ad.adb.pull("{} {}".format(DEVICE_DIAGMDLOG_FOLDER, 150 local_logpath)) 151 ad.log.debug("Pulling diag_logs from the device to local") 152 else: 153 # errno.ESRCH - No such process 154 raise ProcessLookupError(errno.ESRCH, os.strerror(errno.ESRCH), 155 "diag_mdlog") 156 else: 157 # errno.ESRCH - No such process 158 raise ProcessLookupError(errno.ESRCH, os.strerror(errno.ESRCH), 159 "diag_mdlog") 160 161 162def get_gpstool_logs(ad, local_logpath, keep_logs=True): 163 """ 164 165 Pulls gpstool Logs from android device 166 167 Args: 168 ad: the target android device, AndroidDevice object 169 local_logpath: Local file path to pull the gpstool logs 170 keep_logs: False, delete log files from the gpstool log path 171 """ 172 173 gps_log_path = os.path.join(local_logpath, 'GPSLogs') 174 os.makedirs(gps_log_path, exist_ok=True) 175 ad.adb.pull("{} {}".format(DEVICE_GPSLOG_FOLDER, gps_log_path)) 176 ad.log.debug("gpstool logs are pulled from device") 177 178 if not keep_logs: 179 gpstool_log_path = os.path.join(DEVICE_GPSLOG_FOLDER, "*") 180 ad.adb.shell("rm -rf " + gpstool_log_path) 181 ad.log.debug("gpstool logs are deleted from device") 182 183def get_pixellogger_bcm_log(ad, local_logpath, keep_logs=True): 184 """ 185 186 Pulls BCM Logs from android device 187 188 Args: 189 ad: the target android device, AndroidDevice object 190 local_logpath: Local file path to pull the gpstool logs 191 keep_logs: False, delete log files from the gpstool log path 192 """ 193 194 ad.adb.pull("{} {}".format(DEVICE_PIXEL_LOGGER_FOLDER, local_logpath)) 195 ad.log.debug("pixellogger logs are pulled from device") 196 197 if not keep_logs: 198 bcm_log_path = os.path.join(DEVICE_PIXEL_LOGGER_FOLDER, "*") 199 ad.adb.shell("rm -rf " + bcm_log_path) 200 ad.log.debug("pixellogger logs are deleted from device")