def start_logcat(self, save_dir, process_list=[], params=''): '''运行logcat进程 :param list process_list: 要捕获日志的进程名或进程ID列表,为空则捕获所有进程,输入 ['system_server']可捕获系统进程的日志 :param str params: 参数 ''' if not os.path.exists(save_dir): os.makedirs(save_dir) if hasattr(self, '_logcat_running') and self._logcat_running == True: logger.warning('logcat process have started,not need start') return # sdk 26一下可以执行logcat -c的操作, 8.0以上的系统不能执行,会报"failed to clear the 'main' log"的错 图兰朵没问题 # if self.get_sdk_version() < 26: try: # 有些机型上会报permmison denied,但是logcat -c的代码仍会部分执行,所以加try 保护 self.run_shell_cmd('logcat -c ' + params) # 清除缓冲区 except RuntimeError as e: logger.warning(e) self._logcat_running = True # logcat进程是否启动 self._log_pipe = self.run_shell_cmd('logcat -v threadtime ' + params, sync=False) self._logcat_thread = threading.Thread( target=self._logcat_thread_func, args=[save_dir, process_list, params]) self._logcat_thread.setDaemon(True) self._logcat_thread.start()
def wait_for_device(self, timeout=180): '''等待设备连接 ''' if not self.run_adb_cmd("wait-for-device", timeout=180): logger.warning("adb wait-for-device timeout") return False return True
def _timer(self, process, timeout): '''进程超时器,监控adb同步命令执行是否超时,超时强制结束执行。当timeout<=0时,永不超时 :param Popen process: 子进程对象 :param int timeout: 超时时间 ''' num = 0 while process.poll() == None and num < timeout * 10: num += 1 time.sleep(0.1) if process.poll() == None: logger.warning("%d process timeout,force close" % process.pid) process.terminate()
def _install_apk(self, apk_path, over_install=True, downgrade=False): ''' ''' timeout = 3 * 60 # TODO: 确认3分钟是否足够 tmp_path = '/data/local/tmp/' + os.path.split(apk_path)[-1] self.push_file(apk_path, tmp_path) cmdline = 'pm install %s %s %s' % ('-r -t' if over_install else '', "-d" if downgrade else "", tmp_path) ret = '' for i in range(3): # TODO: 处理一些必然会失败的情况,如方法数超标之类的问题 try: ret = self.run_shell_cmd( cmdline, retry_count=1, timeout=timeout) # 使用root权限安装,可以在小米2S上不弹出确认对话框 logger.debug(ret) if i > 1 and 'INSTALL_FAILED_ALREADY_EXISTS' in ret: # 出现至少一次超时,认为安装完成 ret = 'Success' break if 'INSTALL_PARSE_FAILED_NO_CERTIFICATES' in ret or \ 'INSTALL_FAILED_INSUFFICIENT_STORAGE' in ret: raise RuntimeError('安装应用失败:%s' % ret) if 'INSTALL_FAILED_UID_CHANGED' in ret: logger.error(ret) # /data/data目录下存在文件夹没有删除 # package_name = self._get_package_name(apk_path) # dir_path = '/data/data/%s' % package_name # for _ in range(3): # # 防止删除没有成功 # self.delete_folder(dir_path) # if 'No such file or directory' in self.run_root_shell_cmd('ls -l %s' % dir_path): break continue if 'Success' in ret or 'INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES' in ret or \ 'INSTALL_FAILED_ALREADY_EXISTS' in ret: break except: if i >= 2: logger.warning('install app failed') ret = self.run_shell_cmd(cmdline, timeout=timeout) # 改用非root权限安装 logger.debug(ret) if ret and 'INSTALL_FAILED_ALREADY_EXISTS' in ret: ret = 'Success' try: self.delete_file('/data/local/tmp/*.apk') except: pass return ret
def checkAdbNormal(): sub = subprocess.Popen("adb devices", stdout=subprocess.PIPE, shell=True) adbRet = str(sub.stdout.read(),"utf-8") sub.wait() logger.debug("adb device ret:%s" % adbRet) if not adbRet: logger.debug("devices list maybe is empty") return True else: if "daemon not running." in adbRet: logger.warning("daemon not running.") return False elif "ADB server didn't ACK" in adbRet: logger.warning("error: ADB server didn't ACK,kill occupy 5037 port process") return False else: return True
def start_server(): ADB.killOccupy5037Process() logger.warning("fork-server") os.system("adb fork-server server -a")
def kill_server(): logger.warning("kill-server") os.system("adb kill-server")