From 5d9cc9c3242fc741ac6c8a4c4ed3d44cfc4cbb1a Mon Sep 17 00:00:00 2001 From: rusefi Date: Sat, 4 Jul 2020 10:06:22 -0400 Subject: [PATCH] steps towards Android --- .../java/com/rusefi/io/LinkConnector.java | 3 ++ .../main/java/com/rusefi/io/LinkManager.java | 35 ++++++++++++++++--- .../java/com/rusefi/io/serial/PortHolder.java | 17 +++++---- .../com/rusefi/io/serial/SerialConnector.java | 17 ++++----- .../java/com/rusefi/io/tcp/TcpConnector.java | 2 +- .../src/main/java/com/rusefi/ConsoleUI.java | 4 +-- .../java/com/rusefi/ui/console/MainFrame.java | 17 +++++++++ .../io/TcpCommunicationIntegrationTest.java | 2 ++ 8 files changed, 75 insertions(+), 22 deletions(-) diff --git a/java_console/io/src/main/java/com/rusefi/io/LinkConnector.java b/java_console/io/src/main/java/com/rusefi/io/LinkConnector.java index c11fb4eea8..8ad2466b47 100644 --- a/java_console/io/src/main/java/com/rusefi/io/LinkConnector.java +++ b/java_console/io/src/main/java/com/rusefi/io/LinkConnector.java @@ -69,4 +69,7 @@ public interface LinkConnector extends LinkDecoder { default BinaryProtocolState getBinaryProtocolState() { return getBinaryProtocol().getBinaryProtocolState(); } + + default void stop() { + } } diff --git a/java_console/io/src/main/java/com/rusefi/io/LinkManager.java b/java_console/io/src/main/java/com/rusefi/io/LinkManager.java index ff56cc1375..f895d0e409 100644 --- a/java_console/io/src/main/java/com/rusefi/io/LinkManager.java +++ b/java_console/io/src/main/java/com/rusefi/io/LinkManager.java @@ -2,21 +2,27 @@ package com.rusefi.io; import com.fazecast.jSerialComm.SerialPort; import com.opensr5.Logger; +import com.rusefi.Callable; import com.rusefi.NamedThreadFactory; import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.binaryprotocol.BinaryProtocolState; import com.rusefi.core.EngineState; import com.rusefi.io.serial.SerialConnector; +import com.rusefi.io.serial.SerialIoStreamJSerialComm; import com.rusefi.io.tcp.TcpConnector; +import com.rusefi.io.tcp.TcpIoStream; import org.jetbrains.annotations.NotNull; +import java.net.Socket; import java.util.Arrays; import java.util.Objects; import java.util.concurrent.*; /** + * See TcpCommunicationIntegrationTest + * * @author Andrey Belomutskiy - * 3/3/14 + * 3/3/14 */ public class LinkManager { @NotNull @@ -127,6 +133,7 @@ public class LinkManager { public final LinkedBlockingQueue COMMUNICATION_QUEUE = new LinkedBlockingQueue<>(); /** * All request/responses to underlying controller are happening on this single-threaded executor in a FIFO manner + * * @see #TCP_READ_EXECUTOR */ public final ExecutorService COMMUNICATION_EXECUTOR = new ThreadPoolExecutor(1, 1, @@ -172,7 +179,7 @@ public class LinkManager { public void startAndConnect(String port, ConnectionStateListener stateListener) { Objects.requireNonNull(port, "port"); - start(port); + start(port, stateListener); connector.connectAndReadConfiguration(stateListener); } @@ -180,7 +187,7 @@ public class LinkManager { return connector; } - public void start(String port) { + public void start(String port, ConnectionStateListener stateListener) { if (isStarted) { throw new IllegalStateException("Already started"); } @@ -190,10 +197,24 @@ public class LinkManager { if (isLogViewerMode(port)) { connector = LinkConnector.VOID; } else if (TcpConnector.isTcpPort(port)) { - connector = new TcpConnector(this, port, logger); + connector = new SerialConnector(this, port, logger, new Callable() { + @Override + public IoStream call() { + Socket socket; + try { + int portPart = TcpConnector.getTcpPort(port); + String hostname = TcpConnector.getHostname(port); + socket = new Socket(hostname, portPart); + return new TcpIoStream(logger, LinkManager.this, socket); + } catch (Throwable e) { + stateListener.onConnectionFailed(); + return null; + } + } + }); isSimulationMode = true; } else { - connector = new SerialConnector(this, port, logger); + connector = new SerialConnector(this, port, logger, () -> SerialIoStreamJSerialComm.openPort(port, logger)); } } @@ -221,6 +242,10 @@ public class LinkManager { connector.restart(); } + public void stop() { + connector.stop(); + } + public static String unpackConfirmation(String message) { if (message.startsWith(CommandQueue.CONFIRMATION_PREFIX)) return message.substring(CommandQueue.CONFIRMATION_PREFIX.length()); diff --git a/java_console/io/src/main/java/com/rusefi/io/serial/PortHolder.java b/java_console/io/src/main/java/com/rusefi/io/serial/PortHolder.java index 14f4e96ea5..cd2e07fb44 100644 --- a/java_console/io/src/main/java/com/rusefi/io/serial/PortHolder.java +++ b/java_console/io/src/main/java/com/rusefi/io/serial/PortHolder.java @@ -1,6 +1,7 @@ package com.rusefi.io.serial; import com.opensr5.Logger; +import com.rusefi.Callable; import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.core.MessagesCentral; import com.rusefi.io.ConnectionStateListener; @@ -18,33 +19,39 @@ import java.awt.*; * 7/25/13 * Andrey Belomutskiy, (c) 2013-2020 */ -public abstract class PortHolder { +public class PortHolder { private final DataListener dataListener; private final Logger logger; + private final Callable streamFactory; private final LinkManager linkManager; public ConnectionStateListener listener; private final Object portLock = new Object(); private final String port; + private IoStream stream; @Nullable private BinaryProtocol bp; - protected PortHolder(String port, LinkManager linkManager, Logger logger) { + protected PortHolder(String port, LinkManager linkManager, Logger logger, Callable streamFactory) { this.port = port; this.linkManager = linkManager; dataListener = freshData -> linkManager.getEngineState().processNewData(new String(freshData), LinkManager.ENCODER); this.logger = logger; + this.streamFactory = streamFactory; } - boolean connectAndReadConfiguration() { if (port == null) return false; MessagesCentral.getInstance().postMessage(logger, getClass(), "Opening port: " + port); - IoStream stream = openStream(); + stream = streamFactory.call(); + if (stream == null) { + // error already reported + return false; + } synchronized (portLock) { bp = new BinaryProtocol(linkManager, logger, stream); portLock.notifyAll(); @@ -61,8 +68,6 @@ public abstract class PortHolder { return result; } - protected abstract IoStream openStream(); - public void close() { synchronized (portLock) { if (bp != null) { diff --git a/java_console/io/src/main/java/com/rusefi/io/serial/SerialConnector.java b/java_console/io/src/main/java/com/rusefi/io/serial/SerialConnector.java index 4add0db7b9..52fbe705a6 100644 --- a/java_console/io/src/main/java/com/rusefi/io/serial/SerialConnector.java +++ b/java_console/io/src/main/java/com/rusefi/io/serial/SerialConnector.java @@ -1,13 +1,13 @@ package com.rusefi.io.serial; import com.opensr5.Logger; +import com.rusefi.Callable; import com.rusefi.binaryprotocol.BinaryProtocol; import com.rusefi.core.MessagesCentral; import com.rusefi.io.ConnectionStateListener; import com.rusefi.io.IoStream; import com.rusefi.io.LinkConnector; import com.rusefi.io.LinkManager; -import org.jetbrains.annotations.NotNull; /** * @author Andrey Belomutskiy @@ -19,15 +19,11 @@ public class SerialConnector implements LinkConnector { private final Logger logger; private final LinkManager linkManager; - public SerialConnector(LinkManager linkManager, String serialPort, Logger logger) { + public SerialConnector(LinkManager linkManager, String portName, Logger logger, Callable streamFactory) { this.linkManager = linkManager; this.logger = logger; - portHolder = new PortHolder(serialPort, linkManager, logger) { - @NotNull - public IoStream openStream() { - return SerialIoStreamJSerialComm.openPort(serialPort, logger); - } - }; + + portHolder = new PortHolder(portName, linkManager, logger, streamFactory); } @Override @@ -49,6 +45,11 @@ public class SerialConnector implements LinkConnector { return portHolder.getBp(); } + @Override + public void stop() { + portHolder.close(); + } + @Override public void restart() { linkManager.execute(new Runnable() { diff --git a/java_console/io/src/main/java/com/rusefi/io/tcp/TcpConnector.java b/java_console/io/src/main/java/com/rusefi/io/tcp/TcpConnector.java index ffa81794af..e9056f693d 100644 --- a/java_console/io/src/main/java/com/rusefi/io/tcp/TcpConnector.java +++ b/java_console/io/src/main/java/com/rusefi/io/tcp/TcpConnector.java @@ -84,7 +84,7 @@ public class TcpConnector implements LinkConnector { } } - private static String getHostname(String port) { + public static String getHostname(String port) { String[] portParts = port.split(":"); return (portParts.length == 1 ? LOCALHOST : portParts[0].length() > 0 ? portParts[0] : LOCALHOST); } diff --git a/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java b/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java index b70539cfbe..59821a9c2f 100644 --- a/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java +++ b/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java @@ -29,7 +29,6 @@ import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; -import static com.rusefi.StartupFrame.createLogoLabel; import static com.rusefi.StartupFrame.setFrameIcon; import static com.rusefi.rusEFIVersion.CONSOLE_VERSION; import static com.rusefi.ui.storage.PersistentConfiguration.getConfig; @@ -75,7 +74,8 @@ public class ConsoleUI { getConfig().getRoot().setProperty(SPEED_KEY, BaudRateHolder.INSTANCE.baudRate); LinkManager linkManager = uiContext.getLinkManager(); - linkManager.start(port); + // todo: this blocking IO operation should NOT be happening on the UI thread + linkManager.start(port, mainFrame.listener); engineSnifferPanel = new EngineSnifferPanel(uiContext, getConfig().getRoot().getChild("digital_sniffer")); if (!LinkManager.isLogViewerMode(port)) diff --git a/java_console/ui/src/main/java/com/rusefi/ui/console/MainFrame.java b/java_console/ui/src/main/java/com/rusefi/ui/console/MainFrame.java index 0429fca8d2..7c42ecc378 100644 --- a/java_console/ui/src/main/java/com/rusefi/ui/console/MainFrame.java +++ b/java_console/ui/src/main/java/com/rusefi/ui/console/MainFrame.java @@ -42,10 +42,27 @@ public class MainFrame { } }; + public ConnectionStateListener listener; + public MainFrame(ConsoleUI consoleUI, TabbedPanel tabbedPane) { this.consoleUI = consoleUI; this.tabbedPane = tabbedPane; + listener = new ConnectionStateListener() { + @Override + public void onConnectionFailed() { + } + + @Override + public void onConnectionEstablished() { + FileLog.MAIN.logLine("onConnectionEstablished"); + // tabbedPane.romEditorPane.showContent(); + tabbedPane.settingsTab.showContent(); + tabbedPane.logsManager.showContent(); + tabbedPane.fuelTunePane.showContent(); + new BinaryProtocolServer(FileLog.LOGGER).start(consoleUI.uiContext.getLinkManager()); + } + }; } private void windowOpenedHandler() { diff --git a/java_console/ui/src/test/java/com/rusefi/io/TcpCommunicationIntegrationTest.java b/java_console/ui/src/test/java/com/rusefi/io/TcpCommunicationIntegrationTest.java index 0793bcb716..88c4c8b610 100644 --- a/java_console/ui/src/test/java/com/rusefi/io/TcpCommunicationIntegrationTest.java +++ b/java_console/ui/src/test/java/com/rusefi/io/TcpCommunicationIntegrationTest.java @@ -77,6 +77,8 @@ public class TcpCommunicationIntegrationTest { }); assertTrue(connectionEstablishedCountDownLatch.await(30, TimeUnit.SECONDS)); assertEquals(0, server.unknownCommands.get()); + + clientManager.stop(); } @NotNull