From e5d1e6e68b0f3b9e5214b2675f171f919553941e Mon Sep 17 00:00:00 2001 From: "yineng.huang" Date: Mon, 4 Nov 2024 19:35:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=88=AA=E5=9B=BE=E4=BD=BF=E7=94=A8session,wda?= =?UTF-8?q?=E6=8C=82=E4=BA=86=E4=B9=8B=E5=90=8E=E9=87=8D=E5=BB=BAnkAgent?= =?UTF-8?q?=E5=8D=A1=E6=AD=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thread/IosDeviceInitThread.java | 55 ++++++++------ .../thread/MacIosDeviceInitThread.java | 44 +++++------ .../WindowsAndLinuxIosDeviceInitThread.java | 16 ++-- .../driver/ios/packet/PacketTransfer.java | 3 +- .../service/AndroidDebuggerServiceImpl.java | 73 +++++++++++++------ 5 files changed, 112 insertions(+), 79 deletions(-) diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/IosDeviceInitThread.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/IosDeviceInitThread.java index e4b0be4..4ae85d0 100644 --- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/IosDeviceInitThread.java +++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/IosDeviceInitThread.java @@ -27,6 +27,14 @@ public abstract class IosDeviceInitThread extends Thread { protected AppleDevice appleDevice; + /** + * wda进程信息 + */ + protected Process process; + + protected boolean isFBServerReady = false; + + private int frame = 12; public IosDeviceInitThread(PhoneEntity phone, AppleDevice appleDevice) { @@ -36,24 +44,25 @@ public abstract class IosDeviceInitThread extends Thread { } - protected void createNKAgent() { + protected synchronized void createNKAgent(String tag) { + logger.debug("createNKAgent:{}",tag); nkAgent = new NKAgent(this.appleDevice); + nkAgent.setOnDisconnectListener(() -> { + if(!isFBServerReady) return; + logger.warn("设备【{}】的nkAgent失效了,需要重新创建...........", phone.getUdid()); + createNKAgent("回调重试"); + logger.warn("设备【{}】的nkAgent重新创建完成...........", phone.getUdid()); + }); boolean nkAgentReady = false; int reTryTime = 1; - do { + while (!nkAgentReady && reTryTime <= 5 && isFBServerReady) { logger.debug("尝试第{}次连接设备【{}】的nkAgent", reTryTime, phone.getUdid()); try { nkAgent.connect(); nkAgentReady = nkAgent.getStatus(); - logger.debug("设备【{}】的nkAgent连接完成,结果:{}", phone.getUdid(),nkAgentReady); - if (nkAgentReady) { - logger.debug("设置设备【{}】的帧数为:{}", phone.getUdid(), frame); - nkAgent.setMJPEGServerRate(frame); - } else { - logger.error("第{}次连接设备【{}】的agent不成功,等待下一次......",reTryTime, phone.getUdid()); - } + logger.debug("设备【{}】的nkAgent连接完成,结果:{}", phone.getUdid(), nkAgentReady); } catch (IOException e) { - logger.error("第{}次连接设备【{}】的agent出错",reTryTime, phone.getUdid(), e); + logger.error("第{}次连接设备【{}】的agent出错", reTryTime, phone.getUdid(), e); try { Thread.sleep(3000); } catch (InterruptedException ex) { @@ -61,25 +70,23 @@ public abstract class IosDeviceInitThread extends Thread { } } reTryTime++; - } while (!nkAgentReady && reTryTime <= 5); - if (!nkAgentReady) { - throw new ExecuteException(String.format("无法创建设备【%s】nkAgent", phone.getUdid())); } - logger.debug("设置设备【{}】的nkAgent掉线之后的监听器................", phone.getUdid()); - nkAgent.setOnDisconnectListener(() -> { - synchronized (nkAgent) { - if (!nkAgent.getStatus()) { - logger.warn("设备【{}】的nkAgent失效了,需要重新创建...........", phone.getUdid()); - IOSDeviceManager.getInstance().getIosInitThread(phone.getUdid()).createNKAgent(); - logger.warn("设备【{}】的nkAgent重新创建完成...........", phone.getUdid()); - } else { - logger.warn("设备【{}】的nkAgent失效了,但是已经创建好了,不再创建了...........", phone.getUdid()); - } + if (!nkAgentReady) { + nkAgent.setOnDisconnectListener(null); + nkAgent = null; + if (null != process) { + process.destroy(); } - }); + isFBServerReady = false; + throw new ExecuteException(String.format("无法创建设备【%s】nkAgent", phone.getUdid())); + }else{ + logger.debug("设置设备【{}】的帧数为:{}", phone.getUdid(), frame); + nkAgent.setMJPEGServerRate(frame); + } logger.debug("设备【{}】的nkAgent连接完毕................", phone.getUdid()); } + public NKAgent getNkAgent() { return nkAgent; } diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/MacIosDeviceInitThread.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/MacIosDeviceInitThread.java index a68715f..a37d9c3 100644 --- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/MacIosDeviceInitThread.java +++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/MacIosDeviceInitThread.java @@ -12,6 +12,7 @@ import net.northking.cctp.upperComputer.driver.ios.NKAgent; import net.northking.cctp.upperComputer.driver.ios.command.data.ScreenInfoData; import net.northking.cctp.upperComputer.driver.usbmuxd.AppleDevice; import net.northking.cctp.upperComputer.entity.PhoneEntity; +import net.northking.cctp.upperComputer.exception.ExecuteException; import net.northking.cctp.upperComputer.utils.SpringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,11 +32,6 @@ public class MacIosDeviceInitThread extends IosDeviceInitThread { */ public static final int IOS_CORE_DEVICE_VERSION = 17; - /** - * xcodebuild进程信息 - */ - private Process process = null; - /** * xcodebuild的退出码 */ @@ -47,10 +43,6 @@ public class MacIosDeviceInitThread extends IosDeviceInitThread { private OutputLineCallback outputLineCallback; - private boolean isFBServerReady = false; - - private final Object waitFbServerReadyLock = new Object(); - public MacIosDeviceInitThread(PhoneEntity phoneEntity, AppleDevice device) { super(phoneEntity, device); init(); @@ -112,18 +104,20 @@ public class MacIosDeviceInitThread extends IosDeviceInitThread { if (wdaConfig.isPrintWdaOutput()) { logger.debug("WDA-" + appleDevice.getConnectionDetail().serialNumber + "->" + line); } + logOutput.write(line.getBytes()); + logOutput.write(10); if (!isFBServerReady && line.contains("ServerURLHere")) { + logger.debug("发现WDA启动完成信号"); isFBServerReady = true; - synchronized (waitFbServerReadyLock) { - waitFbServerReadyLock.notifyAll(); + try { + createNKAgent("WDA启动"); + } catch (ExecuteException e) { + logger.error("WDA启动后创建NKAgent失败", e); + process.destroy(); + break; } - createNKAgent(); apiPortReady(); } - if (logOutput != null) { - logOutput.write(line.getBytes()); - logOutput.write(10); - } if (outputLineCallback != null) { try { outputLineCallback.onLine(line); @@ -134,7 +128,7 @@ public class MacIosDeviceInitThread extends IosDeviceInitThread { } } catch (IOException e) { logger.warn("读取WDA输出时发生IO异常,设备" + appleDevice.getConnectionDetail().serialNumber, e); - }finally { + } finally { if (null != inputStreamReader) { try { inputStreamReader.close(); @@ -150,20 +144,22 @@ public class MacIosDeviceInitThread extends IosDeviceInitThread { } } } + isFBServerReady = false; + if (nkAgent != null) { + nkAgent.setOnDisconnectListener(null); + } try { exitCode = process.waitFor(); } catch (InterruptedException ignored) { break; } - if (logOutput != null) { - try { - logOutput.close(); - } catch (IOException e) { - logger.warn("关闭WDA独立日志流时发生IO异常,路径:{}", logFileName, e); - } + try { + logOutput.close(); + } catch (IOException e) { + logger.warn("关闭WDA独立日志流时发生IO异常,路径:{}", logFileName, e); } + IOSDeviceManager.getInstance().publishDeviceAgentDead(phone.getUdid()); logger.debug("设备【{}】的wda退出了,重启一次......................", appleDevice.getConnectionDetail().serialNumber); - isFBServerReady = false; } logger.debug("设备【{}】的wda退出了,不在重启了......................", appleDevice.getConnectionDetail().serialNumber); } diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/WindowsAndLinuxIosDeviceInitThread.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/WindowsAndLinuxIosDeviceInitThread.java index d172171..77c8d58 100644 --- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/WindowsAndLinuxIosDeviceInitThread.java +++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/deviceManager/thread/WindowsAndLinuxIosDeviceInitThread.java @@ -35,8 +35,6 @@ public class WindowsAndLinuxIosDeviceInitThread extends IosDeviceInitThread { super(phone,device); } - private Process wdaProcess; - @Override public void run() { logger.debug("不是mac作为上位机,用tidevice启动wda"); @@ -91,13 +89,12 @@ public class WindowsAndLinuxIosDeviceInitThread extends IosDeviceInitThread { FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(wdaLogFile); - this.wdaProcess = processBuilder.start(); + this.process = processBuilder.start(); if (UpperComputerManager.getInstance().getOperatingSystem().startsWith("Windows")) { - input = new LineNumberReader(new InputStreamReader(this.wdaProcess.getInputStream(),"GBK")); + input = new LineNumberReader(new InputStreamReader(this.process.getInputStream(),"GBK")); } else if (UpperComputerManager.getInstance().getOperatingSystem().startsWith("Linux")) { - input = new LineNumberReader(new InputStreamReader(this.wdaProcess.getInputStream(),"UTF-8")); + input = new LineNumberReader(new InputStreamReader(this.process.getInputStream(),"UTF-8")); } - input = new LineNumberReader(new InputStreamReader(this.wdaProcess.getInputStream())); String line = null; while (null != (line = input.readLine())) { if (line.contains("NKLog:")) { @@ -106,7 +103,8 @@ public class WindowsAndLinuxIosDeviceInitThread extends IosDeviceInitThread { } if (line.contains(SUCCESS_FLAG)) { logger.info("设备【{}】的wda程序启动成功,开启nkAgent。。。。。。。。。", phone.getUdid()); - createNKAgent(); + isFBServerReady = true; + createNKAgent("非macOS启动wda第一创建NKAgent"); logger.info("设备【{}】即将启动8100端口代理。。。。。。。。。", phone.getUdid()); apiProxyThread = new Device8100WatchThread(phone); apiProxyThread.start(); @@ -125,7 +123,7 @@ public class WindowsAndLinuxIosDeviceInitThread extends IosDeviceInitThread { } int code = 0; try { - code = this.wdaProcess.waitFor(); + code = this.process.waitFor(); } catch (InterruptedException e) { logger.warn("wda线程中断了。。。。"); interrupt(); @@ -254,7 +252,7 @@ public class WindowsAndLinuxIosDeviceInitThread extends IosDeviceInitThread { } public void exitWdaAndProxy() { - this.wdaProcess.destroyForcibly(); + this.process.destroy(); interrupt(); } diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/packet/PacketTransfer.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/packet/PacketTransfer.java index acdafc3..d0b2e1a 100644 --- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/packet/PacketTransfer.java +++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/driver/ios/packet/PacketTransfer.java @@ -201,7 +201,8 @@ public class PacketTransfer { return connected; } - private void onDisconnected() { + private synchronized void onDisconnected() { + if (!connected) return; connected = false; sendHandler.stop(); receiveHandler.stop(); diff --git a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/service/AndroidDebuggerServiceImpl.java b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/service/AndroidDebuggerServiceImpl.java index ca88deb..23a612b 100644 --- a/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/service/AndroidDebuggerServiceImpl.java +++ b/cctp-atu/atu-upper-computer/src/main/java/net/northking/cctp/upperComputer/service/AndroidDebuggerServiceImpl.java @@ -50,7 +50,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.*; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.*; import static io.appium.java_client.remote.AndroidMobileCapabilityType.RESET_KEYBOARD; import static io.appium.java_client.remote.AndroidMobileCapabilityType.UNICODE_KEYBOARD; @@ -74,6 +74,10 @@ public class AndroidDebuggerServiceImpl extends AbstractDebuggerService { private ConcurrentHashMap screenShotAgentMap = new ConcurrentHashMap<>(); + private ConcurrentHashMap screenShotAgentSessionMap = new ConcurrentHashMap<>(); + + private ExecutorService service = Executors.newFixedThreadPool(10); + private Adb adb; @Autowired @@ -1018,30 +1022,57 @@ public class AndroidDebuggerServiceImpl extends AbstractDebuggerService { private File getScreenShotInCommand(String deviceId) { File tmpPicFile = null; - try { - AndroidAgent androidAgent = screenShotAgentMap.get(deviceId); - if (null == androidAgent) { - AdbDevice currentDevice = null; - ArrayList adbDevices = adb.listDevices(); - if (!CollectionUtils.isEmpty(adbDevices)) { - for (AdbDevice adbDevice : adbDevices) { - if (deviceId.equals(adbDevice.getSerial())) { - currentDevice = adbDevice; - break; + byte[] screenShotData = null; + Future submit = service.submit(new Callable() { + @Override + public byte[] call() throws Exception { + AndroidAgentSession agentSession = screenShotAgentSessionMap.get(deviceId); + if (null == agentSession || !agentSession.isState()) { + AdbDevice currentDevice = AndroidDeviceManager.getInstance().getCurrentDevice(deviceId); + if (null == currentDevice) { + throw new ExecuteException("当前设备不在线"); + } + agentSession = new AndroidAgentSession(currentDevice, false); + agentSession.start(); + screenShotAgentSessionMap.put(deviceId, agentSession); + } else { + String send = agentSession.send(new EchoCommand("hello")); //检查 + if (!"hello".equals(send)) { + logger.warn("设备【{}】当前使用的截图的session失效了,重新创建一个。。。。。", deviceId); + agentSession.closeSilence(); + AdbDevice currentDevice = AndroidDeviceManager.getInstance().getCurrentDevice(deviceId); + if (null == currentDevice) { + return null; } + agentSession = new AndroidAgentSession(currentDevice, false); + agentSession.start(); + screenShotAgentSessionMap.put(deviceId, agentSession); + } else { + logger.debug("设备【{}】当前使用的截图的session还能用,继续使用。。。。。", deviceId); } } - if (null == currentDevice) { - logger.warn("设备【{}】不在线。。。。。",deviceId); - throw new ExecuteException("截图失败,当前设备不在线"); - } - logger.warn("设备【{}】没有androidAgent创建一个。。。。。",deviceId); - androidAgent = new AndroidAgent(adb, currentDevice); - screenShotAgentMap.put(deviceId, androidAgent); - } else { - logger.warn("设备【{}】已经存在androidAgent。。。。。",deviceId); + byte[] temData = agentSession.send(TakeScreenshotCommand.getInstance()); + return temData; } - byte[] screenShotData = androidAgent.takeScreenshot(); + }); + try { + screenShotData = submit.get(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + logger.debug("设备【{}】截图的时候被中断了。。。。。", deviceId); + return null; + } catch (ExecutionException e) { + logger.error("设备【{}】截图的时候报错了。。。。。", deviceId,e); + return null; + } catch (TimeoutException e) { + logger.debug("设备【{}】截图的时候超时了。。。。。", deviceId,e); + submit.cancel(true); + AndroidAgentSession agentSession = screenShotAgentSessionMap.remove(deviceId); + if (null != agentSession) { + agentSession.closeSilence(); + } + return null; + } + try { if (null != screenShotData && screenShotData.length > 0) { logger.debug("收到手机【{}】截图,大小:{}",deviceId,screenShotData.length); File tmpPicDir = new File(System.getProperty("user.dir")+"/tempPic");