From 28be3a4f12ef7ba69eaaf42aa39c4a3b7dcab533 Mon Sep 17 00:00:00 2001
From: "yineng.huang" <huangyineng_zxl@163.com>
Date: Fri, 7 Mar 2025 14:54:14 +0800
Subject: [PATCH] =?UTF-8?q?=E8=A6=86=E7=9B=96=E5=AE=89=E8=A3=85?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../se/debug/service/DefaultDebugSession.java |  8 +++
 .../device/bean/MobileDeviceConnection.java   | 68 ++++++++++++-------
 .../cctp/se/exec/DefaultExecThread.java       | 12 ++++
 .../handler/HarmonyAutomationHandler.java     | 56 +++++++++------
 .../handler/IosAutomationHandler.java         | 45 +++++++-----
 .../upperComputer/driver/harmony/hdc/Hdc.java |  2 +-
 .../android/AndroidDeviceHelper.java          | 18 +++++
 7 files changed, 144 insertions(+), 65 deletions(-)

diff --git a/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/debug/service/DefaultDebugSession.java b/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/debug/service/DefaultDebugSession.java
index 16a2667..7f3c42b 100644
--- a/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/debug/service/DefaultDebugSession.java
+++ b/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/debug/service/DefaultDebugSession.java
@@ -688,12 +688,20 @@ public class DefaultDebugSession implements DebugSession {
                 boolean isReInstall = Boolean.parseBoolean(target.get(MobileDeviceConnection.IS_REINSTALL));
                 boolean isCleanData = Boolean.parseBoolean(target.get(MobileDeviceConnection.IS_CLEAN_DATA));
                 boolean isAppRestart = Boolean.parseBoolean(target.get(MobileDeviceConnection.IS_APP_RESTART));
+                boolean isCoverInstall = Boolean.parseBoolean(target.get(MobileDeviceConnection.IS_COVER_INSTALL));
                 if (isReInstall) {  //卸载安装
                     initMap.put("appId", target.get("appId"));
                     initMap.put("appVersion", target.get("appVersion"));
                     initMap.put("forceReInstall", isReInstall);
                     initMap.put("forceCleanData", isCleanData);
                     initMap.put("type", "2");
+                } else if (isCoverInstall) {
+                    initMap.put("appId", target.get("appId"));
+                    initMap.put("appVersion", target.get("appVersion"));
+                    initMap.put("forceReInstall", false);
+                    initMap.put("coverInstall", isCoverInstall);
+                    initMap.put("forceCleanData", isCleanData);
+                    initMap.put("type", "2");
                 } else {
                     if (isCleanData && !isAppRestart) { //只清除数据
                         initMap.put("type", "1");
diff --git a/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/device/bean/MobileDeviceConnection.java b/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/device/bean/MobileDeviceConnection.java
index 7ca7f5d..e81b2e5 100644
--- a/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/device/bean/MobileDeviceConnection.java
+++ b/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/device/bean/MobileDeviceConnection.java
@@ -87,6 +87,7 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
     public static final String IS_REINSTALL = "forceReInstall";
     public static final String IS_CLEAN_DATA = "forceCleanData";
     public static final String IS_APP_RESTART = "restartApp";
+    public static final String IS_COVER_INSTALL = "coverInstall";
     public static final String IS_RECORD_DEVICE_PER = "debug";
 
     private DevicePerInfo devicePerInfo;
@@ -403,12 +404,17 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
         String deviceId = this.deviceInfo.getDeviceId();
         boolean reInstall = false;
         boolean cleanData = false;
+        boolean coverInstall = false;
         if (null != config.get("forceCleanData")) {
             cleanData = (boolean) config.get("forceCleanData");
         }
         if (null != config.get("forceReInstall")) {
             reInstall = (boolean) config.get("forceReInstall");
         }
+        if (null != config.get("coverInstall")) {
+            coverInstall = (boolean) config.get("coverInstall");
+        }
+        log.debug("覆盖安装:{}", coverInstall);
         String appId = (String) config.get("appId");
         if (appId == null) {
             throw new ExecuteException("无匹配该平台的应用,无法初始化");
@@ -427,40 +433,51 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
             pressHome();
         }
         try {
-            // 安装方式,重新安装的逻辑:1.清除应用的缓存和用户数据 2.安装应用(adb -s <deviceId> install -r|-d <app-path>)
             boolean appInstalled = isAppInstalled(appPackage);
-            if (reInstall || cleanData) {
+            log.debug("手机【{}】上app【{}】安装结果:{}", this.deviceInfo.getDeviceId(), appPackage, appInstalled);
+            boolean needInstall = !appInstalled;
+            if (reInstall) {
                 if (appInstalled) {
-                    log.info("Begin to clear data: app[{}] from device[{}]...", appPackage, deviceId);
-                    cleanData(deviceId, appPackage);
+                    log.info("开始从设备【{}】卸载app【{}】", this.deviceInfo.getDeviceId(), appPackage);
+                    removeApp(appPackage);
+                    log.info("从设备【{}】卸载app【{}】完成", this.deviceInfo.getDeviceId(), appPackage);
                 } else {
-                    log.info("App[{}] on device[{}] is not installed.", appPackage, deviceId);
+                    log.info("设备【{}】上未安装app【{}】", this.deviceInfo.getDeviceId(), appPackage);
+                }
+                needInstall = true;
+            } else if (coverInstall) {
+                if (appInstalled) {
+                    String oldPackageCode = AndroidUtil.getOldPackageCode(deviceInfo.getConnectAddress() + ":" + (null == deviceInfo.getPort() ? defaultUpperPort : deviceInfo.getPort()), deviceId, appPackage, this.deviceInfo.getPlatform());
+                    log.info("选择了覆盖安装,设备【{}】上安装app【{}】,版本:{}", this.deviceInfo.getDeviceId(), appPackage, oldPackageCode);
+                } else {
+                    log.info("设备【{}】上未安装app【{}】", this.deviceInfo.getDeviceId(), appPackage);
+                }
+                needInstall = true;
+            }
+            if (needInstall) {  //需要重新安装,直接安装,就无需管清除数据
+                boolean success = installApp(deviceId, appId, appName, appPackage);
+                if (!success) {
+                    log.error("安装应用失败");
+                    throw new ExecuteException("安装应用失败");
                 }
             }
-            if (!appInstalled) {
-                log.info("设备[{}]没有安装应用[{}],准备安装...", deviceId, appPackage);
-                installApp(deviceId, appId, appName, appPackage);
-            } else {
-                log.info("device[{}] already install app[{}]...", deviceId, appPackage);
-                // 设备已安装,查看版本
-                String oldPackageCode = AndroidUtil.getOldPackageCode(deviceInfo.getConnectAddress() + ":" + (null == deviceInfo.getPort() ? defaultUpperPort : deviceInfo.getPort()), deviceId, appPackage, this.deviceInfo.getPlatform());
-                log.info("install app version[{}],app in device version[{}]  ===========> rewrite", appVersion, oldPackageCode);
-                if (!appVersion.equalsIgnoreCase(oldPackageCode)) {
-                    installApp(deviceId, appId, appName, appPackage);
-                } else {
-                    log.info("App[{}] on device[{}] already exists ===========> active", appPackage, deviceId);
-                }
-                if (reInstall) {
-                    installApp(deviceId, appId, appName, appPackage);
-                    log.info("App[{}] on device[{}] already exists ===========> reInstall", appPackage, deviceId);
-                }
+            if (cleanData) {
+                log.debug("设备【{}】选择了清除数据,开始清除数据", this.deviceInfo.getDeviceId());
+                cleanData(deviceId, appPackage);
+                log.debug("设备【{}】清除数据完成", this.deviceInfo.getDeviceId());
             }
+            if (!isAppInstalled(appPackage)) {
+                log.error("安装应用失败");
+                throw new ExecuteException("安装应用失败");
+            }
+            // 安装方式,重新安装的逻辑:1.清除应用的缓存和用户数据 2.安装应用(adb -s <deviceId> install -r|-d <app-path>)
             long t3 = System.currentTimeMillis();
             log.debug("卸载安装应用全过程耗时:{}", (t3 - t2) / 1000);
             if (!isAppInstalled(appPackage)) {
                 log.error("设备【{}】安装应用【{}】失败", deviceId, appPackage);
                 throw new ExecuteException("安装应用失败");
             }
+            log.info("activate app[{}]", appPackage);
             activateApp(appPackage);
         } catch (Exception e) {
             log.error("应用初始化失败", e);
@@ -637,7 +654,7 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
      * @param appName
      * @param packageName
      */
-    private void installApp(String deviceId, String appId, String appName, String packageName) {
+    private boolean installApp(String deviceId, String appId, String appName, String packageName) {
         StopWatch watchAppInstall = null;
         if (isRecord) {
             watchAppInstall = new StopWatch();
@@ -673,8 +690,8 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
             log.warn("安装app时前停止。。。。。。。。。。");
             throw new ExecuteException("执行停止");
         }
+        boolean success = false;
         try {
-            boolean success = false;
             try {
                 success = PhoneUtil.installApp(this.remoteAddress, deviceId, appPath, deviceInfo.getPlatform());
                 long t3 = System.currentTimeMillis();
@@ -737,7 +754,8 @@ public class MobileDeviceConnection extends AbstractDeviceConnection {
                 devicePerInfo.getAppPerInfo().setAppInstallTime(time);
             }
         }
-        log.info("App[{}] on device[{}] installed successfully.", packageName, deviceId);
+        log.info("App[{}] on device[{}] installed finish,result-------------->{}.", packageName, deviceId,success);
+        return success;
     }
 
 
diff --git a/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/exec/DefaultExecThread.java b/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/exec/DefaultExecThread.java
index b73e54a..83454e9 100644
--- a/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/exec/DefaultExecThread.java
+++ b/cctp-atu/atu-engine/atu-script-engine/src/main/java/net/northking/cctp/se/exec/DefaultExecThread.java
@@ -686,6 +686,7 @@ public class DefaultExecThread implements AtuExecThread{
             }
             initData.put("forceCleanData",false);
             initData.put("forceReInstall",false);
+            initData.put("coverInstall", false);
             if(StringUtils.isNotBlank(task.getAppSet())){
                 //清楚数据
                 if("1".equalsIgnoreCase(task.getAppSet())){
@@ -700,6 +701,17 @@ public class DefaultExecThread implements AtuExecThread{
                     initData.put("forceReInstall",true);
                     initData.put("forceCleanData",true);
                 }
+                //覆盖安装
+                if("4".equalsIgnoreCase(task.getAppSet())){
+                    initData.put("forceReInstall",false);
+                    initData.put("coverInstall",true);
+                }
+                //覆盖安装+清除数据
+                if("5".equalsIgnoreCase(task.getAppSet())){
+                    initData.put("forceReInstall",false);
+                    initData.put("coverInstall",true);
+                    initData.put("forceCleanData",true);
+                }
             }
             log.debug("初始化app参数:-----> "+JsonUtils.toJson(initData));
             deviceConnection.initConfig(initData);
diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/automation/handler/HarmonyAutomationHandler.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/automation/handler/HarmonyAutomationHandler.java
index f4a9e01..4163cd8 100644
--- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/automation/handler/HarmonyAutomationHandler.java
+++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/automation/handler/HarmonyAutomationHandler.java
@@ -31,6 +31,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.xpath.*;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -85,12 +86,18 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
     @Override
     public void initApplication(CmdAutomationRequest request) {
         CmdAutomationResponse response = null;
+        Map<String, String> data = new HashMap<>();
         try {
             Map<String, Object> initData = request.getData();
             boolean reInstall = false;
             if (null != initData.get("forceReInstall")) {
                 reInstall = (boolean) initData.get("forceReInstall");
             }
+            boolean coverInstall = false;
+            if (null != initData.get("coverInstall")) {
+                coverInstall = (boolean) initData.get("coverInstall");
+            }
+            logger.debug("覆盖安装:{}",coverInstall);
             String appId = (String) initData.get("appId");
             Map<String, Object> appDetail = null;
             try {
@@ -108,31 +115,36 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
             String appPackage = (String) appDetail.get("packageName");
             String appVersion = (String) appDetail.get("buildVersion");
             String appName = appUrl.substring(appUrl.lastIndexOf("_") + 1);
-            if (reInstall) {
-                if (deviceHandleHelper.isAppInstalled(this.serial, appPackage)) {
-                    logger.info("Begin to uninstall app[{}] from device[{}]...", appPackage, this.serial);
-                    deviceHandleHelper.removeApp(this.serial, appPackage);
-                    logger.info("App[{}] from device[{}] uninstalled.", appPackage, this.serial);
+            boolean appInstalled = deviceHandleHelper.isAppInstalled(serial, appPackage);
+            logger.debug("手机[{}]上app[{}]安装的结果:{}",serial,appPackage,appInstalled);
+            boolean needInstall = !appInstalled;
+            if (reInstall) {  //选择了卸载安装
+                if (appInstalled) {
+                    logger.info("开始从设备【{}】卸载 app[{}] ...", serial, appPackage);
+                    deviceHandleHelper.removeApp(serial, appPackage);
+                    logger.info("从设备【{}】上卸载App[{}] 完成", serial, appPackage);
                 } else {
-                    logger.info("App[{}] on device[{}] is not installed.", appPackage, this.serial);
+                    logger.info("设备【{}】上App[{}]未安装,无需卸载", serial, appPackage);
+                }
+                needInstall = true;
+            }else if (coverInstall) { //覆盖安装
+                if (appInstalled) {
+                    String oldPackageCode = deviceHandleHelper.getOldPackageCode(serial, appPackage);
+                    logger.debug("选择了覆盖安装,设备【{}】上app【{}】的版本是:{}", serial, appPackage, oldPackageCode);
+                } else {
+                    logger.info("设备【{}】上App[{}]未安装", serial, appPackage);
+                }
+                needInstall = true;
+            }
+            if(needInstall) {
+                boolean installSuccess = installApp(appId, appName);
+                if (!installSuccess) {
+                    response = CmdAutomationResponse.builderFailure(request, "app安装失败").withData(data);
+                    return;
                 }
             }
-            if (!deviceHandleHelper.isAppInstalled(this.serial, appPackage)) {
-                installApp(appId, appName);
-            } else {
-                logger.info("device[{}] already install app[{}]...", this.serial, appPackage);
-                String oldPackageCode = deviceHandleHelper.getOldPackageCode(this.serial, appPackage);
-                if (!appVersion.equalsIgnoreCase(oldPackageCode)) {
-                    logger.info("install app version[{}],app in device version[{}]  ===========> reInstall", appVersion, oldPackageCode);
-                    deviceHandleHelper.removeApp(this.serial, appPackage);
-                    logger.info("app version[{}] remove from device[{}] successfully", appVersion, this.serial);
-                    installApp(appId, appName);
-                } else {
-                    logger.info("App[{}] on device[{}] already exists ===========> terminate", appPackage, this.serial);
-                }
-            }
-            if (!deviceHandleHelper.isAppInstalled(this.serial, appPackage)) {
-                response = CmdAutomationResponse.builderFailure(request, "app安装失败");
+            if (!deviceHandleHelper.isAppInstalled(serial, appPackage)) {
+                response = CmdAutomationResponse.builderFailure(request, "app安装失败").withData(data);
                 return;
             }
             logger.info("activate app[{}]", appPackage);
diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/automation/handler/IosAutomationHandler.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/automation/handler/IosAutomationHandler.java
index 2c878f7..fcfe44b 100644
--- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/automation/handler/IosAutomationHandler.java
+++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/automation/handler/IosAutomationHandler.java
@@ -102,12 +102,18 @@ public class IosAutomationHandler extends AbstractAutomationHandler {
     @Override
     public void initApplication(CmdAutomationRequest request) {
         CmdAutomationResponse response = null;
+        Map<String, String> data = new HashMap<>();
         try {
             Map<String, Object> initData = request.getData();
             boolean reInstall = false;
             if (null != initData.get("forceReInstall")) {
                 reInstall = (boolean) initData.get("forceReInstall");
             }
+            boolean coverInstall = false;
+            if (null != initData.get("coverInstall")) {
+                coverInstall = (boolean) initData.get("coverInstall");
+            }
+            logger.debug("覆盖安装:{}",coverInstall);
             String appId = (String) initData.get("appId");
             Map<String, Object> appDetail = null;
             try {
@@ -125,27 +131,32 @@ public class IosAutomationHandler extends AbstractAutomationHandler {
             String appPackage = (String) appDetail.get("packageName");
             String appVersion = (String) appDetail.get("buildVersion");
             String appName = appUrl.substring(appUrl.lastIndexOf("_") + 1);
-            if (reInstall) {
-                if (deviceHandleHelper.isAppInstalled(phoneEntity.getUdid(), appPackage)) {
-                    logger.info("Begin to uninstall app[{}] from device[{}]...", appPackage, phoneEntity.getUdid());
+            boolean appInstalled = deviceHandleHelper.isAppInstalled(phoneEntity.getUdid(), appPackage);
+            logger.debug("手机[{}]上app[{}]安装的结果:{}",serial,appPackage,appInstalled);
+            boolean needInstall = !appInstalled;
+            if (reInstall) {  //选择了卸载安装
+                if (appInstalled) {
+                    logger.info("开始从设备【{}】卸载 app[{}] ...", phoneEntity.getUdid(), appPackage);
                     deviceHandleHelper.removeApp(phoneEntity.getUdid(), appPackage);
-                    logger.info("App[{}] from device[{}] uninstalled.", appPackage, phoneEntity.getUdid());
+                    logger.info("从设备【{}】上卸载App[{}] 完成", phoneEntity.getUdid(), appPackage);
                 } else {
-                    logger.info("App[{}] on device[{}] is not installed.", appPackage, phoneEntity.getUdid());
+                    logger.info("设备【{}】上App[{}]未安装,无需卸载", phoneEntity.getUdid(), appPackage);
                 }
-            }
-            if (!deviceHandleHelper.isAppInstalled(phoneEntity.getUdid(), appPackage)) {
-                installApp(appId, appName);
-            } else {
-                logger.info("device[{}] already install app[{}]...", phoneEntity.getUdid(), appPackage);
-                String oldPackageCode = deviceHandleHelper.getOldPackageCode(phoneEntity.getUdid(), appPackage);
-                if (!appVersion.equalsIgnoreCase(oldPackageCode)) {
-                    logger.info("install app version[{}],app in device version[{}]  ===========> reInstall", appVersion, oldPackageCode);
-                    deviceHandleHelper.removeApp(phoneEntity.getUdid(), appPackage);
-                    logger.info("app version[{}] remove from device[{}] successfully", appVersion, phoneEntity.getUdid());
-                    installApp(appId, appName);
+                needInstall = true;
+            }else if (coverInstall) { //覆盖安装
+                if (appInstalled) {
+                    String oldPackageCode = deviceHandleHelper.getOldPackageCode(phoneEntity.getUdid(), appPackage);
+                    logger.debug("选择了覆盖安装,设备【{}】上app【{}】的版本是:{}", serial, appPackage, oldPackageCode);
                 } else {
-                    logger.info("App[{}] on device[{}] already exists ===========> terminate", appPackage, phoneEntity.getUdid());
+                    logger.info("设备【{}】上App[{}]未安装", phoneEntity.getUdid(), appPackage);
+                }
+                needInstall = true;
+            }
+            if(needInstall) {
+                boolean installSuccess = installApp(appId, appName);
+                if (!installSuccess) {
+                    response = CmdAutomationResponse.builderFailure(request, "app安装失败").withData(data);
+                    return;
                 }
             }
             if (!deviceHandleHelper.isAppInstalled(phoneEntity.getUdid(), appPackage)) {
diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/harmony/hdc/Hdc.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/harmony/hdc/Hdc.java
index 39dc086..d7da635 100644
--- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/harmony/hdc/Hdc.java
+++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/harmony/hdc/Hdc.java
@@ -347,7 +347,7 @@ public class Hdc {
             reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
             String line;
             while ((line = reader.readLine()) != null) {
-                if (line.startsWith("[Fail]")) {
+                if (line.startsWith("[Fail]")||line.contains("failed")) {
                     log.error("设备{}安装HAP文件失败:{}", hdcDevice.getConnectKey(), line);
                     return false;
                 }
diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/utils/deviceHepler/android/AndroidDeviceHelper.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/utils/deviceHepler/android/AndroidDeviceHelper.java
index e82dbfe..8df596f 100644
--- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/utils/deviceHepler/android/AndroidDeviceHelper.java
+++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/utils/deviceHepler/android/AndroidDeviceHelper.java
@@ -126,6 +126,24 @@ public class AndroidDeviceHelper extends AbstractDeviceHelper {
 
     @Override
     public boolean installApp(String deviceId, String appPath) {
+        logger.debug("收到设备【{}】安装应用【{}】的请求",deviceId,appPath);
+        String[] installAppCmd = {"adb", "-s", deviceId, "install", appPath};
+        try {
+            Process process = new ProcessBuilder(installAppCmd).redirectErrorStream(true).start();
+            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            String line = null;
+            StringBuilder stringBuilder = new StringBuilder();
+            while (null != (line = in.readLine())) {
+                logger.debug("设备[{}]安装app[{}]打印:{}",deviceId,appPath,line);
+                stringBuilder.append(line);
+            }
+            String result = stringBuilder.toString();
+            if (result.contains("Success")) {
+                return true;
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
         return false;
     }