From 63f4e6ae4a1f3cd0248a44d695c9ec6222fe3622 Mon Sep 17 00:00:00 2001 From: zhangshuai Date: Mon, 18 Nov 2024 14:50:34 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20ASW-176=20exec=20playbook=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=A2=9E=E5=8A=A0reInstall=EF=BC=8CclearCache?= =?UTF-8?q?=EF=BC=8CunInstall=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../geedge/api/controller/APIController.java | 86 +++++++++++++++---- .../geedge/api/util/AdbCommandBuilder.java | 30 +++++++ .../java/net/geedge/api/util/AdbUtil.java | 41 +++++++++ 3 files changed, 138 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/geedge/api/controller/APIController.java b/src/main/java/net/geedge/api/controller/APIController.java index b557b9d..14a4996 100644 --- a/src/main/java/net/geedge/api/controller/APIController.java +++ b/src/main/java/net/geedge/api/controller/APIController.java @@ -2,6 +2,7 @@ package net.geedge.api.controller; import cn.hutool.core.codec.Base32Codec; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.log.Log; @@ -20,7 +21,6 @@ import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.util.*; -import java.util.zip.ZipEntry; @RestController @RequestMapping("/api/v1/env") @@ -264,7 +264,10 @@ public class APIController { @PostMapping("/playbook") public R execPlaybook(@RequestParam("file") MultipartFile file, @RequestParam("packageName") String packageName, - @RequestParam("id") String id) { + @RequestParam("id") String id, + @RequestParam("reInstall") Boolean reInstall, + @RequestParam("clearCache") Boolean clearCache, + @RequestParam("unInstall") Boolean unInstall) { File apkFile = null; File playbookAirDir = null; File destination = null; @@ -307,7 +310,8 @@ public class APIController { } finally { T.FileUtil.del(destination); } - PlaybookRunnable playbookRunnable = new PlaybookRunnable(apiYml, apkFile, playbookAirDir, id, packageName); + + PlaybookRunnable playbookRunnable = new PlaybookRunnable(apiYml, apkFile, playbookAirDir, id, packageName, reInstall, clearCache, unInstall); playbookRunnable.setName(T.StrUtil.concat(true, id, "-", apkFile.getName())); ThreadUtil.execAsync(playbookRunnable); return R.ok(); @@ -406,14 +410,20 @@ public class APIController { private File apkFile; private String packageName; private File playbookDir; + private boolean reInstall; + private boolean clearCache; + private boolean unInstall; private boolean interrupt; - public PlaybookRunnable(EnvApiYml envApiYml, File apkFile, File playbookDir, String tid, String packageName) { + public PlaybookRunnable(EnvApiYml envApiYml, File apkFile, File playbookDir, String tid, String packageName, Boolean reInstall, Boolean clearCache, Boolean unInstall) { this.envApiYml = envApiYml; this.tid = tid; this.apkFile = apkFile; this.packageName = packageName; this.playbookDir = playbookDir; + this.reInstall = reInstall; + this.clearCache = clearCache; + this.unInstall = unInstall; this.interrupt = false; } @@ -425,31 +435,57 @@ public class APIController { AdbUtil.CommandResult tcpdumpPackage = null; AdbUtil.CommandResult tcpdumpAll = null; try { - - T.FileUtil.appendString(String.format("Running with %s:%s Android Simulator \n", envApiYml.getAdb().getHost(), envApiYml.getAdb().getPort()), logFile, "UTF-8"); - adbUtil = new AdbUtil(envApiYml.getAdb(), new CommandExec(logFile)); - Map resultMap = T.MapUtil.builder() .put("status", "running") .build(); T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8"); - // install apk if (interrupt) return; - AdbUtil.CommandResult install = adbUtil.install(apkFile.getAbsolutePath(), true, true); - if (0 != install.exitCode()) { - T.FileUtil.appendString(String.format("ERROR: Install apk failed: exit code %s \n", install.exitCode()), logFile, "UTF-8"); - throw new APIException(install.output()); + T.FileUtil.appendString(String.format("Running with %s:%s Android Simulator \n", envApiYml.getAdb().getHost(), envApiYml.getAdb().getPort()), logFile, "UTF-8"); + adbUtil = new AdbUtil(envApiYml.getAdb(), new CommandExec(logFile)); + + // Check if the package is installed + if (interrupt) return; + boolean packageIsInstall = adbUtil.findPackageInstall(packageName); + if (packageIsInstall){ + if (!reInstall){ + // install apk + if (interrupt) return; + AdbUtil.CommandResult install = adbUtil.install(apkFile.getAbsolutePath(), true, true); + if (0 != install.exitCode()) { + T.FileUtil.appendString(String.format("ERROR: Install apk failed: exit code %s \n", install.exitCode()), logFile, "UTF-8"); + throw new APIException(install.output()); + } + } + }else { + // install apk + if (interrupt) return; + AdbUtil.CommandResult install = adbUtil.install(apkFile.getAbsolutePath(), true, true); + if (0 != install.exitCode()) { + T.FileUtil.appendString(String.format("ERROR: Install apk failed: exit code %s \n", install.exitCode()), logFile, "UTF-8"); + throw new APIException(install.output()); + } } + //Close other apps + if (interrupt) return; + List packageNameList = adbUtil.findPackageNameList(); + this.closeApp(packageNameList, packageName); + // clear app data if (interrupt) return; - AdbUtil.CommandResult clearData = adbUtil.clearAppData(packageName); - if (0 != clearData.exitCode()) { - T.FileUtil.appendString(String.format("ERROR: Clear %s data error: exit code %s \n", packageName, install.exitCode()), logFile, "UTF-8"); - throw new APIException(clearData.output()); + if (clearCache){ + AdbUtil.CommandResult clearData = adbUtil.clearAppData(packageName); + if (0 != clearData.exitCode()) { + T.FileUtil.appendString(String.format("ERROR: Clear %s data error: exit code %s \n", packageName, clearData.exitCode()), logFile, "UTF-8"); + throw new APIException(clearData.output()); + } } + // Launch the app + if (interrupt) return; + adbUtil.startApp(packageName); + // star tcpdump: package name if (interrupt) return; tcpdumpPackage = adbUtil.startTcpdump(packageName); @@ -501,12 +537,24 @@ public class APIController { AdbUtil.CommandResult allTcpdump = adbUtil.stopTcpdump(tcpdumpAll.output()); adbUtil.execShellCommand(String.format("shell rm -rf %s", allTcpdump.output())); } - adbUtil.stopApp(packageName); - T.FileUtil.appendString(String.format("Job succeeded"), logFile, "UTF-8"); + this.closeApp(ListUtil.empty(), packageName); + if (unInstall) { + adbUtil.uninstall(packageName); + } + T.FileUtil.appendString(String.format("Job execution ends"), logFile, "UTF-8"); ACTIVE_TASKS.remove(this); } } + private void closeApp(List packageNameList, String packageName) { + if (CollUtil.isNotEmpty(packageNameList)){ + for (String name : packageNameList) { + adbUtil.stopApp(name); + } + } + adbUtil.stopApp(packageName); + } + @Override public void interrupt() { super.interrupt(); diff --git a/src/main/java/net/geedge/api/util/AdbCommandBuilder.java b/src/main/java/net/geedge/api/util/AdbCommandBuilder.java index e0b6b12..b93c8f7 100644 --- a/src/main/java/net/geedge/api/util/AdbCommandBuilder.java +++ b/src/main/java/net/geedge/api/util/AdbCommandBuilder.java @@ -111,6 +111,36 @@ public class AdbCommandBuilder { return this; } + public AdbCommandBuilder buildCheckPackage(String packageName) { + this.command.add("shell"); + this.command.add("pm"); + this.command.add("list"); + this.command.add("packages"); + this.command.add("-3"); + this.command.add(packageName); + return this; + } + + public AdbCommandBuilder buildFindPackageNameList() { + this.command.add("shell"); + this.command.add("pm"); + this.command.add("list"); + this.command.add("packages"); + this.command.add("-3"); + return this; + } + + public AdbCommandBuilder buildStartAPP(String packageName) { + this.command.add("shell"); + this.command.add("monkey"); + this.command.add("-p"); + this.command.add(packageName); + this.command.add("-c"); + this.command.add("android.intent.category.LAUNCHER"); + this.command.add("1"); + return this; + } + public AdbCommandBuilder buildMd5sumCommand(String path) { this.command.add("shell"); this.command.add("md5sum"); diff --git a/src/main/java/net/geedge/api/util/AdbUtil.java b/src/main/java/net/geedge/api/util/AdbUtil.java index 09e8692..fa2d651 100644 --- a/src/main/java/net/geedge/api/util/AdbUtil.java +++ b/src/main/java/net/geedge/api/util/AdbUtil.java @@ -845,6 +845,47 @@ public class AdbUtil { return new CommandResult(T.StrUtil.isNotEmpty(result) ? 1 : 0, result); } + + public boolean findPackageInstall(String packageName) { + String result = commandExec.exec(AdbCommandBuilder.builder() + .serial(this.getSerial()) + .buildCheckPackage(packageName) + .build() + ); + + return T.StrUtil.equals(result, packageName); + } + + + public List findPackageNameList() { + String result = commandExec.exec(AdbCommandBuilder.builder() + .serial(this.getSerial()) + .buildFindPackageNameList() + .build() + ); + List packageNameList = T.ListUtil.list(true); + + String prefix = "package:"; + String[] lines = result.split("\\n"); + for (String line : lines) { + String packageName = T.StrUtil.trim(line.substring(prefix.length())); + if (T.StrUtil.equals(DEFAULT_DROIDVNC_NG_PKG_NAME, packageName)) continue; + packageNameList.add(packageName); + } + return packageNameList; + } + + + public CommandResult startApp(String packageName) { + String result = commandExec.exec(AdbCommandBuilder.builder() + .serial(this.getSerial()) + .buildStartAPP(packageName) + .build() + ); + log.info("[startApp] [result: {}]", result); + return new CommandResult(T.StrUtil.isNotEmpty(result) ? 1 : 0, result); + } + private synchronized ExecutorService getThreadPool() { if (threadPool == null) { threadPool = new ThreadPoolExecutor(