From fe7f1cda9ee8e6ffa5955c19a6bc4bb8a7af6d97 Mon Sep 17 00:00:00 2001
From: "yineng.huang" <huangyineng_zxl@163.com>
Date: Fri, 27 Sep 2024 10:17:25 +0800
Subject: [PATCH] =?UTF-8?q?=E6=88=AA=E5=9B=BE=E6=94=B9=E4=B8=BAwda?=
 =?UTF-8?q?=E6=88=AA=E5=9B=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../upperComputer/driver/ios/NKAgent.java     |  27 +++++
 .../ios/command/data/ScreenShotData.java      |  27 +++++
 .../service/IosDebuggerServiceImpl.java       |   2 +-
 .../utils/ios/MacIosHandleHelper.java         | 110 ++++++++++++------
 4 files changed, 131 insertions(+), 35 deletions(-)
 create mode 100644 cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/command/data/ScreenShotData.java

diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/NKAgent.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/NKAgent.java
index daaed50..051faa6 100644
--- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/NKAgent.java
+++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/NKAgent.java
@@ -250,6 +250,33 @@ public final class NKAgent {
         return bool.isSuccess();
     }
 
+    /**
+     * 启动app
+     * @param string bundleId
+     * @return 是否设置成功
+     */
+    public boolean launchApp(String string) {
+        if (string.isEmpty()) {
+            throw new IllegalArgumentException("bundleId不能为空");
+        }
+        TextData data = new TextData();
+        data.setText(string);
+        ICommandPacket packet = packetTransfer.syncSend(32, data);
+        if (packet == null) return false;
+        BooleanCommandData bool = new BooleanCommandData();
+        packet.fillICommandData(bool);
+        return bool.isSuccess();
+    }
+
+    public ScreenShotData screenShot() {
+        ICommandPacket packet = packetTransfer.syncSend(33);
+        if (packet == null) return null;
+        ScreenShotData screenShotData = new ScreenShotData();
+        packet.fillICommandData(screenShotData);
+        return screenShotData;
+    }
+
+
 
     public boolean getStatus() {
         return this.packetTransfer.isConnected();
diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/command/data/ScreenShotData.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/command/data/ScreenShotData.java
new file mode 100644
index 0000000..1e33052
--- /dev/null
+++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/command/data/ScreenShotData.java
@@ -0,0 +1,27 @@
+package net.northking.cctp.upperComputer.driver.ios.command.data;
+
+
+import net.northking.cctp.upperComputer.driver.ios.packet.ICommandData;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class ScreenShotData implements ICommandData {
+    public int dataLength;
+
+    public byte[] data;
+
+    @Override
+    public void buildFromInput(DataInput dataInput) throws IOException {
+        dataLength = dataInput.readInt();
+        data = new byte[dataLength];
+        dataInput.readFully(data);
+    }
+
+    @Override
+    public void encodeToOutput(DataOutput dataOutput) throws IOException {
+        dataOutput.writeInt(dataLength);
+        dataOutput.write(data);
+    }
+}
diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/service/IosDebuggerServiceImpl.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/service/IosDebuggerServiceImpl.java
index 3f7be98..151236e 100644
--- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/service/IosDebuggerServiceImpl.java
+++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/service/IosDebuggerServiceImpl.java
@@ -344,7 +344,7 @@ public class IosDebuggerServiceImpl extends AbstractDebuggerService {
                     stringBuilder.append(line);
                 }
                 String result = stringBuilder.toString();
-                if (result.trim().startsWith("Kill pid:")) {
+                if (result.trim().startsWith("Kill pid:") || result.trim().contains("No app killed")) {
                     logger.debug("手机【{}】应用【{}】已关闭,关闭消息:{}", deviceId, appPackage, result);
                     return true;
                 } else {
diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/utils/ios/MacIosHandleHelper.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/utils/ios/MacIosHandleHelper.java
index b755738..b87f133 100644
--- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/utils/ios/MacIosHandleHelper.java
+++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/utils/ios/MacIosHandleHelper.java
@@ -2,14 +2,21 @@ package net.northking.cctp.upperComputer.utils.ios;
 
 import com.alibaba.fastjson.JSON;
 import net.northking.cctp.upperComputer.deviceManager.IOSDeviceManager;
+import net.northking.cctp.upperComputer.deviceManager.UpperComputerManager;
 import net.northking.cctp.upperComputer.deviceManager.common.PyMobileDevice;
 import net.northking.cctp.upperComputer.deviceManager.entity.AppleApplicationInfo;
+import net.northking.cctp.upperComputer.deviceManager.thread.IosDeviceInitThread;
+import net.northking.cctp.upperComputer.driver.ios.NKAgent;
+import net.northking.cctp.upperComputer.driver.ios.command.data.ScreenShotData;
 import net.northking.cctp.upperComputer.exception.ExecuteException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.HashMap;
+import java.util.UUID;
 
 /**
  * @author : yineng.huang
@@ -24,13 +31,13 @@ public class MacIosHandleHelper extends IosDeviceHandleHelper {
         PyMobileDevice.SpecificAppleDeviceInfo specificAppleDeviceInfo = IOSDeviceManager.getInstance().getSpecificAppleDeviceInfo(deviceId);
         HashMap<String, AppleApplicationInfo> appMap = PyMobileDevice.getInstance().listApp(specificAppleDeviceInfo, false, true);
         if (null == appMap) {
-            logger.warn("没有在设备【{}】上找到app【{}】信息",deviceId,appPackage);
+            logger.warn("没有在设备【{}】上找到app【{}】信息", deviceId, appPackage);
             return false;
         }
         boolean contain = appMap.containsKey(appPackage);
         if (contain) {
             AppleApplicationInfo appleApplicationInfo = appMap.get(appPackage);
-            logger.debug("设备【{}】上的app信息:{}",deviceId,JSON.toJSONString(appleApplicationInfo));
+            logger.debug("设备【{}】上的app信息:{}", deviceId, JSON.toJSONString(appleApplicationInfo));
             return true;
         }
         return false;
@@ -40,7 +47,7 @@ public class MacIosHandleHelper extends IosDeviceHandleHelper {
     public boolean removeApp(String deviceId, String appPackage) {
         PyMobileDevice.SpecificAppleDeviceInfo specificAppleDeviceInfo = IOSDeviceManager.getInstance().getSpecificAppleDeviceInfo(deviceId);
         boolean success = PyMobileDevice.getInstance().uninstallApp(specificAppleDeviceInfo, appPackage, null);
-        logger.debug("设备【{}】卸载app【{}】的结果:{}",deviceId,appPackage,success);
+        logger.debug("设备【{}】卸载app【{}】的结果:{}", deviceId, appPackage, success);
         return success;
     }
 
@@ -49,16 +56,16 @@ public class MacIosHandleHelper extends IosDeviceHandleHelper {
         PyMobileDevice.SpecificAppleDeviceInfo specificAppleDeviceInfo = IOSDeviceManager.getInstance().getSpecificAppleDeviceInfo(deviceId);
         HashMap<String, AppleApplicationInfo> appMap = PyMobileDevice.getInstance().listApp(specificAppleDeviceInfo, false, true);
         if (null == appMap) {
-            logger.warn("没有在设备【{}】上找到app【{}】信息",deviceId,appPackage);
+            logger.warn("没有在设备【{}】上找到app【{}】信息", deviceId, appPackage);
             return null;
         }
         boolean contain = appMap.containsKey(appPackage);
         if (contain) {
             AppleApplicationInfo appleApplicationInfo = appMap.get(appPackage);
-            logger.debug("设备【{}】上的app信息:{}",deviceId,JSON.toJSONString(appleApplicationInfo));
+            logger.debug("设备【{}】上的app信息:{}", deviceId, JSON.toJSONString(appleApplicationInfo));
             return appleApplicationInfo.getCFBundleShortVersionString();
         } else {
-            logger.warn("没有在设备【{}】上找到app【{}】信息",deviceId,appPackage);
+            logger.warn("没有在设备【{}】上找到app【{}】信息", deviceId, appPackage);
         }
         return null;
     }
@@ -67,48 +74,83 @@ public class MacIosHandleHelper extends IosDeviceHandleHelper {
     public boolean installApp(String deviceId, String appPath) {
         PyMobileDevice.SpecificAppleDeviceInfo specificAppleDeviceInfo = IOSDeviceManager.getInstance().getSpecificAppleDeviceInfo(deviceId);
         boolean success = PyMobileDevice.getInstance().installApp(specificAppleDeviceInfo, appPath, null);
-        logger.debug("设备【{}】安装app【{}】的结果:{}",deviceId,appPath,success);
+        logger.debug("设备【{}】安装app【{}】的结果:{}", deviceId, appPath, success);
         return success;
     }
 
     @Override
     public boolean activateApp(String deviceId, String appPackage) {
         PyMobileDevice.SpecificAppleDeviceInfo specificAppleDeviceInfo = IOSDeviceManager.getInstance().getSpecificAppleDeviceInfo(deviceId);
-        boolean success = PyMobileDevice.getInstance().launchApp(specificAppleDeviceInfo,appPackage);
-        logger.debug("设备【{}】启动app【{}】的结果:{}",deviceId,appPackage,success);
+        boolean success = PyMobileDevice.getInstance().launchApp(specificAppleDeviceInfo, appPackage);
+        logger.debug("设备【{}】启动app【{}】的结果:{}", deviceId, appPackage, success);
         return success;
     }
 
     @Override
     public File getScreenShotFile(String deviceId, Integer startX, Integer startY, Integer cutWidth, Integer cutHeight, Integer screenWidth, Integer screenHeight) {
-        PyMobileDevice.SpecificAppleDeviceInfo specificAppleDeviceInfo = IOSDeviceManager.getInstance().getSpecificAppleDeviceInfo(deviceId);
-        File file = null;
-        File screenShotFile = null;
-        try {
-            screenShotFile = PyMobileDevice.getInstance().takeScreenshotSaveAsFile(specificAppleDeviceInfo,System.getProperty("user.dir") + "/tempPic");
-            if (screenShotFile == null) {
-                logger.error("设备【{}】未截出来图...............", deviceId);
-                throw new ExecuteException(String.format("设备【%s】截图失败", deviceId));
-            } else {
-                logger.debug("设备【{}】截图的结果:{}",deviceId,screenShotFile.getAbsolutePath());
-            }
-            if (null != startX || null != startY) {
-                if (cutWidth <= 0 || cutHeight <= 0) {
-                    throw new ExecuteException("截取图片的宽高不满足要求");
+        if (cutWidth <= 0 || cutHeight <= 0) {
+            throw new ExecuteException("截取图片的宽高不满足要求");
+        }
+        int screenShotTime = 1;
+        while (screenShotTime <= 3) {
+            logger.debug("设备【{}】第{}次截图开始.................", deviceId, screenShotTime);
+            NKAgent nkAgent = getNkAgent(deviceId);
+            ScreenShotData screenShotData = nkAgent.screenShot();
+            logger.debug("设备【{}】第{}次截图的大小:{}", deviceId, screenShotTime, screenShotData.dataLength);
+            if (screenShotData.dataLength > 0) {
+                File file = null;
+                File screenShotFile = null;
+                FileOutputStream fileOutputStream = null;
+                try {
+                    File picDir = new File(UpperComputerManager.getInstance().getApplicationPath() + "/tempPic");
+                    if (!picDir.exists()) {
+                        picDir.mkdirs();
+                    }
+                    screenShotFile = new File(picDir.getAbsolutePath() + "/" + UUID.randomUUID() + ".jpg");
+                    fileOutputStream = new FileOutputStream(screenShotFile);
+                    fileOutputStream.write(screenShotData.data);
+                    fileOutputStream.flush();
+                    logger.debug("设备【】第{}次截图在磁盘的位置为:{}", deviceId, screenShotTime, screenShotFile.getAbsolutePath());
+                    file = cutImageFile(screenShotFile, deviceId, startX, startY, cutWidth, cutHeight, screenWidth, screenHeight);
+                    logger.debug("截取出来的图像为:{}", file.getAbsolutePath());
+                    return file;
+                } catch (IOException e) {
+                    logger.error("截图写入磁盘失败", e);
+                } finally {
+                    if (null != fileOutputStream) {
+                        try {
+                            fileOutputStream.close();
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                    if (null != screenShotFile) {
+                        //删除
+                    }
+                    if (null != file) {
+                        //删除
+                    }
                 }
-                file = cutImageFile(screenShotFile, deviceId, startX, startY, cutWidth, cutHeight, screenWidth, screenHeight);
-                logger.debug("截取出来的图像为:{}", file.getAbsolutePath());
-            } else {
-                file = screenShotFile;
             }
-        } finally {
-            if (null != screenShotFile) {
-                //删除
-            }
-            if (null != file) {
-                //删除
+            screenShotTime++;
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
             }
         }
-        return file;
+        throw new ExecuteException("设备截图失败");
+    }
+
+    private NKAgent getNkAgent(String deviceId) {
+        IosDeviceInitThread iosInitThread = IOSDeviceManager.getInstance().getIosInitThread(deviceId);
+        if (null == iosInitThread || !iosInitThread.isAlive() || iosInitThread.isInterrupted()) {
+            throw new ExecuteException("设备已经掉线,请重新接入设备");
+        }
+        NKAgent nkAgent = iosInitThread.getNkAgent();
+        if (!nkAgent.getStatus()) {
+            throw new ExecuteException("设备Agent还未准备好,稍后再试");
+        }
+        return nkAgent;
     }
 }