From 56f4fe8953a411582109f4d85077ca0c7ac0effc Mon Sep 17 00:00:00 2001 From: ZhouYixun <291028775@qq.com> Date: Fri, 18 Nov 2022 00:15:19 +0800 Subject: [PATCH] fix: keyboard --- .../agent/automation/AndroidStepHandler.java | 99 +++++++++++++++++-- .../websockets/AndroidTerminalWSServer.java | 3 +- .../agent/websockets/AndroidWSServer.java | 11 ++- 3 files changed, 103 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java index dbc9a19b..479f4ee7 100755 --- a/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java +++ b/src/main/java/org/cloud/sonic/agent/automation/AndroidStepHandler.java @@ -68,6 +68,10 @@ import javax.imageio.stream.FileImageOutputStream; import java.io.File; import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.Future; @@ -90,6 +94,9 @@ public class AndroidStepHandler { private int pocoPort = 0; private int targetPort = 0; + private Thread keyboardThread = null; + private OutputStream keyboardOutputStream = null; + public LogUtil getLog() { return log; } @@ -157,6 +164,7 @@ public void switchWindowMode(HandleDes handleDes, boolean isMulti) throws SonicR */ public void closeAndroidDriver() { try { + stopKeyboard(); if (chromeDriver != null) { chromeDriver.quit(); } @@ -1610,13 +1618,92 @@ public void stepHold(HandleDes handleDes, int time) { public void sendKeyForce(HandleDes handleDes, String text) { text = TextHandler.replaceTrans(text, globalParams); - handleDes.setStepDes("键盘输入文本"); - handleDes.setDetail("键盘输入" + text); - try { - androidDriver.sendKeys(text); - } catch (SonicRespException e) { - handleDes.setE(e); + handleDes.setStepDes("Sonic输入法输入文本"); + handleDes.setDetail("输入" + text); + startKeyboard(); + if (keyboardOutputStream != null) { + try { + keyboardOutputStream.write(text.getBytes(StandardCharsets.UTF_8)); + keyboardOutputStream.flush(); + } catch (IOException e) { + handleDes.setE(e); + } + } + } + + public void startKeyboard() { + if (keyboardThread != null && keyboardThread.isAlive()) { + return; + } + AndroidDeviceBridgeTool.executeCommand(iDevice, "ime enable org.cloud.sonic.android/.keyboard.SonicKeyboard"); + AndroidDeviceBridgeTool.executeCommand(iDevice, "ime set org.cloud.sonic.android/.keyboard.SonicKeyboard"); + Thread keyboard = new Thread(() -> { + int socketPort = PortTool.getPort(); + AndroidDeviceBridgeTool.forward(iDevice, socketPort, 2335); + Socket keyboardSocket = null; + try { + keyboardSocket = new Socket("localhost", socketPort); + keyboardOutputStream = keyboardSocket.getOutputStream(); + while (keyboardSocket.isConnected() && !Thread.interrupted()) { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + break; + } + } + } catch (IOException e) { + } finally { + if (keyboardOutputStream != null) { + try { + keyboardOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (keyboardSocket != null) { + try { + keyboardSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + AndroidDeviceBridgeTool.removeForward(iDevice, socketPort, 2335); + keyboardOutputStream = null; + }); + keyboard.start(); + int w = 0; + while (keyboardOutputStream == null) { + if (w > 10) { + break; + } + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + w++; + } + keyboardThread = keyboard; + } + + private void stopKeyboard() { + if (keyboardThread != null) { + keyboardThread.interrupt(); + int wait = 0; + while (!keyboardThread.isInterrupted()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + wait++; + if (wait >= 3) { + break; + } + } } + keyboardThread = null; } private int holdTime = 0; diff --git a/src/main/java/org/cloud/sonic/agent/websockets/AndroidTerminalWSServer.java b/src/main/java/org/cloud/sonic/agent/websockets/AndroidTerminalWSServer.java index c917baea..f5139ce2 100755 --- a/src/main/java/org/cloud/sonic/agent/websockets/AndroidTerminalWSServer.java +++ b/src/main/java/org/cloud/sonic/agent/websockets/AndroidTerminalWSServer.java @@ -101,6 +101,7 @@ public void onOpen(Session session, @PathParam("key") String secretKey, if (!isInstall) { logger.info("等待安装超时!"); } + startService(udIdMap.get(session), session); } @OnMessage @@ -282,7 +283,7 @@ public void startService(IDevice iDevice, Session session) { return; } try { - Thread.sleep(2000); + Thread.sleep(2500); } catch (InterruptedException e) { log.info(e.getMessage()); } diff --git a/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java b/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java index 99eef73a..6b25df06 100755 --- a/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java +++ b/src/main/java/org/cloud/sonic/agent/websockets/AndroidWSServer.java @@ -150,9 +150,6 @@ true, new InstallReceiver(), 180L, 180L, TimeUnit.MINUTES .replaceAll("\t", ""); } AndroidDeviceBridgeTool.executeCommand(iDevice, "am start -n org.cloud.sonic.android/.SonicServiceActivity"); - AndroidDeviceBridgeTool.executeCommand(iDevice, "ime enable org.cloud.sonic.android/.keyboard.SonicKeyboard"); - AndroidDeviceBridgeTool.executeCommand(iDevice, "ime set org.cloud.sonic.android/.keyboard.SonicKeyboard"); - startKeyboard(iDevice,session); AndroidAPKMap.getMap().put(udId, true); if (AndroidDeviceBridgeTool.getOrientation(iDevice) != 0) { AndroidDeviceBridgeTool.pressKey(iDevice, 3); @@ -568,6 +565,9 @@ private void openDriver(IDevice iDevice, Session session) { } finally { result.put("msg", "openDriver"); BytesTool.sendText(session, result.toJSONString()); + AndroidDeviceBridgeTool.executeCommand(iDevice, "ime enable org.cloud.sonic.android/.keyboard.SonicKeyboard"); + AndroidDeviceBridgeTool.executeCommand(iDevice, "ime set org.cloud.sonic.android/.keyboard.SonicKeyboard"); + startKeyboard(iDevice, session); } }); } @@ -609,6 +609,11 @@ public void startKeyboard(IDevice iDevice, Session session) { if (keyboardThreadMap.get(session) != null && keyboardThreadMap.get(session).isAlive()) { return; } + try { + Thread.sleep(2500); + } catch (InterruptedException e) { + log.info(e.getMessage()); + } Thread keyboard = new Thread(() -> { int socketPort = PortTool.getPort(); AndroidDeviceBridgeTool.forward(iDevice, socketPort, 2335);